KiCad PCB EDA Suite
Loading...
Searching...
No Matches
pcb_constraint.cpp
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
21
22#include <algorithm>
23
24#include <base_units.h>
25#include <bitmaps.h>
26#include <eda_units.h>
27#include <geometry/eda_angle.h>
29#include <i18n_utility.h>
30#include <pcb_shape.h>
31#include <properties/property.h>
33
34#include <api/api_enums.h>
35#include <api/board/board_types.pb.h>
36#include <google/protobuf/any.pb.h>
37
38
40{
41 switch( aType )
42 {
43 case PCB_CONSTRAINT_TYPE::COINCIDENT: return "coincident";
44 case PCB_CONSTRAINT_TYPE::HORIZONTAL: return "horizontal";
45 case PCB_CONSTRAINT_TYPE::VERTICAL: return "vertical";
46 case PCB_CONSTRAINT_TYPE::PARALLEL: return "parallel";
47 case PCB_CONSTRAINT_TYPE::PERPENDICULAR: return "perpendicular";
48 case PCB_CONSTRAINT_TYPE::COLLINEAR: return "collinear";
49 case PCB_CONSTRAINT_TYPE::SYMMETRIC: return "symmetric";
50 case PCB_CONSTRAINT_TYPE::EQUAL_LENGTH: return "equal_length";
51 case PCB_CONSTRAINT_TYPE::EQUAL_RADIUS: return "equal_radius";
52 case PCB_CONSTRAINT_TYPE::POINT_ON_LINE: return "point_on_line";
53 case PCB_CONSTRAINT_TYPE::MIDPOINT: return "midpoint";
54 case PCB_CONSTRAINT_TYPE::FIXED_POSITION: return "fixed_position";
55 case PCB_CONSTRAINT_TYPE::FIXED_LENGTH: return "fixed_length";
56 case PCB_CONSTRAINT_TYPE::CONCENTRIC: return "concentric";
57 case PCB_CONSTRAINT_TYPE::FIXED_RADIUS: return "fixed_radius";
58 case PCB_CONSTRAINT_TYPE::ANGULAR_DIMENSION: return "angular_dimension";
59 case PCB_CONSTRAINT_TYPE::TANGENT: return "tangent";
60 case PCB_CONSTRAINT_TYPE::ARC_ANGLE: return "arc_angle";
61 case PCB_CONSTRAINT_TYPE::UNDEFINED: return "undefined";
62 }
63
64 return "undefined";
65}
66
67
69{
70 for( int i = 0; i <= static_cast<int>( PCB_CONSTRAINT_TYPE::ARC_ANGLE ); ++i )
71 {
72 PCB_CONSTRAINT_TYPE type = static_cast<PCB_CONSTRAINT_TYPE>( i );
73
74 if( aToken == ConstraintTypeToken( type ) )
75 return type;
76 }
77
79}
80
81
83{
84 switch( aType )
85 {
88 return true;
89 default:
90 return false; // the angular types are angles; everything else is valueless
91 }
92}
93
94
96{
97 switch( aAnchor )
98 {
99 case CONSTRAINT_ANCHOR::WHOLE: return "whole";
100 case CONSTRAINT_ANCHOR::START: return "start";
101 case CONSTRAINT_ANCHOR::END: return "end";
102 case CONSTRAINT_ANCHOR::MID: return "mid";
103 case CONSTRAINT_ANCHOR::CENTER: return "center";
104 case CONSTRAINT_ANCHOR::RADIUS: return "radius";
105 case CONSTRAINT_ANCHOR::VERTEX: return "vertex";
106 }
107
108 return "whole";
109}
110
111
113{
114 for( int i = 0; i <= static_cast<int>( CONSTRAINT_ANCHOR::VERTEX ); ++i )
115 {
116 CONSTRAINT_ANCHOR anchor = static_cast<CONSTRAINT_ANCHOR>( i );
117
118 if( aToken == ConstraintAnchorToken( anchor ) )
119 return anchor;
120 }
121
123}
124
125
127{
128 // Single-codepoint marks carried by both the newstroke stroke font and the OpenGL glyph atlas
129 // so every GAL backend renders them without a missing-glyph box.
130 switch( aType )
131 {
132 case PCB_CONSTRAINT_TYPE::COINCIDENT: return wxT( "●" );
133 case PCB_CONSTRAINT_TYPE::HORIZONTAL: return wxT( "↔" );
134 case PCB_CONSTRAINT_TYPE::VERTICAL: return wxT( "↕" );
135 case PCB_CONSTRAINT_TYPE::PARALLEL: return wxT( "∥" );
136 case PCB_CONSTRAINT_TYPE::PERPENDICULAR: return wxT( "⊥" );
137 case PCB_CONSTRAINT_TYPE::COLLINEAR: return wxT( "─" );
138 case PCB_CONSTRAINT_TYPE::SYMMETRIC: return wxT( "⧓" );
139 case PCB_CONSTRAINT_TYPE::EQUAL_LENGTH: return wxT( "=" );
140 case PCB_CONSTRAINT_TYPE::EQUAL_RADIUS: return wxT( "⊜" );
141 case PCB_CONSTRAINT_TYPE::POINT_ON_LINE: return wxT( "∈" );
142 case PCB_CONSTRAINT_TYPE::MIDPOINT: return wxT( "½" );
143 case PCB_CONSTRAINT_TYPE::FIXED_POSITION: return wxT( "⌖" );
144 case PCB_CONSTRAINT_TYPE::FIXED_LENGTH: return wxT( "⟷" );
145 case PCB_CONSTRAINT_TYPE::CONCENTRIC: return wxT( "◎" );
146 case PCB_CONSTRAINT_TYPE::FIXED_RADIUS: return wxT( "r" );
147 case PCB_CONSTRAINT_TYPE::ANGULAR_DIMENSION: return wxT( "∠" );
148 case PCB_CONSTRAINT_TYPE::TANGENT: return wxT( "T" );
149 case PCB_CONSTRAINT_TYPE::ARC_ANGLE: return wxT( "α" );
150 case PCB_CONSTRAINT_TYPE::UNDEFINED: return wxEmptyString;
151 }
152
153 return wxEmptyString;
154}
155
156
158{
159 switch( aType )
160 {
180 }
181
183}
184
185
187{
188 switch( aAnchor )
189 {
190 case CONSTRAINT_ANCHOR::WHOLE: return wxEmptyString;
191 case CONSTRAINT_ANCHOR::START: return _( "start" );
192 case CONSTRAINT_ANCHOR::END: return _( "end" );
193 case CONSTRAINT_ANCHOR::MID: return _( "mid" );
194 case CONSTRAINT_ANCHOR::CENTER: return _( "center" );
195 case CONSTRAINT_ANCHOR::RADIUS: return _( "radius" );
196 case CONSTRAINT_ANCHOR::VERTEX: return _( "vertex" );
197 }
198
199 return wxEmptyString;
200}
201
202
204{
205 switch( aType )
206 {
207 case PCB_CONSTRAINT_TYPE::COINCIDENT: return _( "Coincident" );
208 case PCB_CONSTRAINT_TYPE::HORIZONTAL: return _( "Horizontal" );
209 case PCB_CONSTRAINT_TYPE::VERTICAL: return _( "Vertical" );
210 case PCB_CONSTRAINT_TYPE::PARALLEL: return _( "Parallel" );
211 case PCB_CONSTRAINT_TYPE::PERPENDICULAR: return _( "Perpendicular" );
212 case PCB_CONSTRAINT_TYPE::COLLINEAR: return _( "Collinear" );
213 case PCB_CONSTRAINT_TYPE::SYMMETRIC: return _( "Symmetric" );
214 case PCB_CONSTRAINT_TYPE::EQUAL_LENGTH: return _( "Equal length" );
215 case PCB_CONSTRAINT_TYPE::EQUAL_RADIUS: return _( "Equal radius" );
216 case PCB_CONSTRAINT_TYPE::POINT_ON_LINE: return _( "Point on line" );
217 case PCB_CONSTRAINT_TYPE::MIDPOINT: return _( "Midpoint" );
218 case PCB_CONSTRAINT_TYPE::FIXED_POSITION: return _( "Fixed position" );
219 case PCB_CONSTRAINT_TYPE::FIXED_LENGTH: return _( "Fixed length" );
220 case PCB_CONSTRAINT_TYPE::CONCENTRIC: return _( "Concentric" );
221 case PCB_CONSTRAINT_TYPE::FIXED_RADIUS: return _( "Fixed radius" );
222 case PCB_CONSTRAINT_TYPE::ANGULAR_DIMENSION: return _( "Angular dimension" );
223 case PCB_CONSTRAINT_TYPE::TANGENT: return _( "Tangent" );
224 case PCB_CONSTRAINT_TYPE::ARC_ANGLE: return _( "Arc angle" );
225 case PCB_CONSTRAINT_TYPE::UNDEFINED: return _( "Undefined" );
226 }
227
228 return _( "Undefined" );
229}
230
231
236
237
240 m_type( aType ),
241 m_driving( true )
242{
243}
244
245
246void PCB_CONSTRAINT::Serialize( google::protobuf::Any& aContainer ) const
247{
248 using namespace kiapi::board::types;
249 Constraint constraint;
250
251 constraint.mutable_id()->set_value( m_Uuid.AsStdString() );
252
254 constraint.set_driving( m_driving );
255
256 if( m_value.has_value() )
257 constraint.set_value( *m_value );
258
259 for( const CONSTRAINT_MEMBER& member : m_members )
260 {
261 ConstraintMember* m = constraint.add_members();
262 m->mutable_item()->set_value( member.m_item.AsStdString() );
263 m->set_anchor( ToProtoEnum<CONSTRAINT_ANCHOR, ConstraintAnchor>( member.m_anchor ) );
264
265 // Only vertex anchors carry an index leaving it absent elsewhere keeps the negative one
266 // sentinel out of the wire format
267 if( member.m_anchor == CONSTRAINT_ANCHOR::VERTEX )
268 m->set_index( member.m_index );
269 }
270
271 aContainer.PackFrom( constraint );
272}
273
274
275bool PCB_CONSTRAINT::Deserialize( const google::protobuf::Any& aContainer )
276{
277 using namespace kiapi::board::types;
278 Constraint constraint;
279
280 if( !aContainer.UnpackTo( &constraint ) )
281 return false;
282
283 SetUuidDirect( KIID( constraint.id().value() ) );
284
286 m_driving = constraint.driving();
287
288 if( constraint.has_value() )
289 m_value = constraint.value();
290 else
291 m_value = std::nullopt;
292
293 m_members.clear();
294
295 // Members reference items by KIID, so they need no board to resolve (resolved on use).
296 for( const auto& m : constraint.members() )
297 {
299
300 // A vertex member without an explicit index gets the negative one sentinel rather than a
301 // silent vertex zero no other anchor may carry an index at all
302 int index = anchor == CONSTRAINT_ANCHOR::VERTEX && m.has_index() ? m.index() : -1;
303
304 m_members.emplace_back( KIID( m.item().value() ), anchor, index );
305 }
306
307 return true;
308}
309
310
312{
313 // Copy constructor preserves the uuid and all members, matching PCB_GROUP.
314 return new PCB_CONSTRAINT( *this );
315}
316
317
319{
320 assert( aImage->Type() == PCB_CONSTRAINT_T );
321
322 std::swap( *this, *static_cast<PCB_CONSTRAINT*>( aImage ) );
323}
324
325
326void PCB_CONSTRAINT::RemapKIIDs( const std::map<KIID, KIID>& aIdMap )
327{
328 for( CONSTRAINT_MEMBER& member : m_members )
329 {
330 if( auto it = aIdMap.find( member.m_item ); it != aIdMap.end() )
331 member.m_item = it->second;
332 }
333}
334
335
336bool PCB_CONSTRAINT::operator==( const BOARD_ITEM& aOther ) const
337{
338 if( aOther.Type() != Type() )
339 return false;
340
341 return *this == static_cast<const PCB_CONSTRAINT&>( aOther );
342}
343
344
346{
347 // Members are positional (a symmetric constraint's axis is not interchangeable with its
348 // mirrored points), so compare them in order.
349 return m_type == aOther.m_type
350 && m_driving == aOther.m_driving
351 && m_value == aOther.m_value
352 && m_members == aOther.m_members;
353}
354
355
356double PCB_CONSTRAINT::Similarity( const BOARD_ITEM& aOther ) const
357{
358 if( aOther.Type() != Type() )
359 return 0.0;
360
361 const PCB_CONSTRAINT& other = static_cast<const PCB_CONSTRAINT&>( aOther );
362
363 if( m_type != other.m_type )
364 return 0.0;
365
366 double similarity = 0.5;
367
368 if( m_members == other.m_members )
369 similarity += 0.3;
370
371 if( m_driving == other.m_driving && m_value == other.m_value )
372 similarity += 0.2;
373
374 return similarity;
375}
376
377
379{
380 return wxString::Format( _( "Constraint: %s (%zu members)" ),
382}
383
384
385wxString ConstraintDisplayLabel( const PCB_CONSTRAINT& aConstraint, EDA_UNITS aUnits )
386{
387 wxString label = ConstraintTypeLabel( aConstraint.GetConstraintType() );
388
389 if( !aConstraint.HasValue() )
390 return label;
391
392 double value = *aConstraint.GetValue();
393 wxString text;
394
395 if( ConstraintValueIsLength( aConstraint.GetConstraintType() ) )
397 else
399
400 // Reference (non-driving) dimensions only measure, so show them parenthesized like CAD does.
401 return wxString::Format( aConstraint.IsDriving() ? wxT( "%s: %s" ) : wxT( "%s: (%s)" ), label, text );
402}
403
404
405wxString ConstraintMemberLabel( BOARD_ITEM* aItem, const CONSTRAINT_MEMBER& aMember,
406 UNITS_PROVIDER* aUnitsProvider )
407{
408 if( !aItem )
409 return _( "(missing)" );
410
411 wxString text = aItem->GetItemDescription( aUnitsProvider, false );
412 wxString anchor;
413
414 if( aMember.m_anchor == CONSTRAINT_ANCHOR::VERTEX && aMember.m_index >= 0 )
415 {
416 const PCB_SHAPE* shape = dynamic_cast<const PCB_SHAPE*>( aItem );
417
418 // Ordinals read 1 based matching the vertex editor pane grid row numbering Widened so a
419 // hostile INT_MAX index from a file cannot overflow
420 if( shape && shape->GetShape() == SHAPE_T::RECTANGLE )
421 anchor = wxString::Format( _( "corner %lld" ), static_cast<long long>( aMember.m_index ) + 1 );
422 else
423 anchor = wxString::Format( _( "vertex %lld" ), static_cast<long long>( aMember.m_index ) + 1 );
424 }
425 else
426 {
428 }
429
430 if( !anchor.IsEmpty() )
431 text += wxString::Format( wxT( " (%s)" ), anchor );
432
433 return text;
434}
435
436
438{
439 if( aA.GetConstraintType() != aB.GetConstraintType() )
440 return false;
441
442 const std::vector<CONSTRAINT_MEMBER>& a = aA.GetMembers();
443 const std::vector<CONSTRAINT_MEMBER>& b = aB.GetMembers();
444
445 if( a.empty() || a.size() != b.size() )
446 return false;
447
448 // Match members as a multiset so member order does not matter (A-B is the same as B-A).
449 // Roles survive this because a member's anchor encodes them; in SYMMETRIC and the point
450 // families the mirror/probe points carry endpoint anchors while the axis/line is WHOLE, so
451 // two constraints with the same multiset genuinely relate the same geometry the same way.
452 return std::is_permutation( a.begin(), a.end(), b.begin(), b.end() );
453}
454
455
460
461
463{
464 return std::make_shared<SHAPE_COMPOUND>();
465}
466
467
469{
471 {
476
477 // A constraint has no geometry, so hide the inherited positional/layer properties.
478 propMgr.Mask( TYPE_HASH( PCB_CONSTRAINT ), TYPE_HASH( BOARD_ITEM ), _HKI( "Position X" ) );
479 propMgr.Mask( TYPE_HASH( PCB_CONSTRAINT ), TYPE_HASH( BOARD_ITEM ), _HKI( "Position Y" ) );
480 propMgr.Mask( TYPE_HASH( PCB_CONSTRAINT ), TYPE_HASH( BOARD_ITEM ), _HKI( "Layer" ) );
481 propMgr.Mask( TYPE_HASH( PCB_CONSTRAINT ), TYPE_HASH( BOARD_ITEM ), _HKI( "Locked" ) );
482
483 const wxString constraintTab = _HKI( "Constraint Properties" );
484
485 // Driving vs reference is the one freely-editable property (the "convert to reference"
486 // toggle); type and members are intrinsic and set at creation.
487 propMgr.AddProperty( new PROPERTY<PCB_CONSTRAINT, bool>( _HKI( "Driving" ),
489 constraintTab );
490 }
int index
types::KiCadObjectType ToProtoEnum(KICAD_T aValue)
KICAD_T FromProtoEnum(types::KiCadObjectType aValue)
Definition api_enums.cpp:47
constexpr EDA_IU_SCALE pcbIUScale
Definition base_units.h:121
BITMAPS
A list of all bitmap identifiers.
@ constraint_tangent
@ constraint_fixed_radius
@ constraint_vertical
@ constraint_arc_angle
@ constraint_parallel
@ constraint_equal_radius
@ constraint_horizontal
@ constraint_fixed_position
@ constraint_equal_length
@ constraint_symmetric
@ constraint_fixed_length
@ INVALID_BITMAP
@ constraint_collinear
@ constraint_concentric
@ constraint_angular_dimension
@ constraint_coincident
@ constraint_midpoint
@ constraint_perpendicular
@ constraint_point_on_line
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition board_item.h:83
BOARD_ITEM(BOARD_ITEM *aParent, KICAD_T idtype, PCB_LAYER_ID aLayer=F_Cu)
Definition board_item.h:85
void SetUuidDirect(const KIID &aUuid)
Raw UUID assignment.
virtual wxString GetItemDescription(UNITS_PROVIDER *aUnitsProvider, bool aFull) const
Return a user-visible description string of this item.
Definition eda_item.cpp:169
const KIID m_Uuid
Definition eda_item.h:531
KICAD_T Type() const
Returns the type of object.
Definition eda_item.h:108
EDA_ITEM(EDA_ITEM *parent, KICAD_T idType, bool isSCH_ITEM=false, bool isBOARD_ITEM=false)
Definition eda_item.cpp:37
SHAPE_T GetShape() const
Definition eda_shape.h:185
Definition kiid.h:44
A geometric constraint between board items (issue #2329).
void swapData(BOARD_ITEM *aImage) override
const std::vector< CONSTRAINT_MEMBER > & GetMembers() const
void Serialize(google::protobuf::Any &aContainer) const override
Serializes this object to the given Any message.
std::optional< double > GetValue() const
PCB_CONSTRAINT(BOARD_ITEM *aParent=nullptr)
BITMAPS GetMenuImage() const override
Return a pointer to an image to be used in menus.
bool IsDriving() const
A driving constraint forces its value; a reference (non-driving) one only measures it.
PCB_CONSTRAINT_TYPE GetConstraintType() const
double Similarity(const BOARD_ITEM &aOther) const override
Return a measure of how likely the other object is to represent the same object.
bool operator==(const PCB_CONSTRAINT &aOther) const
std::optional< double > m_value
PCB_CONSTRAINT_TYPE m_type
bool HasValue() const
bool Deserialize(const google::protobuf::Any &aContainer) override
Deserializes the given protobuf message into this object.
void RemapKIIDs(const std::map< KIID, KIID > &aIdMap) override
Remap KIIDs this item stores to reference other items (e.g.
void SetDriving(bool aDriving)
std::vector< CONSTRAINT_MEMBER > m_members
EDA_ITEM * Clone() const override
Create a duplicate of this item with linked list members set to NULL.
std::shared_ptr< SHAPE > GetEffectiveShape(PCB_LAYER_ID aLayer=UNDEFINED_LAYER, FLASHING aFlash=FLASHING::DEFAULT) const override
Empty shape so any generic GetItemSet()/RunOnChildren consumer stays safe.
wxString GetItemDescription(UNITS_PROVIDER *aUnitsProvider, bool aFull) const override
Return a user-visible description string of this item.
Provide class metadata.Helper macro to map type hashes to names.
void InheritsAfter(TYPE_ID aDerived, TYPE_ID aBase)
Declare an inheritance relationship between types.
void Mask(TYPE_ID aDerived, TYPE_ID aBase, const wxString &aName)
Sets a base class property as masked in a derived class.
static PROPERTY_MANAGER & Instance()
PROPERTY_BASE & AddProperty(PROPERTY_BASE *aProperty, const wxString &aGroup=wxEmptyString)
Register a property.
void AddTypeCast(TYPE_CAST_BASE *aCast)
Register a type converter.
#define _(s)
@ DEGREES_T
Definition eda_angle.h:31
@ RECTANGLE
Use RECTANGLE instead of RECT to avoid collision in a Windows header.
Definition eda_shape.h:47
EDA_UNITS
Definition eda_units.h:44
Some functions to handle hotkeys in KiCad.
FLASHING
Enum used during connectivity building to ensure we do not query connectivity while building the data...
Definition layer_ids.h:180
PCB_LAYER_ID
A quick note on layer IDs:
Definition layer_ids.h:56
@ UNDEFINED_LAYER
Definition layer_ids.h:57
KICOMMON_API wxString MessageTextFromValue(const EDA_IU_SCALE &aIuScale, EDA_UNITS aUnits, double aValue, bool aAddUnitsText=true, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE)
A helper to convert the double length aValue to a string in inches, millimeters, or unscaled units.
#define _HKI(x)
Definition page_info.cpp:40
bool ConstraintsAreDuplicate(const PCB_CONSTRAINT &aA, const PCB_CONSTRAINT &aB)
True if two constraints express the same relation, meaning the same type and the same members compare...
wxString ConstraintTypeGlyph(PCB_CONSTRAINT_TYPE aType)
Compact glyph for a constraint type (e.g. "//", "=") for on-canvas badges.
PCB_CONSTRAINT_TYPE ConstraintTypeFromToken(const wxString &aToken)
Parse a constraint-type token; returns UNDEFINED for an unknown token.
BITMAPS ConstraintTypeBitmap(PCB_CONSTRAINT_TYPE aType)
Badge icon for a constraint type; INVALID_BITMAP for UNDEFINED.
bool ConstraintValueIsLength(PCB_CONSTRAINT_TYPE aType)
True if this type's value is a length in IU (serialized in mm); false for an angle in degrees.
wxString ConstraintTypeLabel(PCB_CONSTRAINT_TYPE aType)
Human-readable name of a constraint type (e.g. "Parallel"), for menus and lists.
wxString ConstraintMemberLabel(BOARD_ITEM *aItem, const CONSTRAINT_MEMBER &aMember, UNITS_PROVIDER *aUnitsProvider)
Label for one constrained item in a list combining the item description with its anchored feature suc...
CONSTRAINT_ANCHOR ConstraintAnchorFromToken(const wxString &aToken)
Parse an anchor token; returns WHOLE for an unknown token.
const char * ConstraintTypeToken(PCB_CONSTRAINT_TYPE aType)
Stable file-format token for a constraint type (e.g. "parallel"). Used by serialization.
const char * ConstraintAnchorToken(CONSTRAINT_ANCHOR aAnchor)
Stable file-format token for a member anchor (e.g. "start").
static struct PCB_CONSTRAINT_DESC _PCB_CONSTRAINT_DESC
wxString ConstraintAnchorLabel(CONSTRAINT_ANCHOR aAnchor)
Translated name of the feature an anchor references (e.g.
wxString ConstraintDisplayLabel(const PCB_CONSTRAINT &aConstraint, EDA_UNITS aUnits)
Display label for a constraint in lists and menus.
CONSTRAINT_ANCHOR
Which feature of a referenced board item participates in a constraint.
@ VERTEX
An indexed rectangle corner or polygon outline vertex; pairs with CONSTRAINT_MEMBER::m_index.
@ MID
Midpoint of a segment or arc.
@ RADIUS
The radius (scalar feature) of an arc or circle.
@ WHOLE
The item as a whole (a segment as a line, a circle).
@ START
First endpoint of a segment or arc.
@ END
Second endpoint of a segment or arc.
@ CENTER
Center of an arc or circle.
wxString ConstraintTypeLabel(PCB_CONSTRAINT_TYPE aType)
Human-readable name of a constraint type (e.g. "Parallel"), for menus and lists.
PCB_CONSTRAINT_TYPE
The geometric relationship a PCB_CONSTRAINT enforces between its members.
@ CONCENTRIC
Two arcs/circles share a center.
@ SYMMETRIC
Two points are mirror images about an axis.
@ FIXED_POSITION
A point is locked at its current location.
@ VERTICAL
A segment (or two points) is vertical.
@ TANGENT
A line and a curve, or two curves, touch tangentially.
@ COINCIDENT
Two points are made to coincide.
@ PERPENDICULAR
Two segments are perpendicular.
@ FIXED_RADIUS
An arc/circle has a driving radius value.
@ HORIZONTAL
A segment (or two points) is horizontal.
@ EQUAL_RADIUS
Two arcs/circles have equal radius.
@ MIDPOINT
A point is the midpoint of a segment.
@ POINT_ON_LINE
A point lies on a segment's supporting line.
@ FIXED_LENGTH
A segment has a driving length value.
@ ANGULAR_DIMENSION
An angle between members (driving or reference).
@ COLLINEAR
Two segments lie on the same line.
@ ARC_ANGLE
An arc has a driving or reference swept-angle value.
@ PARALLEL
Two segments are parallel.
@ EQUAL_LENGTH
Two segments have equal length.
#define TYPE_HASH(x)
Definition property.h:74
#define REGISTER_TYPE(x)
One participant in a constraint: a referenced board item plus the feature of that item that participa...
CONSTRAINT_ANCHOR m_anchor
Which feature of that item participates.
int m_index
Vertex ordinal; only meaningful for the VERTEX anchor.
@ PCB_CONSTRAINT_T
class PCB_CONSTRAINT, a geometric constraint between board items
Definition typeinfo.h:238