KiCad PCB EDA Suite
Loading...
Searching...
No Matches
board_constraint_adapter.h
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <https://www.gnu.org/licenses/>.
18 */
19
20#ifndef BOARD_CONSTRAINT_ADAPTER_H_
21#define BOARD_CONSTRAINT_ADAPTER_H_
22
23#include <deque>
24#include <functional>
25#include <map>
26#include <memory>
27#include <optional>
28#include <set>
29#include <unordered_set>
30#include <vector>
31
33#include <kiid.h>
34#include <math/vector2d.h>
35#include <snap/snap_resolver.h>
36
38
39class BOARD;
40class BOARD_ITEM;
43class PCB_SHAPE;
44
45// planegcs is an Eigen-heavy implementation detail; keep its header out of this one (PIMPL).
46namespace GCS
47{
48class System;
49}
50
51
56{
57 bool solved = false;
58 int freeDof = -1;
59 std::vector<KIID> conflicting;
60 std::vector<KIID> redundant;
61
62 bool IsWellConstrained() const { return solved && freeDof == 0; }
63 bool IsUnderConstrained() const { return freeDof > 0; }
64 bool IsOverConstrained() const { return !conflicting.empty(); }
65};
66
67
76
77
83{
84 int totalFreeDof = 0;
85 std::map<KIID, CONSTRAINT_STATE> shapeStates;
86 std::vector<KIID> conflicting;
87 std::vector<KIID> redundant;
88 std::vector<KIID> errored;
90};
91
92
107{
108public:
111
114
126 bool Build( const std::vector<PCB_SHAPE*>& aShapes, const std::vector<PCB_CONSTRAINT*>& aConstraints,
127 const std::set<KIID>* aFixedShapes = nullptr,
128 const std::vector<PCB_DIMENSION_BASE*>& aDimensions = {} );
129
133 const std::vector<KIID>& UnmappedConstraints() const { return m_unmapped; }
134
151 bool Solve( const CONSTRAINT_MEMBER& aDragged, const VECTOR2I& aCursor, bool aStabilize = false,
152 const std::set<KIID>& aEdited = {},
153 const std::optional<std::pair<CONSTRAINT_MEMBER, VECTOR2I>>& aCoDragged = std::nullopt,
154 bool aHoldDraggedRigid = false );
155 bool SolveSnapRelations( const CONSTRAINT_MEMBER& aDragged,
156 const std::vector<SNAP_CANDIDATE>& aCandidates,
157 const VECTOR2I& aCursor );
158 bool SolveRigidTranslation( const std::set<KIID>& aEditedShapes,
159 const VECTOR2I& aTranslation );
160 bool SolveRigidSnapRelations( const std::set<KIID>& aEditedShapes,
161 const VECTOR2I& aReference,
162 const std::vector<SNAP_CANDIDATE>& aCandidates,
163 const VECTOR2I& aCursor, VECTOR2I& aResolvedCursor );
164
166 bool Solve( bool aStabilize = false );
167
170 bool SolveAfterResize( const KIID& aResizedShape );
171
181 std::vector<PCB_SHAPE*> Apply( const std::function<void( BOARD_ITEM* )>& aBeforeWrite = {} );
182
191 void ApplyReferenceValues( const std::function<void( BOARD_ITEM* )>& aBeforeWrite = {} );
192
196 CONSTRAINT_DIAGNOSIS Diagnose();
197
199
200 SNAPSHOT Snapshot() const { return m_system.Snapshot(); }
201 bool Restore( const SNAPSHOT& aSnapshot ) { return m_system.RestorePrefix( aSnapshot ); }
202 std::optional<VECTOR2I> AnchorPosition( const CONSTRAINT_MEMBER& aMember ) const;
205
206private:
221
228 {
229 PCB_SHAPE* shape = nullptr;
232 int startX = -1;
233 int endX = -1;
234 int radius = -1;
235 int focusX = -1;
236 int arcStartX = -1;
237 int arcEndX = -1;
238 int startAngle = -1;
239 int endAngle = -1;
241
243 int vertexCount = 0;
244
247 bool startIsLeft = true;
248 bool startIsTop = true;
249 };
250
254 {
255 int x = -1;
256 int y = -1;
257
258 bool IsValid() const { return x >= 0 && y >= 0; }
259 };
260
262 {
265 };
266
268 {
269 std::set<int> points;
270 std::vector<RIGID_RADIUS_HOLD> radii;
271 };
272
274 int pushParam( double aValue );
275 int temporaryParam( double aValue );
277 bool addSnapRelations( const ANCHOR_PARAMS& aAnchor,
278 const std::vector<SNAP_CANDIDATE>& aCandidates,
279 const VECTOR2I& aOffset );
280 RIGID_STATE collectRigidState( const std::set<KIID>& aEditedShapes ) const;
281 void holdRigidRadii( const std::vector<RIGID_RADIUS_HOLD>& aRadii, int aTag );
282
285 void recordReferenceValue( PCB_CONSTRAINT* aConstraint );
286
289 void holdFreeSegmentLengths( int aTag, const std::set<KIID>& aShapes );
290
293 void holdFreeArcRadii( int aTag, const std::set<KIID>& aShapes );
294
297 void holdShapesRigid( int aTag, const std::set<KIID>& aShapes );
298
300 void holdArcRadius( const SHAPE_VARS& aVars, int aTag );
301
304 void softPinPoint( const ANCHOR_PARAMS& aPoint, int aTag, std::optional<double> aWeight = std::nullopt );
305
307 void softPinPoint( int aPointX, int aTag, std::optional<double> aWeight = std::nullopt );
308
311 void holdPolygonVertices( const std::set<KIID>& aShapes, int aTag );
312
315 void pinDraggedShapeRest( const CONSTRAINT_MEMBER& aDragged, int aTag,
316 const CONSTRAINT_MEMBER* aCoDragged = nullptr );
317
320 void pinUneditedShapes( const std::set<KIID>& aEdited, int aTag );
321
324 bool solveSucceeded( int aSolveResult );
325 bool hardRelationsSatisfied() const;
326
329 ANCHOR_PARAMS anchorParams( const CONSTRAINT_MEMBER& aMember ) const;
330
333 PCB_DIM_ORTHOGONAL* orthogonalDimensionForMembers( const std::vector<CONSTRAINT_MEMBER>& aMembers ) const;
334
336 double normalizeX( int aIU ) const { return m_system.NormalizeX( aIU ); }
337 double normalizeY( int aIU ) const { return m_system.NormalizeY( aIU ); }
338 double denormalizeX( double aNorm ) const { return m_system.DenormalizeX( aNorm ); }
339 double denormalizeY( double aNorm ) const { return m_system.DenormalizeY( aNorm ); }
340
342 GCS::System* m_gcs;
343
344 // Compatibility alias while board geometry mapping remains in this adapter.
345 std::deque<double>& m_params;
346
347 std::map<KIID, SHAPE_VARS> m_shapeVars;
348 std::map<int, KIID> m_tagToConstraint;
349 std::set<int> m_nonDrivingTags;
350 std::map<int, std::vector<KIID>> m_tagMembers;
351 std::vector<PCB_CONSTRAINT*> m_referenceConstraints;
352 std::vector<KIID> m_unmapped;
353
357
358 double m_scale = 1.0;
359 double m_invScale = 1.0;
360
361 int m_dragTargetX = -1;
362 int m_dragTargetY = -1;
365 std::vector<int> m_temporaryParams;
367
368 // Hold tags reserved by Build() just past the mapped constraints' tags, so a hold can never
369 // collide with (and clear) a real constraint on a large cluster.
372
373 bool m_built = false;
374};
375
376
386{
387public:
388 bool HasBaseConflict() const { return m_baseConflict; }
389
390protected:
397 bool buildCluster( BOARD* aBoard, const std::unordered_set<KIID>& aClusterShapes,
398 const std::vector<PCB_CONSTRAINT*>& aConstraints );
399
401 void reset();
402
403 bool usable() const { return m_adapter && !m_baseConflict; }
404
406 bool rewind() { return m_adapter && m_adapter->Restore( m_baseline ); }
407
409 SNAP_RESULT startResult( const SNAP_SOURCE_CONTEXT& aContext ) const;
410
418 static void accept( SNAP_RESULT& aResult, const SNAP_CANDIDATE& aCandidate, double aResidual );
419
420 BOARD* m_board = nullptr;
421 std::unique_ptr<BOARD_CONSTRAINT_ADAPTER> m_adapter;
423 bool m_baseConflict = false;
424};
425
426
428{
429public:
430 bool Build( BOARD* aBoard, const CONSTRAINT_MEMBER& aDragged );
431 bool Matches( const CONSTRAINT_MEMBER& aDragged ) const;
432 bool IsExactFeasible( const VECTOR2I& aTarget );
434 const std::vector<SNAP_CANDIDATE>& aCandidates );
435
437 Solve( const VECTOR2I& aCursor, std::vector<PCB_SHAPE*>* aModified,
438 const std::function<void( BOARD_ITEM* )>& aBeforeModify, bool aIncludeDragged,
439 bool aStabilize, const std::set<KIID>& aEdited = {},
440 const std::optional<std::pair<CONSTRAINT_MEMBER, VECTOR2I>>& aCoDragged = std::nullopt );
441
442private:
445};
446
447
449{
450public:
451 bool Build( BOARD* aBoard, const std::vector<PCB_SHAPE*>& aEditedShapes,
452 const VECTOR2I& aReference );
454 const std::vector<SNAP_CANDIDATE>& aCandidates );
455 bool Solve( const VECTOR2I& aTarget, std::vector<PCB_SHAPE*>* aModified,
456 const std::function<void( BOARD_ITEM* )>& aBeforeModify );
457
458private:
459 bool feasibleAt( const VECTOR2I& aTarget );
460
462 std::set<KIID> m_edited;
463};
464
465
494SolveCluster( BOARD* aBoard, const CONSTRAINT_MEMBER& aDragged, const VECTOR2I& aCursor,
495 std::vector<PCB_SHAPE*>* aModified = nullptr,
496 const std::function<void( BOARD_ITEM* )>& aBeforeModify = {}, bool aIncludeDragged = false,
497 bool aStabilize = false, const std::set<KIID>& aEdited = {},
498 const std::optional<std::pair<CONSTRAINT_MEMBER, VECTOR2I>>& aCoDragged = std::nullopt,
499 const std::set<KIID>& aFixedShapes = {}, bool aHoldDraggedRigid = false );
500
501
515std::set<KIID> ConstraintReferenceShapes( BOARD* aBoard, const PCB_CONSTRAINT* aConstraint );
516
517
530 std::vector<PCB_SHAPE*>* aModified = nullptr,
531 const std::function<void( BOARD_ITEM* )>& aBeforeModify = {},
532 const std::set<KIID>& aFixedShapes = {} );
533
534
537bool BoardHasConstraints( BOARD* aBoard );
538
539
544bool ConstraintItemIsLocked( const BOARD_ITEM* aItem );
545
546
549void ReSolveShapeClusters( BOARD* aBoard, const std::vector<PCB_SHAPE*>& aShapes,
550 std::vector<PCB_SHAPE*>* aModified = nullptr,
551 const std::function<void( BOARD_ITEM* )>& aBeforeModify = {} );
552
553
556bool ReSolveShapeClustersHoldingEdited( BOARD* aBoard, const std::vector<PCB_SHAPE*>& aEditedShapes,
557 std::vector<PCB_SHAPE*>* aModified = nullptr,
558 const std::function<void( BOARD_ITEM* )>& aBeforeModify = {} );
559
560
562void ReSolveAfterShapeResize( BOARD* aBoard, PCB_SHAPE* aShape, std::vector<PCB_SHAPE*>* aModified = nullptr,
563 const std::function<void( BOARD_ITEM* )>& aBeforeModify = {} );
564
565
572
573
579{
581 std::vector<KIID> shapeIds;
582 std::vector<KIID> dimensionIds;
583 int freeDof = 0;
584 std::vector<KIID> conflicting;
585 std::vector<KIID> redundant;
586 std::vector<KIID> erroredUnmapped;
587};
588
589
597{
598public:
601
603 void Clear();
604
606 std::size_t SolveCount() const { return m_solveCount; }
607
608private:
610 {
611 std::size_t hash = 0;
613 };
614
615 // Keyed by the cluster sorted constraint-id set which is stable across a geometry or value
616 // edit and changes only when a constraint is added to or removed from the cluster
617 std::map<std::vector<KIID>, CACHE_ENTRY> m_cache;
618 std::size_t m_solveCount = 0;
619};
620
621#endif // BOARD_CONSTRAINT_ADAPTER_H_
std::set< KIID > ConstraintReferenceShapes(BOARD *aBoard, const PCB_CONSTRAINT *aConstraint)
The shapes a just-authored constraint should treat as an immovable reference, for the caller to pass ...
CONSTRAINT_STATE
The constraint state of a shape, for the diagnostics overlay tint.
@ UNCONSTRAINED
Not referenced by any constraint.
@ OVER_CONSTRAINED
In a cluster the solver reports as conflicting.
@ UNDER_CONSTRAINED
In a cluster with remaining free degrees of freedom.
@ WELL_CONSTRAINED
In a fully-determined cluster (zero free DOF).
bool BoardHasConstraints(BOARD *aBoard)
True if the board or any of its footprints carries at least one geometric constraint.
bool ReSolveShapeClustersHoldingEdited(BOARD *aBoard, const std::vector< PCB_SHAPE * > &aEditedShapes, std::vector< PCB_SHAPE * > *aModified=nullptr, const std::function< void(BOARD_ITEM *)> &aBeforeModify={})
Re-solve clusters whose new geometry is authoritative holding every edited shape fully fixed so only ...
bool ConstraintItemIsLocked(const BOARD_ITEM *aItem)
True when the solver must treat aItem as immovable, either locked itself or living inside a locked fo...
void ReSolveShapeClusters(BOARD *aBoard, const std::vector< PCB_SHAPE * > &aShapes, std::vector< PCB_SHAPE * > *aModified=nullptr, const std::function< void(BOARD_ITEM *)> &aBeforeModify={})
Re-solve the clusters of shapes edited outside the solver, e.g.
BOARD_CONSTRAINT_DIAGNOSTICS DiagnoseBoardConstraints(BOARD *aBoard)
Diagnose every constraint cluster on the board (validate only – geometry is not changed) and return t...
CONSTRAINT_DIAGNOSIS ApplyConstraintImmediately(BOARD *aBoard, const PCB_CONSTRAINT *aConstraint, std::vector< PCB_SHAPE * > *aModified=nullptr, const std::function< void(BOARD_ITEM *)> &aBeforeModify={}, const std::set< KIID > &aFixedShapes={})
Solve a just-created constraint's cluster so the geometry snaps to satisfy it (SolidWorks-style),...
void ReSolveAfterShapeResize(BOARD *aBoard, PCB_SHAPE *aShape, std::vector< PCB_SHAPE * > *aModified=nullptr, const std::function< void(BOARD_ITEM *)> &aBeforeModify={})
Re-solve after a resize, e.g. a circle radius edit. Holds aShape fixed so its neighbors adjust.
CONSTRAINT_DIAGNOSIS SolveCluster(BOARD *aBoard, const CONSTRAINT_MEMBER &aDragged, const VECTOR2I &aCursor, std::vector< PCB_SHAPE * > *aModified=nullptr, const std::function< void(BOARD_ITEM *)> &aBeforeModify={}, bool aIncludeDragged=false, bool aStabilize=false, const std::set< KIID > &aEdited={}, const std::optional< std::pair< CONSTRAINT_MEMBER, VECTOR2I > > &aCoDragged=std::nullopt, const std::set< KIID > &aFixedShapes={}, bool aHoldDraggedRigid=false)
Gather the cluster of shapes transitively constrained with the dragged shape, solve with the dragged ...
void recordReferenceValue(PCB_CONSTRAINT *aConstraint)
Note a non-driving valued constraint so its measured value can be read back after a solve.
void holdShapesRigid(int aTag, const std::set< KIID > &aShapes)
Hold the shapes in aShapes rigid, tagged aTag, so a shape the solve moves translates instead of stret...
BOARD_CONSTRAINT_ADAPTER(const BOARD_CONSTRAINT_ADAPTER &)=delete
BOARD_CONSTRAINT_ADAPTER & operator=(const BOARD_CONSTRAINT_ADAPTER &)=delete
int m_coDragTargetY
Backing slot for the co-dragged pin y target.
PCB_DIM_ORTHOGONAL * orthogonalDimensionForMembers(const std::vector< CONSTRAINT_MEMBER > &aMembers) const
The orthogonal dimension a two-point length constraint drives or nullptr requires both members to be ...
std::vector< KIID > m_unmapped
Constraints Build() could not map (not enforced).
double denormalizeX(double aNorm) const
void softPinPoint(const ANCHOR_PARAMS &aPoint, int aTag, std::optional< double > aWeight=std::nullopt)
Pin the point at aPoint where it sits tagged aTag with aWeight rescaling the tier or the default weig...
bool addSnapRelations(const ANCHOR_PARAMS &aAnchor, const std::vector< SNAP_CANDIDATE > &aCandidates, const VECTOR2I &aOffset)
void pinUneditedShapes(const std::set< KIID > &aEdited, int aTag)
Soft-pin every cluster shape not in aEdited at its current geometry tagged aTag for a minimal-movemen...
bool Solve(const CONSTRAINT_MEMBER &aDragged, const VECTOR2I &aCursor, bool aStabilize=false, const std::set< KIID > &aEdited={}, const std::optional< std::pair< CONSTRAINT_MEMBER, VECTOR2I > > &aCoDragged=std::nullopt, bool aHoldDraggedRigid=false)
Solve the system, pinning a dragged anchor to a cursor position.
RIGID_STATE collectRigidState(const std::set< KIID > &aEditedShapes) const
int m_dragTargetX
Stable backing slot for the drag pin's x target (-1 = unset).
void holdFreeSegmentLengths(int aTag, const std::set< KIID > &aShapes)
Length hold on the free segments in aShapes tagged aTag so only those shapes are protected while a me...
std::vector< PCB_CONSTRAINT * > m_referenceConstraints
Non-driving valued, read back after a solve.
bool solveSucceeded(int aSolveResult)
Decide whether a solve reached a usable result a raw Success or Converged always qualifies while a Fa...
void holdRigidRadii(const std::vector< RIGID_RADIUS_HOLD > &aRadii, int aTag)
const std::vector< KIID > & UnmappedConstraints() const
Constraints from the last Build() that could not be mapped onto a solver primitive (wrong member coun...
ANCHOR_PARAMS anchorParams(const CONSTRAINT_MEMBER &aMember) const
Indices into m_params of the coordinates an anchor maps to invalid if the shape has no such anchor fo...
std::map< KIID, SHAPE_VARS > m_shapeVars
bool SolveAfterResize(const KIID &aResizedShape)
Solve after a resize.
int m_coDragTargetX
Backing slot for the co-dragged pin x target.
CONSTRAINT_SYSTEM_2D::SNAPSHOT SNAPSHOT
double denormalizeY(double aNorm) const
void pinDraggedShapeRest(const CONSTRAINT_MEMBER &aDragged, int aTag, const CONSTRAINT_MEMBER *aCoDragged=nullptr)
Hold the parts of the dragged shape meant to stay put tagged aTag a segment holds its far endpoint an...
std::map< int, std::vector< KIID > > m_tagMembers
Member items per tag, for collapse attribution.
int m_dragTargetY
Stable backing slot for the drag pin's y target.
double m_scale
IU per normalized unit.
std::optional< VECTOR2I > AnchorPosition(const CONSTRAINT_MEMBER &aMember) const
bool Restore(const SNAPSHOT &aSnapshot)
bool SolveRigidTranslation(const std::set< KIID > &aEditedShapes, const VECTOR2I &aTranslation)
std::map< int, KIID > m_tagToConstraint
std::set< KIID > m_angleConstrainedShapes
Shapes a direction or angle constraint could collapse to a point only these get a stabilize length or...
void holdFreeArcRadii(int aTag, const std::set< KIID > &aShapes)
Radius hold on the free arcs in aShapes tagged aTag so an angle change rotates an endpoint instead of...
bool SolveRigidSnapRelations(const std::set< KIID > &aEditedShapes, const VECTOR2I &aReference, const std::vector< SNAP_CANDIDATE > &aCandidates, const VECTOR2I &aCursor, VECTOR2I &aResolvedCursor)
bool Build(const std::vector< PCB_SHAPE * > &aShapes, const std::vector< PCB_CONSTRAINT * > &aConstraints, const std::set< KIID > *aFixedShapes=nullptr, const std::vector< PCB_DIMENSION_BASE * > &aDimensions={})
Translate a cluster into a planegcs system.
void holdPolygonVertices(const std::set< KIID > &aShapes, int aTag)
Soft-pin every vertex of each POLYGON in aShapes tagged aTag for edited shapes pinUneditedShapes excl...
std::vector< PCB_SHAPE * > Apply(const std::function< void(BOARD_ITEM *)> &aBeforeWrite={})
Write the solved coordinates back into the shapes, de-normalized to IU.
int pushParam(double aValue)
Append a normalized coordinate to the backing store, returning its stable index.
CONSTRAINT_DIAGNOSIS Diagnose()
Report degrees of freedom and conflicting/redundant constraints.
std::set< int > m_nonDrivingTags
Measurement-only; excluded from conflict residuals.
double normalizeX(int aIU) const
IU <-> normalized (millimetre, cluster-centred) frame, per axis.
@ RECT
An axis-aligned rectangle whose four corners alias the two stored corners params so rectness holds by...
@ POINT_PAIR
A dimension's two feature points (start + end); no line/curve geometry.
@ POLYGON
A single hole-free outline with one free param pair per vertex since write-back rebuilds one outline ...
@ BEZIER
A cubic bezier only its start and end endpoints are exposed as free points.
bool SolveSnapRelations(const CONSTRAINT_MEMBER &aDragged, const std::vector< SNAP_CANDIDATE > &aCandidates, const VECTOR2I &aCursor)
void ApplyReferenceValues(const std::function< void(BOARD_ITEM *)> &aBeforeWrite={})
Propagate solved reference (non-driving) constraint values back into their m_value so a reference dim...
void holdArcRadius(const SHAPE_VARS &aVars, int aTag)
Hold aVars's arc at its current radius (tagged aTag).
An incremental DiagnoseBoardConstraints for the interactive edit path.
std::size_t SolveCount() const
Clusters actually re-solved across this diagnoser lifetime for testing cache isolation.
BOARD_CONSTRAINT_DIAGNOSTICS Diagnose(BOARD *aBoard)
Diagnose every cluster reusing cached per-cluster results whose solve inputs are unchanged.
std::map< std::vector< KIID >, CACHE_ENTRY > m_cache
void Clear()
Drop the cache call when the board or view reloads and item-identity assumptions break.
bool IsExactFeasible(const VECTOR2I &aTarget)
bool Build(BOARD *aBoard, const CONSTRAINT_MEMBER &aDragged)
CONSTRAINT_DIAGNOSIS Solve(const VECTOR2I &aCursor, std::vector< PCB_SHAPE * > *aModified, const std::function< void(BOARD_ITEM *)> &aBeforeModify, bool aIncludeDragged, bool aStabilize, const std::set< KIID > &aEdited={}, const std::optional< std::pair< CONSTRAINT_MEMBER, VECTOR2I > > &aCoDragged=std::nullopt)
SNAP_RESULT ResolveCandidates(const SNAP_SOURCE_CONTEXT &aContext, const std::vector< SNAP_CANDIDATE > &aCandidates)
bool Matches(const CONSTRAINT_MEMBER &aDragged) const
bool feasibleAt(const VECTOR2I &aTarget)
bool Solve(const VECTOR2I &aTarget, std::vector< PCB_SHAPE * > *aModified, const std::function< void(BOARD_ITEM *)> &aBeforeModify)
bool Build(BOARD *aBoard, const std::vector< PCB_SHAPE * > &aEditedShapes, const VECTOR2I &aReference)
SNAP_RESULT ResolveCandidates(const SNAP_SOURCE_CONTEXT &aContext, const std::vector< SNAP_CANDIDATE > &aCandidates)
One editing session over a constraint cluster.
BOARD_CONSTRAINT_ADAPTER::SNAPSHOT m_baseline
bool rewind()
Rewind to the state the next speculative solve starts from.
SNAP_RESULT startResult(const SNAP_SOURCE_CONTEXT &aContext) const
Seed a snap result at the cursor, rejecting a cluster that was already broken.
void reset()
Drop the built cluster, leaving the session unusable until the next successful build.
bool buildCluster(BOARD *aBoard, const std::unordered_set< KIID > &aClusterShapes, const std::vector< PCB_CONSTRAINT * > &aConstraints)
Assemble the adapter for one cluster and record its baseline.
std::unique_ptr< BOARD_CONSTRAINT_ADAPTER > m_adapter
static void accept(SNAP_RESULT &aResult, const SNAP_CANDIDATE &aCandidate, double aResidual)
Record one candidate the session honoured.
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition board_item.h:83
Information pertinent to a Pcbnew printed circuit board.
Definition board.h:373
std::vector< double > SNAPSHOT
A geometric constraint between board items (issue #2329).
Abstract dimension API.
An orthogonal dimension is like an aligned dimension, but the extension lines are locked to the X or ...
Param indices of an anchor coordinates a rect corner aliases mixed start end params so y is not alway...
int radius
radius scalar (circle, arc) / minor radius (ellipse).
bool startIsLeft
Rect corner roles frozen at Build so VERTEX 0 to 3 as TL TR BR BL bind the same physical corners what...
int fixedLengthParam
param index of a driving fixed-length target, or -1.
int focusX
first focus.x (ellipse kinds only).
int startX
start.x (segment) / center.x (circle, arc, ellipse).
PCB_DIMENSION_BASE * dimension
set instead of shape for a POINT_PAIR
int vertexCount
Outline-0 vertex count of a POLYGON vertex i x param is startX plus 2 times i.
CLUSTER_DIAGNOSIS result
std::size_t hash
Board-wide diagnostics for the constraint overlay and info bar.
std::map< KIID, CONSTRAINT_STATE > shapeStates
std::vector< KIID > errored
Invalid constraints (member missing, deleted, or of a kind incompatible with the type).
One cluster's diagnosis, the unit DiagnoseBoardConstraints assembles the board-wide result from and B...
int freeDof
Remaining free DOF folded into the board total.
std::vector< KIID > dimensionIds
Cluster dimensions.
std::vector< KIID > conflicting
std::vector< KIID > erroredUnmapped
Constraints Build could not map and so not enforced.
std::vector< KIID > shapeIds
Cluster shapes in the order the state is written.
std::vector< KIID > redundant
The outcome of a constraint solve, in plain data so callers need not know planegcs.
bool solved
Solver reached Success or Converged.
std::vector< KIID > conflicting
Constraints the solver reports as over-constraining.
std::vector< KIID > redundant
Constraints the solver reports as redundant.
int freeDof
Remaining degrees of freedom (-1 if not diagnosed).
One participant in a constraint: a referenced board item plus the feature of that item that participa...
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:683