KiCad PCB EDA Suite
class_module.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 (C) 2017 Jean-Pierre Charras, jp.charras at wanadoo.fr
5  * Copyright (C) 2015 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
6  * Copyright (C) 2015 Wayne Stambaugh <stambaughw@gmail.com>
7  * Copyright (C) 1992-2020 KiCad Developers, see AUTHORS.txt for contributors.
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License
11  * as published by the Free Software Foundation; either version 2
12  * of the License, or (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, you may find one here:
21  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
22  * or you may search the http://www.gnu.org website for the version 2 license,
23  * or you may write to the Free Software Foundation, Inc.,
24  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
25  */
26 
27 #include <fctsys.h>
28 #include <gr_basic.h>
29 #include <confirm.h>
30 #include <refdes_utils.h>
31 #include <bitmaps.h>
32 #include <unordered_set>
33 #include <pcb_edit_frame.h>
34 #include <class_board.h>
35 #include <class_edge_mod.h>
36 #include <class_module.h>
37 #include <view/view.h>
38 #include <geometry/shape_null.h>
39 
40 MODULE::MODULE( BOARD* parent ) :
42  m_initial_comments( 0 )
43 {
44  m_Attributs = 0;
45  m_Layer = F_Cu;
46  m_Orient = 0;
48  m_arflag = 0;
49  m_CntRot90 = m_CntRot180 = 0;
50  m_Link = 0;
51  m_LastEditTime = 0;
52  m_LocalClearance = 0;
56  m_ZoneConnection = ZONE_CONNECTION::INHERITED; // Use zone setting by default
57  m_ThermalWidth = 0; // Use zone setting by default
58  m_ThermalGap = 0; // Use zone setting by default
59 
60  // These are special and mandatory text fields
63 
64  m_3D_Drawings.clear();
65 }
66 
67 
68 MODULE::MODULE( const MODULE& aModule ) :
69  BOARD_ITEM_CONTAINER( aModule )
70 {
71  m_Pos = aModule.m_Pos;
72  m_fpid = aModule.m_fpid;
73  m_Attributs = aModule.m_Attributs;
75  m_Orient = aModule.m_Orient;
76  m_BoundaryBox = aModule.m_BoundaryBox;
77  m_CntRot90 = aModule.m_CntRot90;
78  m_CntRot180 = aModule.m_CntRot180;
80  m_Link = aModule.m_Link;
81  m_Path = aModule.m_Path;
82 
89  m_ThermalGap = aModule.m_ThermalGap;
90 
91  // Copy reference and value.
92  m_Reference = new TEXTE_MODULE( *aModule.m_Reference );
93  m_Reference->SetParent( this );
94  m_Value = new TEXTE_MODULE( *aModule.m_Value );
95  m_Value->SetParent( this );
96 
97  // Copy auxiliary data: Pads
98  for( D_PAD* pad : aModule.Pads() )
99  Add( static_cast<D_PAD*>( pad->Clone() ) );
100 
101  // Copy auxiliary data: Zones
102  for( MODULE_ZONE_CONTAINER* item : aModule.Zones() )
103  {
104  Add( static_cast<MODULE_ZONE_CONTAINER*>( item->Clone() ) );
105 
106  // Ensure the net info is OK and especially uses the net info list
107  // living in the current board
108  // Needed when copying a fp from fp editor that has its own board
109  // Must be NETINFO_LIST::ORPHANED_ITEM for a keepout that has no net.
110  item->SetNetCode( -1 );
111  }
112 
113  // Copy auxiliary data: Drawings
114  for( BOARD_ITEM* item : aModule.GraphicalItems() )
115  {
116  switch( item->Type() )
117  {
118  case PCB_MODULE_TEXT_T:
119  case PCB_MODULE_EDGE_T:
120  Add( static_cast<BOARD_ITEM*>( item->Clone() ) );
121  break;
122 
123  default:
124  wxLogMessage( wxT( "Class MODULE copy constructor internal error: unknown type" ) );
125  break;
126  }
127  }
128 
129  // Copy auxiliary data: 3D_Drawings info
130  m_3D_Drawings = aModule.m_3D_Drawings;
131 
132  m_Doc = aModule.m_Doc;
133  m_KeyWord = aModule.m_KeyWord;
134  m_properties = aModule.m_properties;
135 
136  m_arflag = 0;
137 
138  // Ensure auxiliary data is up to date
140 
142  new wxArrayString( *aModule.m_initial_comments ) : nullptr;
143 }
144 
145 
146 MODULE::MODULE( MODULE&& aModule ) :
147  BOARD_ITEM_CONTAINER( aModule )
148 {
149  *this = std::move( aModule );
150 }
151 
152 
154 {
155  // Clean up the owned elements
156  delete m_Reference;
157  delete m_Value;
158  delete m_initial_comments;
159 
160  for( D_PAD* p : m_pads )
161  delete p;
162 
163  m_pads.clear();
164 
166  delete p;
167 
168  m_fp_zones.clear();
169 
170  for( BOARD_ITEM* d : m_drawings )
171  delete d;
172 
173  m_drawings.clear();
174 }
175 
176 
178 {
179  BOARD_ITEM::operator=( aOther );
180 
181  m_Pos = aOther.m_Pos;
182  m_fpid = aOther.m_fpid;
183  m_Attributs = aOther.m_Attributs;
184  m_ModuleStatus = aOther.m_ModuleStatus;
185  m_Orient = aOther.m_Orient;
186  m_BoundaryBox = aOther.m_BoundaryBox;
187  m_CntRot90 = aOther.m_CntRot90;
188  m_CntRot180 = aOther.m_CntRot180;
189  m_LastEditTime = aOther.m_LastEditTime;
190  m_Link = aOther.m_Link;
191  m_Path = aOther.m_Path;
192 
193  m_LocalClearance = aOther.m_LocalClearance;
194  m_LocalSolderMaskMargin = aOther.m_LocalSolderMaskMargin;
195  m_LocalSolderPasteMargin = aOther.m_LocalSolderPasteMargin;
196  m_LocalSolderPasteMarginRatio = aOther.m_LocalSolderPasteMarginRatio;
197  m_ZoneConnection = aOther.m_ZoneConnection;
198  m_ThermalWidth = aOther.m_ThermalWidth;
199  m_ThermalGap = aOther.m_ThermalGap;
200 
201  // Move reference and value
202  m_Reference = aOther.m_Reference;
203  m_Reference->SetParent( this );
204  m_Value = aOther.m_Value;
205  m_Value->SetParent( this );
206 
207 
208  // Move the pads
209  m_pads.clear();
210 
211  for( D_PAD* pad : aOther.Pads() )
212  Add( pad );
213 
214  // Move the zones
215  m_fp_zones.clear();
216 
217  for( MODULE_ZONE_CONTAINER* item : aOther.Zones() )
218  {
219  Add( static_cast<MODULE_ZONE_CONTAINER*>( item ) );
220 
221  // Ensure the net info is OK and especially uses the net info list
222  // living in the current board
223  // Needed when copying a fp from fp editor that has its own board
224  // Must be NETINFO_LIST::ORPHANED_ITEM for a keepout that has no net.
225  item->SetNetCode( -1 );
226  }
227 
228  // Move the drawings
229  m_drawings.clear();
230 
231  for( BOARD_ITEM* item : aOther.GraphicalItems() )
232  {
233  switch( item->Type() )
234  {
235  case PCB_MODULE_TEXT_T:
236  case PCB_MODULE_EDGE_T:
237  Add( static_cast<BOARD_ITEM*>( item ) );
238  break;
239 
240  default:
241  wxLogMessage( wxT( "MODULE::operator=() internal error: unknown type" ) );
242  break;
243  }
244  }
245 
246  // Copy auxiliary data: 3D_Drawings info
247  m_3D_Drawings.clear();
248  m_3D_Drawings = aOther.m_3D_Drawings;
249  m_Doc = aOther.m_Doc;
250  m_KeyWord = aOther.m_KeyWord;
251  m_properties = aOther.m_properties;
252 
253  // Ensure auxiliary data is up to date
255 
256  m_initial_comments = aOther.m_initial_comments;
257 
258  // Clear the other item's containers since this is a move
259  aOther.Pads().clear();
260  aOther.Zones().clear();
261  aOther.GraphicalItems().clear();
262  aOther.m_Value = nullptr;
263  aOther.m_Reference = nullptr;
264  aOther.m_initial_comments = nullptr;
265 
266  return *this;
267 }
268 
269 
270 MODULE& MODULE::operator=( const MODULE& aOther )
271 {
272  BOARD_ITEM::operator=( aOther );
273 
274  m_Pos = aOther.m_Pos;
275  m_fpid = aOther.m_fpid;
276  m_Attributs = aOther.m_Attributs;
278  m_Orient = aOther.m_Orient;
279  m_BoundaryBox = aOther.m_BoundaryBox;
280  m_CntRot90 = aOther.m_CntRot90;
281  m_CntRot180 = aOther.m_CntRot180;
283  m_Link = aOther.m_Link;
284  m_Path = aOther.m_Path;
285 
292  m_ThermalGap = aOther.m_ThermalGap;
293 
294  // Copy reference and value
295  *m_Reference = *aOther.m_Reference;
296  m_Reference->SetParent( this );
297  *m_Value = *aOther.m_Value;
298  m_Value->SetParent( this );
299 
300  // Copy auxiliary data: Pads
301  m_pads.clear();
302 
303  for( D_PAD* pad : aOther.Pads() )
304  Add( new D_PAD( *pad ) );
305 
306  // Copy auxiliary data: Zones
307  m_fp_zones.clear();
308 
309  for( MODULE_ZONE_CONTAINER* item : aOther.Zones() )
310  {
311  Add( static_cast<MODULE_ZONE_CONTAINER*>( item->Clone() ) );
312 
313  // Ensure the net info is OK and especially uses the net info list
314  // living in the current board
315  // Needed when copying a fp from fp editor that has its own board
316  // Must be NETINFO_LIST::ORPHANED_ITEM for a keepout that has no net.
317  item->SetNetCode( -1 );
318  }
319 
320  // Copy auxiliary data: Drawings
321  m_drawings.clear();
322 
323  for( BOARD_ITEM* item : aOther.GraphicalItems() )
324  {
325  switch( item->Type() )
326  {
327  case PCB_MODULE_TEXT_T:
328  case PCB_MODULE_EDGE_T:
329  Add( static_cast<BOARD_ITEM*>( item->Clone() ) );
330  break;
331 
332  default:
333  wxLogMessage( wxT( "MODULE::operator=() internal error: unknown type" ) );
334  break;
335  }
336  }
337 
338  // Copy auxiliary data: 3D_Drawings info
339  m_3D_Drawings.clear();
340  m_3D_Drawings = aOther.m_3D_Drawings;
341  m_Doc = aOther.m_Doc;
342  m_KeyWord = aOther.m_KeyWord;
343  m_properties = aOther.m_properties;
344 
345  // Ensure auxiliary data is up to date
347 
349  new wxArrayString( *aOther.m_initial_comments ) : nullptr;
350 
351  return *this;
352 }
353 
354 
355 void MODULE::GetContextualTextVars( wxArrayString* aVars ) const
356 {
357  aVars->push_back( wxT( "REFERENCE" ) );
358  aVars->push_back( wxT( "VALUE" ) );
359  aVars->push_back( wxT( "LAYER" ) );
360 }
361 
362 
363 bool MODULE::ResolveTextVar( wxString* token, int aDepth ) const
364 {
365  if( token->IsSameAs( wxT( "REFERENCE" ) ) )
366  {
367  *token = m_Reference->GetShownText( aDepth + 1 );
368  return true;
369  }
370  else if( token->IsSameAs( wxT( "VALUE" ) ) )
371  {
372  *token = m_Value->GetShownText( aDepth + 1 );
373  return true;
374  }
375  else if( token->IsSameAs( wxT( "LAYER" ) ) )
376  {
377  *token = GetLayerName();
378  return true;
379  }
380  else if( m_properties.count( *token ) )
381  {
382  *token = m_properties.at( *token );
383  return true;
384  }
385 
386  return false;
387 }
388 
389 
391 {
392  // Force the ORPHANED dummy net info for all pads.
393  // ORPHANED dummy net does not depend on a board
394  for( auto pad : m_pads )
395  pad->SetNetCode( NETINFO_LIST::ORPHANED );
396 }
397 
398 
399 void MODULE::Add( BOARD_ITEM* aBoardItem, ADD_MODE aMode )
400 {
401  switch( aBoardItem->Type() )
402  {
403  case PCB_MODULE_TEXT_T:
404  // Only user text can be added this way.
405  assert( static_cast<TEXTE_MODULE*>( aBoardItem )->GetType() == TEXTE_MODULE::TEXT_is_DIVERS );
407 
408  case PCB_MODULE_EDGE_T:
409  if( aMode == ADD_MODE::APPEND )
410  m_drawings.push_back( aBoardItem );
411  else
412  m_drawings.push_front( aBoardItem );
413  break;
414 
415  case PCB_PAD_T:
416  if( aMode == ADD_MODE::APPEND )
417  m_pads.push_back( static_cast<D_PAD*>( aBoardItem ) );
418  else
419  m_pads.push_front( static_cast<D_PAD*>( aBoardItem ) );
420  break;
421 
423  if( aMode == ADD_MODE::APPEND )
424  m_fp_zones.push_back( static_cast<MODULE_ZONE_CONTAINER*>( aBoardItem ) );
425  else
426  m_fp_zones.insert( m_fp_zones.begin(), static_cast<MODULE_ZONE_CONTAINER*>( aBoardItem ) );
427  break;
428 
429  default:
430  {
431  wxString msg;
432  msg.Printf( wxT( "MODULE::Add() needs work: BOARD_ITEM type (%d) not handled" ),
433  aBoardItem->Type() );
434  wxFAIL_MSG( msg );
435 
436  return;
437  }
438  }
439 
440  aBoardItem->ClearEditFlags();
441  aBoardItem->SetParent( this );
442 }
443 
444 
445 void MODULE::Remove( BOARD_ITEM* aBoardItem )
446 {
447  switch( aBoardItem->Type() )
448  {
449  case PCB_MODULE_TEXT_T:
450  // Only user text can be removed this way.
451  wxCHECK_RET(
452  static_cast<TEXTE_MODULE*>( aBoardItem )->GetType() == TEXTE_MODULE::TEXT_is_DIVERS,
453  "Please report this bug: Invalid remove operation on required text" );
455 
456  case PCB_MODULE_EDGE_T:
457  for( auto it = m_drawings.begin(); it != m_drawings.end(); ++it )
458  {
459  if( *it == aBoardItem )
460  {
461  m_drawings.erase( it );
462  break;
463  }
464  }
465 
466  break;
467 
468  case PCB_PAD_T:
469  for( auto it = m_pads.begin(); it != m_pads.end(); ++it )
470  {
471  if( *it == static_cast<D_PAD*>( aBoardItem ) )
472  {
473  m_pads.erase( it );
474  break;
475  }
476  }
477 
478  break;
479 
481  for( auto it = m_fp_zones.begin(); it != m_fp_zones.end(); ++it )
482  {
483  if( *it == static_cast<MODULE_ZONE_CONTAINER*>( aBoardItem ) )
484  {
485  m_fp_zones.erase( it );
486  break;
487  }
488  }
489 
490  break;
491 
492  default:
493  {
494  wxString msg;
495  msg.Printf( wxT( "MODULE::Remove() needs work: BOARD_ITEM type (%d) not handled" ),
496  aBoardItem->Type() );
497  wxFAIL_MSG( msg );
498  }
499  }
500 }
501 
502 
504 {
506 }
507 
508 
509 double MODULE::GetArea( int aPadding ) const
510 {
511  double w = std::abs( m_BoundaryBox.GetWidth() ) + aPadding;
512  double h = std::abs( m_BoundaryBox.GetHeight() ) + aPadding;
513  return w * h;
514 }
515 
516 
518 {
519  EDA_RECT area;
520 
521  area.SetOrigin( m_Pos );
522  area.SetEnd( m_Pos );
523  area.Inflate( Millimeter2iu( 0.25 ) ); // Give a min size to the area
524 
525  for( BOARD_ITEM* item : m_drawings )
526  {
527  if( item->Type() == PCB_MODULE_EDGE_T )
528  area.Merge( item->GetBoundingBox() );
529  }
530 
531  for( D_PAD* pad : m_pads )
532  area.Merge( pad->GetBoundingBox() );
533 
534  for( MODULE_ZONE_CONTAINER* zone : m_fp_zones )
535  area.Merge( zone->GetBoundingBox() );
536 
537  return area;
538 }
539 
540 
542 {
543  EDA_RECT area;
544 
545  // We want the bounding box of the footprint pads at rot 0, not flipped
546  // Create such a image:
547  MODULE dummy( *this );
548 
549  dummy.SetPosition( wxPoint( 0, 0 ) );
550  if( dummy.IsFlipped() )
551  dummy.Flip( wxPoint( 0, 0 ) , false );
552 
553  if( dummy.GetOrientation() )
554  dummy.SetOrientation( 0 );
555 
556  for( auto pad : dummy.Pads() )
557  area.Merge( pad->GetBoundingBox() );
558 
559  return area;
560 }
561 
562 
564 {
565  return GetBoundingBox( true );
566 }
567 
568 
569 const EDA_RECT MODULE::GetBoundingBox( bool aIncludeInvisibleText ) const
570 {
571  EDA_RECT area = GetFootprintRect();
572 
573  // Add in items not collected by GetFootprintRect():
574  for( BOARD_ITEM* item : m_drawings )
575  {
576  if( item->Type() != PCB_MODULE_EDGE_T )
577  area.Merge( item->GetBoundingBox() );
578  }
579 
580  // This can be further optimized when aIncludeInvisibleText is true, but currently
581  // leaving this as is until it's determined there is a noticeable speed hit.
582  bool valueLayerIsVisible = true;
583  bool refLayerIsVisible = true;
584  BOARD* board = GetBoard();
585 
586  if( board )
587  {
588  // The first "&&" conditional handles the user turning layers off as well as layers
589  // not being present in the current PCB stackup. Values, references, and all
590  // footprint text can also be turned off via the GAL meta-layers, so the 2nd and
591  // 3rd "&&" conditionals handle that.
592  valueLayerIsVisible = board->IsLayerVisible( m_Value->GetLayer() )
594  && board->IsElementVisible( LAYER_MOD_TEXT_FR );
595 
596  refLayerIsVisible = board->IsLayerVisible( m_Reference->GetLayer() )
598  && board->IsElementVisible( LAYER_MOD_TEXT_FR );
599  }
600 
601 
602  if( ( m_Value->IsVisible() && valueLayerIsVisible ) || aIncludeInvisibleText )
603  area.Merge( m_Value->GetBoundingBox() );
604 
605  if( ( m_Reference->IsVisible() && refLayerIsVisible ) || aIncludeInvisibleText )
606  area.Merge( m_Reference->GetBoundingBox() );
607 
608  return area;
609 }
610 
611 
627 {
628  SHAPE_POLY_SET poly;
629 
630  double orientation = GetOrientationRadians();
631 
632  MODULE temp = *this;
633  temp.SetOrientation( 0.0 );
634  BOX2I area = temp.GetFootprintRect();
635 
636  poly.NewOutline();
637 
638  VECTOR2I p = area.GetPosition();
639  poly.Append( p );
640  p.x = area.GetRight();
641  poly.Append( p );
642  p.y = area.GetBottom();
643  poly.Append( p );
644  p.x = area.GetX();
645  poly.Append( p );
646 
647  BOARD* board = GetBoard();
648  if( board )
649  {
650  int biggest_clearance = board->GetDesignSettings().GetBiggestClearanceValue();
651  poly.Inflate( biggest_clearance, 4 );
652  }
653 
654  poly.Inflate( Millimeter2iu( 0.01 ), 4 );
655  poly.Rotate( -orientation, m_Pos );
656 
657  return poly;
658 }
659 
660 
661 void MODULE::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList )
662 {
663  wxString msg, msg2;
664 
665  aList.emplace_back( m_Reference->GetShownText(), m_Value->GetShownText(), DARKCYAN );
666 
667  if( aFrame->IsType( FRAME_FOOTPRINT_VIEWER )
669  || aFrame->IsType( FRAME_FOOTPRINT_EDITOR ) )
670  {
671  wxDateTime date( static_cast<time_t>( m_LastEditTime ) );
672 
673  // Date format: see http://www.cplusplus.com/reference/ctime/strftime
674  if( m_LastEditTime && date.IsValid() )
675  msg = date.Format( wxT( "%b %d, %Y" ) ); // Abbreviated_month_name Day, Year
676  else
677  msg = _( "Unknown" );
678 
679  aList.emplace_back( _( "Last Change" ), msg, BROWN );
680  }
681  else if( aFrame->IsType( FRAME_PCB_EDITOR ) )
682  {
683  aList.emplace_back( _( "Board Side" ), IsFlipped() ? _( "Back (Flipped)" )
684  : _( "Front" ), RED );
685  }
686 
687  auto addToken = []( wxString* aStr, const wxString& aAttr )
688  {
689  if( !aStr->IsEmpty() )
690  *aStr += wxT( ", " );
691 
692  *aStr += aAttr;
693  };
694 
695  wxString status;
696  wxString attrs;
697 
698  if( IsLocked() )
699  addToken( &status, _( "locked" ) );
700 
702  addToken( &status, _( "autoplaced" ) );
703 
705  addToken( &attrs, _( "not in schematic" ) );
706 
708  addToken( &attrs, _( "exclude from pos files" ) );
709 
711  addToken( &attrs, _( "exclude from BOM" ) );
712 
713  aList.emplace_back( _( "Status: " ) + status, _( "Attributes: " ) + attrs, BROWN );
714 
715  msg.Printf( "%.2f", GetOrientationDegrees() );
716  aList.emplace_back( _( "Rotation" ), msg, BROWN );
717 
718  msg.Printf( _( "Footprint: %s" ),
719  GetChars( m_fpid.Format().c_str() ) );
720  msg2.Printf( _( "3D-Shape: %s" ),
721  m_3D_Drawings.empty() ? _( "none" ) : m_3D_Drawings.front().m_Filename );
722  aList.emplace_back( msg, msg2, BLUE );
723 
724  msg.Printf( _( "Doc: %s" ), m_Doc );
725  msg2.Printf( _( "Keywords: %s" ), m_KeyWord );
726  aList.emplace_back( msg, msg2, BLACK );
727 }
728 
729 
730 bool MODULE::HitTest( const wxPoint& aPosition, int aAccuracy ) const
731 {
732  EDA_RECT rect = m_BoundaryBox;//.GetBoundingBoxRotated( GetPosition(), m_Orient );
733  return rect.Inflate( aAccuracy ).Contains( aPosition );
734 }
735 
736 
737 bool MODULE::HitTestAccurate( const wxPoint& aPosition, int aAccuracy ) const
738 {
739  return GetBoundingPoly().Collide( aPosition, aAccuracy );
740 }
741 
742 
743 bool MODULE::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const
744 {
745  EDA_RECT arect = aRect;
746  arect.Inflate( aAccuracy );
747 
748  if( aContained )
749  return arect.Contains( m_BoundaryBox );
750  else
751  {
752  // If the rect does not intersect the bounding box, skip any tests
753  if( !aRect.Intersects( GetBoundingBox() ) )
754  return false;
755 
756  // Determine if any elements in the MODULE intersect the rect
757  for( D_PAD* pad : m_pads )
758  {
759  if( pad->HitTest( arect, false, 0 ) )
760  return true;
761  }
762 
763  for( MODULE_ZONE_CONTAINER* zone : m_fp_zones )
764  {
765  if( zone->HitTest( arect, false, 0 ) )
766  return true;
767  }
768 
769  for( BOARD_ITEM* item : m_drawings )
770  {
771  if( item->HitTest( arect, false, 0 ) )
772  return true;
773  }
774 
775  // No items were hit
776  return false;
777  }
778 }
779 
780 
781 D_PAD* MODULE::FindPadByName( const wxString& aPadName ) const
782 {
783  for( D_PAD* pad : m_pads )
784  {
785  if( pad->GetName() == aPadName )
786  return pad;
787  }
788 
789  return NULL;
790 }
791 
792 
793 D_PAD* MODULE::GetPad( const wxPoint& aPosition, LSET aLayerMask )
794 {
795  for( D_PAD* pad : m_pads )
796  {
797  // ... and on the correct layer.
798  if( !( pad->GetLayerSet() & aLayerMask ).any() )
799  continue;
800 
801  if( pad->HitTest( aPosition ) )
802  return pad;
803  }
804 
805  return NULL;
806 }
807 
808 
810 {
811  D_PAD* topLeftPad = GetFirstPad();
812 
813  for( D_PAD* p : m_pads )
814  {
815  wxPoint pnt = p->GetPosition(); // GetPosition() returns the center of the pad
816 
817  if( ( pnt.x < topLeftPad->GetPosition().x ) ||
818  ( topLeftPad->GetPosition().x == pnt.x && pnt.y < topLeftPad->GetPosition().y ) )
819  {
820  topLeftPad = p;
821  }
822  }
823 
824  return topLeftPad;
825 }
826 
827 
828 unsigned MODULE::GetPadCount( INCLUDE_NPTH_T aIncludeNPTH ) const
829 {
830  if( aIncludeNPTH )
831  return m_pads.size();
832 
833  unsigned cnt = 0;
834 
835  for( D_PAD* pad : m_pads )
836  {
837  if( pad->GetAttribute() == PAD_ATTRIB_HOLE_NOT_PLATED )
838  continue;
839 
840  cnt++;
841  }
842 
843  return cnt;
844 }
845 
846 
847 unsigned MODULE::GetUniquePadCount( INCLUDE_NPTH_T aIncludeNPTH ) const
848 {
849  std::set<wxString> usedNames;
850 
851  // Create a set of used pad numbers
852  for( D_PAD* pad : m_pads )
853  {
854  // Skip pads not on copper layers (used to build complex
855  // solder paste shapes for instance)
856  if( ( pad->GetLayerSet() & LSET::AllCuMask() ).none() )
857  continue;
858 
859  // Skip pads with no name, because they are usually "mechanical"
860  // pads, not "electrical" pads
861  if( pad->GetName().IsEmpty() )
862  continue;
863 
864  if( !aIncludeNPTH )
865  {
866  // skip NPTH
867  if( pad->GetAttribute() == PAD_ATTRIB_HOLE_NOT_PLATED )
868  {
869  continue;
870  }
871  }
872 
873  usedNames.insert( pad->GetName() );
874  }
875 
876  return usedNames.size();
877 }
878 
879 
881 {
882  if( NULL == a3DModel )
883  return;
884 
885  if( !a3DModel->m_Filename.empty() )
886  m_3D_Drawings.push_back( *a3DModel );
887 
888  delete a3DModel;
889 }
890 
891 
892 // see class_module.h
893 SEARCH_RESULT MODULE::Visit( INSPECTOR inspector, void* testData, const KICAD_T scanTypes[] )
894 {
895  KICAD_T stype;
897  const KICAD_T* p = scanTypes;
898  bool done = false;
899 
900 #if 0 && defined(DEBUG)
901  std::cout << GetClass().mb_str() << ' ';
902 #endif
903 
904  while( !done )
905  {
906  stype = *p;
907 
908  switch( stype )
909  {
910  case PCB_MODULE_T:
911  result = inspector( this, testData ); // inspect me
912  ++p;
913  break;
914 
915  case PCB_PAD_T:
916  result = IterateForward<D_PAD*>( m_pads, inspector, testData, p );
917  ++p;
918  break;
919 
921  result = IterateForward<MODULE_ZONE_CONTAINER*>( m_fp_zones, inspector, testData, p );
922  ++p;
923  break;
924 
925  case PCB_MODULE_TEXT_T:
926  result = inspector( m_Reference, testData );
927 
928  if( result == SEARCH_RESULT::QUIT )
929  break;
930 
931  result = inspector( m_Value, testData );
932 
933  if( result == SEARCH_RESULT::QUIT )
934  break;
935 
936  // Intentionally fall through since m_Drawings can hold TYPETEXTMODULE also
938 
939  case PCB_MODULE_EDGE_T:
940  result = IterateForward<BOARD_ITEM*>( m_drawings, inspector, testData, p );
941 
942  // skip over any types handled in the above call.
943  for( ; ; )
944  {
945  switch( stype = *++p )
946  {
947  case PCB_MODULE_TEXT_T:
948  case PCB_MODULE_EDGE_T:
949  continue;
950 
951  default:
952  ;
953  }
954 
955  break;
956  }
957 
958  break;
959 
960  default:
961  done = true;
962  break;
963  }
964 
965  if( result == SEARCH_RESULT::QUIT )
966  break;
967  }
968 
969  return result;
970 }
971 
972 
973 wxString MODULE::GetSelectMenuText( EDA_UNITS aUnits ) const
974 {
975  wxString reference = GetReference();
976 
977  if( reference.IsEmpty() )
978  reference = _( "<no reference designator>" );
979 
980  return wxString::Format( _( "Footprint %s" ), reference );
981 }
982 
983 
985 {
986  return module_xpm;
987 }
988 
989 
991 {
992  return new MODULE( *this );
993 }
994 
995 
996 void MODULE::RunOnChildren( const std::function<void (BOARD_ITEM*)>& aFunction )
997 {
998  try
999  {
1000  for( D_PAD* pad : m_pads )
1001  aFunction( static_cast<BOARD_ITEM*>( pad ) );
1002 
1003  for( MODULE_ZONE_CONTAINER* zone : m_fp_zones )
1004  aFunction( static_cast<MODULE_ZONE_CONTAINER*>( zone ) );
1005 
1006  for( BOARD_ITEM* drawing : m_drawings )
1007  aFunction( static_cast<BOARD_ITEM*>( drawing ) );
1008 
1009  aFunction( static_cast<BOARD_ITEM*>( m_Reference ) );
1010  aFunction( static_cast<BOARD_ITEM*>( m_Value ) );
1011  }
1012  catch( std::bad_function_call& )
1013  {
1014  wxFAIL_MSG( "Error running MODULE::RunOnChildren" );
1015  }
1016 }
1017 
1018 
1019 void MODULE::GetAllDrawingLayers( int aLayers[], int& aCount, bool aIncludePads ) const
1020 {
1021  std::unordered_set<int> layers;
1022 
1023  for( BOARD_ITEM* item : m_drawings )
1024  layers.insert( static_cast<int>( item->GetLayer() ) );
1025 
1026  if( aIncludePads )
1027  {
1028  for( D_PAD* pad : m_pads )
1029  {
1030  int pad_layers[KIGFX::VIEW::VIEW_MAX_LAYERS], pad_layers_count;
1031  pad->ViewGetLayers( pad_layers, pad_layers_count );
1032 
1033  for( int i = 0; i < pad_layers_count; i++ )
1034  layers.insert( pad_layers[i] );
1035  }
1036  }
1037 
1038  aCount = layers.size();
1039  int i = 0;
1040 
1041  for( int layer : layers )
1042  aLayers[i++] = layer;
1043 }
1044 
1045 
1046 void MODULE::ViewGetLayers( int aLayers[], int& aCount ) const
1047 {
1048  aCount = 2;
1049  aLayers[0] = LAYER_ANCHOR;
1050 
1051  switch( m_Layer )
1052  {
1053  default:
1054  wxASSERT_MSG( false, "Illegal layer" ); // do you really have modules placed on other layers?
1056 
1057  case F_Cu:
1058  aLayers[1] = LAYER_MOD_FR;
1059  break;
1060 
1061  case B_Cu:
1062  aLayers[1] = LAYER_MOD_BK;
1063  break;
1064  }
1065 
1066  // If there are no pads, and only drawings on a silkscreen layer, then report the silkscreen
1067  // layer as well so that the component can be edited with the silkscreen layer
1068  bool f_silk = false, b_silk = false, non_silk = false;
1069 
1070  for( auto item : m_drawings )
1071  {
1072  if( item->GetLayer() == F_SilkS )
1073  f_silk = true;
1074  else if( item->GetLayer() == B_SilkS )
1075  b_silk = true;
1076  else
1077  non_silk = true;
1078  }
1079 
1080  if( ( f_silk || b_silk ) && !non_silk && m_pads.empty() )
1081  {
1082  if( f_silk )
1083  aLayers[ aCount++ ] = F_SilkS;
1084 
1085  if( b_silk )
1086  aLayers[ aCount++ ] = B_SilkS;
1087  }
1088 }
1089 
1090 
1091 double MODULE::ViewGetLOD( int aLayer, KIGFX::VIEW* aView ) const
1092 {
1093  int layer = ( m_Layer == F_Cu ) ? LAYER_MOD_FR :
1095 
1096  // Currently this is only pertinent for the anchor layer; everything else is drawn from the
1097  // children.
1098  // The "good" value is experimentally chosen.
1099  #define MINIMAL_ZOOM_LEVEL_FOR_VISIBILITY 1.5
1100 
1101  if( aView->IsLayerVisible( layer ) )
1103 
1104  return std::numeric_limits<double>::max();
1105 }
1106 
1107 
1109 {
1110  EDA_RECT area = GetFootprintRect();
1111 
1112  // Calculate extended area including text fields
1113  area.Merge( m_Reference->GetBoundingBox() );
1114  area.Merge( m_Value->GetBoundingBox() );
1115 
1116  // Add the Clearance shape size: (shape around the pads when the clearance is shown. Not
1117  // optimized, but the draw cost is small (perhaps smaller than optimization).
1118  BOARD* board = GetBoard();
1119  if( board )
1120  {
1121  int biggest_clearance = board->GetDesignSettings().GetBiggestClearanceValue();
1122  area.Inflate( biggest_clearance );
1123  }
1124 
1125  return area;
1126 }
1127 
1128 
1129 bool MODULE::IsLibNameValid( const wxString & aName )
1130 {
1131  const wxChar * invalids = StringLibNameInvalidChars( false );
1132 
1133  if( aName.find_first_of( invalids ) != std::string::npos )
1134  return false;
1135 
1136  return true;
1137 }
1138 
1139 
1140 const wxChar* MODULE::StringLibNameInvalidChars( bool aUserReadable )
1141 {
1142  // This list of characters is also duplicated in validators.cpp and
1143  // lib_id.cpp
1144  // TODO: Unify forbidden character lists
1145  static const wxChar invalidChars[] = wxT("%$<>\t\n\r\"\\/:");
1146  static const wxChar invalidCharsReadable[] = wxT("% $ < > 'tab' 'return' 'line feed' \\ \" / :");
1147 
1148  if( aUserReadable )
1149  return invalidCharsReadable;
1150  else
1151  return invalidChars;
1152 }
1153 
1154 
1155 void MODULE::Move( const wxPoint& aMoveVector )
1156 {
1157  wxPoint newpos = m_Pos + aMoveVector;
1158  SetPosition( newpos );
1159 }
1160 
1161 
1162 void MODULE::Rotate( const wxPoint& aRotCentre, double aAngle )
1163 {
1164  double orientation = GetOrientation();
1165  double newOrientation = orientation + aAngle;
1166  wxPoint newpos = m_Pos;
1167  RotatePoint( &newpos, aRotCentre, aAngle );
1168  SetPosition( newpos );
1169  SetOrientation( newOrientation );
1170 
1171  m_Reference->KeepUpright( orientation, newOrientation );
1172  m_Value->KeepUpright( orientation, newOrientation );
1173 
1174  for( BOARD_ITEM* item : m_drawings )
1175  {
1176  if( item->Type() == PCB_MODULE_TEXT_T )
1177  static_cast<TEXTE_MODULE*>( item )->KeepUpright( orientation, newOrientation );
1178  }
1179 }
1180 
1181 
1182 void MODULE::Flip( const wxPoint& aCentre, bool aFlipLeftRight )
1183 {
1184  // Move module to its final position:
1185  wxPoint finalPos = m_Pos;
1186 
1187  // Now Flip the footprint.
1188  // Flipping a footprint is a specific transform:
1189  // it is not mirrored like a text.
1190  // We have to change the side, and ensure the footprint rotation is
1191  // modified accordint to the transform, because this parameter is used
1192  // in pick and place files, and when updating the footprint from library.
1193  // When flipped around the X axis (Y coordinates changed) orientation is negated
1194  // When flipped around the Y axis (X coordinates changed) orientation is 180 - old orient.
1195  // Because it is specfic to a footprint, we flip around the X axis, and after rotate 180 deg
1196 
1197  MIRROR( finalPos.y, aCentre.y );
1198 
1199  SetPosition( finalPos );
1200 
1201  // Flip layer
1202  SetLayer( FlipLayer( GetLayer() ) );
1203 
1204  // Reverse mirror orientation.
1205  m_Orient = -m_Orient;
1206 
1208 
1209  // Mirror pads to other side of board.
1210  for( auto pad : m_pads )
1211  pad->Flip( m_Pos, false );
1212 
1213  // Mirror zones to other side of board.
1214  for( auto zone : m_fp_zones )
1215  zone->Flip( m_Pos, aFlipLeftRight );
1216 
1217  // Mirror reference and value.
1218  m_Reference->Flip( m_Pos, false );
1219  m_Value->Flip( m_Pos, false );
1220 
1221  // Reverse mirror module graphics and texts.
1222  for( auto item : m_drawings )
1223  {
1224  switch( item->Type() )
1225  {
1226  case PCB_MODULE_EDGE_T:
1227  static_cast<EDGE_MODULE*>( item )->Flip( m_Pos, false );
1228  break;
1229 
1230  case PCB_MODULE_TEXT_T:
1231  static_cast<TEXTE_MODULE*>( item )->Flip( m_Pos, false );
1232  break;
1233 
1234  default:
1235  wxMessageBox( wxT( "MODULE::Flip() error: Unknown Draw Type" ) );
1236  break;
1237  }
1238  }
1239 
1240  // Now rotate 180 deg if required
1241  if( aFlipLeftRight )
1242  Rotate( aCentre, 1800.0 );
1243 
1245 }
1246 
1247 
1248 void MODULE::SetPosition( const wxPoint& aPos )
1249 {
1250  wxPoint delta = aPos - m_Pos;
1251 
1252  m_Pos += delta;
1253 
1254  m_Reference->EDA_TEXT::Offset( delta );
1255  m_Value->EDA_TEXT::Offset( delta );
1256 
1257  for( auto pad : m_pads )
1258  {
1259  pad->SetPosition( pad->GetPosition() + delta );
1260  }
1261 
1262  for( auto zone : m_fp_zones )
1263  zone->Move( delta );
1264 
1265  for( auto item : m_drawings )
1266  {
1267  switch( item->Type() )
1268  {
1269  case PCB_MODULE_EDGE_T:
1270  {
1271  EDGE_MODULE* pt_edgmod = (EDGE_MODULE*) item;
1272  pt_edgmod->SetDrawCoord();
1273  break;
1274  }
1275 
1276  case PCB_MODULE_TEXT_T:
1277  {
1278  TEXTE_MODULE* text = static_cast<TEXTE_MODULE*>( item );
1279  text->EDA_TEXT::Offset( delta );
1280  break;
1281  }
1282 
1283  default:
1284  wxMessageBox( wxT( "Draw type undefined." ) );
1285  break;
1286  }
1287  }
1288 
1289  m_BoundaryBox.Move( delta );
1290 }
1291 
1292 
1293 void MODULE::MoveAnchorPosition( const wxPoint& aMoveVector )
1294 {
1295  /* Move the reference point of the footprint
1296  * the footprints elements (pads, outlines, edges .. ) are moved
1297  * but:
1298  * - the footprint position is not modified.
1299  * - the relative (local) coordinates of these items are modified
1300  * - Draw coordinates are updated
1301  */
1302 
1303 
1304  // Update (move) the relative coordinates relative to the new anchor point.
1305  wxPoint moveVector = aMoveVector;
1306  RotatePoint( &moveVector, -GetOrientation() );
1307 
1308  // Update of the reference and value.
1309  m_Reference->SetPos0( m_Reference->GetPos0() + moveVector );
1311  m_Value->SetPos0( m_Value->GetPos0() + moveVector );
1312  m_Value->SetDrawCoord();
1313 
1314  // Update the pad local coordinates.
1315  for( auto pad : m_pads )
1316  {
1317  pad->SetPos0( pad->GetPos0() + moveVector );
1318  pad->SetDrawCoord();
1319  }
1320 
1321  // Update the draw element coordinates.
1322  for( auto item : GraphicalItems() )
1323  {
1324  switch( item->Type() )
1325  {
1326  case PCB_MODULE_EDGE_T:
1327  {
1328  EDGE_MODULE* edge = static_cast<EDGE_MODULE*>( item );
1329  edge->Move( moveVector );
1330  }
1331  break;
1332 
1333  case PCB_MODULE_TEXT_T:
1334  {
1335  TEXTE_MODULE* text = static_cast<TEXTE_MODULE*>( item );
1336  text->SetPos0( text->GetPos0() + moveVector );
1337  text->SetDrawCoord();
1338  }
1339  break;
1340 
1341  default:
1342  break;
1343  }
1344  }
1345 
1347 }
1348 
1349 
1350 void MODULE::SetOrientation( double aNewAngle )
1351 {
1352  double angleChange = aNewAngle - m_Orient; // change in rotation
1353 
1354  NORMALIZE_ANGLE_180( aNewAngle );
1355 
1356  m_Orient = aNewAngle;
1357 
1358  for( auto pad : m_pads )
1359  {
1360  pad->SetOrientation( pad->GetOrientation() + angleChange );
1361  pad->SetDrawCoord();
1362  }
1363 
1364  for( auto zone : m_fp_zones )
1365  {
1366  zone->Rotate( GetPosition(), angleChange );
1367  }
1368 
1369  // Update of the reference and value.
1371  m_Value->SetDrawCoord();
1372 
1373  // Displace contours and text of the footprint.
1374  for( auto item : m_drawings )
1375  {
1376  if( item->Type() == PCB_MODULE_EDGE_T )
1377  {
1378  static_cast<EDGE_MODULE*>( item )->SetDrawCoord();
1379  }
1380  else if( item->Type() == PCB_MODULE_TEXT_T )
1381  {
1382  static_cast<TEXTE_MODULE*>( item )->SetDrawCoord();
1383  }
1384  }
1385 }
1386 
1387 
1389 {
1390  MODULE* dupe = (MODULE*) Clone();
1391  const_cast<KIID&>( dupe->m_Uuid ) = KIID();
1392 
1393  dupe->RunOnChildren( [&]( BOARD_ITEM* child )
1394  {
1395  const_cast<KIID&>( child->m_Uuid ) = KIID();
1396  });
1397 
1398  return static_cast<BOARD_ITEM*>( dupe );
1399 }
1400 
1401 
1402 BOARD_ITEM* MODULE::DuplicateItem( const BOARD_ITEM* aItem, bool aAddToModule )
1403 {
1404  BOARD_ITEM* new_item = NULL;
1405  MODULE_ZONE_CONTAINER* new_zone = NULL;
1406 
1407  switch( aItem->Type() )
1408  {
1409  case PCB_PAD_T:
1410  {
1411  D_PAD* new_pad = new D_PAD( *static_cast<const D_PAD*>( aItem ) );
1412  const_cast<KIID&>( new_pad->m_Uuid ) = KIID();
1413 
1414  if( aAddToModule )
1415  m_pads.push_back( new_pad );
1416 
1417  new_item = new_pad;
1418  break;
1419  }
1420 
1422  {
1423  new_zone = new MODULE_ZONE_CONTAINER( *static_cast<const MODULE_ZONE_CONTAINER*>( aItem ) );
1424  const_cast<KIID&>( new_zone->m_Uuid ) = KIID();
1425 
1426  if( aAddToModule )
1427  m_fp_zones.push_back( new_zone );
1428 
1429  new_item = new_zone;
1430  break;
1431  }
1432 
1433  case PCB_MODULE_TEXT_T:
1434  {
1435  TEXTE_MODULE* new_text = new TEXTE_MODULE( *static_cast<const TEXTE_MODULE*>( aItem ) );
1436  const_cast<KIID&>( new_text->m_Uuid ) = KIID();
1437 
1438  if( new_text->GetType() == TEXTE_MODULE::TEXT_is_REFERENCE )
1439  {
1440  new_text->SetText( wxT( "${REFERENCE}" ) );
1442  }
1443  else if( new_text->GetType() == TEXTE_MODULE::TEXT_is_VALUE )
1444  {
1445  new_text->SetText( wxT( "${VALUE}" ) );
1447  }
1448 
1449  if( aAddToModule )
1450  Add( new_text );
1451 
1452  new_item = new_text;
1453 
1454  break;
1455  }
1456 
1457  case PCB_MODULE_EDGE_T:
1458  {
1459  EDGE_MODULE* new_edge = new EDGE_MODULE( *static_cast<const EDGE_MODULE*>(aItem) );
1460  const_cast<KIID&>( new_edge->m_Uuid ) = KIID();
1461 
1462  if( aAddToModule )
1463  Add( new_edge );
1464 
1465  new_item = new_edge;
1466  break;
1467  }
1468 
1469  case PCB_MODULE_T:
1470  // Ignore the module itself
1471  break;
1472 
1473  default:
1474  // Un-handled item for duplication
1475  wxFAIL_MSG( "Duplication not supported for items of class " + aItem->GetClass() );
1476  break;
1477  }
1478 
1479  return new_item;
1480 }
1481 
1482 
1483 wxString MODULE::GetNextPadName( const wxString& aLastPadName ) const
1484 {
1485  std::set<wxString> usedNames;
1486 
1487  // Create a set of used pad numbers
1488  for( D_PAD* pad : m_pads )
1489  usedNames.insert( pad->GetName() );
1490 
1491  wxString prefix = UTIL::GetReferencePrefix( aLastPadName );
1492  int num = GetTrailingInt( aLastPadName );
1493 
1494  while( usedNames.count( wxString::Format( "%s%d", prefix, num ) ) )
1495  num++;
1496 
1497  return wxString::Format( "%s%d", prefix, num );
1498 }
1499 
1500 
1501 void MODULE::IncrementReference( int aDelta )
1502 {
1503  const auto& refdes = GetReference();
1504  SetReference( wxString::Format( wxT( "%s%i" ), UTIL::GetReferencePrefix( refdes ),
1505  GetTrailingInt( refdes ) + aDelta ) );
1506 }
1507 
1508 
1509 // Calculate the area of aPolySet, after fracturation, because
1510 // polygons with no hole are expected.
1511 static double polygonArea( SHAPE_POLY_SET& aPolySet )
1512 {
1513  double area = 0.0;
1514  for( int ii = 0; ii < aPolySet.OutlineCount(); ii++ )
1515  {
1516  SHAPE_LINE_CHAIN& outline = aPolySet.Outline( ii );
1517  // Ensure the curr outline is closed, to calculate area
1518  outline.SetClosed( true );
1519 
1520  area += outline.Area();
1521  }
1522 
1523  return area;
1524 }
1525 
1526 // a helper function to add a rectangular polygon aRect to aPolySet
1527 static void addRect( SHAPE_POLY_SET& aPolySet, wxRect aRect )
1528 {
1529  aPolySet.NewOutline();
1530 
1531  aPolySet.Append( aRect.GetX(), aRect.GetY() );
1532  aPolySet.Append( aRect.GetX()+aRect.width, aRect.GetY() );
1533  aPolySet.Append( aRect.GetX()+aRect.width, aRect.GetY()+aRect.height );
1534  aPolySet.Append( aRect.GetX(), aRect.GetY()+aRect.height );
1535 }
1536 
1537 double MODULE::CoverageRatio( const GENERAL_COLLECTOR& aCollector ) const
1538 {
1539  double moduleArea = GetFootprintRect().GetArea();
1540  SHAPE_POLY_SET coveredRegion;
1541  addRect( coveredRegion, GetFootprintRect() );
1542 
1543  // build list of holes (covered areas not available for selection)
1544  SHAPE_POLY_SET holes;
1545 
1546  for( auto pad : m_pads )
1547  addRect( holes, pad->GetBoundingBox() );
1548 
1549  addRect( holes, m_Reference->GetBoundingBox() );
1550  addRect( holes, m_Value->GetBoundingBox() );
1551 
1552  for( int i = 0; i < aCollector.GetCount(); ++i )
1553  {
1554  BOARD_ITEM* item = aCollector[i];
1555 
1556  switch( item->Type() )
1557  {
1558  case PCB_TEXT_T:
1559  case PCB_MODULE_TEXT_T:
1560  case PCB_TRACE_T:
1561  case PCB_ARC_T:
1562  case PCB_VIA_T:
1563  addRect( holes, item->GetBoundingBox() );
1564  break;
1565  default:
1566  break;
1567  }
1568  }
1569 
1570  SHAPE_POLY_SET uncoveredRegion;
1571 
1572  try
1573  {
1574  uncoveredRegion.BooleanSubtract( coveredRegion, holes, SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
1575  uncoveredRegion.Simplify( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
1576  uncoveredRegion.Fracture( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
1577  }
1578  catch( ClipperLib::clipperException& )
1579  {
1580  // better to be conservative (this will result in the disambiguate dialog)
1581  return 1.0;
1582  }
1583 
1584  double uncoveredRegionArea = polygonArea( uncoveredRegion );
1585  double coveredArea = moduleArea - uncoveredRegionArea;
1586  double ratio = ( coveredArea / moduleArea );
1587 
1588  return std::min( ratio, 1.0 );
1589 }
1590 
1591 
1592 // see convert_drawsegment_list_to_polygon.cpp:
1593 extern bool ConvertOutlineToPolygon( std::vector<DRAWSEGMENT*>& aSegList, SHAPE_POLY_SET& aPolygons,
1594  wxString* aErrorText, unsigned int aTolerance, wxPoint* aErrorLocation = nullptr );
1595 
1596 
1597 std::shared_ptr<SHAPE> MODULE::GetEffectiveShape( PCB_LAYER_ID aLayer ) const
1598 {
1599  std::shared_ptr<SHAPE> shape ( new SHAPE_NULL );
1600 
1601  return shape;
1602 }
1603 
1604 
1606 {
1609  // Build the courtyard area from graphic items on the courtyard.
1610  // Only PCB_MODULE_EDGE_T have meaning, graphic texts are ignored.
1611  // Collect items:
1612  std::vector< DRAWSEGMENT* > list_front;
1613  std::vector< DRAWSEGMENT* > list_back;
1614 
1615  for( BOARD_ITEM* item : GraphicalItems() )
1616  {
1617  if( item->GetLayer() == B_CrtYd && item->Type() == PCB_MODULE_EDGE_T )
1618  list_back.push_back( static_cast< DRAWSEGMENT* > ( item ) );
1619 
1620  if( item->GetLayer() == F_CrtYd && item->Type() == PCB_MODULE_EDGE_T )
1621  list_front.push_back( static_cast< DRAWSEGMENT* > ( item ) );
1622  }
1623 
1624  // Note: if no item found on courtyard layers, return true.
1625  // false is returned only when the shape defined on courtyard layers
1626  // is not convertible to a polygon
1627  if( !list_front.size() && !list_back.size() )
1628  return true;
1629 
1630  wxString error_msg;
1631 
1632  #define ARC_ERROR_MAX 0.02 /* error max in mm to approximate a arc by segments */
1633  bool success = ConvertOutlineToPolygon( list_front, m_poly_courtyard_front,
1634  &error_msg,
1635  (unsigned) Millimeter2iu( ARC_ERROR_MAX ) );
1636 
1637  if( success )
1638  {
1639  success = ConvertOutlineToPolygon( list_back, m_poly_courtyard_back,
1640  &error_msg,
1641  (unsigned) Millimeter2iu( ARC_ERROR_MAX ) );
1642  }
1643 
1644  if( !error_msg.IsEmpty() )
1645  {
1646  wxLogMessage( wxString::Format( _( "Processing courtyard of \"%s\": %s" ),
1647  GetChars( GetFPID().Format() ),
1648  error_msg) );
1649  }
1650 
1651  return success;
1652 }
1653 
1654 
1656 {
1657  assert( aImage->Type() == PCB_MODULE_T );
1658 
1659  std::swap( *((MODULE*) this), *((MODULE*) aImage) );
1660 }
1661 
1662 
1664 {
1665  for( D_PAD* pad : Pads() )
1666  {
1667  if( pad->GetAttribute() != PAD_ATTRIB_SMD )
1668  return true;
1669  }
1670 
1671  return false;
1672 }
1673 
1674 
1675 bool MODULE::cmp_drawings::operator()( const BOARD_ITEM* aFirst, const BOARD_ITEM* aSecond ) const
1676 {
1677  if( aFirst->Type() != aSecond->Type() )
1678  return aFirst->Type() < aSecond->Type();
1679 
1680  if( aFirst->GetLayer() != aSecond->GetLayer() )
1681  return aFirst->GetLayer() < aSecond->GetLayer();
1682 
1683  if( aFirst->Type() == PCB_MODULE_EDGE_T )
1684  {
1685  const EDGE_MODULE* dwgA = static_cast<const EDGE_MODULE*>( aFirst );
1686  const EDGE_MODULE* dwgB = static_cast<const EDGE_MODULE*>( aSecond );
1687 
1688  if( dwgA->GetShape() != dwgB->GetShape() )
1689  return dwgA->GetShape() < dwgB->GetShape();
1690  }
1691 
1692  return aFirst->m_Uuid < aSecond->m_Uuid;
1693 }
1694 
1695 
1696 bool MODULE::cmp_pads::operator()( const D_PAD* aFirst, const D_PAD* aSecond ) const
1697 {
1698  if( aFirst->GetName() != aSecond->GetName() )
1699  return StrNumCmp( aFirst->GetName(), aSecond->GetName() ) < 0;
1700 
1701  return aFirst->m_Uuid < aSecond->m_Uuid;
1702 }
1703 
1704 
1705 static struct MODULE_DESC
1706 {
1708  {
1710 
1711  if( layerEnum.Choices().GetCount() == 0 )
1712  {
1713  layerEnum.Undefined( UNDEFINED_LAYER );
1714 
1715  for( LSEQ seq = LSET::AllLayersMask().Seq(); seq; ++seq )
1716  layerEnum.Map( *seq, LSET::Name( *seq ) );
1717  }
1718 
1719  wxPGChoices fpLayers; // footprints might be placed only on F.Cu & B.Cu
1720  fpLayers.Add( LSET::Name( F_Cu ), F_Cu );
1721  fpLayers.Add( LSET::Name( B_Cu ), B_Cu );
1722 
1724  REGISTER_TYPE( MODULE );
1729 
1730  auto layer = new PROPERTY_ENUM<MODULE, PCB_LAYER_ID, BOARD_ITEM>( _( "Layer" ),
1732  layer->SetChoices( fpLayers );
1733  propMgr.ReplaceProperty( TYPE_HASH( BOARD_ITEM ), _( "Layer" ), layer );
1734 
1735  propMgr.AddProperty( new PROPERTY<MODULE, wxString>( _( "Reference" ),
1737  propMgr.AddProperty( new PROPERTY<MODULE, wxString>( _( "Value" ),
1739  propMgr.AddProperty( new PROPERTY<MODULE, double>( _( "Orientation" ),
1742  propMgr.AddProperty( new PROPERTY<MODULE, int>( _( "Local Clearance" ),
1745  propMgr.AddProperty( new PROPERTY<MODULE, int>( _( "Local Solderpaste Margin" ),
1748  propMgr.AddProperty( new PROPERTY<MODULE, double>( _( "Local Solderpaste Margin Ratio" ),
1750  propMgr.AddProperty( new PROPERTY<MODULE, int>( _( "Thermal Width" ),
1753  propMgr.AddProperty( new PROPERTY<MODULE, int>( _( "Thermal Gap" ),
1756  // TODO zone connection, FPID?
1757  }
1758 } _MODULE_DESC;
void GetMsgPanelInfo(EDA_DRAW_FRAME *aFrame, std::vector< MSG_PANEL_ITEM > &aList) override
unsigned GetPadCount(INCLUDE_NPTH_T aIncludeNPTH=INCLUDE_NPTH_T(INCLUDE_NPTH)) const
GetPadCount returns the number of pads.
LIB_ID m_fpid
Definition: class_module.h:721
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Return a mask holding the requested number of Cu PCB_LAYER_IDs.
Definition: lset.cpp:749
Display value expressed in degrees.
Definition: property.h:48
EDA_UNITS
Definition: common.h:198
bool BuildPolyCourtyard()
Builds a complex polygon of the courtyard area from graphic items on the courtyard layer.
double ViewGetLOD(int aLayer, KIGFX::VIEW *aView) const override
Function ViewGetLOD() Returns the level of detail (LOD) of the item.
double GetOrientation() const
Definition: class_module.h:224
double GetArea(int aPadding=0) const
static PROPERTY_MANAGER & Instance()
Definition: property_mgr.h:61
#define TYPE_HASH(x)
Macro to generate unique identifier for a type
Definition: property.h:53
void Move(const wxPoint &aMoveVector)
Function Move moves the rectangle by the aMoveVector.
const BITMAP_OPAQUE module_xpm[1]
Definition: module.cpp:29
void SetThermalGap(int aGap)
Definition: class_module.h:266
int m_CntRot90
Definition: class_module.h:740
int OutlineCount() const
Returns the number of outlines in the set
int StrNumCmp(const wxString &aString1, const wxString &aString2, bool aIgnoreCase)
Compare two strings with alphanumerical content.
Definition: string.cpp:409
void Merge(const EDA_RECT &aRect)
Function Merge modifies the position and size of the rectangle in order to contain aRect.
void RunOnChildren(const std::function< void(BOARD_ITEM *)> &aFunction)
Function RunOnChildren.
void Rotate(const wxPoint &aRotCentre, double aAngle) override
Function Rotate Rotate this object.
unsigned GetUniquePadCount(INCLUDE_NPTH_T aIncludeNPTH=INCLUDE_NPTH_T(INCLUDE_NPTH)) const
GetUniquePadCount returns the number of unique pads.
SHAPE_POLY_SET m_poly_courtyard_back
Definition: class_module.h:749
PNG memory record (file in memory).
Definition: bitmap_def.h:29
bool HitTest(const wxPoint &aPosition, int aAccuracy=0) const override
Function HitTest tests if aPosition is contained within or on the bounding box of an item.
void SetLocalClearance(int aClearance)
Definition: class_module.h:244
like PAD_STANDARD, but not plated mechanical use only, no connection allowed
Definition: pad_shapes.h:85
void KeepUpright(double aOldOrientation, double aNewOrientation)
Called when rotating the parent footprint.
bool ResolveTextVar(wxString *token, int aDepth=0) const
Resolve any references to system tokens supported by the component.
bool IsFlipped() const
function IsFlipped
Definition: class_module.h:302
wxString m_KeyWord
Definition: class_module.h:735
virtual void SetLayer(PCB_LAYER_ID aLayer)
Function SetLayer sets the layer this item is on.
This file is part of the common library.
coord_type GetX() const
Definition: box2.h:190
virtual void SetPosition(const wxPoint &aPos)
Definition: base_struct.h:338
BOARD_ITEM is a base class for any item which can be embedded within the BOARD container class,...
void GetAllDrawingLayers(int aLayers[], int &aCount, bool aIncludePads=true) const
Returns a set of all layers that this module has drawings on similar to ViewGetLayers()
SHAPE_POLY_SET GetBoundingPoly() const
Returns a bounding polygon for the shapes and pads in the module This operation is slower but more ac...
bool ConvertOutlineToPolygon(std::vector< DRAWSEGMENT * > &aSegList, SHAPE_POLY_SET &aPolygons, wxString *aErrorText, unsigned int aTolerance, wxPoint *aErrorLocation=nullptr)
Function ConvertOutlineToPolygon build a polygon (with holes) from a DRAWSEGMENT list,...
int m_ThermalWidth
Definition: class_module.h:727
int GetBiggestClearanceValue()
Function GetBiggestClearanceValue.
wxPoint GetPosition() const override
Definition: class_pad.h:165
double CoverageRatio(const GENERAL_COLLECTOR &aCollector) const
Function CoverageRatio Calculates the ratio of total area of the footprint pads and graphical items t...
STROKE_T GetShape() const
anchor of items having an anchor point (texts, footprints)
static double polygonArea(SHAPE_POLY_SET &aPolySet)
void CalculateBoundingBox()
Function CalculateBoundingBox calculates the bounding box in board coordinates.
ENUM_MAP & Undefined(T aValue)
Definition: property.h:531
double m_LocalSolderPasteMarginRatio
Definition: class_module.h:732
bool IsVisible() const
Definition: eda_text.h:186
void GetContextualTextVars(wxArrayString *aVars) const
Return the list of system text vars for this footprint.
PCB_LAYER_ID FlipLayer(PCB_LAYER_ID aLayerId, int aCopperLayersCount)
Definition: lset.cpp:520
int m_LocalSolderPasteMargin
Definition: class_module.h:731
int m_ThermalGap
Definition: class_module.h:728
Smd pad, appears on the solder paste layer (default)
Definition: pad_shapes.h:81
Collection of utility functions for component reference designators (refdes)
int GetWidth() const
Definition: eda_rect.h:119
PADS & Pads()
Definition: class_module.h:181
const wxString GetValue() const
Function GetValue.
Definition: class_module.h:476
static ENUM_MAP< T > & Instance()
Definition: property.h:517
Definition: color4d.h:61
KIID_PATH m_Path
Definition: class_module.h:736
class TEXTE_PCB, text on a layer
Definition: typeinfo.h:92
class ARC, an arc track segment on a copper layer
Definition: typeinfo.h:98
coord_type GetRight() const
Definition: box2.h:199
void SetOrigin(const wxPoint &pos)
Definition: eda_rect.h:131
show modules values (when texts are visibles)
PADS m_pads
Definition: class_module.h:714
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: class_board.h:514
EDA_RECT GetFootprintRect() const
Function GetFootprintRect() Build and returns the boundary box of the module footprint excluding any ...
MODULE(BOARD *parent)
void SetOrientationDegrees(double aOrientation)
Definition: class_module.h:223
class D_PAD, a pad in a footprint
Definition: typeinfo.h:90
bool operator()(const BOARD_ITEM *aFirst, const BOARD_ITEM *aSecond) const
void Add3DModel(MODULE_3D_SETTINGS *a3DModel)
Function Add3DModel adds a3DModel definition to the end of the 3D model list.
#define KI_FALLTHROUGH
The KI_FALLTHROUGH macro is to be used when switch statement cases should purposely fallthrough from ...
Definition: macros.h:88
const LIB_ID & GetFPID() const
Definition: class_module.h:228
#define ARC_ERROR_MAX
D_PAD * GetFirstPad() const
Gets the first pad in the list or NULL if none.
Definition: class_module.h:526
void Rotate(double aAngle, const VECTOR2I &aCenter={ 0, 0 }) override
Function Rotate rotates all vertices by a given angle.
static const wxChar * StringLibNameInvalidChars(bool aUserReadable)
static function StringLibNameInvalidChars Test for validity of the name in a library of the footprint...
Definition: color4d.h:44
void NORMALIZE_ANGLE_180(T &Angle)
Definition: trigo.h:373
DRAWINGS & GraphicalItems()
Definition: class_module.h:191
coord_type GetBottom() const
Definition: box2.h:200
wxPGChoices & Choices()
Definition: property.h:557
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:208
void Inflate(int aAmount, int aCircleSegmentsCount, CORNER_STRATEGY aCornerStrategy=ROUND_ALL_CORNERS)
Performs outline inflation/deflation.
The base class for create windows for drawing purpose.
bool operator()(const D_PAD *aFirst, const D_PAD *aSecond) const
void MoveAnchorPosition(const wxPoint &aMoveVector)
Function MoveAnchorPosition Move the reference point of the footprint It looks like a move footprint:...
virtual std::shared_ptr< SHAPE > GetEffectiveShape(PCB_LAYER_ID aLayer=UNDEFINED_LAYER) const override
Function GetEffectiveShape Some pad shapes can be complex (rounded/chamfered rectangle),...
wxArrayString * m_initial_comments
Definition: class_module.h:745
void SetLocalSolderPasteMarginRatio(double aRatio)
Definition: class_module.h:258
class EDGE_MODULE, a footprint edge
Definition: typeinfo.h:94
#define REGISTER_TYPE(x)
Helper macro to map type hashes to names
Definition: property_mgr.h:244
bool Contains(const wxPoint &aPoint) const
Function Contains.
#define MODULE_PADS_LOCKED
In autoplace: module waiting for autoplace.
Definition: class_module.h:308
KICAD_T
Enum KICAD_T is the set of class identification values, stored in EDA_ITEM::m_StructType.
Definition: typeinfo.h:78
virtual void SetParent(EDA_ITEM *aParent)
Definition: base_struct.h:196
static constexpr int VIEW_MAX_LAYERS
maximum number of layers that may be shown
Definition: view.h:697
class TRACK, a track segment (segment on a copper layer)
Definition: typeinfo.h:96
wxString m_Doc
Definition: class_module.h:734
timestamp_t m_LastEditTime
Definition: class_module.h:737
static struct MODULE_DESC _MODULE_DESC
const wxString GetReference() const
Function GetReference.
Definition: class_module.h:451
const char * c_str() const
Definition: utf8.h:107
#define MODULE_is_PLACED
In autoplace: module automatically placed.
Definition: class_module.h:306
show modules on front
int m_LocalClearance
Definition: class_module.h:729
const INSPECTOR_FUNC & INSPECTOR
Definition: base_struct.h:105
PCB_LAYER_ID m_Layer
double m_Orient
Definition: class_module.h:717
void MIRROR(T &aPoint, const T &aMirrorRef)
Definition: macros.h:175
int GetCount() const
Function GetCount returns the number of objects in the list.
Definition: collector.h:101
static void addRect(SHAPE_POLY_SET &aPolySet, wxRect aRect)
Definition: common.h:68
class MODULE, a footprint
Definition: typeinfo.h:89
void SetClosed(bool aClosed)
Function SetClosed()
void ClearAllNets()
Function ClearAllNets Clear (i.e.
const EDA_RECT GetBoundingBox() const override
Function GetBoundingBox returns the orthogonal, bounding box of this object for display purposes.
PCB_LAYER_ID
A quick note on layer IDs:
virtual void ViewGetLayers(int aLayers[], int &aCount) const override
Function ViewGetLayers() Returns the all the layers within the VIEW the object is painted on.
D_PAD * FindPadByName(const wxString &aPadName) const
Function FindPadByName returns a D_PAD* with a matching name.
Display value expressed in distance units (mm/inch)
Definition: property.h:47
EDA_RECT m_BoundaryBox
Definition: class_module.h:724
wxString GetSelectMenuText(EDA_UNITS aUnits) const override
Function GetSelectMenuText returns the text to display to be used in the selection clarification cont...
LSET is a set of PCB_LAYER_IDs.
EDA_RECT GetFpPadsLocalBbox() const
Returns the bounding box containing pads when the footprint is on the front side, orientation 0,...
virtual void SetText(const wxString &aText)
Definition: eda_text.cpp:121
int GetLocalClearance() const
Definition: class_module.h:243
#define NULL
static const wxChar * Name(PCB_LAYER_ID aLayerId)
Return the fixed name association with aLayerId.
Definition: lset.cpp:81
SHAPE_POLY_SET.
SHAPE_LINE_CHAIN & Outline(int aIndex)
Returns the reference to aIndex-th outline in the set
void SetEnd(int x, int y)
Definition: eda_rect.h:192
void Flip(const wxPoint &aCentre, bool aFlipLeftRight) override
Function Flip Flip this object, i.e.
TEXT_TYPE GetType() const
ZONE_CONNECTION m_ZoneConnection
Definition: class_module.h:726
virtual BOARD * GetBoard() const
Function GetBoard returns the BOARD in which this BOARD_ITEM resides, or NULL if none.
virtual const BOX2I ViewBBox() const override
Function ViewBBox() returns the bounding box of the item covering all its layers.
void InheritsAfter(TYPE_ID aDerived, TYPE_ID aBase)
Declares an inheritance relationship between types.
void SetThermalWidth(int aWidth)
Definition: class_module.h:263
int m_LocalSolderMaskMargin
Definition: class_module.h:730
const wxString & GetName() const
Definition: class_pad.h:132
std::list< MODULE_3D_SETTINGS > m_3D_Drawings
Definition: class_module.h:743
double GetOrientationRadians() const
Definition: class_module.h:226
#define MINIMAL_ZOOM_LEVEL_FOR_VISIBILITY
int m_arflag
Definition: class_module.h:738
double GetOrientationDegrees() const
Definition: class_module.h:225
MODULE_ZONE_CONTAINERS m_fp_zones
Definition: class_module.h:715
wxString GetNextPadName(const wxString &aLastPadName) const
Function GetNextPadName returns the next available pad name in the module.
static LSET AllLayersMask()
Definition: lset.cpp:786
void Simplify(POLYGON_MODE aFastMode)
Simplifies the polyset (merges overlapping polys, eliminates degeneracy/self-intersections) For aFast...
void SetReference(const wxString &aReference)
Function SetReference.
Definition: class_module.h:461
EDA_ITEM * Clone() const override
Function Clone creates a duplicate of this item with linked list members set to NULL.
const EDA_RECT GetBoundingBox() const override
Function GetBoundingBox returns the orthogonal, bounding box of this object for display purposes.
SHAPE_POLY_SET m_poly_courtyard_front
Definition: class_module.h:748
virtual void SetPosition(const wxPoint &aPos) override
void Remove(BOARD_ITEM *aItem) override
void SetPosition(const wxPoint &aPos) override
double GetArea() const
Function GetArea returns the area of the rectangle.
BOARD_ITEM * DuplicateItem(const BOARD_ITEM *aItem, bool aAddToModule=false)
Function DuplicateItem Duplicate a given item within the module, optionally adding it to the board.
int NewOutline()
Creates a new empty polygon in the set and returns its index
bool IsLocked() const override
Function IsLocked.
Definition: class_module.h:311
Definition: color4d.h:59
void SetType(TEXT_TYPE aType)
DRAWINGS m_drawings
Definition: class_module.h:713
EDA_ITEM & operator=(const EDA_ITEM &aItem)
Operator assignment is used to assign the members of aItem to another object.
void Fracture(POLYGON_MODE aFastMode)
Converts a set of polygons with holes to a singe outline with "slits"/"fractures" connecting the oute...
LSEQ is a sequence (and therefore also a set) of PCB_LAYER_IDs.
int GetHeight() const
Definition: eda_rect.h:120
D_PAD * GetTopLeftPad()
void SetPos0(const wxPoint &aPos)
UTF8 Format() const
Definition: lib_id.cpp:237
bool Collide(const VECTOR2I &aP, int aClearance=0, int *aActual=nullptr) const override
Function Collide Checks whether the point aP is either inside or on the edge of the polygon set.
int GetLocalSolderPasteMargin() const
Definition: class_module.h:254
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT) override
static const int ORPHANED
Constant that forces initialization of a netinfo item to the NETINFO_ITEM ORPHANED (typically -1) whe...
Definition: netinfo.h:482
MODULE & operator=(const MODULE &aOther)
wxString m_Filename
The 3D shape filename in 3D library.
Definition: class_module.h:97
void SetOrientation(double aNewAngle)
BITMAP_DEF GetMenuImage() const override
Function GetMenuImage returns a pointer to an image to be used in menus.
const KIID m_Uuid
Definition: base_struct.h:162
const wxPoint & GetPos0() const
const Vec & GetPosition() const
Definition: box2.h:194
bool IsElementVisible(GAL_LAYER_ID aLayer) const
Test whether a given element category is visible.
class TEXTE_MODULE, text in a footprint
Definition: typeinfo.h:93
static bool IsLibNameValid(const wxString &aName)
static function IsLibNameValid Test for validity of a name of a footprint to be used in a footprint l...
bool HitTestAccurate(const wxPoint &aPosition, int aAccuracy=0) const
Tests if a point is inside the bounding polygon of the module.
void Flip(const wxPoint &aCentre, bool aFlipLeftRight) override
Flip entity during module flip.
BOARD_ITEM * Duplicate() const override
Function Duplicate creates a copy of a BOARD_ITEM.
D_PAD * GetPad(const wxPoint &aPosition, LSET aLayerMask=LSET::AllLayersMask())
Function GetPad get a pad at aPosition on aLayerMask in the footprint.
void SetLocalSolderPasteMargin(int aMargin)
Definition: class_module.h:255
bool IsLayerVisible(PCB_LAYER_ID aLayer) const
A proxy function that calls the correspondent function in m_BoardSettings tests whether a given layer...
Definition: color4d.h:56
double GetLocalSolderPasteMarginRatio() const
Definition: class_module.h:257
virtual wxString GetShownText(int aDepth=0) const override
Return the string actually shown after processing of the base text.
int m_CntRot180
Definition: class_module.h:741
static const wxChar * GetChars(const wxString &s)
Function GetChars returns a wxChar* to the actual wxChar* data within a wxString, and is helpful for ...
Definition: macros.h:153
virtual wxString GetClass() const =0
Function GetClass returns the class name.
bool IsType(FRAME_T aType) const
wxString GetReferencePrefix(const wxString &aRefDes)
Get the (non-numeric) prefix from a refdes - e.g.
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, CPTREE &aTree)
Function Format outputs a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:201
void IncrementReference(int aDelta)
Function IncrementReference Bumps the current reference by aDelta.
SEARCH_RESULT Visit(INSPECTOR inspector, void *testData, const KICAD_T scanTypes[]) override
Function Visit may be re-implemented for each derived class in order to handle all the types given by...
static LIB_PART * dummy()
Used to draw a dummy shape when a LIB_PART is not found in library.
Information pertinent to a Pcbnew printed circuit board.
Definition: class_board.h:176
#define _(s)
Definition: 3d_actions.cpp:33
int m_ModuleStatus
Definition: class_module.h:723
SHAPE_LINE_CHAIN.
void Move(const wxPoint &aMoveVector) override
Function Move move this object.
Used when the right click button is pressed, or when the select tool is in effect.
Definition: collectors.h:240
virtual void SwapData(BOARD_ITEM *aImage) override
Swap data between aItem and aImage.
void Move(const wxPoint &aMoveVector) override
Move an edge of the footprint.
std::map< wxString, wxString > m_properties
Definition: class_module.h:744
void AddTypeCast(TYPE_CAST_BASE *aCast)
Registers a type converter.
void AddProperty(PROPERTY_BASE *aProperty)
Registers a property.
wxString GetClass() const override
Function GetClass returns the class name.
Definition: class_module.h:595
void RemoveAllContours()
Removes all outlines & holes (clears) the polygon set.
void SetDrawCoord()
Set absolute coordinates.
void SetDrawCoord()
Set draw coordinates (absolute values ) from relative coordinates.
EDA_RECT handles the component boundary box.
Definition: eda_rect.h:44
void SetValue(const wxString &aValue)
Function SetValue.
Definition: class_module.h:485
TEXTE_MODULE * m_Value
Definition: class_module.h:720
EDA_ITEM is a base class for most all the KiCad significant classes, used in schematics and boards.
Definition: base_struct.h:159
MODULE_ZONE_CONTAINER is the same item as ZONE_CONTAINER, but with a specific type id ZONE_CONTAINER ...
Definition: class_zone.h:954
wxPoint m_Pos
Definition: class_module.h:718
int GetTrailingInt(const wxString &aStr)
Gets the trailing int, if any, from a string.
Definition: string.cpp:705
bool Intersects(const EDA_RECT &aRect) const
Function Intersects tests for a common area between rectangles.
void ReplaceProperty(size_t aBase, const wxString &aName, PROPERTY_BASE *aNew)
Replaces an existing property for a specific type.
MODULE_ZONE_CONTAINERS & Zones()
Definition: class_module.h:201
Provides class metadata.
Definition: property_mgr.h:58
class VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:97
TEXTE_MODULE * m_Reference
Definition: class_module.h:719
wxPoint GetPosition() const override
Definition: class_module.h:219
void BooleanSubtract(const SHAPE_POLY_SET &b, POLYGON_MODE aFastMode)
Performs boolean polyset difference For aFastMode meaning, see function booleanOp
Abstract interface for BOARD_ITEMs capable of storing other items inside.
virtual const EDA_RECT GetBoundingBox() const
Function GetBoundingBox returns the orthogonal, bounding box of this object for display purposes.
Definition: base_struct.cpp:97
class ZONE_CONTAINER, managed by a footprint
Definition: typeinfo.h:95
VIEW.
Definition: view.h:61
ENUM_MAP & Map(T aValue, const wxString &aName)
Definition: property.h:523
SEARCH_RESULT
Definition: base_struct.h:51
int GetThermalWidth() const
Definition: class_module.h:264
EDGE_MODULE class definition.
void ClearEditFlags()
Definition: base_struct.h:251
wxString GetLayerName() const
Function GetLayerName returns the name of the PCB layer on which the item resides.
static constexpr int Millimeter2iu(double mm)
INCLUDE_NPTH_T
Definition: class_module.h:54
virtual PCB_LAYER_ID GetLayer() const
Function GetLayer returns the primary layer this item is on.
int GetThermalGap() const
Definition: class_module.h:267
show modules references (when texts are visibles)
EDA_RECT & Inflate(wxCoord dx, wxCoord dy)
Function Inflate inflates the rectangle horizontally by dx and vertically by dy.
KIID m_Link
Definition: class_module.h:739
KICAD_T Type() const
Function Type()
Definition: base_struct.h:193
int m_Attributs
Definition: class_module.h:722
bool HasThroughHolePads() const
bool IsLayerVisible(int aLayer) const
Function IsLayerVisible() Returns information about visibility of a particular layer.
Definition: view.h:405
int Append(int x, int y, int aOutline=-1, int aHole=-1, bool aAllowDuplication=false)
Appends a vertex at the end of the given outline/hole (default: the last outline)