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 <plotter.h>
30 #include <trigo.h>
31 #include <confirm.h>
32 #include <kicad_string.h>
33 #include <pcbnew.h>
34 #include <refdes_utils.h>
35 #include <richio.h>
36 #include <filter_reader.h>
37 #include <macros.h>
38 #include <msgpanel.h>
39 #include <bitmaps.h>
40 #include <unordered_set>
41 #include <pcb_edit_frame.h>
42 #include <class_board.h>
43 #include <class_edge_mod.h>
44 #include <class_module.h>
46 #include <validators.h>
47 #include <view/view.h>
48 
49 MODULE::MODULE( BOARD* parent ) :
51  m_initial_comments( 0 )
52 {
54  m_Layer = F_Cu;
55  m_Orient = 0;
57  m_arflag = 0;
58  m_CntRot90 = m_CntRot180 = 0;
59  m_Link = 0;
60  m_LastEditTime = 0;
61  m_LocalClearance = 0;
65  m_ZoneConnection = ZONE_CONNECTION::INHERITED; // Use zone setting by default
66  m_ThermalWidth = 0; // Use zone setting by default
67  m_ThermalGap = 0; // Use zone setting by default
68 
69  // These are special and mandatory text fields
72 
73  m_3D_Drawings.clear();
74 }
75 
76 
77 MODULE::MODULE( const MODULE& aModule ) :
78  BOARD_ITEM_CONTAINER( aModule )
79 {
80  m_Pos = aModule.m_Pos;
81  m_fpid = aModule.m_fpid;
82  m_Attributs = aModule.m_Attributs;
84  m_Orient = aModule.m_Orient;
85  m_BoundaryBox = aModule.m_BoundaryBox;
86  m_CntRot90 = aModule.m_CntRot90;
87  m_CntRot180 = aModule.m_CntRot180;
89  m_Link = aModule.m_Link;
90  m_Path = aModule.m_Path;
91 
98  m_ThermalGap = aModule.m_ThermalGap;
99 
100  // Copy reference and value.
101  m_Reference = new TEXTE_MODULE( *aModule.m_Reference );
102  m_Reference->SetParent( this );
103  m_Value = new TEXTE_MODULE( *aModule.m_Value );
104  m_Value->SetParent( this );
105 
106  // Copy auxiliary data: Pads
107  for( auto pad : aModule.Pads() )
108  {
109  Add( new D_PAD( *pad ) );
110  }
111 
112  // Copy auxiliary data: Zones
113  for( auto item : aModule.Zones() )
114  {
115  Add( static_cast<MODULE_ZONE_CONTAINER*>( item->Clone() ) );
116 
117  // Ensure the net info is OK and especially uses the net info list
118  // living in the current board
119  // Needed when copying a fp from fp editor that has its own board
120  // Must be NETINFO_LIST::ORPHANED_ITEM for a keepout that has no net.
121  item->SetNetCode( -1 );
122  }
123 
124  // Copy auxiliary data: Drawings
125  for( auto item : aModule.GraphicalItems() )
126  {
127  switch( item->Type() )
128  {
129  case PCB_MODULE_TEXT_T:
130  case PCB_MODULE_EDGE_T:
131  Add( static_cast<BOARD_ITEM*>( item->Clone() ) );
132  break;
133 
134  default:
135  wxLogMessage( wxT( "Class MODULE copy constructor internal error: unknown type" ) );
136  break;
137  }
138  }
139 
140  // Copy auxiliary data: 3D_Drawings info
141  m_3D_Drawings = aModule.m_3D_Drawings;
142 
143  m_Doc = aModule.m_Doc;
144  m_KeyWord = aModule.m_KeyWord;
145 
146  m_arflag = 0;
147 
148  // Ensure auxiliary data is up to date
150 
152  new wxArrayString( *aModule.m_initial_comments ) : nullptr;
153 }
154 
155 
157 {
158  // Clean up the owned elements
159  delete m_Reference;
160  delete m_Value;
161  delete m_initial_comments;
162 
163  for( auto p : m_pads )
164  delete p;
165 
166  m_pads.clear();
167 
168  for( auto p : m_fp_zones )
169  delete p;
170 
171  m_fp_zones.clear();
172 
173  for( auto d : m_drawings )
174  delete d;
175 
176  m_drawings.clear();
177 }
178 
179 
180 MODULE& MODULE::operator=( const MODULE& aOther )
181 {
182  BOARD_ITEM::operator=( aOther );
183 
184  m_Pos = aOther.m_Pos;
185  m_fpid = aOther.m_fpid;
186  m_Attributs = aOther.m_Attributs;
188  m_Orient = aOther.m_Orient;
189  m_BoundaryBox = aOther.m_BoundaryBox;
190  m_CntRot90 = aOther.m_CntRot90;
191  m_CntRot180 = aOther.m_CntRot180;
193  m_Link = aOther.m_Link;
194  m_Path = aOther.m_Path;
195 
202  m_ThermalGap = aOther.m_ThermalGap;
203 
204  // Copy reference and value
205  *m_Reference = *aOther.m_Reference;
206  m_Reference->SetParent( this );
207  *m_Value = *aOther.m_Value;
208  m_Value->SetParent( this );
209 
210  // Copy auxiliary data: Pads
211  m_pads.clear();
212 
213  for( auto pad : aOther.Pads() )
214  {
215  Add( new D_PAD( *pad ) );
216  }
217 
218  // Copy auxiliary data: Zones
219  m_fp_zones.clear();
220 
221  for( auto item : aOther.Zones() )
222  {
223  Add( static_cast<MODULE_ZONE_CONTAINER*>( item->Clone() ) );
224 
225  // Ensure the net info is OK and especially uses the net info list
226  // living in the current board
227  // Needed when copying a fp from fp editor that has its own board
228  // Must be NETINFO_LIST::ORPHANED_ITEM for a keepout that has no net.
229  item->SetNetCode( -1 );
230  }
231 
232  // Copy auxiliary data: Drawings
233  m_drawings.clear();
234 
235  for( auto item : aOther.GraphicalItems() )
236  {
237  switch( item->Type() )
238  {
239  case PCB_MODULE_TEXT_T:
240  case PCB_MODULE_EDGE_T:
241  Add( static_cast<BOARD_ITEM*>( item->Clone() ) );
242  break;
243 
244  default:
245  wxLogMessage( wxT( "MODULE::operator=() internal error: unknown type" ) );
246  break;
247  }
248  }
249 
250  // Copy auxiliary data: 3D_Drawings info
251  m_3D_Drawings.clear();
252  m_3D_Drawings = aOther.m_3D_Drawings;
253  m_Doc = aOther.m_Doc;
254  m_KeyWord = aOther.m_KeyWord;
255 
256  // Ensure auxiliary data is up to date
258 
259  return *this;
260 }
261 
262 
264 {
265  // Force the ORPHANED dummy net info for all pads.
266  // ORPHANED dummy net does not depend on a board
267  for( auto pad : m_pads )
268  pad->SetNetCode( NETINFO_LIST::ORPHANED );
269 }
270 
271 
272 void MODULE::Add( BOARD_ITEM* aBoardItem, ADD_MODE aMode )
273 {
274  switch( aBoardItem->Type() )
275  {
276  case PCB_MODULE_TEXT_T:
277  // Only user text can be added this way.
278  assert( static_cast<TEXTE_MODULE*>( aBoardItem )->GetType() == TEXTE_MODULE::TEXT_is_DIVERS );
279 
280  // no break
281 
282  case PCB_MODULE_EDGE_T:
283  if( aMode == ADD_MODE::APPEND )
284  m_drawings.push_back( aBoardItem );
285  else
286  m_drawings.push_front( aBoardItem );
287  break;
288 
289  case PCB_PAD_T:
290  if( aMode == ADD_MODE::APPEND )
291  m_pads.push_back( static_cast<D_PAD*>( aBoardItem ) );
292  else
293  m_pads.push_front( static_cast<D_PAD*>( aBoardItem ) );
294  break;
295 
297  if( aMode == ADD_MODE::APPEND )
298  m_fp_zones.push_back( static_cast<MODULE_ZONE_CONTAINER*>( aBoardItem ) );
299  else
300  m_fp_zones.insert( m_fp_zones.begin(), static_cast<MODULE_ZONE_CONTAINER*>( aBoardItem ) );
301  break;
302 
303  default:
304  {
305  wxString msg;
306  msg.Printf( wxT( "MODULE::Add() needs work: BOARD_ITEM type (%d) not handled" ),
307  aBoardItem->Type() );
308  wxFAIL_MSG( msg );
309 
310  return;
311  }
312  }
313 
314  aBoardItem->ClearEditFlags();
315  aBoardItem->SetParent( this );
316 }
317 
318 
319 void MODULE::Remove( BOARD_ITEM* aBoardItem )
320 {
321  switch( aBoardItem->Type() )
322  {
323  case PCB_MODULE_TEXT_T:
324  // Only user text can be removed this way.
325  wxCHECK_RET(
326  static_cast<TEXTE_MODULE*>( aBoardItem )->GetType() == TEXTE_MODULE::TEXT_is_DIVERS,
327  "Please report this bug: Invalid remove operation on required text" );
328 
329  // no break
330 
331  case PCB_MODULE_EDGE_T:
332  for( auto it = m_drawings.begin(); it != m_drawings.end(); ++it )
333  {
334  if( *it == aBoardItem )
335  {
336  m_drawings.erase( it );
337  break;
338  }
339  }
340 
341  break;
342 
343  case PCB_PAD_T:
344  for( auto it = m_pads.begin(); it != m_pads.end(); ++it )
345  {
346  if( *it == static_cast<D_PAD*>( aBoardItem ) )
347  {
348  m_pads.erase( it );
349  break;
350  }
351  }
352 
353  break;
354 
356  for( auto it = m_fp_zones.begin(); it != m_fp_zones.end(); ++it )
357  {
358  if( *it == static_cast<MODULE_ZONE_CONTAINER*>( aBoardItem ) )
359  {
360  m_fp_zones.erase( it );
361  break;
362  }
363  }
364 
365  break;
366 
367  default:
368  {
369  wxString msg;
370  msg.Printf( wxT( "MODULE::Remove() needs work: BOARD_ITEM type (%d) not handled" ),
371  aBoardItem->Type() );
372  wxFAIL_MSG( msg );
373  }
374  }
375 }
376 
377 
378 void MODULE::Print( PCB_BASE_FRAME* aFrame, wxDC* aDC, const wxPoint& aOffset )
379 {
380  for( auto pad : m_pads )
381  pad->Print( aFrame, aDC, aOffset );
382 
383  for( auto zone : m_fp_zones )
384  zone->Print( aFrame, aDC, aOffset );
385 
386  BOARD* brd = GetBoard();
387 
388  // Draw graphic items
390  m_Reference->Print( aFrame, aDC, aOffset );
391 
392  if( brd->IsElementVisible( LAYER_MOD_VALUES ) )
393  m_Value->Print( aFrame, aDC, aOffset );
394 
395  for( auto item : m_drawings )
396  {
397  switch( item->Type() )
398  {
399  case PCB_MODULE_TEXT_T:
400  case PCB_MODULE_EDGE_T:
401  item->Print( aFrame, aDC, aOffset );
402  break;
403 
404  default:
405  break;
406  }
407  }
408 }
409 
410 
412 {
414 }
415 
416 
417 double MODULE::GetArea( int aPadding ) const
418 {
419  double w = std::abs( m_BoundaryBox.GetWidth() ) + aPadding;
420  double h = std::abs( m_BoundaryBox.GetHeight() ) + aPadding;
421  return w * h;
422 }
423 
424 
426 {
427  EDA_RECT area;
428 
429  area.SetOrigin( m_Pos );
430  area.SetEnd( m_Pos );
431  area.Inflate( Millimeter2iu( 0.25 ) ); // Give a min size to the area
432 
433  for( auto item : m_drawings )
434  {
435  if( item->Type() == PCB_MODULE_EDGE_T )
436  area.Merge( item->GetBoundingBox() );
437  }
438 
439  for( auto pad : m_pads )
440  area.Merge( pad->GetBoundingBox() );
441 
442  for( auto zone : m_fp_zones )
443  area.Merge( zone->GetBoundingBox() );
444 
445  return area;
446 }
447 
448 
450 {
451  EDA_RECT area;
452 
453  // We want the bounding box of the footprint pads at rot 0, not flipped
454  // Create such a image:
455  MODULE dummy( *this );
456 
457  dummy.SetPosition( wxPoint( 0, 0 ) );
458  if( dummy.IsFlipped() )
459  dummy.Flip( wxPoint( 0, 0 ) , false );
460 
461  if( dummy.GetOrientation() )
462  dummy.SetOrientation( 0 );
463 
464  for( auto pad : dummy.Pads() )
465  area.Merge( pad->GetBoundingBox() );
466 
467  return area;
468 }
469 
470 
472 {
473  EDA_RECT area = GetFootprintRect();
474 
475  // Add in items not collected by GetFootprintRect():
476  for( auto item : m_drawings )
477  {
478  if( item->Type() != PCB_MODULE_EDGE_T )
479  area.Merge( item->GetBoundingBox() );
480  }
481 
482  area.Merge( m_Value->GetBoundingBox() );
483  area.Merge( m_Reference->GetBoundingBox() );
484 
485  return area;
486 }
487 
488 
489 const EDA_RECT MODULE::GetBoundingBox( bool aIncludeInvisibleText ) const
490 {
491  EDA_RECT area = GetFootprintRect();
492 
493  // Add in items not collected by GetFootprintRect():
494  for( auto item : m_drawings )
495  {
496  if( item->Type() != PCB_MODULE_EDGE_T )
497  area.Merge( item->GetBoundingBox() );
498  }
499 
500  if( m_Value->IsVisible() || aIncludeInvisibleText )
501  area.Merge( m_Value->GetBoundingBox() );
502 
503  if( m_Reference->IsVisible() || aIncludeInvisibleText )
504  area.Merge( m_Reference->GetBoundingBox() );
505 
506  return area;
507 }
508 
509 
525 {
526  SHAPE_POLY_SET poly;
527 
528  double orientation = GetOrientationRadians();
529 
530  MODULE temp = *this;
531  temp.SetOrientation( 0.0 );
532  BOX2I area = temp.GetFootprintRect();
533 
534  poly.NewOutline();
535 
536  VECTOR2I p = area.GetPosition();
537  poly.Append( p );
538  p.x = area.GetRight();
539  poly.Append( p );
540  p.y = area.GetBottom();
541  poly.Append( p );
542  p.x = area.GetX();
543  poly.Append( p );
544 
545  BOARD* board = GetBoard();
546  if( board )
547  {
548  int biggest_clearance = board->GetDesignSettings().GetBiggestClearanceValue();
549  poly.Inflate( biggest_clearance, 4 );
550  }
551 
552  poly.Inflate( Millimeter2iu( 0.01 ), 4 );
553  poly.Rotate( -orientation, m_Pos );
554 
555  return poly;
556 }
557 
558 
559 void MODULE::GetMsgPanelInfo( EDA_UNITS aUnits, std::vector<MSG_PANEL_ITEM>& aList )
560 {
561  wxString msg;
562 
563  aList.emplace_back( MSG_PANEL_ITEM( m_Reference->GetShownText(), m_Value->GetShownText(), DARKCYAN ) );
564 
565  // Display last date the component was edited (useful in Module Editor).
566  wxDateTime date( static_cast<time_t>( m_LastEditTime ) );
567 
568  if( m_LastEditTime && date.IsValid() )
569  // Date format: see http://www.cplusplus.com/reference/ctime/strftime
570  msg = date.Format( wxT( "%b %d, %Y" ) ); // Abbreviated_month_name Day, Year
571  else
572  msg = _( "Unknown" );
573 
574  aList.emplace_back( MSG_PANEL_ITEM( _( "Last Change" ), msg, BROWN ) );
575 
576  // display the board side placement
577  aList.emplace_back( MSG_PANEL_ITEM( _( "Board Side" ),
578  IsFlipped()? _( "Back (Flipped)" ) : _( "Front" ), RED ) );
579 
580  msg.Printf( wxT( "%zu" ), m_pads.size() );
581  aList.emplace_back( MSG_PANEL_ITEM( _( "Pads" ), msg, BLUE ) );
582 
583  msg = wxT( ".." );
584 
585  if( IsLocked() )
586  msg[0] = 'L';
587 
589  msg[1] = 'P';
590 
591  aList.emplace_back( MSG_PANEL_ITEM( _( "Status" ), msg, MAGENTA ) );
592 
593  msg.Printf( wxT( "%.1f" ), GetOrientationDegrees() );
594  aList.emplace_back( MSG_PANEL_ITEM( _( "Rotation" ), msg, BROWN ) );
595 
596  // Controls on right side of the dialog
597  switch( m_Attributs & 255 )
598  {
599  case 0:
600  msg = _( "Normal" );
601  break;
602 
603  case MOD_CMS:
604  msg = _( "Insert" );
605  break;
606 
607  case MOD_VIRTUAL:
608  msg = _( "Virtual" );
609  break;
610 
611  default:
612  msg = wxT( "???" );
613  break;
614  }
615 
616  aList.emplace_back( MSG_PANEL_ITEM( _( "Attributes" ), msg, BROWN ) );
617  aList.emplace_back( MSG_PANEL_ITEM( _( "Footprint" ), FROM_UTF8( m_fpid.Format().c_str() ), BLUE ) );
618 
619  if( m_3D_Drawings.empty() )
620  msg = _( "No 3D shape" );
621  else
622  msg = m_3D_Drawings.front().m_Filename;
623 
624  // Search the first active 3D shape in list
625 
626  aList.emplace_back( MSG_PANEL_ITEM( _( "3D-Shape" ), msg, RED ) );
627 
628  wxString doc, keyword;
629  doc.Printf( _( "Doc: %s" ), m_Doc );
630  keyword.Printf( _( "Key Words: %s" ), m_KeyWord );
631  aList.emplace_back( MSG_PANEL_ITEM( doc, keyword, BLACK ) );
632 }
633 
634 
635 bool MODULE::HitTest( const wxPoint& aPosition, int aAccuracy ) const
636 {
637  EDA_RECT rect = m_BoundaryBox;
638  return rect.Inflate( aAccuracy ).Contains( aPosition );
639 }
640 
641 
642 bool MODULE::HitTestAccurate( const wxPoint& aPosition, int aAccuracy ) const
643 {
644  return GetBoundingPoly().Collide( aPosition, aAccuracy );
645 }
646 
647 
648 bool MODULE::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const
649 {
650  EDA_RECT arect = aRect;
651  arect.Inflate( aAccuracy );
652 
653  if( aContained )
654  return arect.Contains( m_BoundaryBox );
655  else
656  {
657  // If the rect does not intersect the bounding box, skip any tests
658  if( !aRect.Intersects( GetBoundingBox() ) )
659  return false;
660 
661  // Determine if any elements in the MODULE intersect the rect
662  for( auto pad : m_pads )
663  {
664  if( pad->HitTest( arect, false, 0 ) )
665  return true;
666  }
667 
668  for( auto zone : m_fp_zones )
669  {
670  if( zone->HitTest( arect, false, 0 ) )
671  return true;
672  }
673 
674  for( auto item : m_drawings )
675  {
676  if( item->HitTest( arect, false, 0 ) )
677  return true;
678  }
679 
680  // No items were hit
681  return false;
682  }
683 }
684 
685 
686 D_PAD* MODULE::FindPadByName( const wxString& aPadName ) const
687 {
688  for( auto pad : m_pads )
689  {
690  if( pad->GetName() == aPadName )
691  return pad;
692  }
693 
694  return NULL;
695 }
696 
697 
698 D_PAD* MODULE::GetPad( const wxPoint& aPosition, LSET aLayerMask )
699 {
700  for( auto pad : m_pads )
701  {
702  // ... and on the correct layer.
703  if( !( pad->GetLayerSet() & aLayerMask ).any() )
704  continue;
705 
706  if( pad->HitTest( aPosition ) )
707  return pad;
708  }
709 
710  return NULL;
711 }
712 
713 
715 {
716  D_PAD* topLeftPad = GetFirstPad();
717 
718  for( auto p : m_pads )
719  {
720  wxPoint pnt = p->GetPosition(); // GetPosition() returns the center of the pad
721 
722  if( ( pnt.x < topLeftPad->GetPosition().x ) ||
723  ( ( topLeftPad->GetPosition().x == pnt.x ) &&
724  ( pnt.y < topLeftPad->GetPosition().y ) ) )
725  {
726  topLeftPad = p;
727  }
728  }
729 
730  return topLeftPad;
731 }
732 
733 
734 unsigned MODULE::GetPadCount( INCLUDE_NPTH_T aIncludeNPTH ) const
735 {
736  if( aIncludeNPTH )
737  return m_pads.size();
738 
739  unsigned cnt = 0;
740 
741  for( auto pad : m_pads )
742  {
743  if( pad->GetAttribute() == PAD_ATTRIB_HOLE_NOT_PLATED )
744  continue;
745 
746  cnt++;
747  }
748 
749  return cnt;
750 }
751 
752 
753 unsigned MODULE::GetUniquePadCount( INCLUDE_NPTH_T aIncludeNPTH ) const
754 {
755  std::set<wxString> usedNames;
756 
757  // Create a set of used pad numbers
758  for( auto pad : m_pads )
759  {
760  // Skip pads not on copper layers (used to build complex
761  // solder paste shapes for instance)
762  if( ( pad->GetLayerSet() & LSET::AllCuMask() ).none() )
763  continue;
764 
765  // Skip pads with no name, because they are usually "mechanical"
766  // pads, not "electrical" pads
767  if( pad->GetName().IsEmpty() )
768  continue;
769 
770  if( !aIncludeNPTH )
771  {
772  // skip NPTH
773  if( pad->GetAttribute() == PAD_ATTRIB_HOLE_NOT_PLATED )
774  {
775  continue;
776  }
777  }
778 
779  usedNames.insert( pad->GetName() );
780  }
781 
782  return usedNames.size();
783 }
784 
785 
787 {
788  if( NULL == a3DModel )
789  return;
790 
791  if( !a3DModel->m_Filename.empty() )
792  m_3D_Drawings.push_back( *a3DModel );
793 
794  delete a3DModel;
795 }
796 
797 
798 // see class_module.h
799 SEARCH_RESULT MODULE::Visit( INSPECTOR inspector, void* testData, const KICAD_T scanTypes[] )
800 {
801  KICAD_T stype;
803  const KICAD_T* p = scanTypes;
804  bool done = false;
805 
806 #if 0 && defined(DEBUG)
807  std::cout << GetClass().mb_str() << ' ';
808 #endif
809 
810  while( !done )
811  {
812  stype = *p;
813 
814  switch( stype )
815  {
816  case PCB_MODULE_T:
817  result = inspector( this, testData ); // inspect me
818  ++p;
819  break;
820 
821  case PCB_PAD_T:
822  result = IterateForward<D_PAD*>( m_pads, inspector, testData, p );
823  ++p;
824  break;
825 
827  result = IterateForward<MODULE_ZONE_CONTAINER*>( m_fp_zones, inspector, testData, p );
828  ++p;
829  break;
830 
831  case PCB_MODULE_TEXT_T:
832  result = inspector( m_Reference, testData );
833 
834  if( result == SEARCH_RESULT::QUIT )
835  break;
836 
837  result = inspector( m_Value, testData );
838 
839  if( result == SEARCH_RESULT::QUIT )
840  break;
841 
842  // Intentionally fall through since m_Drawings can hold TYPETEXTMODULE also
843 
844  case PCB_MODULE_EDGE_T:
845  result = IterateForward<BOARD_ITEM*>( m_drawings, inspector, testData, p );
846 
847  // skip over any types handled in the above call.
848  for( ; ; )
849  {
850  switch( stype = *++p )
851  {
852  case PCB_MODULE_TEXT_T:
853  case PCB_MODULE_EDGE_T:
854  continue;
855 
856  default:
857  ;
858  }
859 
860  break;
861  }
862 
863  break;
864 
865  default:
866  done = true;
867  break;
868  }
869 
870  if( result == SEARCH_RESULT::QUIT )
871  break;
872  }
873 
874  return result;
875 }
876 
877 
878 wxString MODULE::GetSelectMenuText( EDA_UNITS aUnits ) const
879 {
880  wxString reference = GetReference();
881 
882  if( reference.IsEmpty() )
883  reference = _( "<no reference designator>" );
884 
885  return wxString::Format( _( "Footprint %s on %s" ), reference, GetLayerName() );
886 }
887 
888 
890 {
891  return module_xpm;
892 }
893 
894 
896 {
897  return new MODULE( *this );
898 }
899 
900 
901 void MODULE::RunOnChildren( const std::function<void (BOARD_ITEM*)>& aFunction )
902 {
903  try
904  {
905  for( auto pad : m_pads )
906  aFunction( static_cast<BOARD_ITEM*>( pad ) );
907 
908  for( auto zone : m_fp_zones )
909  aFunction( static_cast<MODULE_ZONE_CONTAINER*>( zone ) );
910 
911  for( auto drawing : m_drawings )
912  aFunction( static_cast<BOARD_ITEM*>( drawing ) );
913 
914  aFunction( static_cast<BOARD_ITEM*>( m_Reference ) );
915  aFunction( static_cast<BOARD_ITEM*>( m_Value ) );
916  }
917  catch( std::bad_function_call& )
918  {
919  DisplayError( NULL, wxT( "Error running MODULE::RunOnChildren" ) );
920  }
921 }
922 
923 
924 void MODULE::GetAllDrawingLayers( int aLayers[], int& aCount, bool aIncludePads ) const
925 {
926  std::unordered_set<int> layers;
927 
928  for( auto item : m_drawings )
929  {
930  layers.insert( static_cast<int>( item->GetLayer() ) );
931  }
932 
933  if( aIncludePads )
934  {
935  for( auto pad : m_pads )
936  {
937  int pad_layers[KIGFX::VIEW::VIEW_MAX_LAYERS], pad_layers_count;
938  pad->ViewGetLayers( pad_layers, pad_layers_count );
939 
940  for( int i = 0; i < pad_layers_count; i++ )
941  layers.insert( pad_layers[i] );
942  }
943  }
944 
945  aCount = layers.size();
946  int i = 0;
947 
948  for( auto layer : layers )
949  aLayers[i++] = layer;
950 }
951 
952 
953 void MODULE::ViewGetLayers( int aLayers[], int& aCount ) const
954 {
955  aCount = 2;
956  aLayers[0] = LAYER_ANCHOR;
957 
958  switch( m_Layer )
959  {
960 
961  default:
962  wxASSERT_MSG( false, "Illegal layer" ); // do you really have modules placed on other layers?
963  // pass through
964  case F_Cu:
965  aLayers[1] = LAYER_MOD_FR;
966  break;
967 
968  case B_Cu:
969  aLayers[1] = LAYER_MOD_BK;
970  break;
971  }
972 
973  // If there are no pads, and only drawings on a silkscreen layer, then
974  // report the silkscreen layer as well so that the component can be edited
975  // with the silkscreen layer
976  bool f_silk = false, b_silk = false, non_silk = false;
977 
978  for( auto item : m_drawings )
979  {
980  if( item->GetLayer() == F_SilkS )
981  f_silk = true;
982  else if( item->GetLayer() == B_SilkS )
983  b_silk = true;
984  else
985  non_silk = true;
986  }
987 
988  if( ( f_silk || b_silk ) && !non_silk && m_pads.empty() )
989  {
990  if( f_silk )
991  aLayers[ aCount++ ] = F_SilkS;
992 
993  if( b_silk )
994  aLayers[ aCount++ ] = B_SilkS;
995  }
996 }
997 
998 
999 unsigned int MODULE::ViewGetLOD( int aLayer, KIGFX::VIEW* aView ) const
1000 {
1001  int layer = ( m_Layer == F_Cu ) ? LAYER_MOD_FR :
1003 
1004  // Currently it is only for anchor layer
1005  if( aView->IsLayerVisible( layer ) )
1006  return 3;
1007 
1008  return std::numeric_limits<unsigned int>::max();
1009 }
1010 
1011 
1013 {
1014  EDA_RECT area = GetFootprintRect();
1015 
1016  // Calculate extended area including text fields
1017  area.Merge( m_Reference->GetBoundingBox() );
1018  area.Merge( m_Value->GetBoundingBox() );
1019 
1020  // Add the Clearance shape size: (shape around the pads when the
1021  // clearance is shown. Not optimized, but the draw cost is small
1022  // (perhaps smaller than optimization).
1023  BOARD* board = GetBoard();
1024  if( board )
1025  {
1026  int biggest_clearance = board->GetDesignSettings().GetBiggestClearanceValue();
1027  area.Inflate( biggest_clearance );
1028  }
1029 
1030  return area;
1031 }
1032 
1033 
1034 bool MODULE::IsLibNameValid( const wxString & aName )
1035 {
1036  const wxChar * invalids = StringLibNameInvalidChars( false );
1037 
1038  if( aName.find_first_of( invalids ) != std::string::npos )
1039  return false;
1040 
1041  return true;
1042 }
1043 
1044 
1045 const wxChar* MODULE::StringLibNameInvalidChars( bool aUserReadable )
1046 {
1047  // This list of characters is also duplicated in validators.cpp and
1048  // lib_id.cpp
1049  // TODO: Unify forbidden character lists
1050  static const wxChar invalidChars[] = wxT("%$<>\t\n\r\"\\/:");
1051  static const wxChar invalidCharsReadable[] = wxT("% $ < > 'tab' 'return' 'line feed' \\ \" / :");
1052 
1053  if( aUserReadable )
1054  return invalidCharsReadable;
1055  else
1056  return invalidChars;
1057 }
1058 
1059 
1060 void MODULE::Move( const wxPoint& aMoveVector )
1061 {
1062  wxPoint newpos = m_Pos + aMoveVector;
1063  SetPosition( newpos );
1064 }
1065 
1066 
1067 void MODULE::Rotate( const wxPoint& aRotCentre, double aAngle )
1068 {
1069  double orientation = GetOrientation();
1070  double newOrientation = orientation + aAngle;
1071  wxPoint newpos = m_Pos;
1072  RotatePoint( &newpos, aRotCentre, aAngle );
1073  SetPosition( newpos );
1074  SetOrientation( newOrientation );
1075 
1076  m_Reference->KeepUpright( orientation, newOrientation );
1077  m_Value->KeepUpright( orientation, newOrientation );
1078 
1079  for( auto item : m_drawings )
1080  {
1081  if( item->Type() == PCB_MODULE_TEXT_T )
1082  static_cast<TEXTE_MODULE*>( item )->KeepUpright( orientation, newOrientation );
1083  }
1084 }
1085 
1086 
1087 void MODULE::Flip( const wxPoint& aCentre, bool aFlipLeftRight )
1088 {
1089  // Move module to its final position:
1090  wxPoint finalPos = m_Pos;
1091 
1092  // Now Flip the footprint.
1093  // Flipping a footprint is a specific transform:
1094  // it is not mirrored like a text.
1095  // We have to change the side, and ensure the footprint rotation is
1096  // modified accordint to the transform, because this parameter is used
1097  // in pick and place files, and when updating the footprint from library.
1098  // When flipped around the X axis (Y coordinates changed) orientation is negated
1099  // When flipped around the Y axis (X coordinates changed) orientation is 180 - old orient.
1100  // Because it is specfic to a footprint, we flip around the X axis, and after rotate 180 deg
1101 
1102  MIRROR( finalPos.y, aCentre.y );
1103 
1104  SetPosition( finalPos );
1105 
1106  // Flip layer
1107  SetLayer( FlipLayer( GetLayer() ) );
1108 
1109  // Reverse mirror orientation.
1110  m_Orient = -m_Orient;
1111 
1113 
1114  // Mirror pads to other side of board.
1115  for( auto pad : m_pads )
1116  pad->Flip( m_Pos, false );
1117 
1118  // Mirror zones to other side of board.
1119  for( auto zone : m_fp_zones )
1120  zone->Flip( m_Pos, aFlipLeftRight );
1121 
1122  // Mirror reference and value.
1123  m_Reference->Flip( m_Pos, false );
1124  m_Value->Flip( m_Pos, false );
1125 
1126  // Reverse mirror module graphics and texts.
1127  for( auto item : m_drawings )
1128  {
1129  switch( item->Type() )
1130  {
1131  case PCB_MODULE_EDGE_T:
1132  static_cast<EDGE_MODULE*>( item )->Flip( m_Pos, false );
1133  break;
1134 
1135  case PCB_MODULE_TEXT_T:
1136  static_cast<TEXTE_MODULE*>( item )->Flip( m_Pos, false );
1137  break;
1138 
1139  default:
1140  wxMessageBox( wxT( "MODULE::Flip() error: Unknown Draw Type" ) );
1141  break;
1142  }
1143  }
1144 
1145  // Now rotate 180 deg if required
1146  if( aFlipLeftRight )
1147  Rotate( aCentre, 1800.0 );
1148 
1150 }
1151 
1152 
1153 void MODULE::SetPosition( const wxPoint& newpos )
1154 {
1155  wxPoint delta = newpos - m_Pos;
1156 
1157  m_Pos += delta;
1158 
1159  m_Reference->EDA_TEXT::Offset( delta );
1160  m_Value->EDA_TEXT::Offset( delta );
1161 
1162  for( auto pad : m_pads )
1163  {
1164  pad->SetPosition( pad->GetPosition() + delta );
1165  }
1166 
1167  for( auto zone : m_fp_zones )
1168  zone->Move( delta );
1169 
1170  for( auto item : m_drawings )
1171  {
1172  switch( item->Type() )
1173  {
1174  case PCB_MODULE_EDGE_T:
1175  {
1176  EDGE_MODULE* pt_edgmod = (EDGE_MODULE*) item;
1177  pt_edgmod->SetDrawCoord();
1178  break;
1179  }
1180 
1181  case PCB_MODULE_TEXT_T:
1182  {
1183  TEXTE_MODULE* text = static_cast<TEXTE_MODULE*>( item );
1184  text->EDA_TEXT::Offset( delta );
1185  break;
1186  }
1187 
1188  default:
1189  wxMessageBox( wxT( "Draw type undefined." ) );
1190  break;
1191  }
1192  }
1193 
1195 }
1196 
1197 
1198 void MODULE::MoveAnchorPosition( const wxPoint& aMoveVector )
1199 {
1200  /* Move the reference point of the footprint
1201  * the footprints elements (pads, outlines, edges .. ) are moved
1202  * but:
1203  * - the footprint position is not modified.
1204  * - the relative (local) coordinates of these items are modified
1205  * - Draw coordinates are updated
1206  */
1207 
1208 
1209  // Update (move) the relative coordinates relative to the new anchor point.
1210  wxPoint moveVector = aMoveVector;
1211  RotatePoint( &moveVector, -GetOrientation() );
1212 
1213  // Update of the reference and value.
1214  m_Reference->SetPos0( m_Reference->GetPos0() + moveVector );
1216  m_Value->SetPos0( m_Value->GetPos0() + moveVector );
1217  m_Value->SetDrawCoord();
1218 
1219  // Update the pad local coordinates.
1220  for( auto pad : m_pads )
1221  {
1222  pad->SetPos0( pad->GetPos0() + moveVector );
1223  pad->SetDrawCoord();
1224  }
1225 
1226  // Update the draw element coordinates.
1227  for( auto item : GraphicalItems() )
1228  {
1229  switch( item->Type() )
1230  {
1231  case PCB_MODULE_EDGE_T:
1232  {
1233  EDGE_MODULE* edge = static_cast<EDGE_MODULE*>( item );
1234  edge->Move( moveVector );
1235  }
1236  break;
1237 
1238  case PCB_MODULE_TEXT_T:
1239  {
1240  TEXTE_MODULE* text = static_cast<TEXTE_MODULE*>( item );
1241  text->SetPos0( text->GetPos0() + moveVector );
1242  text->SetDrawCoord();
1243  }
1244  break;
1245 
1246  default:
1247  break;
1248  }
1249  }
1250 
1252 }
1253 
1254 
1255 void MODULE::SetOrientation( double newangle )
1256 {
1257  double angleChange = newangle - m_Orient; // change in rotation
1258 
1259  NORMALIZE_ANGLE_180( newangle );
1260 
1261  m_Orient = newangle;
1262 
1263  for( auto pad : m_pads )
1264  {
1265  pad->SetOrientation( pad->GetOrientation() + angleChange );
1266  pad->SetDrawCoord();
1267  }
1268 
1269  for( auto zone : m_fp_zones )
1270  {
1271  zone->Rotate( GetPosition(), angleChange );
1272  }
1273 
1274  // Update of the reference and value.
1276  m_Value->SetDrawCoord();
1277 
1278  // Displace contours and text of the footprint.
1279  for( auto item : m_drawings )
1280  {
1281  if( item->Type() == PCB_MODULE_EDGE_T )
1282  {
1283  static_cast<EDGE_MODULE*>( item )->SetDrawCoord();
1284  }
1285  else if( item->Type() == PCB_MODULE_TEXT_T )
1286  {
1287  static_cast<TEXTE_MODULE*>( item )->SetDrawCoord();
1288  }
1289  }
1290 
1292 }
1293 
1294 BOARD_ITEM* MODULE::DuplicateItem( const BOARD_ITEM* aItem, bool aIncrementPadNumbers,
1295  bool aAddToModule )
1296 {
1297  BOARD_ITEM* new_item = NULL;
1298  MODULE_ZONE_CONTAINER* new_zone = NULL;
1299 
1300  switch( aItem->Type() )
1301  {
1302  case PCB_PAD_T:
1303  {
1304  D_PAD* new_pad = new D_PAD( *static_cast<const D_PAD*>( aItem ) );
1305 
1306  if( aAddToModule )
1307  m_pads.push_back( new_pad );
1308 
1309  if( aIncrementPadNumbers && !new_pad->IsAperturePad() )
1310  new_pad->IncrementPadName( true, true );
1311 
1312  new_item = new_pad;
1313  break;
1314  }
1315 
1317  {
1318  new_zone = new MODULE_ZONE_CONTAINER( *static_cast<const MODULE_ZONE_CONTAINER*>( aItem ) );
1319 
1320  if( aAddToModule )
1321  m_fp_zones.push_back( new_zone );
1322 
1323  new_item = new_zone;
1324  break;
1325  }
1326 
1327  case PCB_MODULE_TEXT_T:
1328  {
1329  TEXTE_MODULE* new_text = new TEXTE_MODULE( *static_cast<const TEXTE_MODULE*>( aItem ) );
1330 
1331  if( new_text->GetType() == TEXTE_MODULE::TEXT_is_REFERENCE )
1332  {
1333  new_text->SetText( wxT( "%R" ) );
1335  }
1336  else if( new_text->GetType() == TEXTE_MODULE::TEXT_is_VALUE )
1337  {
1338  new_text->SetText( wxT( "%V" ) );
1340  }
1341 
1342  if( aAddToModule )
1343  Add( new_text );
1344 
1345  new_item = new_text;
1346 
1347  break;
1348  }
1349 
1350  case PCB_MODULE_EDGE_T:
1351  {
1352  EDGE_MODULE* new_edge = new EDGE_MODULE( *static_cast<const EDGE_MODULE*>(aItem) );
1353 
1354  if( aAddToModule )
1355  Add( new_edge );
1356 
1357  new_item = new_edge;
1358  break;
1359  }
1360 
1361  case PCB_MODULE_T:
1362  // Ignore the module itself
1363  break;
1364 
1365  default:
1366  // Un-handled item for duplication
1367  wxFAIL_MSG( "Duplication not supported for items of class " + aItem->GetClass() );
1368  break;
1369  }
1370 
1371  return new_item;
1372 }
1373 
1374 
1375 wxString MODULE::GetNextPadName( bool aFillSequenceGaps ) const
1376 {
1377  std::set<int> usedNumbers;
1378 
1379  // Create a set of used pad numbers
1380  for( auto pad : m_pads )
1381  {
1382  int padNumber = GetTrailingInt( pad->GetName() );
1383  usedNumbers.insert( padNumber );
1384  }
1385 
1386  const int nextNum = getNextNumberInSequence( usedNumbers, aFillSequenceGaps );
1387 
1388  return wxString::Format( wxT( "%i" ), nextNum );
1389 }
1390 
1391 
1392 void MODULE::IncrementReference( int aDelta )
1393 {
1394  const auto& refdes = GetReference();
1395  SetReference( wxString::Format( wxT( "%s%i" ), UTIL::GetReferencePrefix( refdes ),
1396  GetTrailingInt( refdes ) + aDelta ) );
1397 }
1398 
1399 
1400 // Calculate the area of aPolySet, after fracturation, because
1401 // polygons with no hole are expected.
1402 static double polygonArea( SHAPE_POLY_SET& aPolySet )
1403 {
1404  double area = 0.0;
1405  for( int ii = 0; ii < aPolySet.OutlineCount(); ii++ )
1406  {
1407  SHAPE_LINE_CHAIN& outline = aPolySet.Outline( ii );
1408  // Ensure the curr outline is closed, to calculate area
1409  outline.SetClosed( true );
1410 
1411  area += outline.Area();
1412  }
1413 
1414  return area;
1415 }
1416 
1417 // a helper function to add a rectangular polygon aRect to aPolySet
1418 static void addRect( SHAPE_POLY_SET& aPolySet, wxRect aRect )
1419 {
1420  aPolySet.NewOutline();
1421 
1422  aPolySet.Append( aRect.GetX(), aRect.GetY() );
1423  aPolySet.Append( aRect.GetX()+aRect.width, aRect.GetY() );
1424  aPolySet.Append( aRect.GetX()+aRect.width, aRect.GetY()+aRect.height );
1425  aPolySet.Append( aRect.GetX(), aRect.GetY()+aRect.height );
1426 }
1427 
1428 double MODULE::CoverageRatio( const GENERAL_COLLECTOR& aCollector ) const
1429 {
1430  double moduleArea = GetFootprintRect().GetArea();
1431  SHAPE_POLY_SET coveredRegion;
1432  addRect( coveredRegion, GetFootprintRect() );
1433 
1434  // build list of holes (covered areas not available for selection)
1435  SHAPE_POLY_SET holes;
1436 
1437  for( auto pad : m_pads )
1438  addRect( holes, pad->GetBoundingBox() );
1439 
1440  addRect( holes, m_Reference->GetBoundingBox() );
1441  addRect( holes, m_Value->GetBoundingBox() );
1442 
1443  for( int i = 0; i < aCollector.GetCount(); ++i )
1444  {
1445  BOARD_ITEM* item = aCollector[i];
1446 
1447  switch( item->Type() )
1448  {
1449  case PCB_TEXT_T:
1450  case PCB_MODULE_TEXT_T:
1451  case PCB_TRACE_T:
1452  case PCB_ARC_T:
1453  case PCB_VIA_T:
1454  addRect( holes, item->GetBoundingBox() );
1455  break;
1456  default:
1457  break;
1458  }
1459  }
1460 
1461  SHAPE_POLY_SET uncoveredRegion;
1462 
1463  try
1464  {
1465  uncoveredRegion.BooleanSubtract( coveredRegion, holes, SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
1466  uncoveredRegion.Simplify( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
1467  uncoveredRegion.Fracture( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
1468  }
1469  catch( ClipperLib::clipperException& )
1470  {
1471  // better to be conservative (this will result in the disambiguate dialog)
1472  return 1.0;
1473  }
1474 
1475  double uncoveredRegionArea = polygonArea( uncoveredRegion );
1476  double coveredArea = moduleArea - uncoveredRegionArea;
1477  double ratio = ( coveredArea / moduleArea );
1478 
1479  return std::min( ratio, 1.0 );
1480 }
1481 
1482 
1483 // see convert_drawsegment_list_to_polygon.cpp:
1484 extern bool ConvertOutlineToPolygon( std::vector<DRAWSEGMENT*>& aSegList, SHAPE_POLY_SET& aPolygons,
1485  wxString* aErrorText, unsigned int aTolerance, wxPoint* aErrorLocation = nullptr );
1486 
1488 {
1491  // Build the courtyard area from graphic items on the courtyard.
1492  // Only PCB_MODULE_EDGE_T have meaning, graphic texts are ignored.
1493  // Collect items:
1494  std::vector< DRAWSEGMENT* > list_front;
1495  std::vector< DRAWSEGMENT* > list_back;
1496 
1497  for( auto item : GraphicalItems() )
1498  {
1499  if( item->GetLayer() == B_CrtYd && item->Type() == PCB_MODULE_EDGE_T )
1500  list_back.push_back( static_cast< DRAWSEGMENT* > ( item ) );
1501 
1502  if( item->GetLayer() == F_CrtYd && item->Type() == PCB_MODULE_EDGE_T )
1503  list_front.push_back( static_cast< DRAWSEGMENT* > ( item ) );
1504  }
1505 
1506  // Note: if no item found on courtyard layers, return true.
1507  // false is returned only when the shape defined on courtyard layers
1508  // is not convertible to a polygon
1509  if( !list_front.size() && !list_back.size() )
1510  return true;
1511 
1512  wxString error_msg;
1513 
1514  #define ARC_ERROR_MAX 0.02 /* error max in mm to approximate a arc by segments */
1515  bool success = ConvertOutlineToPolygon( list_front, m_poly_courtyard_front,
1516  &error_msg,
1517  (unsigned) Millimeter2iu( ARC_ERROR_MAX ) );
1518 
1519  if( success )
1520  {
1521  success = ConvertOutlineToPolygon( list_back, m_poly_courtyard_back,
1522  &error_msg,
1523  (unsigned) Millimeter2iu( ARC_ERROR_MAX ) );
1524  }
1525 
1526  if( !error_msg.IsEmpty() )
1527  {
1528  wxLogMessage( wxString::Format( _( "Processing courtyard of \"%s\": %s" ),
1529  GetChars( GetFPID().Format() ),
1530  error_msg) );
1531  }
1532 
1533  return success;
1534 }
1535 
1536 
1538 {
1539  assert( aImage->Type() == PCB_MODULE_T );
1540 
1541  std::swap( *((MODULE*) this), *((MODULE*) aImage) );
1542 }
1543 
1544 
1546 {
1547  // returns true if the given module has at lesat one non smd pin, such as through hole
1548 
1549  for( auto pad : Pads() )
1550  {
1551  if( pad->GetAttribute() != PAD_ATTRIB_SMD )
1552  return true;
1553  }
1554 
1555  return false;
1556 }
unsigned GetPadCount(INCLUDE_NPTH_T aIncludeNPTH=INCLUDE_NPTH_T(INCLUDE_NPTH)) const
GetPadCount returns the number of pads.
wxString GetNextPadName(bool aFillSequenceGaps) const
Function GetNextPadName returns the next available pad name in the module.
LIB_ID m_fpid
Definition: class_module.h:693
Definition: colors.h:57
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Function AllCuMask returns a mask holding the requested number of Cu PCB_LAYER_IDs.
Definition: lset.cpp:686
EDA_UNITS
Definition: common.h:184
void DisplayError(wxWindow *aParent, const wxString &aText, int aDisplayTime)
Display an error or warning message box with aMessage.
Definition: confirm.cpp:239
bool BuildPolyCourtyard()
Used in DRC to build the courtyard area (a complex polygon) from graphic items put on the courtyard.
bool IncrementPadName(bool aSkipUnconnectable, bool aFillSequenceGaps)
Function IncrementPadName.
Definition: class_pad.cpp:585
void Rotate(double aAngle, const VECTOR2I &aCenter={ 0, 0 })
Function Rotate rotates all vertices by a given angle.
double GetOrientation() const
Definition: class_module.h:215
double GetArea(int aPadding=0) const
const BITMAP_OPAQUE module_xpm[1]
Definition: module.cpp:29
int m_CntRot90
Definition: class_module.h:712
int OutlineCount() const
Returns the number of outlines in the set
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:721
PNG memory record (file in memory).
Definition: bitmap_def.h:29
static wxString FROM_UTF8(const char *cstring)
function FROM_UTF8 converts a UTF8 encoded C string to a wxString for all wxWidgets build modes.
Definition: macros.h:62
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.
like PAD_STANDARD, but not plated mechanical use only, no connection allowed
Definition: pad_shapes.h:66
void KeepUpright(double aOldOrientation, double aNewOrientation)
Called when rotating the parent footprint.
bool IsFlipped() const
function IsFlipped
Definition: class_module.h:292
wxString m_KeyWord
Definition: class_module.h:707
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:189
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:699
int GetBiggestClearanceValue()
Function GetBiggestClearanceValue.
double CoverageRatio(const GENERAL_COLLECTOR &aCollector) const
Function CoverageRatio Calculates the ratio of total area of the footprint pads and graphical items t...
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.
double m_LocalSolderPasteMarginRatio
Definition: class_module.h:704
bool IsVisible() const
Definition: eda_text.h:170
Definition: colors.h:61
PCB_LAYER_ID FlipLayer(PCB_LAYER_ID aLayerId, int aCopperLayersCount)
Function FlippedLayerNumber.
Definition: lset.cpp:485
int m_LocalSolderPasteMargin
Definition: class_module.h:703
int m_ThermalGap
Definition: class_module.h:700
Smd pad, appears on the solder paste layer (default)
Definition: pad_shapes.h:62
Collection of utility functions for component reference designators (refdes)
int GetWidth() const
Definition: eda_rect.h:119
PADS & Pads()
Definition: class_module.h:173
bool HasNonSMDPins() const
Set for modules listed in the automatic insertion list (usually SMD footprints)
Definition: class_module.h:74
KIID_PATH m_Path
Definition: class_module.h:708
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:198
void SetOrigin(const wxPoint &pos)
Definition: eda_rect.h:131
show modules values (when texts are visibles)
PADS m_pads
Definition: class_module.h:685
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Function GetDesignSettings.
Definition: class_board.h:512
EDA_RECT GetFootprintRect() const
Function GetFootprintRect() Returns the area of the module footprint excluding any text.
MODULE(BOARD *parent)
class D_PAD, a pad in a footprint
Definition: typeinfo.h:90
void Add3DModel(MODULE_3D_SETTINGS *a3DModel)
Function Add3DModel adds a3DModel definition to the end of the 3D model list.
const LIB_ID & GetFPID() const
Definition: class_module.h:219
#define ARC_ERROR_MAX
D_PAD * GetFirstPad() const
Gets the first pad in the list or NULL if none.
Definition: class_module.h:508
static const wxChar * StringLibNameInvalidChars(bool aUserReadable)
static function StringLibNameInvalidChars Test for validity of the name in a library of the footprint...
void NORMALIZE_ANGLE_180(T &Angle)
Definition: trigo.h:354
DRAWINGS & GraphicalItems()
Definition: class_module.h:183
coord_type GetBottom() const
Definition: box2.h:199
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.
virtual wxString GetShownText() const override
Return the string actually shown after processing of the base text.
void MoveAnchorPosition(const wxPoint &aMoveVector)
Function MoveAnchorPosition Move the reference point of the footprint It looks like a move footprint:...
wxArrayString * m_initial_comments
leading s-expression comments in the module, lazily allocated only if needed for speed
Definition: class_module.h:715
class EDGE_MODULE, a footprint edge
Definition: typeinfo.h:94
bool Contains(const wxPoint &aPoint) const
Function Contains.
#define MODULE_PADS_LOCKED
In autoplace: module waiting for autoplace.
Definition: class_module.h:298
static int getNextNumberInSequence(const std::set< int > &aSeq, bool aFillSequenceGaps)
KICAD_T
Enum KICAD_T is the set of class identification values, stored in EDA_ITEM::m_StructType.
Definition: typeinfo.h:78
static constexpr int VIEW_MAX_LAYERS
maximum number of layers that may be shown
Definition: view.h:701
class TRACK, a track segment (segment on a copper layer)
Definition: typeinfo.h:96
wxString m_Doc
Definition: class_module.h:706
timestamp_t m_LastEditTime
Definition: class_module.h:709
This file contains miscellaneous commonly used macros and functions.
const wxString GetReference() const
Function GetReference.
Definition: class_module.h:436
const char * c_str() const
Definition: utf8.h:107
#define MODULE_is_PLACED
In autoplace: module automatically placed.
Definition: class_module.h:296
show modules on front
int m_LocalClearance
Definition: class_module.h:701
const INSPECTOR_FUNC & INSPECTOR
Definition: base_struct.h:108
PCB_LAYER_ID m_Layer
double m_Orient
Definition: class_module.h:689
void MIRROR(T &aPoint, const T &aMirrorRef)
Definition: macros.h:123
int GetCount() const
Function GetCount returns the number of objects in the list.
Definition: collector.h:100
static void addRect(SHAPE_POLY_SET &aPolySet, wxRect aRect)
void Print(PCB_BASE_FRAME *aFrame, wxDC *aDC, const wxPoint &aOffset=ZeroOffset) override
Function Print Print the text according to the footprint pos and orient.
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.
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.
EDA_RECT m_BoundaryBox
Definition: class_module.h:696
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:111
#define NULL
void SetParent(EDA_ITEM *aParent)
Definition: base_struct.h:218
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:698
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.
int m_LocalSolderMaskMargin
Definition: class_module.h:702
std::list< MODULE_3D_SETTINGS > m_3D_Drawings
Definition: class_module.h:687
double GetOrientationRadians() const
Definition: class_module.h:217
int m_arflag
Definition: class_module.h:710
double GetOrientationDegrees() const
Definition: class_module.h:216
MODULE_ZONE_CONTAINERS m_fp_zones
Definition: class_module.h:686
Definition: colors.h:60
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:446
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.
bool Collide(const VECTOR2I &aP, int aClearance=0) const override
Function Collide Checks whether the point aP collides with the inside of the polygon set; if the poin...
SHAPE_POLY_SET m_poly_courtyard_front
Used in DRC to test the courtyard area (a polygon which can be not basic Note also a footprint can ha...
Definition: class_module.h:720
virtual void SetPosition(const wxPoint &aPos) override
void Remove(BOARD_ITEM *aItem) override
virtual unsigned int ViewGetLOD(int aLayer, KIGFX::VIEW *aView) const override
Function ViewGetLOD() Returns the level of detail (LOD) of the item.
void SetPosition(const wxPoint &aPos) override
double GetArea() const
Function GetArea returns the area of the rectangle.
int NewOutline()
Creates a new empty polygon in the set and returns its index
bool IsLocked() const override
Function IsLocked.
Definition: class_module.h:301
void SetType(TEXT_TYPE aType)
DRAWINGS m_drawings
Definition: class_module.h:684
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...
const MODULE_ZONE_CONTAINERS & Zones() const
Definition: class_module.h:188
int GetHeight() const
Definition: eda_rect.h:120
D_PAD * GetTopLeftPad()
void SetPos0(const wxPoint &aPos)
UTF8 Format() const
Definition: lib_id.cpp:237
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:466
MODULE & operator=(const MODULE &aOther)
double Area() const
wxString m_Filename
The 3D shape filename in 3D library.
Definition: class_module.h:100
default
Definition: class_module.h:73
BITMAP_DEF GetMenuImage() const override
Function GetMenuImage returns a pointer to an image to be used in menus.
const wxPoint & GetPos0() const
const Vec & GetPosition() const
Definition: box2.h:193
bool IsElementVisible(GAL_LAYER_ID aLayer) const
Function IsElementVisible tests 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.
D_PAD * GetPad(const wxPoint &aPosition, LSET aLayerMask=LSET::AllLayersMask())
Function GetPad get a pad at aPosition on aLayerMask in the footprint.
int m_CntRot180
Definition: class_module.h:713
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:101
virtual wxString GetClass() const =0
Function GetClass returns the class name.
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:205
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.
BOARD holds information pertinent to a Pcbnew printed circuit board.
Definition: class_board.h:163
#define _(s)
Definition: 3d_actions.cpp:33
int m_ModuleStatus
Definition: class_module.h:695
SHAPE_LINE_CHAIN.
void Move(const wxPoint &aMoveVector) override
Function Move move this object.
void SetOrientation(double newangle)
Virtual component: when created by copper shapes on board (Like edge card connectors,...
Definition: class_module.h:76
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.
wxString GetClass() const override
Function GetClass returns the class name.
Definition: class_module.h:576
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 GetMsgPanelInfo(EDA_UNITS aUnits, std::vector< MSG_PANEL_ITEM > &aList) override
TEXTE_MODULE * m_Value
Definition: class_module.h:692
bool IsAperturePad() const
Definition: class_pad.h:456
EDA_ITEM is a base class for most all the KiCad significant classes, used in schematics and boards.
Definition: base_struct.h:166
MODULE_ZONE_CONTAINER is the same item as ZONE_CONTAINER, but with a specific type id ZONE_CONTAINER ...
Definition: class_zone.h:848
wxPoint m_Pos
Definition: class_module.h:690
int GetTrailingInt(const wxString &aStr)
Gets the trailing int, if any, from a string.
Definition: string.cpp:650
bool Intersects(const EDA_RECT &aRect) const
Function Intersects tests for a common area between rectangles.
class VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:97
TEXTE_MODULE * m_Reference
Definition: class_module.h:691
BOARD_ITEM * DuplicateItem(const BOARD_ITEM *aItem, bool aIncrementPadNumbers, bool aAddToModule=false)
Function DuplicateItem Duplicate a given item within the module, without adding to the board.
void BooleanSubtract(const SHAPE_POLY_SET &b, POLYGON_MODE aFastMode)
Performs boolean polyset difference For aFastMode meaning, see function booleanOp
Module description (excepted pads)
Definition: colors.h:45
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.
class ZONE_CONTAINER, managed by a footprint
Definition: typeinfo.h:95
EDA_MSG_ITEM is used EDA_MSG_PANEL as the item type for displaying messages.
Definition: msgpanel.h:53
VIEW.
Definition: view.h:61
void Print(PCB_BASE_FRAME *aFrame, wxDC *aDC, const wxPoint &aOffset=ZeroOffset) override
Function Print Prints the footprint to the aDC.
SEARCH_RESULT
Definition: base_struct.h:54
const wxPoint GetPosition() const override
Definition: class_pad.h:241
EDGE_MODULE class definition.
void ClearEditFlags()
Definition: base_struct.h:275
Message panel definition file.
wxString GetLayerName() const
Function GetLayerName returns the name of the PCB layer on which the item resides.
INCLUDE_NPTH_T
Definition: class_module.h:59
virtual PCB_LAYER_ID GetLayer() const
Function GetLayer returns the primary layer this item is on.
const wxPoint GetPosition() const override
Definition: class_module.h:210
Custom text control validator definitions.
PCB_BASE_FRAME basic PCB main window class for Pcbnew, Gerbview, and CvPcb footprint viewer.
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:711
KICAD_T Type() const
Function Type()
Definition: base_struct.h:212
int m_Attributs
Definition: class_module.h:694
bool IsLayerVisible(int aLayer) const
Function IsLayerVisible() Returns information about visibility of a particular layer.
Definition: view.h:416
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)
Definition: colors.h:62