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* aUpdated )
177{
178 EDA_GROUP* parentGroup = aExisting->GetParentGroup();
179 bool dummyBool = false;
180
181 if( !aUpdated )
182 aUpdated = &dummyBool;
183
184 if( parentGroup )
185 {
186 aCommit.Modify( parentGroup->AsEdaItem(), nullptr, RECURSE_MODE::NO_RECURSE );
187 parentGroup->RemoveItem( aExisting );
188 parentGroup->AddItem( aNew );
189 }
190
191 aNew->SetParent( this );
192
193 // This is the position and angle shift to apply to the new footprint if the footprint
194 // has a change anchor point or rotation compared to the existing footprint.
195 VECTOR2I posShift( 0, 0 );
196 EDA_ANGLE angleShift = ANGLE_0;
197
198 VECTOR2I position = aExisting->GetPosition();
199 EDA_ANGLE orientation = aExisting->GetOrientation();
200
201 if( matchPadPositions )
202 {
203 if( ComputeFootprintShift( *aExisting, *aNew, posShift, angleShift ) )
204 {
205 position += posShift;
206 orientation += angleShift;
207 }
208 }
209
210 aNew->SetPosition( position );
211
212 if( aNew->GetLayer() != aExisting->GetLayer() )
214
215 if( aNew->GetOrientation() != orientation )
216 aNew->SetOrientation( orientation );
217
218 aNew->SetLocked( aExisting->IsLocked() );
219
220 aNew->SetUuid( aExisting->m_Uuid );
221 aNew->Reference().SetUuid( aExisting->Reference().m_Uuid );
222 aNew->Value().SetUuid( aExisting->Value().m_Uuid );
223
224 std::vector<PAD*> oldPads;
225 oldPads.reserve( aExisting->Pads().size() );
226
227 for( PAD* pad : aExisting->Pads() )
228 oldPads.push_back( pad );
229
230 std::vector<PAD*> newPads;
231 newPads.reserve( aNew->Pads().size() );
232
233 for( PAD* pad : aNew->Pads() )
234 newPads.push_back( pad );
235
236 auto padMatches = matchItemsBySimilarity<PAD>( oldPads, newPads );
237 std::unordered_set<PAD*> matchedNewPads;
238
239 for( const auto& match : padMatches )
240 {
241 PAD* oldPad = match.first;
242 PAD* newPad = match.second;
243
244 matchedNewPads.insert( newPad );
245 newPad->SetUuid( oldPad->m_Uuid );
247 newPad->SetPinFunction( oldPad->GetPinFunction() );
248 newPad->SetPinType( oldPad->GetPinType() );
249
250 if( newPad->IsOnCopperLayer() )
251 newPad->SetNetCode( oldPad->GetNetCode() );
252 else
254 }
255
256 for( PAD* newPad : aNew->Pads() )
257 {
258 if( matchedNewPads.find( newPad ) != matchedNewPads.end() )
259 continue;
260
261 newPad->ResetUuid();
262 newPad->SetNetCode( NETINFO_LIST::UNCONNECTED );
263 }
264
265 std::vector<BOARD_ITEM*> oldDrawings;
266 oldDrawings.reserve( aExisting->GraphicalItems().size() );
267
268 for( BOARD_ITEM* item : aExisting->GraphicalItems() )
269 oldDrawings.push_back( item );
270
271 std::vector<BOARD_ITEM*> newDrawings;
272 newDrawings.reserve( aNew->GraphicalItems().size() );
273
274 for( BOARD_ITEM* item : aNew->GraphicalItems() )
275 newDrawings.push_back( item );
276
277 auto drawingMatches = matchItemsBySimilarity<BOARD_ITEM>( oldDrawings, newDrawings );
278 std::unordered_map<BOARD_ITEM*, BOARD_ITEM*> oldToNewDrawings;
279 std::unordered_set<BOARD_ITEM*> matchedNewDrawings;
280
281 for( const auto& match : drawingMatches )
282 {
283 BOARD_ITEM* oldItem = match.first;
284 BOARD_ITEM* newItem = match.second;
285
286 oldToNewDrawings[ oldItem ] = newItem;
287 matchedNewDrawings.insert( newItem );
288 newItem->SetUuid( oldItem->m_Uuid );
289 }
290
291 for( BOARD_ITEM* newItem : newDrawings )
292 {
293 if( matchedNewDrawings.find( newItem ) == matchedNewDrawings.end() )
294 newItem->ResetUuid();
295 }
296
297 std::vector<ZONE*> oldZones;
298 oldZones.reserve( aExisting->Zones().size() );
299
300 for( ZONE* zone : aExisting->Zones() )
301 oldZones.push_back( zone );
302
303 std::vector<ZONE*> newZones;
304 newZones.reserve( aNew->Zones().size() );
305
306 for( ZONE* zone : aNew->Zones() )
307 newZones.push_back( zone );
308
309 auto zoneMatches = matchItemsBySimilarity<ZONE>( oldZones, newZones );
310 std::unordered_set<ZONE*> matchedNewZones;
311
312 for( const auto& match : zoneMatches )
313 {
314 ZONE* oldZone = match.first;
315 ZONE* newZone = match.second;
316
317 matchedNewZones.insert( newZone );
318 newZone->SetUuid( oldZone->m_Uuid );
319 }
320
321 for( ZONE* newZone : newZones )
322 {
323 if( matchedNewZones.find( newZone ) == matchedNewZones.end() )
324 newZone->ResetUuid();
325 }
326
327 std::vector<PCB_POINT*> oldPoints;
328 oldPoints.reserve( aExisting->Points().size() );
329
330 for( PCB_POINT* point : aExisting->Points() )
331 oldPoints.push_back( point );
332
333 std::vector<PCB_POINT*> newPoints;
334 newPoints.reserve( aNew->Points().size() );
335
336 for( PCB_POINT* point : aNew->Points() )
337 newPoints.push_back( point );
338
339 auto pointMatches = matchItemsBySimilarity<PCB_POINT>( oldPoints, newPoints );
340 std::unordered_set<PCB_POINT*> matchedNewPoints;
341
342 for( const auto& match : pointMatches )
343 {
344 PCB_POINT* oldPoint = match.first;
345 PCB_POINT* newPoint = match.second;
346
347 matchedNewPoints.insert( newPoint );
348 newPoint->SetUuid( oldPoint->m_Uuid );
349 }
350
351 for( PCB_POINT* newPoint : newPoints )
352 {
353 if( matchedNewPoints.find( newPoint ) == matchedNewPoints.end() )
354 newPoint->ResetUuid();
355 }
356
357 std::vector<PCB_GROUP*> oldGroups;
358 oldGroups.reserve( aExisting->Groups().size() );
359
360 for( PCB_GROUP* group : aExisting->Groups() )
361 oldGroups.push_back( group );
362
363 std::vector<PCB_GROUP*> newGroups;
364 newGroups.reserve( aNew->Groups().size() );
365
366 for( PCB_GROUP* group : aNew->Groups() )
367 newGroups.push_back( group );
368
369 auto groupMatches = matchItemsBySimilarity<PCB_GROUP>( oldGroups, newGroups );
370 std::unordered_set<PCB_GROUP*> matchedNewGroups;
371
372 for( const auto& match : groupMatches )
373 {
374 PCB_GROUP* oldGroup = match.first;
375 PCB_GROUP* newGroup = match.second;
376
377 matchedNewGroups.insert( newGroup );
378 newGroup->SetUuid( oldGroup->m_Uuid );
379 }
380
381 for( PCB_GROUP* newGroup : newGroups )
382 {
383 if( matchedNewGroups.find( newGroup ) == matchedNewGroups.end() )
384 newGroup->ResetUuid();
385 }
386
387 std::vector<PCB_FIELD*> oldFieldsVec;
388 std::vector<PCB_FIELD*> newFieldsVec;
389
390 oldFieldsVec.reserve( aExisting->GetFields().size() );
391
392 for( PCB_FIELD* field : aExisting->GetFields() )
393 {
394 wxCHECK2( field, continue );
395
396 if( field->IsReference() || field->IsValue() )
397 continue;
398
399 oldFieldsVec.push_back( field );
400 }
401
402 newFieldsVec.reserve( aNew->GetFields().size() );
403
404 for( PCB_FIELD* field : aNew->GetFields() )
405 {
406 wxCHECK2( field, continue );
407
408 if( field->IsReference() || field->IsValue() )
409 continue;
410
411 newFieldsVec.push_back( field );
412 }
413
414 auto fieldMatches = matchItemsBySimilarity<PCB_FIELD>( oldFieldsVec, newFieldsVec );
415 std::unordered_map<PCB_FIELD*, PCB_FIELD*> oldToNewFields;
416 std::unordered_set<PCB_FIELD*> matchedNewFields;
417
418 for( const auto& match : fieldMatches )
419 {
420 PCB_FIELD* oldField = match.first;
421 PCB_FIELD* newField = match.second;
422
423 oldToNewFields[ oldField ] = newField;
424 matchedNewFields.insert( newField );
425 newField->SetUuid( oldField->m_Uuid );
426 }
427
428 for( PCB_FIELD* newField : newFieldsVec )
429 {
430 if( matchedNewFields.find( newField ) == matchedNewFields.end() )
431 newField->ResetUuid();
432 }
433
434 std::unordered_map<PCB_TEXT*, PCB_TEXT*> oldToNewTexts;
435
436 for( const auto& match : drawingMatches )
437 {
438 PCB_TEXT* oldText = dynamic_cast<PCB_TEXT*>( match.first );
439 PCB_TEXT* newText = dynamic_cast<PCB_TEXT*>( match.second );
440
441 if( oldText && newText )
442 oldToNewTexts[ oldText ] = newText;
443 }
444
445 std::set<PCB_TEXT*> handledTextItems;
446
447 for( BOARD_ITEM* oldItem : aExisting->GraphicalItems() )
448 {
449 PCB_TEXT* oldTextItem = dynamic_cast<PCB_TEXT*>( oldItem );
450
451 if( oldTextItem )
452 {
453 // Dimensions have PCB_TEXT base but are not treated like texts in the updater
454 if( dynamic_cast<PCB_DIMENSION_BASE*>( oldTextItem ) )
455 continue;
456
457 PCB_TEXT* newTextItem = nullptr;
458
459 auto textMatchIt = oldToNewTexts.find( oldTextItem );
460
461 if( textMatchIt != oldToNewTexts.end() )
462 newTextItem = textMatchIt->second;
463
464 if( newTextItem )
465 {
466 handledTextItems.insert( newTextItem );
467 processTextItem( *oldTextItem, *newTextItem, posShift, angleShift, resetTextContent, resetTextLayers,
468 resetTextEffects, resetTextPositions, aUpdated );
469 }
470 else if( deleteExtraTexts )
471 {
472 *aUpdated = true;
473 }
474 else
475 {
476 newTextItem = static_cast<PCB_TEXT*>( oldTextItem->Clone() );
477 handledTextItems.insert( newTextItem );
478 aNew->Add( newTextItem );
479 }
480 }
481 }
482
483 // Check for any newly-added text items and set the update flag as appropriate
484 for( BOARD_ITEM* newItem : aNew->GraphicalItems() )
485 {
486 PCB_TEXT* newTextItem = dynamic_cast<PCB_TEXT*>( newItem );
487
488 if( newTextItem )
489 {
490 // Dimensions have PCB_TEXT base but are not treated like texts in the updater
491 if( dynamic_cast<PCB_DIMENSION_BASE*>( newTextItem ) )
492 continue;
493
494 if( !handledTextItems.contains( newTextItem ) )
495 {
496 *aUpdated = true;
497 break;
498 }
499 }
500 }
501
502 // Copy reference. The initial text is always used, never resetted
503 processTextItem( aExisting->Reference(), aNew->Reference(), posShift, angleShift, false, resetTextLayers,
504 resetTextEffects, resetTextPositions, aUpdated );
505
506 // Copy value
507 processTextItem( aExisting->Value(), aNew->Value(), posShift, angleShift,
508 // reset value text only when it is a proxy for the footprint ID
509 // (cf replacing value "MountingHole-2.5mm" with "MountingHole-4.0mm")
510 aExisting->GetValue() == aExisting->GetFPID().GetLibItemName().wx_str(),
511 resetTextLayers, resetTextEffects, resetTextPositions, aUpdated );
512
513 std::set<PCB_FIELD*> handledFields;
514
515 // Copy fields in accordance with the reset* flags
516 for( PCB_FIELD* oldField : aExisting->GetFields() )
517 {
518 wxCHECK2( oldField, continue );
519
520 // Reference and value are already handled
521 if( oldField->IsReference() || oldField->IsValue() )
522 continue;
523
524 PCB_FIELD* newField = nullptr;
525
526 auto fieldMatchIt = oldToNewFields.find( oldField );
527
528 if( fieldMatchIt != oldToNewFields.end() )
529 newField = fieldMatchIt->second;
530
531 if( newField )
532 {
533 handledFields.insert( newField );
534 processTextItem( *oldField, *newField, posShift, angleShift, resetTextContent, resetTextLayers,
535 resetTextEffects, resetTextPositions, aUpdated );
536 }
537 else if( deleteExtraTexts )
538 {
539 *aUpdated = true;
540 }
541 else
542 {
543 newField = new PCB_FIELD( *oldField );
544 handledFields.insert( newField );
545 aNew->Add( newField );
546 }
547 }
548
549 // Check for any newly-added fields and set the update flag as appropriate
550 for( PCB_FIELD* newField : aNew->GetFields() )
551 {
552 wxCHECK2( newField, continue );
553
554 // Reference and value are already handled
555 if( newField->IsReference() || newField->IsValue() )
556 continue;
557
558 if( !handledFields.contains( newField ) )
559 {
560 *aUpdated = true;
561 break;
562 }
563 }
564
565 if( resetFabricationAttrs )
566 {
567 // We've replaced the existing footprint with the library one, so the fabrication attrs
568 // are already reset. Just set the aUpdated flag if appropriate.
569 if( aNew->GetAttributes() != aExisting->GetAttributes() )
570 *aUpdated = true;
571 }
572 else
573 {
574 aNew->SetAttributes( aExisting->GetAttributes() );
575 }
576
577 if( resetClearanceOverrides )
578 {
579 if( aExisting->AllowSolderMaskBridges() != aNew->AllowSolderMaskBridges() )
580 *aUpdated = true;
581
582 if( ( aExisting->GetLocalClearance() != aNew->GetLocalClearance() )
583 || ( aExisting->GetLocalSolderMaskMargin() != aNew->GetLocalSolderMaskMargin() )
584 || ( aExisting->GetLocalSolderPasteMargin() != aNew->GetLocalSolderPasteMargin() )
586 || ( aExisting->GetLocalZoneConnection() != aNew->GetLocalZoneConnection() ) )
587 {
588 *aUpdated = true;
589 }
590 }
591 else
592 {
593 aNew->SetLocalClearance( aExisting->GetLocalClearance() );
599 }
600
601 if( reset3DModels )
602 {
603 // We've replaced the existing footprint with the library one, so the 3D models are
604 // already reset. Just set the aUpdated flag if appropriate.
605 if( aNew->Models().size() != aExisting->Models().size() )
606 {
607 *aUpdated = true;
608 }
609 else
610 {
611 for( size_t ii = 0; ii < aNew->Models().size(); ++ii )
612 {
613 if( aNew->Models()[ii] != aExisting->Models()[ii] )
614 {
615 *aUpdated = true;
616 break;
617 }
618 }
619 }
620 }
621 else
622 {
623 // Preserve model references and all embedded model data.
624 aNew->Models() = aExisting->Models();
625
626 // Preserve extruded 3D body settings.
627 if( aExisting->HasExtrudedBody() )
628 aNew->SetExtrudedBody( std::make_unique<EXTRUDED_3D_BODY>( *aExisting->GetExtrudedBody() ) );
629 else
630 aNew->ClearExtrudedBody();
631
632 for( const auto& [name, file] : aExisting->GetEmbeddedFiles()->EmbeddedFileMap() )
633 {
635 continue;
636
637 aNew->GetEmbeddedFiles()->RemoveFile( name, true );
639 }
640 }
641
642 // Updating other parameters
643 aNew->SetPath( aExisting->GetPath() );
644 aNew->SetSheetfile( aExisting->GetSheetfile() );
645 aNew->SetSheetname( aExisting->GetSheetname() );
646 aNew->SetFilters( aExisting->GetFilters() );
647 aNew->SetStaticComponentClass( aExisting->GetComponentClass() );
648
649 if( *aUpdated == false )
650 {
651 // Check pad shapes, graphics, zones, etc. for changes
653 *aUpdated = true;
654 }
655
656 aCommit.Remove( aExisting );
657 aCommit.Add( aNew );
658
659 aNew->ClearFlags();
660}
661
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:82
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
Definition board_item.h:264
void SetLocked(bool aLocked) override
Definition board_item.h:355
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:312
VECTOR2I GetFPRelativePosition() const
@ INSTANCE_TO_INSTANCE
Definition board_item.h:474
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 *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
const EDA_ANGLE & GetTextAngle() const
Definition eda_text.h:168
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
virtual void SetTextAngle(const EDA_ANGLE &aAngle)
Definition eda_text.cpp:294
int GetTextThickness() const
Definition eda_text.h:149
VECTOR2I GetTextSize() const
Definition eda_text.h:282
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, EMBEDDED_FILE * > & EmbeddedFileMap() const
bool AllowSolderMaskBridges() const
Definition footprint.h:497
void SetPosition(const VECTOR2I &aPos) override
ZONE_CONNECTION GetLocalZoneConnection() const
Definition footprint.h:473
void SetLocked(bool isLocked) override
Set the #MODULE_is_LOCKED bit in the m_ModuleStatus.
Definition footprint.h:628
EDA_ANGLE GetOrientation() const
Definition footprint.h:404
ZONES & Zones()
Definition footprint.h:379
PCB_POINTS & Points()
Definition footprint.h:385
void SetOrientation(const EDA_ANGLE &aNewAngle)
void SetAllowSolderMaskBridges(bool aAllow)
Definition footprint.h:498
void SetLocalSolderPasteMarginRatio(std::optional< double > aRatio)
Definition footprint.h:470
wxString GetSheetname() const
Definition footprint.h:451
void SetPath(const KIID_PATH &aPath)
Definition footprint.h:449
void SetFilters(const wxString &aFilters)
Definition footprint.h:458
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:394
void SetAttributes(int aAttributes)
Definition footprint.h:492
void SetSheetfile(const wxString &aSheetfile)
Definition footprint.h:455
std::optional< int > GetLocalSolderPasteMargin() const
Definition footprint.h:466
PCB_FIELD & Value()
read/write accessors:
Definition footprint.h:861
bool HasExtrudedBody() const
Definition footprint.h:393
std::optional< int > GetLocalClearance() const
Definition footprint.h:460
void ClearExtrudedBody()
Definition footprint.h:398
std::deque< PAD * > & Pads()
Definition footprint.h:373
int GetAttributes() const
Definition footprint.h:491
const COMPONENT_CLASS * GetComponentClass() const
Returns the component class for this footprint.
void SetLocalZoneConnection(ZONE_CONNECTION aType)
Definition footprint.h:472
PCB_LAYER_ID GetLayer() const override
Return the primary layer this item is on.
Definition footprint.h:413
void SetExtrudedBody(std::unique_ptr< EXTRUDED_3D_BODY > aBody)
wxString GetSheetfile() const
Definition footprint.h:454
const LIB_ID & GetFPID() const
Definition footprint.h:425
bool IsLocked() const override
Definition footprint.h:618
PCB_FIELD & Reference()
Definition footprint.h:862
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:469
void Flip(const VECTOR2I &aCentre, FLIP_DIRECTION aFlipDirection) override
Flip this object, i.e.
GROUPS & Groups()
Definition footprint.h:382
wxString GetFilters() const
Definition footprint.h:457
void SetSheetname(const wxString &aSheetname)
Definition footprint.h:452
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:390
const wxString & GetValue() const
Definition footprint.h:847
void SetLocalSolderMaskMargin(std::optional< int > aMargin)
Definition footprint.h:464
void SetLocalClearance(std::optional< int > aClearance)
Definition footprint.h:461
const KIID_PATH & GetPath() const
Definition footprint.h:448
std::optional< int > GetLocalSolderMaskMargin() const
Definition footprint.h:463
void SetLocalSolderPasteMargin(std::optional< int > aMargin)
Definition footprint.h:467
EMBEDDED_FILES * GetEmbeddedFiles() override
Definition footprint.h:1289
VECTOR2I GetPosition() const override
Definition footprint.h:401
DRAWINGS & GraphicalItems()
Definition footprint.h:376
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:1591
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_ITEM * Clone() const override
Create a duplicate of this item with linked list members set to NULL.
Definition pcb_text.cpp:520
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