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
162 bool TravelsWhole( const std::set<KIID>& aEditedShapes ) const;
163 bool SolveRigidSnapRelations( const std::set<KIID>& aEditedShapes,
164 const VECTOR2I& aReference,
165 const std::vector<SNAP_CANDIDATE>& aCandidates,
166 const VECTOR2I& aCursor, VECTOR2I& aResolvedCursor );
167
169 bool Solve( bool aStabilize = false );
170
173 bool SolveAfterResize( const KIID& aResizedShape );
174
184 std::vector<PCB_SHAPE*> Apply( const std::function<void( BOARD_ITEM* )>& aBeforeWrite = {} );
185
194 void ApplyReferenceValues( const std::function<void( BOARD_ITEM* )>& aBeforeWrite = {} );
195
199 CONSTRAINT_DIAGNOSIS Diagnose();
200
202
203 SNAPSHOT Snapshot() const { return m_system.Snapshot(); }
204 bool Restore( const SNAPSHOT& aSnapshot ) { return m_system.RestorePrefix( aSnapshot ); }
205 std::optional<VECTOR2I> AnchorPosition( const CONSTRAINT_MEMBER& aMember ) const;
208
209private:
224
231 {
232 PCB_SHAPE* shape = nullptr;
235 int startX = -1;
236 int endX = -1;
237 int radius = -1;
238 int focusX = -1;
239 int arcStartX = -1;
240 int arcEndX = -1;
241 int startAngle = -1;
242 int endAngle = -1;
244
246 int vertexCount = 0;
247
250 bool startIsLeft = true;
251 bool startIsTop = true;
252 };
253
257 {
258 int x = -1;
259 int y = -1;
260
261 bool IsValid() const { return x >= 0 && y >= 0; }
262 };
263
265 {
268 };
269
271 {
272 std::set<int> points;
273 std::vector<RIGID_RADIUS_HOLD> radii;
274 };
275
277 int pushParam( double aValue );
278 int temporaryParam( double aValue );
280 bool addSnapRelations( const ANCHOR_PARAMS& aAnchor,
281 const std::vector<SNAP_CANDIDATE>& aCandidates,
282 const VECTOR2I& aOffset );
283 RIGID_STATE collectRigidState( const std::set<KIID>& aEditedShapes ) const;
284 void holdRigidRadii( const std::vector<RIGID_RADIUS_HOLD>& aRadii, int aTag );
285
288 void recordReferenceValue( PCB_CONSTRAINT* aConstraint );
289
292 void holdFreeSegmentLengths( int aTag, const std::set<KIID>& aShapes );
293
296 void holdFreeArcRadii( int aTag, const std::set<KIID>& aShapes );
297
300 void holdShapesRigid( int aTag, const std::set<KIID>& aShapes );
301
303 void holdArcRadius( const SHAPE_VARS& aVars, int aTag );
304
307 void softPinPoint( const ANCHOR_PARAMS& aPoint, int aTag, std::optional<double> aWeight = std::nullopt );
308
310 void softPinPoint( int aPointX, int aTag, std::optional<double> aWeight = std::nullopt );
311
314 void holdPolygonVertices( const std::set<KIID>& aShapes, int aTag );
315
318 void pinDraggedShapeRest( const CONSTRAINT_MEMBER& aDragged, int aTag,
319 const CONSTRAINT_MEMBER* aCoDragged = nullptr );
320
323 void pinUneditedShapes( const std::set<KIID>& aEdited, int aTag );
324
327 bool solveSucceeded( int aSolveResult );
328 bool hardRelationsSatisfied() const;
329
332 ANCHOR_PARAMS anchorParams( const CONSTRAINT_MEMBER& aMember ) const;
333
336 PCB_DIM_ORTHOGONAL* orthogonalDimensionForMembers( const std::vector<CONSTRAINT_MEMBER>& aMembers ) const;
337
339 double normalizeX( int aIU ) const { return m_system.NormalizeX( aIU ); }
340 double normalizeY( int aIU ) const { return m_system.NormalizeY( aIU ); }
341 double denormalizeX( double aNorm ) const { return m_system.DenormalizeX( aNorm ); }
342 double denormalizeY( double aNorm ) const { return m_system.DenormalizeY( aNorm ); }
343
345 GCS::System* m_gcs;
346
347 // Compatibility alias while board geometry mapping remains in this adapter.
348 std::deque<double>& m_params;
349
350 std::map<KIID, SHAPE_VARS> m_shapeVars;
351
353 std::set<int> m_fixedParams;
354 std::map<int, KIID> m_tagToConstraint;
355 std::set<int> m_nonDrivingTags;
356 std::map<int, std::vector<KIID>> m_tagMembers;
357 std::vector<PCB_CONSTRAINT*> m_referenceConstraints;
358 std::vector<KIID> m_unmapped;
359
363
364 double m_scale = 1.0;
365 double m_invScale = 1.0;
366
367 int m_dragTargetX = -1;
368 int m_dragTargetY = -1;
371 std::vector<int> m_temporaryParams;
373
374 // Hold tags reserved by Build() just past the mapped constraints' tags, so a hold can never
375 // collide with (and clear) a real constraint on a large cluster.
378
379 bool m_built = false;
380};
381
382
392{
393public:
394 bool HasBaseConflict() const { return m_baseConflict; }
395
396protected:
403 bool buildCluster( BOARD* aBoard, const std::unordered_set<KIID>& aClusterShapes,
404 const std::vector<PCB_CONSTRAINT*>& aConstraints );
405
407 void reset();
408
409 bool usable() const { return m_adapter && !m_baseConflict; }
410
412 bool rewind() { return m_adapter && m_adapter->Restore( m_baseline ); }
413
415 SNAP_RESULT startResult( const SNAP_SOURCE_CONTEXT& aContext ) const;
416
424 static void accept( SNAP_RESULT& aResult, const SNAP_CANDIDATE& aCandidate, double aResidual );
425
426 BOARD* m_board = nullptr;
427 std::unique_ptr<BOARD_CONSTRAINT_ADAPTER> m_adapter;
429 bool m_baseConflict = false;
430};
431
432
434{
435public:
436 bool Build( BOARD* aBoard, const CONSTRAINT_MEMBER& aDragged );
437 bool Matches( const CONSTRAINT_MEMBER& aDragged ) const;
438 bool IsExactFeasible( const VECTOR2I& aTarget );
440 const std::vector<SNAP_CANDIDATE>& aCandidates );
441
443 Solve( const VECTOR2I& aCursor, std::vector<PCB_SHAPE*>* aModified,
444 const std::function<void( BOARD_ITEM* )>& aBeforeModify, bool aIncludeDragged,
445 bool aStabilize, const std::set<KIID>& aEdited = {},
446 const std::optional<std::pair<CONSTRAINT_MEMBER, VECTOR2I>>& aCoDragged = std::nullopt );
447
448private:
451};
452
453
455{
456public:
457 bool Build( BOARD* aBoard, const std::vector<PCB_SHAPE*>& aEditedShapes,
458 const VECTOR2I& aReference );
460 const std::vector<SNAP_CANDIDATE>& aCandidates );
461 bool Solve( const VECTOR2I& aTarget, std::vector<PCB_SHAPE*>* aModified,
462 const std::function<void( BOARD_ITEM* )>& aBeforeModify );
463
464private:
465 bool feasibleAt( const VECTOR2I& aTarget );
466
468 std::set<KIID> m_edited;
469};
470
471
501SolveCluster( BOARD* aBoard, const CONSTRAINT_MEMBER& aDragged, const VECTOR2I& aCursor,
502 std::vector<PCB_SHAPE*>* aModified = nullptr,
503 const std::function<void( BOARD_ITEM* )>& aBeforeModify = {}, bool aIncludeDragged = false,
504 bool aStabilize = false, const std::set<KIID>& aEdited = {},
505 const std::optional<std::pair<CONSTRAINT_MEMBER, VECTOR2I>>& aCoDragged = std::nullopt,
506 const std::set<KIID>& aFixedShapes = {}, bool aHoldDraggedRigid = false );
507
508
522std::set<KIID> ConstraintReferenceShapes( BOARD* aBoard, const PCB_CONSTRAINT* aConstraint );
523
524
539 std::vector<PCB_SHAPE*>* aModified = nullptr,
540 const std::function<void( BOARD_ITEM* )>& aBeforeModify = {},
541 const std::set<KIID>& aFixedShapes = {} );
542
543
546bool BoardHasConstraints( BOARD* aBoard );
547
548
553bool ConstraintItemIsLocked( const BOARD_ITEM* aItem );
554
555
558void ReSolveShapeClusters( BOARD* aBoard, const std::vector<PCB_SHAPE*>& aShapes,
559 std::vector<PCB_SHAPE*>* aModified = nullptr,
560 const std::function<void( BOARD_ITEM* )>& aBeforeModify = {} );
561
562
565bool ReSolveShapeClustersHoldingEdited( BOARD* aBoard, const std::vector<PCB_SHAPE*>& aEditedShapes,
566 std::vector<PCB_SHAPE*>* aModified = nullptr,
567 const std::function<void( BOARD_ITEM* )>& aBeforeModify = {} );
568
569
571void ReSolveAfterShapeResize( BOARD* aBoard, PCB_SHAPE* aShape, std::vector<PCB_SHAPE*>* aModified = nullptr,
572 const std::function<void( BOARD_ITEM* )>& aBeforeModify = {} );
573
574
581
582
588{
590 std::vector<KIID> shapeIds;
591 std::vector<KIID> dimensionIds;
592 int freeDof = 0;
593 std::vector<KIID> conflicting;
594 std::vector<KIID> redundant;
595 std::vector<KIID> erroredUnmapped;
596};
597
598
606{
607public:
610
612 void Clear();
613
615 std::size_t SolveCount() const { return m_solveCount; }
616
617private:
619 {
620 std::size_t hash = 0;
622 };
623
624 // Keyed by the cluster sorted constraint-id set which is stable across a geometry or value
625 // edit and changes only when a constraint is added to or removed from the cluster
626 std::map<std::vector<KIID>, CACHE_ENTRY> m_cache;
627 std::size_t m_solveCount = 0;
628};
629
630#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
std::set< int > m_fixedParams
Parameter indices the solver may not move, so a rigid translation may not either.
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.
bool TravelsWhole(const std::set< KIID > &aEditedShapes) const
True when every shape in the cluster is in aEditedShapes and free to travel with it.
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.
@ RECTANGLE
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:84
Information pertinent to a Pcbnew printed circuit board.
Definition board.h:410
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:708