KiCad PCB EDA Suite
Loading...
Searching...
No Matches
board_exchange_footprint.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
12#include <algorithm>
13#include <memory>
14#include <set>
15#include <type_traits>
16#include <unordered_map>
17#include <unordered_set>
18#include <vector>
19
20#include <board.h>
21#include <board_commit.h>
23#include <board_item.h>
24#include <core/mirror.h>
25#include <eda_group.h>
26#include <embedded_files.h>
27#include <footprint.h>
28#include <footprint_utils.h>
29#include <math/util.h>
30#include <netinfo.h>
31#include <pad.h>
32#include <pcb_dimension.h>
33#include <pcb_field.h>
34#include <pcb_group.h>
35#include <pcb_point.h>
36#include <pcb_text.h>
37#include <zone.h>
38
39
40static void processTextItem( const PCB_TEXT& aSrc, PCB_TEXT& aDest, const VECTOR2I& aPosShift,
41 const EDA_ANGLE& aAngleShift, bool aResetText, bool aResetTextLayers,
42 bool aResetTextEffects, bool aResetTextPositions, bool* aUpdated )
43{
44 if( aResetText )
45 *aUpdated |= aSrc.GetText() != aDest.GetText();
46 else
47 aDest.SetText( aSrc.GetText() );
48
49 if( aResetTextLayers )
50 {
51 *aUpdated |= aSrc.GetLayer() != aDest.GetLayer();
52 *aUpdated |= aSrc.IsVisible() != aDest.IsVisible();
53 }
54 else
55 {
56 aDest.SetLayer( aSrc.GetLayer() );
57 aDest.SetVisible( aSrc.IsVisible() );
58 }
59
60 VECTOR2I origPos = aDest.GetFPRelativePosition();
61
62 if( aResetTextEffects )
63 {
64 *aUpdated |= aSrc.GetHorizJustify() != aDest.GetHorizJustify();
65 *aUpdated |= aSrc.GetVertJustify() != aDest.GetVertJustify();
66 *aUpdated |= aSrc.GetTextSize() != aDest.GetTextSize();
67 *aUpdated |= aSrc.GetTextThickness() != aDest.GetTextThickness();
68 }
69 else
70 {
71 EDA_ANGLE origAngle = aDest.GetTextAngle();
72 aDest.SetAttributes( aSrc );
73 aDest.SetTextAngle( origAngle ); // apply rotation as part of position shift
74 }
75
76 if( aResetTextPositions )
77 {
78 *aUpdated |= aSrc.GetFPRelativePosition() != origPos;
79 *aUpdated |= aSrc.GetTextAngle() != aDest.GetTextAngle();
80
81 aDest.SetFPRelativePosition( origPos );
82 }
83 else
84 {
85 VECTOR2I rotatedShift = GetRotated( aSrc.GetFPRelativePosition() - aPosShift, -aAngleShift );
86
87 aDest.SetFPRelativePosition( rotatedShift );
88 aDest.SetTextAngle( aSrc.GetTextAngle() );
89 }
90
91 aDest.SetLocked( aSrc.IsLocked() );
92 aDest.SetUuid( aSrc.m_Uuid );
93}
94
95
96template<typename T>
97static std::vector<std::pair<T*, T*>> matchItemsBySimilarity( const std::vector<T*>& aExisting,
98 const std::vector<T*>& aNew )
99{
100 struct MATCH_CANDIDATE
101 {
102 T* existing;
103 T* updated;
104 double score;
105 };
106
107 std::vector<MATCH_CANDIDATE> candidates;
108
109 for( T* existing : aExisting )
110 {
111 for( T* updated : aNew )
112 {
113 if( existing->Type() != updated->Type() )
114 continue;
115
116 double similarity = existing->Similarity( *updated );
117
118 if constexpr( std::is_same_v<T, PAD> )
119 {
120 if( existing->GetNumber() == updated->GetNumber() )
121 similarity += 2.0;
122 }
123
124 if( similarity <= 0.0 )
125 continue;
126
127 candidates.push_back( { existing, updated, similarity } );
128 }
129 }
130
131 std::sort( candidates.begin(), candidates.end(),
132 []( const MATCH_CANDIDATE& a, const MATCH_CANDIDATE& b )
133 {
134 if( a.score != b.score )
135 return a.score > b.score;
136
137 if( a.existing != b.existing )
138 return a.existing < b.existing;
139
140 return a.updated < b.updated;
141 } );
142
143 std::vector<std::pair<T*, T*>> matches;
144 matches.reserve( candidates.size() );
145
146 std::unordered_set<T*> matchedExisting;
147 std::unordered_set<T*> matchedNew;
148
149 for( const MATCH_CANDIDATE& candidate : candidates )
150 {
151 if( matchedExisting.find( candidate.existing ) != matchedExisting.end() )
152 continue;
153
154 if( matchedNew.find( candidate.updated ) != matchedNew.end() )
155 continue;
156
157 matchedExisting.insert( candidate.existing );
158 matchedNew.insert( candidate.updated );
159 matches.emplace_back( candidate.existing, candidate.updated );
160 }
161
162 return matches;
163}
164
165
167 bool matchPadPositions,
168 bool deleteExtraTexts,
169 bool resetTextLayers,
170 bool resetTextEffects,
171 bool resetTextPositions,
172 bool resetTextContent,
173 bool resetFabricationAttrs,
174 bool resetClearanceOverrides,
175 bool reset3DModels,
176 bool resetTransform,
177 bool* aUpdated )
178{
179 EDA_GROUP* parentGroup = aExisting->GetParentGroup();
180 bool dummyBool = false;
181
182 if( !aUpdated )
183 aUpdated = &dummyBool;
184
185 if( parentGroup )
186 {
187 aCommit.Modify( parentGroup->AsEdaItem(), nullptr, RECURSE_MODE::NO_RECURSE );
188 parentGroup->RemoveItem( aExisting );
189 parentGroup->AddItem( aNew );
190 }
191
192 aNew->SetParent( this );
193
194 // This is the position and angle shift to apply to the new footprint if the footprint
195 // has a change anchor point or rotation compared to the existing footprint.
196 VECTOR2I posShift( 0, 0 );
197 EDA_ANGLE angleShift = ANGLE_0;
198
199 VECTOR2I position = aExisting->GetPosition();
200 EDA_ANGLE orientation = aExisting->GetOrientation();
201
202 if( matchPadPositions )
203 {
204 if( ComputeFootprintShift( *aExisting, *aNew, posShift, angleShift ) )
205 {
206 position += posShift;
207 orientation += angleShift;
208 }
209 }
210
211 aNew->SetPosition( position );
212
213 if( aNew->GetLayer() != aExisting->GetLayer() )
215
216 if( aNew->GetOrientation() != orientation )
217 aNew->SetOrientation( orientation );
218
219 if( !resetTransform )
220 {
221 const double existingScaleX = aExisting->GetTransform().GetScaleX();
222 const double existingScaleY = aExisting->GetTransform().GetScaleY();
223
224 if( existingScaleX != aNew->GetTransform().GetScaleX()
225 || existingScaleY != aNew->GetTransform().GetScaleY() )
226 {
227 aNew->SetTransformScale( existingScaleX, existingScaleY );
228 }
229 }
230
231 aNew->SetLocked( aExisting->IsLocked() );
232
233 aNew->SetUuid( aExisting->m_Uuid );
234 aNew->Reference().SetUuid( aExisting->Reference().m_Uuid );
235 aNew->Value().SetUuid( aExisting->Value().m_Uuid );
236
237 std::vector<PAD*> oldPads;
238 oldPads.reserve( aExisting->Pads().size() );
239
240 for( PAD* pad : aExisting->Pads() )
241 oldPads.push_back( pad );
242
243 std::vector<PAD*> newPads;
244 newPads.reserve( aNew->Pads().size() );
245
246 for( PAD* pad : aNew->Pads() )
247 newPads.push_back( pad );
248
249 auto padMatches = matchItemsBySimilarity<PAD>( oldPads, newPads );
250 std::unordered_set<PAD*> matchedNewPads;
251
252 for( const auto& match : padMatches )
253 {
254 PAD* oldPad = match.first;
255 PAD* newPad = match.second;
256
257 matchedNewPads.insert( newPad );
258 newPad->SetUuid( oldPad->m_Uuid );
260 newPad->SetPinFunction( oldPad->GetPinFunction() );
261 newPad->SetPinType( oldPad->GetPinType() );
262
263 if( newPad->IsOnCopperLayer() )
264 newPad->SetNetCode( oldPad->GetNetCode() );
265 else
267 }
268
269 for( PAD* newPad : aNew->Pads() )
270 {
271 if( matchedNewPads.find( newPad ) != matchedNewPads.end() )
272 continue;
273
274 newPad->ResetUuid();
275 newPad->SetNetCode( NETINFO_LIST::UNCONNECTED );
276 }
277
278 std::vector<BOARD_ITEM*> oldDrawings;
279 oldDrawings.reserve( aExisting->GraphicalItems().size() );
280
281 for( BOARD_ITEM* item : aExisting->GraphicalItems() )
282 oldDrawings.push_back( item );
283
284 std::vector<BOARD_ITEM*> newDrawings;
285 newDrawings.reserve( aNew->GraphicalItems().size() );
286
287 for( BOARD_ITEM* item : aNew->GraphicalItems() )
288 newDrawings.push_back( item );
289
290 auto drawingMatches = matchItemsBySimilarity<BOARD_ITEM>( oldDrawings, newDrawings );
291 std::unordered_map<BOARD_ITEM*, BOARD_ITEM*> oldToNewDrawings;
292 std::unordered_set<BOARD_ITEM*> matchedNewDrawings;
293
294 for( const auto& match : drawingMatches )
295 {
296 BOARD_ITEM* oldItem = match.first;
297 BOARD_ITEM* newItem = match.second;
298
299 oldToNewDrawings[ oldItem ] = newItem;
300 matchedNewDrawings.insert( newItem );
301 newItem->SetUuid( oldItem->m_Uuid );
302 }
303
304 for( BOARD_ITEM* newItem : newDrawings )
305 {
306 if( matchedNewDrawings.find( newItem ) == matchedNewDrawings.end() )
307 newItem->ResetUuid();
308 }
309
310 std::vector<ZONE*> oldZones;
311 oldZones.reserve( aExisting->Zones().size() );
312
313 for( ZONE* zone : aExisting->Zones() )
314 oldZones.push_back( zone );
315
316 std::vector<ZONE*> newZones;
317 newZones.reserve( aNew->Zones().size() );
318
319 for( ZONE* zone : aNew->Zones() )
320 newZones.push_back( zone );
321
322 auto zoneMatches = matchItemsBySimilarity<ZONE>( oldZones, newZones );
323 std::unordered_set<ZONE*> matchedNewZones;
324
325 for( const auto& match : zoneMatches )
326 {
327 ZONE* oldZone = match.first;
328 ZONE* newZone = match.second;
329
330 matchedNewZones.insert( newZone );
331 newZone->SetUuid( oldZone->m_Uuid );
332 }
333
334 for( ZONE* newZone : newZones )
335 {
336 if( matchedNewZones.find( newZone ) == matchedNewZones.end() )
337 newZone->ResetUuid();
338 }
339
340 std::vector<PCB_POINT*> oldPoints;
341 oldPoints.reserve( aExisting->Points().size() );
342
343 for( PCB_POINT* point : aExisting->Points() )
344 oldPoints.push_back( point );
345
346 std::vector<PCB_POINT*> newPoints;
347 newPoints.reserve( aNew->Points().size() );
348
349 for( PCB_POINT* point : aNew->Points() )
350 newPoints.push_back( point );
351
352 auto pointMatches = matchItemsBySimilarity<PCB_POINT>( oldPoints, newPoints );
353 std::unordered_set<PCB_POINT*> matchedNewPoints;
354
355 for( const auto& match : pointMatches )
356 {
357 PCB_POINT* oldPoint = match.first;
358 PCB_POINT* newPoint = match.second;
359
360 matchedNewPoints.insert( newPoint );
361 newPoint->SetUuid( oldPoint->m_Uuid );
362 }
363
364 for( PCB_POINT* newPoint : newPoints )
365 {
366 if( matchedNewPoints.find( newPoint ) == matchedNewPoints.end() )
367 newPoint->ResetUuid();
368 }
369
370 std::vector<PCB_GROUP*> oldGroups;
371 oldGroups.reserve( aExisting->Groups().size() );
372
373 for( PCB_GROUP* group : aExisting->Groups() )
374 oldGroups.push_back( group );
375
376 std::vector<PCB_GROUP*> newGroups;
377 newGroups.reserve( aNew->Groups().size() );
378
379 for( PCB_GROUP* group : aNew->Groups() )
380 newGroups.push_back( group );
381
382 auto groupMatches = matchItemsBySimilarity<PCB_GROUP>( oldGroups, newGroups );
383 std::unordered_set<PCB_GROUP*> matchedNewGroups;
384
385 for( const auto& match : groupMatches )
386 {
387 PCB_GROUP* oldGroup = match.first;
388 PCB_GROUP* newGroup = match.second;
389
390 matchedNewGroups.insert( newGroup );
391 newGroup->SetUuid( oldGroup->m_Uuid );
392 }
393
394 for( PCB_GROUP* newGroup : newGroups )
395 {
396 if( matchedNewGroups.find( newGroup ) == matchedNewGroups.end() )
397 newGroup->ResetUuid();
398 }
399
400 std::vector<PCB_FIELD*> oldFieldsVec;
401 std::vector<PCB_FIELD*> newFieldsVec;
402
403 oldFieldsVec.reserve( aExisting->GetFields().size() );
404
405 for( PCB_FIELD* field : aExisting->GetFields() )
406 {
407 wxCHECK2( field, continue );
408
409 if( field->IsReference() || field->IsValue() )
410 continue;
411
412 oldFieldsVec.push_back( field );
413 }
414
415 newFieldsVec.reserve( aNew->GetFields().size() );
416
417 for( PCB_FIELD* field : aNew->GetFields() )
418 {
419 wxCHECK2( field, continue );
420
421 if( field->IsReference() || field->IsValue() )
422 continue;
423
424 newFieldsVec.push_back( field );
425 }
426
427 auto fieldMatches = matchItemsBySimilarity<PCB_FIELD>( oldFieldsVec, newFieldsVec );
428 std::unordered_map<PCB_FIELD*, PCB_FIELD*> oldToNewFields;
429 std::unordered_set<PCB_FIELD*> matchedNewFields;
430
431 for( const auto& match : fieldMatches )
432 {
433 PCB_FIELD* oldField = match.first;
434 PCB_FIELD* newField = match.second;
435
436 oldToNewFields[ oldField ] = newField;
437 matchedNewFields.insert( newField );
438 newField->SetUuid( oldField->m_Uuid );
439 }
440
441 for( PCB_FIELD* newField : newFieldsVec )
442 {
443 if( matchedNewFields.find( newField ) == matchedNewFields.end() )
444 newField->ResetUuid();
445 }
446
447 std::unordered_map<PCB_TEXT*, PCB_TEXT*> oldToNewTexts;
448
449 for( const auto& match : drawingMatches )
450 {
451 PCB_TEXT* oldText = dynamic_cast<PCB_TEXT*>( match.first );
452 PCB_TEXT* newText = dynamic_cast<PCB_TEXT*>( match.second );
453
454 if( oldText && newText )
455 oldToNewTexts[ oldText ] = newText;
456 }
457
458 std::set<PCB_TEXT*> handledTextItems;
459
460 for( BOARD_ITEM* oldItem : aExisting->GraphicalItems() )
461 {
462 PCB_TEXT* oldTextItem = dynamic_cast<PCB_TEXT*>( oldItem );
463
464 if( oldTextItem )
465 {
466 // Dimensions have PCB_TEXT base but are not treated like texts in the updater
467 if( dynamic_cast<PCB_DIMENSION_BASE*>( oldTextItem ) )
468 continue;
469
470 PCB_TEXT* newTextItem = nullptr;
471
472 auto textMatchIt = oldToNewTexts.find( oldTextItem );
473
474 if( textMatchIt != oldToNewTexts.end() )
475 newTextItem = textMatchIt->second;
476
477 if( newTextItem )
478 {
479 handledTextItems.insert( newTextItem );
480 processTextItem( *oldTextItem, *newTextItem, posShift, angleShift, resetTextContent, resetTextLayers,
481 resetTextEffects, resetTextPositions, aUpdated );
482 }
483 else if( deleteExtraTexts )
484 {
485 *aUpdated = true;
486 }
487 else
488 {
489 newTextItem = static_cast<PCB_TEXT*>( oldTextItem->Clone() );
490 handledTextItems.insert( newTextItem );
491 aNew->Add( newTextItem );
492 }
493 }
494 }
495
496 // Check for any newly-added text items and set the update flag as appropriate
497 for( BOARD_ITEM* newItem : aNew->GraphicalItems() )
498 {
499 PCB_TEXT* newTextItem = dynamic_cast<PCB_TEXT*>( newItem );
500
501 if( newTextItem )
502 {
503 // Dimensions have PCB_TEXT base but are not treated like texts in the updater
504 if( dynamic_cast<PCB_DIMENSION_BASE*>( newTextItem ) )
505 continue;
506
507 if( !handledTextItems.contains( newTextItem ) )
508 {
509 *aUpdated = true;
510 break;
511 }
512 }
513 }
514
515 // Copy reference. The initial text is always used, never resetted
516 processTextItem( aExisting->Reference(), aNew->Reference(), posShift, angleShift, false, resetTextLayers,
517 resetTextEffects, resetTextPositions, aUpdated );
518
519 // Copy value
520 processTextItem( aExisting->Value(), aNew->Value(), posShift, angleShift,
521 // reset value text only when it is a proxy for the footprint ID
522 // (cf replacing value "MountingHole-2.5mm" with "MountingHole-4.0mm")
523 aExisting->GetValue() == aExisting->GetFPID().GetLibItemName().wx_str(),
524 resetTextLayers, resetTextEffects, resetTextPositions, aUpdated );
525
526 std::set<PCB_FIELD*> handledFields;
527
528 // Copy fields in accordance with the reset* flags
529 for( PCB_FIELD* oldField : aExisting->GetFields() )
530 {
531 wxCHECK2( oldField, continue );
532
533 // Reference and value are already handled
534 if( oldField->IsReference() || oldField->IsValue() )
535 continue;
536
537 PCB_FIELD* newField = nullptr;
538
539 auto fieldMatchIt = oldToNewFields.find( oldField );
540
541 if( fieldMatchIt != oldToNewFields.end() )
542 newField = fieldMatchIt->second;
543
544 if( newField )
545 {
546 handledFields.insert( newField );
547 processTextItem( *oldField, *newField, posShift, angleShift, resetTextContent, resetTextLayers,
548 resetTextEffects, resetTextPositions, aUpdated );
549 }
550 else if( deleteExtraTexts )
551 {
552 *aUpdated = true;
553 }
554 else
555 {
556 newField = new PCB_FIELD( *oldField );
557 handledFields.insert( newField );
558 aNew->Add( newField );
559 }
560 }
561
562 // Check for any newly-added fields and set the update flag as appropriate
563 for( PCB_FIELD* newField : aNew->GetFields() )
564 {
565 wxCHECK2( newField, continue );
566
567 // Reference and value are already handled
568 if( newField->IsReference() || newField->IsValue() )
569 continue;
570
571 if( !handledFields.contains( newField ) )
572 {
573 *aUpdated = true;
574 break;
575 }
576 }
577
578 if( resetFabricationAttrs )
579 {
580 // We've replaced the existing footprint with the library one, so the fabrication attrs
581 // are already reset. Just set the aUpdated flag if appropriate.
582 if( aNew->GetAttributes() != aExisting->GetAttributes() )
583 *aUpdated = true;
584 }
585 else
586 {
587 aNew->SetAttributes( aExisting->GetAttributes() );
588 }
589
590 if( resetClearanceOverrides )
591 {
592 if( aExisting->AllowSolderMaskBridges() != aNew->AllowSolderMaskBridges() )
593 *aUpdated = true;
594
595 if( ( aExisting->GetLocalClearance() != aNew->GetLocalClearance() )
596 || ( aExisting->GetLocalSolderMaskMargin() != aNew->GetLocalSolderMaskMargin() )
597 || ( aExisting->GetLocalSolderPasteMargin() != aNew->GetLocalSolderPasteMargin() )
599 || ( aExisting->GetLocalZoneConnection() != aNew->GetLocalZoneConnection() ) )
600 {
601 *aUpdated = true;
602 }
603 }
604 else
605 {
606 aNew->SetLocalClearance( aExisting->GetLocalClearance() );
612 }
613
614 if( reset3DModels )
615 {
616 // We've replaced the existing footprint with the library one, so the 3D models are
617 // already reset. Just set the aUpdated flag if appropriate.
618 if( aNew->Models().size() != aExisting->Models().size() )
619 {
620 *aUpdated = true;
621 }
622 else
623 {
624 for( size_t ii = 0; ii < aNew->Models().size(); ++ii )
625 {
626 if( aNew->Models()[ii] != aExisting->Models()[ii] )
627 {
628 *aUpdated = true;
629 break;
630 }
631 }
632 }
633 }
634 else
635 {
636 // Preserve model references and all embedded model data.
637 aNew->Models() = aExisting->Models();
638
639 // Preserve extruded 3D body settings.
640 if( aExisting->HasExtrudedBody() )
641 aNew->SetExtrudedBody( std::make_unique<EXTRUDED_3D_BODY>( *aExisting->GetExtrudedBody() ) );
642 else
643 aNew->ClearExtrudedBody();
644
645 for( const auto& [name, file] : aExisting->GetEmbeddedFiles()->EmbeddedFileMap() )
646 {
648 continue;
649
650 aNew->GetEmbeddedFiles()->RemoveFile( name, true );
652 }
653 }
654
655 // Updating other parameters
656 aNew->SetPath( aExisting->GetPath() );
657 aNew->SetSheetfile( aExisting->GetSheetfile() );
658 aNew->SetSheetname( aExisting->GetSheetname() );
659 aNew->SetFilters( aExisting->GetFilters() );
660 aNew->SetStaticComponentClass( aExisting->GetComponentClass() );
661
662 if( *aUpdated == false )
663 {
664 // Check pad shapes, graphics, zones, etc. for changes
666 *aUpdated = true;
667 }
668
669 aCommit.Remove( aExisting );
670 aCommit.Add( aNew );
671
672 aNew->ClearFlags();
673}
674
const char * name
static std::vector< std::pair< T *, T * > > matchItemsBySimilarity(const std::vector< T * > &aExisting, const std::vector< T * > &aNew)
static void processTextItem(const PCB_TEXT &aSrc, PCB_TEXT &aDest, const VECTOR2I &aPosShift, const EDA_ANGLE &aAngleShift, bool aResetText, bool aResetTextLayers, bool aResetTextEffects, bool aResetTextPositions, bool *aUpdated)
virtual bool SetNetCode(int aNetCode, bool aNoAssert)
Set net using a net code.
void SetLocalRatsnestVisible(bool aVisible)
BOARD_ITEM(BOARD_ITEM *aParent, KICAD_T idtype, PCB_LAYER_ID aLayer=F_Cu)
Definition board_item.h:83
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
Definition board_item.h:265
void SetLocked(bool aLocked) override
Definition board_item.h:356
void SetUuid(const KIID &aUuid)
bool IsLocked() const override
virtual void SetLayer(PCB_LAYER_ID aLayer)
Set the layer this item is on.
Definition board_item.h:313
VECTOR2I GetFPRelativePosition() const
@ INSTANCE_TO_INSTANCE
Definition board_item.h:496
void SetFPRelativePosition(const VECTOR2I &aPos)
void ExchangeFootprint(FOOTPRINT *aExisting, FOOTPRINT *aNew, BOARD_COMMIT &aCommit, bool matchPadPositions, bool deleteExtraTexts=true, bool resetTextLayers=true, bool resetTextEffects=true, bool resetTextPositions=true, bool resetTextContent=true, bool resetFabricationAttrs=true, bool resetClearanceOverrides=true, bool reset3DModels=true, bool resetTransform=false, bool *aUpdated=nullptr)
Replace aExisting with aNew, preserving connectivity and metadata.
COMMIT & Remove(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Remove a new item from the model.
Definition commit.h:86
COMMIT & Modify(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr, RECURSE_MODE aRecurse=RECURSE_MODE::NO_RECURSE)
Modify a given item in the model.
Definition commit.h:102
COMMIT & Add(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Add a new item to the model.
Definition commit.h:74
A set of EDA_ITEMs (i.e., without duplicates).
Definition eda_group.h:42
void RemoveItem(EDA_ITEM *aItem)
Remove item from group.
Definition eda_group.cpp:77
void AddItem(EDA_ITEM *aItem)
Add item to group.
Definition eda_group.cpp:58
virtual EDA_ITEM * AsEdaItem()=0
const KIID m_Uuid
Definition eda_item.h:531
virtual EDA_GROUP * GetParentGroup() const
Definition eda_item.h:114
void ClearFlags(EDA_ITEM_FLAGS aMask=EDA_ITEM_ALL_FLAGS)
Definition eda_item.h:154
virtual void SetParent(EDA_ITEM *aParent)
Definition eda_item.cpp:89
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition eda_text.h:110
virtual bool IsVisible() const
Definition eda_text.h:208
void SetAttributes(const EDA_TEXT &aSrc, bool aSetPosition=true)
Set the text attributes from another instance.
Definition eda_text.cpp:428
GR_TEXT_H_ALIGN_T GetHorizJustify() const
Definition eda_text.h:221
virtual void SetVisible(bool aVisible)
Definition eda_text.cpp:381
GR_TEXT_V_ALIGN_T GetVertJustify() const
Definition eda_text.h:224
virtual void SetText(const wxString &aText)
Definition eda_text.cpp:265
void RemoveFile(const wxString &name, bool aErase=true)
Remove a file from the collection and frees the memory.
EMBEDDED_FILE * AddFile(const wxFileName &aName, bool aOverwrite)
Load a file from disk and adds it to the collection.
const std::map< wxString, std::shared_ptr< EMBEDDED_FILE > > & EmbeddedFileMap() const
Provide an iterable view of the file collection.
bool AllowSolderMaskBridges() const
Definition footprint.h:513
void SetPosition(const VECTOR2I &aPos) override
ZONE_CONNECTION GetLocalZoneConnection() const
Definition footprint.h:489
void SetLocked(bool isLocked) override
Set the #MODULE_is_LOCKED bit in the m_ModuleStatus.
Definition footprint.h:644
EDA_ANGLE GetOrientation() const
Definition footprint.h:406
ZONES & Zones()
Definition footprint.h:381
PCB_POINTS & Points()
Definition footprint.h:387
void SetOrientation(const EDA_ANGLE &aNewAngle)
void SetAllowSolderMaskBridges(bool aAllow)
Definition footprint.h:514
const TRANSFORM_TRS & GetTransform() const
Definition footprint.h:419
void SetLocalSolderPasteMarginRatio(std::optional< double > aRatio)
Definition footprint.h:486
wxString GetSheetname() const
Definition footprint.h:467
void SetPath(const KIID_PATH &aPath)
Definition footprint.h:465
void SetFilters(const wxString &aFilters)
Definition footprint.h:474
void SetStaticComponentClass(const COMPONENT_CLASS *aClass) const
Sets the component class object pointer for this footprint.
bool FootprintNeedsUpdate(const FOOTPRINT *aLibFP, int aCompareFlags=0, REPORTER *aReporter=nullptr)
Return true if a board footprint differs from the library version.
const EXTRUDED_3D_BODY * GetExtrudedBody() const
Definition footprint.h:396
void SetAttributes(int aAttributes)
Definition footprint.h:508
void SetSheetfile(const wxString &aSheetfile)
Definition footprint.h:471
std::optional< int > GetLocalSolderPasteMargin() const
Definition footprint.h:482
PCB_FIELD & Value()
read/write accessors:
Definition footprint.h:877
bool HasExtrudedBody() const
Definition footprint.h:395
std::optional< int > GetLocalClearance() const
Definition footprint.h:476
void ClearExtrudedBody()
Definition footprint.h:400
std::deque< PAD * > & Pads()
Definition footprint.h:375
int GetAttributes() const
Definition footprint.h:507
const COMPONENT_CLASS * GetComponentClass() const
Returns the component class for this footprint.
void SetLocalZoneConnection(ZONE_CONNECTION aType)
Definition footprint.h:488
PCB_LAYER_ID GetLayer() const override
Return the primary layer this item is on.
Definition footprint.h:417
void SetExtrudedBody(std::unique_ptr< EXTRUDED_3D_BODY > aBody)
wxString GetSheetfile() const
Definition footprint.h:470
const LIB_ID & GetFPID() const
Definition footprint.h:441
bool IsLocked() const override
Definition footprint.h:634
void SetTransformScale(double aScaleX, double aScaleY)
PCB_FIELD & Reference()
Definition footprint.h:878
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT, bool aSkipConnectivity=false) override
Removes an item from the container.
std::optional< double > GetLocalSolderPasteMarginRatio() const
Definition footprint.h:485
void Flip(const VECTOR2I &aCentre, FLIP_DIRECTION aFlipDirection) override
Flip this object, i.e.
GROUPS & Groups()
Definition footprint.h:384
wxString GetFilters() const
Definition footprint.h:473
void SetSheetname(const wxString &aSheetname)
Definition footprint.h:468
void GetFields(std::vector< PCB_FIELD * > &aVector, bool aVisibleOnly) const
Populate a std::vector with PCB_TEXTs.
std::vector< FP_3DMODEL > & Models()
Definition footprint.h:392
const wxString & GetValue() const
Definition footprint.h:863
void SetLocalSolderMaskMargin(std::optional< int > aMargin)
Definition footprint.h:480
void SetLocalClearance(std::optional< int > aClearance)
Definition footprint.h:477
const KIID_PATH & GetPath() const
Definition footprint.h:464
std::optional< int > GetLocalSolderMaskMargin() const
Definition footprint.h:479
void SetLocalSolderPasteMargin(std::optional< int > aMargin)
Definition footprint.h:483
EMBEDDED_FILES * GetEmbeddedFiles() override
Definition footprint.h:1305
VECTOR2I GetPosition() const override
Definition footprint.h:403
DRAWINGS & GraphicalItems()
Definition footprint.h:378
const UTF8 & GetLibItemName() const
Definition lib_id.h:98
static const int UNCONNECTED
Constant that holds the "unconnected net" number (typically 0) all items "connected" to this net are ...
Definition netinfo.h:256
Definition pad.h:61
void SetPinType(const wxString &aType)
Set the pad electrical type.
Definition pad.h:159
const wxString & GetPinType() const
Definition pad.h:160
const wxString & GetPinFunction() const
Definition pad.h:154
bool IsOnCopperLayer() const override
Definition pad.cpp:1863
void SetPinFunction(const wxString &aName)
Set the pad function (pin name in schematic)
Definition pad.h:153
Abstract dimension API.
A set of BOARD_ITEMs (i.e., without duplicates).
Definition pcb_group.h:49
A PCB_POINT is a 0-dimensional point that is used to mark a position on a PCB, or more usually a foot...
Definition pcb_point.h:39
EDA_ANGLE GetTextAngle() const override
Definition pcb_text.cpp:543
EDA_ITEM * Clone() const override
Create a duplicate of this item with linked list members set to NULL.
Definition pcb_text.cpp:677
int GetTextThickness() const override
Definition pcb_text.cpp:480
void SetTextAngle(const EDA_ANGLE &aAngle) override
Definition pcb_text.cpp:552
VECTOR2I GetTextSize() const override
Definition pcb_text.cpp:453
double GetScaleX() const
double GetScaleY() const
wxString wx_str() const
Definition utf8.cpp:41
Handle a list of polygons defining a copper zone.
Definition zone.h:70
static constexpr EDA_ANGLE ANGLE_0
Definition eda_angle.h:411
@ NO_RECURSE
Definition eda_item.h:50
bool ComputeFootprintShift(const FOOTPRINT &aExisting, const FOOTPRINT &aNew, VECTOR2I &aShift, EDA_ANGLE &aAngleShift)
Compute position and angle shift between two footprints.
Collection of reusable/testable functions for footprint manipulation.
@ TOP_BOTTOM
Flip top to bottom (around the X axis)
Definition mirror.h:25
Class to handle a set of BOARD_ITEMs.
VECTOR2I GetRotated(const VECTOR2I &aVector, const EDA_ANGLE &aAngle)
Return a new VECTOR2I that is the result of rotating aVector by aAngle.
Definition trigo.h:73
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:683