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-2019 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 
32 #include <fctsys.h>
33 #include <gr_basic.h>
34 #include <plotter.h>
35 #include <class_drawpanel.h>
36 #include <trigo.h>
37 #include <confirm.h>
38 #include <kicad_string.h>
39 #include <pcbnew.h>
40 #include <refdes_utils.h>
41 #include <richio.h>
42 #include <filter_reader.h>
43 #include <macros.h>
44 #include <msgpanel.h>
45 #include <bitmaps.h>
46 #include <unordered_set>
47 
48 #include <pcb_edit_frame.h>
49 #include <class_board.h>
50 #include <class_edge_mod.h>
51 #include <class_module.h>
53 
54 #include <view/view.h>
55 
56 MODULE::MODULE( BOARD* parent ) :
58  m_initial_comments( 0 )
59 {
61  m_Layer = F_Cu;
62  m_Orient = 0;
64  m_arflag = 0;
65  m_CntRot90 = m_CntRot180 = 0;
66  m_Link = 0;
67  m_LastEditTime = 0;
68  m_LocalClearance = 0;
72  m_ZoneConnection = PAD_ZONE_CONN_INHERITED; // Use zone setting by default
73  m_ThermalWidth = 0; // Use zone setting by default
74  m_ThermalGap = 0; // Use zone setting by default
75 
76  // These are special and mandatory text fields
79 
80  m_3D_Drawings.clear();
81 }
82 
83 
84 MODULE::MODULE( const MODULE& aModule ) :
85  BOARD_ITEM_CONTAINER( aModule )
86 {
87  m_Pos = aModule.m_Pos;
88  m_fpid = aModule.m_fpid;
89  m_Attributs = aModule.m_Attributs;
91  m_Orient = aModule.m_Orient;
92  m_BoundaryBox = aModule.m_BoundaryBox;
93  m_CntRot90 = aModule.m_CntRot90;
94  m_CntRot180 = aModule.m_CntRot180;
96  m_Link = aModule.m_Link;
97  m_Path = aModule.m_Path; // is this correct behavior?
98 
104  m_ThermalWidth = aModule.m_ThermalWidth;
105  m_ThermalGap = aModule.m_ThermalGap;
106 
107  // Copy reference and value.
108  m_Reference = new TEXTE_MODULE( *aModule.m_Reference );
109  m_Reference->SetParent( this );
110  m_Value = new TEXTE_MODULE( *aModule.m_Value );
111  m_Value->SetParent( this );
112 
113  // Copy auxiliary data: Pads
114  for( D_PAD* pad = aModule.m_Pads; pad; pad = pad->Next() )
115  {
116  Add( new D_PAD( *pad ) );
117  }
118 
119  // Copy auxiliary data: Drawings
120  for( BOARD_ITEM* item = aModule.m_Drawings; item; item = item->Next() )
121  {
122  switch( item->Type() )
123  {
124  case PCB_MODULE_TEXT_T:
125  case PCB_MODULE_EDGE_T:
126  Add( static_cast<BOARD_ITEM*>( item->Clone() ) );
127  break;
128 
129  default:
130  wxLogMessage( wxT( "Class MODULE copy constructor internal error: unknown type" ) );
131  break;
132  }
133  }
134 
135  // Copy auxiliary data: 3D_Drawings info
136  m_3D_Drawings = aModule.m_3D_Drawings;
137 
138  m_Doc = aModule.m_Doc;
139  m_KeyWord = aModule.m_KeyWord;
140 
141  m_arflag = 0;
142 
143  // Ensure auxiliary data is up to date
145 
147  new wxArrayString( *aModule.m_initial_comments ) : 0;
148 }
149 
150 
152 {
153  delete m_Reference;
154  delete m_Value;
155  delete m_initial_comments;
156 }
157 
158 
159 MODULE& MODULE::operator=( const MODULE& aOther )
160 {
161  BOARD_ITEM::operator=( aOther );
162 
163  m_Pos = aOther.m_Pos;
164  m_fpid = aOther.m_fpid;
165  m_Attributs = aOther.m_Attributs;
167  m_Orient = aOther.m_Orient;
168  m_BoundaryBox = aOther.m_BoundaryBox;
169  m_CntRot90 = aOther.m_CntRot90;
170  m_CntRot180 = aOther.m_CntRot180;
172  m_Link = aOther.m_Link;
173  m_Path = aOther.m_Path; //is this correct behavior?
174 
181  m_ThermalGap = aOther.m_ThermalGap;
182 
183  // Copy reference and value
184  *m_Reference = *aOther.m_Reference;
185  m_Reference->SetParent( this );
186  *m_Value = *aOther.m_Value;
187  m_Value->SetParent( this );
188 
189  // Copy auxiliary data: Pads
190  m_Pads.DeleteAll();
191 
192  for( D_PAD* pad = aOther.m_Pads; pad; pad = pad->Next() )
193  {
194  Add( new D_PAD( *pad ) );
195  }
196 
197  // Copy auxiliary data: Drawings
199 
200  for( BOARD_ITEM* item = aOther.m_Drawings; item; item = item->Next() )
201  {
202  switch( item->Type() )
203  {
204  case PCB_MODULE_TEXT_T:
205  case PCB_MODULE_EDGE_T:
206  Add( static_cast<BOARD_ITEM*>( item->Clone() ) );
207  break;
208 
209  default:
210  wxLogMessage( wxT( "MODULE::operator=() internal error: unknown type" ) );
211  break;
212  }
213  }
214 
215  // Copy auxiliary data: 3D_Drawings info
216  m_3D_Drawings.clear();
217  m_3D_Drawings = aOther.m_3D_Drawings;
218  m_Doc = aOther.m_Doc;
219  m_KeyWord = aOther.m_KeyWord;
220 
221  // Ensure auxiliary data is up to date
223 
224  return *this;
225 }
226 
227 
229 {
230  // Force the ORPHANED dummy net info for all pads.
231  // ORPHANED dummy net does not depend on a board
232  for( D_PAD* pad = PadsList(); pad; pad = pad->Next() )
233  pad->SetNetCode( NETINFO_LIST::ORPHANED );
234 }
235 
236 
237 void MODULE::DrawAncre( EDA_DRAW_PANEL* panel, wxDC* DC, const wxPoint& offset,
238  int dim_ancre, GR_DRAWMODE draw_mode )
239 {
240  auto frame = (PCB_EDIT_FRAME*) panel->GetParent();
241 
242  GRSetDrawMode( DC, draw_mode );
243 
244  if( GetBoard()->IsElementVisible( LAYER_ANCHOR ) )
245  {
246  GRDrawAnchor( panel->GetClipBox(), DC, m_Pos.x, m_Pos.y,
247  dim_ancre,
248  frame->Settings().Colors().GetItemColor( LAYER_ANCHOR ) );
249  }
250 }
251 
252 
253 void MODULE::Add( BOARD_ITEM* aBoardItem, ADD_MODE aMode )
254 {
255  switch( aBoardItem->Type() )
256  {
257  case PCB_MODULE_TEXT_T:
258  // Only user texts can be added this way. Reference and value are not hold in the DLIST.
259  assert( static_cast<TEXTE_MODULE*>( aBoardItem )->GetType() == TEXTE_MODULE::TEXT_is_DIVERS );
260 
261  // no break
262 
263  case PCB_MODULE_EDGE_T:
264  if( aMode == ADD_APPEND )
265  m_Drawings.PushBack( aBoardItem );
266  else
267  m_Drawings.PushFront( aBoardItem );
268  break;
269 
270  case PCB_PAD_T:
271  if( aMode == ADD_APPEND )
272  m_Pads.PushBack( static_cast<D_PAD*>( aBoardItem ) );
273  else
274  m_Pads.PushFront( static_cast<D_PAD*>( aBoardItem ) );
275  break;
276 
277  default:
278  {
279  wxString msg;
280  msg.Printf( wxT( "MODULE::Add() needs work: BOARD_ITEM type (%d) not handled" ),
281  aBoardItem->Type() );
282  wxFAIL_MSG( msg );
283 
284  return;
285  }
286  }
287 
288  aBoardItem->SetParent( this );
289 }
290 
291 
292 void MODULE::Remove( BOARD_ITEM* aBoardItem )
293 {
294  switch( aBoardItem->Type() )
295  {
296  case PCB_MODULE_TEXT_T:
297  // Only user texts can be removed this way. Reference and value are not hold in the DLIST.
298  assert( static_cast<TEXTE_MODULE*>( aBoardItem )->GetType() == TEXTE_MODULE::TEXT_is_DIVERS );
299 
300  // no break
301 
302  case PCB_MODULE_EDGE_T:
303  m_Drawings.Remove( aBoardItem );
304  break;
305 
306  case PCB_PAD_T:
307  m_Pads.Remove( static_cast<D_PAD*>( aBoardItem ) );
308  break;
309 
310  default:
311  {
312  wxString msg;
313  msg.Printf( wxT( "MODULE::Remove() needs work: BOARD_ITEM type (%d) not handled" ),
314  aBoardItem->Type() );
315  wxFAIL_MSG( msg );
316  }
317  }
318 }
319 
320 
321 void MODULE::CopyNetlistSettings( MODULE* aModule, bool aCopyLocalSettings )
322 {
323  // Don't do anything foolish like trying to copy to yourself.
324  wxCHECK_RET( aModule != NULL && aModule != this, wxT( "Cannot copy to NULL or yourself." ) );
325 
326  // Not sure what to do with the value field. Use netlist for now.
327  aModule->SetPosition( GetPosition() );
328 
329  if( aModule->GetLayer() != GetLayer() )
330  aModule->Flip( aModule->GetPosition() );
331 
332  if( aModule->GetOrientation() != GetOrientation() )
333  aModule->Rotate( aModule->GetPosition(), GetOrientation() );
334 
335  aModule->SetLocked( IsLocked() );
336 
337  if( aCopyLocalSettings )
338  {
340  aModule->SetLocalClearance( GetLocalClearance() );
343  aModule->SetZoneConnection( GetZoneConnection() );
344  aModule->SetThermalWidth( GetThermalWidth() );
345  aModule->SetThermalGap( GetThermalGap() );
346  }
347 
348  for( D_PAD* pad = aModule->PadsList(); pad; pad = pad->Next() )
349  {
350  // Fix me: if aCopyLocalSettings == true, for "multiple" pads
351  // (set of pads having the same name/number) this is broken
352  // because we copy settings from the first pad found.
353  // When old and new footprints have very few differences, a better
354  // algo can be used.
355  D_PAD* oldPad = FindPadByName( pad->GetName() );
356 
357  if( oldPad )
358  oldPad->CopyNetlistSettings( pad, aCopyLocalSettings );
359  }
360 
361  // Not sure about copying description, keywords, 3D models or any other
362  // local user changes to footprint. Stick with the new footprint settings
363  // called out in the footprint loaded in the netlist.
364  aModule->CalculateBoundingBox();
365 }
366 
367 
368 void MODULE::Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, GR_DRAWMODE aDrawMode,
369  const wxPoint& aOffset )
370 {
371  if( (m_Flags & DO_NOT_DRAW) || (IsMoving()) )
372  return;
373 
374  for( D_PAD* pad = m_Pads; pad; pad = pad->Next() )
375  {
376  if( pad->IsMoving() )
377  continue;
378 
379  pad->Draw( aPanel, aDC, aDrawMode, aOffset );
380  }
381 
382  BOARD* brd = GetBoard();
383 
384  // Draws footprint anchor
385  DrawAncre( aPanel, aDC, aOffset, DIM_ANCRE_MODULE, aDrawMode );
386 
387  // Draw graphic items
389  {
390  if( !(m_Reference->IsMoving()) )
391  m_Reference->Draw( aPanel, aDC, aDrawMode, aOffset );
392  }
393 
394  if( brd->IsElementVisible( LAYER_MOD_VALUES ) )
395  {
396  if( !(m_Value->IsMoving()) )
397  m_Value->Draw( aPanel, aDC, aDrawMode, aOffset );
398  }
399 
400  for( BOARD_ITEM* item = m_Drawings; item; item = item->Next() )
401  {
402  if( item->IsMoving() )
403  continue;
404 
405  switch( item->Type() )
406  {
407  case PCB_MODULE_TEXT_T:
408  case PCB_MODULE_EDGE_T:
409  item->Draw( aPanel, aDC, aDrawMode, aOffset );
410  break;
411 
412  default:
413  break;
414  }
415  }
416 
417  // Enable these line to draw m_BoundaryBox (debug tests purposes only)
418 #if 0
419  GRRect( aPanel->GetClipBox(), aDC, m_BoundaryBox, 0, BROWN );
420 #endif
421 
422 }
423 
424 
425 void MODULE::DrawEdgesOnly( EDA_DRAW_PANEL* panel, wxDC* DC, const wxPoint& offset,
426  GR_DRAWMODE draw_mode )
427 {
428  for( BOARD_ITEM* item = m_Drawings; item; item = item->Next() )
429  {
430  switch( item->Type() )
431  {
432  case PCB_MODULE_EDGE_T:
433  item->Draw( panel, DC, draw_mode, offset );
434  break;
435 
436  default:
437  break;
438  }
439  }
440 }
441 
442 
444 {
446 }
447 
448 
449 double MODULE::GetArea( int aPadding ) const
450 {
451  double w = std::abs( m_BoundaryBox.GetWidth() ) + aPadding;
452  double h = std::abs( m_BoundaryBox.GetHeight() ) + aPadding;
453  return w * h;
454 }
455 
456 
458 {
459  EDA_RECT area;
460 
461  area.SetOrigin( m_Pos );
462  area.SetEnd( m_Pos );
463  area.Inflate( Millimeter2iu( 0.25 ) ); // Give a min size to the area
464 
465  for( const BOARD_ITEM* item = m_Drawings.GetFirst(); item; item = item->Next() )
466  {
467  if( item->Type() == PCB_MODULE_EDGE_T )
468  area.Merge( item->GetBoundingBox() );
469  }
470 
471  for( D_PAD* pad = m_Pads; pad; pad = pad->Next() )
472  area.Merge( pad->GetBoundingBox() );
473 
474  return area;
475 }
476 
477 
479 {
480  EDA_RECT area = GetFootprintRect();
481 
482  // Add in items not collected by GetFootprintRect():
483  for( const BOARD_ITEM* item = m_Drawings.GetFirst(); item; item = item->Next() )
484  {
485  if( item->Type() != PCB_MODULE_EDGE_T )
486  area.Merge( item->GetBoundingBox() );
487  }
488 
489  area.Merge( m_Value->GetBoundingBox() );
490  area.Merge( m_Reference->GetBoundingBox() );
491 
492  return area;
493 }
494 
495 
511 {
512  SHAPE_POLY_SET poly;
513 
514  double orientation = GetOrientationRadians();
515 
516  MODULE temp = *this;
517  temp.SetOrientation( 0.0 );
518  BOX2I area = temp.GetFootprintRect();
519 
520  poly.NewOutline();
521 
522  VECTOR2I p = area.GetPosition();
523  poly.Append( p );
524  p.x = area.GetRight();
525  poly.Append( p );
526  p.y = area.GetBottom();
527  poly.Append( p );
528  p.x = area.GetX();
529  poly.Append( p );
530 
531  BOARD* board = GetBoard();
532  if( board )
533  {
534  int biggest_clearance = board->GetDesignSettings().GetBiggestClearanceValue();
535  poly.Inflate( biggest_clearance, 4 );
536  }
537 
538  poly.Inflate( Millimeter2iu( 0.01 ), 4 );
539  poly.Rotate( -orientation, m_Pos );
540 
541  return poly;
542 }
543 
544 
545 void MODULE::GetMsgPanelInfo( EDA_UNITS_T aUnits, std::vector< MSG_PANEL_ITEM >& aList )
546 {
547  int nbpad;
548  wxString msg;
549 
550  aList.push_back( MSG_PANEL_ITEM( m_Reference->GetShownText(), m_Value->GetShownText(), DARKCYAN ) );
551 
552  // Display last date the component was edited (useful in Module Editor).
553  wxDateTime date( static_cast<time_t>( m_LastEditTime ) );
554 
555  if( m_LastEditTime && date.IsValid() )
556  // Date format: see http://www.cplusplus.com/reference/ctime/strftime
557  msg = date.Format( wxT( "%b %d, %Y" ) ); // Abbreviated_month_name Day, Year
558  else
559  msg = _( "Unknown" );
560 
561  aList.push_back( MSG_PANEL_ITEM( _( "Last Change" ), msg, BROWN ) );
562 
563  // display schematic path
564  aList.push_back( MSG_PANEL_ITEM( _( "Netlist Path" ), m_Path, BROWN ) );
565 
566  // display the board side placement
567  aList.push_back( MSG_PANEL_ITEM( _( "Board Side" ),
568  IsFlipped()? _( "Back (Flipped)" ) : _( "Front" ), RED ) );
569 
570  EDA_ITEM* PtStruct = m_Pads;
571  nbpad = 0;
572 
573  while( PtStruct )
574  {
575  nbpad++;
576  PtStruct = PtStruct->Next();
577  }
578 
579  msg.Printf( wxT( "%d" ), nbpad );
580  aList.push_back( MSG_PANEL_ITEM( _( "Pads" ), msg, BLUE ) );
581 
582  msg = wxT( ".." );
583 
584  if( IsLocked() )
585  msg[0] = 'L';
586 
588  msg[1] = 'P';
589 
590  aList.push_back( MSG_PANEL_ITEM( _( "Status" ), msg, MAGENTA ) );
591 
592  msg.Printf( wxT( "%.1f" ), GetOrientationDegrees() );
593  aList.push_back( MSG_PANEL_ITEM( _( "Rotation" ), msg, BROWN ) );
594 
595  // Controls on right side of the dialog
596  switch( m_Attributs & 255 )
597  {
598  case 0:
599  msg = _( "Normal" );
600  break;
601 
602  case MOD_CMS:
603  msg = _( "Insert" );
604  break;
605 
606  case MOD_VIRTUAL:
607  msg = _( "Virtual" );
608  break;
609 
610  default:
611  msg = wxT( "???" );
612  break;
613  }
614 
615  aList.push_back( MSG_PANEL_ITEM( _( "Attributes" ), msg, BROWN ) );
616  aList.push_back( MSG_PANEL_ITEM( _( "Footprint" ), FROM_UTF8( m_fpid.Format().c_str() ), BLUE ) );
617 
618  if( m_3D_Drawings.empty() )
619  msg = _( "No 3D shape" );
620  else
621  msg = m_3D_Drawings.front().m_Filename;
622 
623  // Search the first active 3D shape in list
624 
625  aList.push_back( MSG_PANEL_ITEM( _( "3D-Shape" ), msg, RED ) );
626 
627  wxString doc, keyword;
628  doc.Printf( _( "Doc: %s" ), GetChars( m_Doc ) );
629  keyword.Printf( _( "Key Words: %s" ), GetChars( m_KeyWord ) );
630  aList.push_back( MSG_PANEL_ITEM( doc, keyword, BLACK ) );
631 }
632 
633 
634 bool MODULE::HitTest( const wxPoint& aPosition, int aAccuracy ) const
635 {
636  EDA_RECT rect = m_BoundaryBox;
637  return rect.Inflate( aAccuracy ).Contains( aPosition );
638 }
639 
640 
641 bool MODULE::HitTestAccurate( const wxPoint& aPosition, int aAccuracy ) const
642 {
644 
645  shape.Inflate( aAccuracy, 4 );
646  return shape.Contains( aPosition, -1, true );
647 }
648 
649 
650 bool MODULE::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const
651 {
652  EDA_RECT arect = aRect;
653  arect.Inflate( aAccuracy );
654 
655  if( aContained )
656  return arect.Contains( m_BoundaryBox );
657  else
658  {
659  // If the rect does not intersect the bounding box, skip any tests
660  if( !aRect.Intersects( GetBoundingBox() ) )
661  return false;
662 
663  // Determine if any elements in the MODULE intersect the rect
664  for( D_PAD* pad = m_Pads; pad; pad = pad->Next() )
665  {
666  if( pad->HitTest( arect, false, 0 ) )
667  return true;
668  }
669 
670  for( BOARD_ITEM* item = m_Drawings; item; item = item->Next() )
671  {
672  if( item->HitTest( arect, false, 0 ) )
673  return true;
674  }
675 
676  // No items were hit
677  return false;
678  }
679 }
680 
681 
682 D_PAD* MODULE::FindPadByName( const wxString& aPadName ) const
683 {
684  for( D_PAD* pad = m_Pads; pad; pad = pad->Next() )
685  {
686  if( pad->GetName().CmpNoCase( aPadName ) == 0 ) // why case insensitive?
687  return pad;
688  }
689 
690  return NULL;
691 }
692 
693 
694 D_PAD* MODULE::GetPad( const wxPoint& aPosition, LSET aLayerMask )
695 {
696  for( D_PAD* pad = m_Pads; pad; pad = pad->Next() )
697  {
698  // ... and on the correct layer.
699  if( !( pad->GetLayerSet() & aLayerMask ).any() )
700  continue;
701 
702  if( pad->HitTest( aPosition ) )
703  return pad;
704  }
705 
706  return NULL;
707 }
708 
709 
711 {
712  D_PAD* topLeftPad = m_Pads;
713 
714  for( D_PAD* p = m_Pads->Next(); p; p = p->Next() )
715  {
716  wxPoint pnt = p->GetPosition(); // GetPosition() returns the center of the pad
717 
718  if( ( pnt.x < topLeftPad->GetPosition().x ) ||
719  ( ( topLeftPad->GetPosition().x == pnt.x ) &&
720  ( pnt.y < topLeftPad->GetPosition().y ) ) )
721  {
722  topLeftPad = p;
723  }
724  }
725 
726  return topLeftPad;
727 }
728 
729 
730 unsigned MODULE::GetPadCount( INCLUDE_NPTH_T aIncludeNPTH ) const
731 {
732  if( aIncludeNPTH )
733  return m_Pads.GetCount();
734 
735  unsigned cnt = 0;
736 
737  for( D_PAD* pad = m_Pads; pad; pad = pad->Next() )
738  {
739  if( pad->GetAttribute() == PAD_ATTRIB_HOLE_NOT_PLATED )
740  continue;
741 
742  cnt++;
743  }
744 
745  return cnt;
746 }
747 
748 
749 unsigned MODULE::GetUniquePadCount( INCLUDE_NPTH_T aIncludeNPTH ) const
750 {
751  std::set<wxString> usedNames;
752 
753  // Create a set of used pad numbers
754  for( D_PAD* pad = PadsList(); pad; pad = pad->Next() )
755  {
756  // Skip pads not on copper layers (used to build complex
757  // solder paste shapes for instance)
758  if( ( pad->GetLayerSet() & LSET::AllCuMask() ).none() )
759  continue;
760 
761  // Skip pads with no name, because they are usually "mechanical"
762  // pads, not "electrical" pads
763  if( pad->GetName().IsEmpty() )
764  continue;
765 
766  if( !aIncludeNPTH )
767  {
768  // skip NPTH
769  if( pad->GetAttribute() == PAD_ATTRIB_HOLE_NOT_PLATED )
770  {
771  continue;
772  }
773  }
774 
775  usedNames.insert( pad->GetName() );
776  }
777 
778  return usedNames.size();
779 }
780 
781 
783 {
784  if( NULL == a3DModel )
785  return;
786 
787  if( !a3DModel->m_Filename.empty() )
788  m_3D_Drawings.push_back( *a3DModel );
789 
790  delete a3DModel;
791 }
792 
793 
794 // see class_module.h
795 SEARCH_RESULT MODULE::Visit( INSPECTOR inspector, void* testData, const KICAD_T scanTypes[] )
796 {
797  KICAD_T stype;
799  const KICAD_T* p = scanTypes;
800  bool done = false;
801 
802 #if 0 && defined(DEBUG)
803  std::cout << GetClass().mb_str() << ' ';
804 #endif
805 
806  while( !done )
807  {
808  stype = *p;
809 
810  switch( stype )
811  {
812  case PCB_MODULE_T:
813  result = inspector( this, testData ); // inspect me
814  ++p;
815  break;
816 
817  case PCB_PAD_T:
818  result = IterateForward( m_Pads, inspector, testData, p );
819  ++p;
820  break;
821 
822  case PCB_MODULE_TEXT_T:
823  result = inspector( m_Reference, testData );
824 
825  if( result == SEARCH_QUIT )
826  break;
827 
828  result = inspector( m_Value, testData );
829 
830  if( result == SEARCH_QUIT )
831  break;
832 
833  // m_Drawings can hold TYPETEXTMODULE also, so fall thru
834 
835  case PCB_MODULE_EDGE_T:
836  result = IterateForward( m_Drawings, inspector, testData, p );
837 
838  // skip over any types handled in the above call.
839  for( ; ; )
840  {
841  switch( stype = *++p )
842  {
843  case PCB_MODULE_TEXT_T:
844  case PCB_MODULE_EDGE_T:
845  continue;
846 
847  default:
848  ;
849  }
850 
851  break;
852  }
853 
854  break;
855 
856  default:
857  done = true;
858  break;
859  }
860 
861  if( result == SEARCH_QUIT )
862  break;
863  }
864 
865  return result;
866 }
867 
868 
869 wxString MODULE::GetSelectMenuText( EDA_UNITS_T aUnits ) const
870 {
871  wxString reference = GetReference();
872 
873  if( reference.IsEmpty() )
874  reference = _( "<no reference>" );
875 
876  return wxString::Format( _( "Footprint %s on %s" ), reference, GetLayerName() );
877 }
878 
879 
880 BITMAP_DEF MODULE::GetMenuImage() const
881 {
882  return module_xpm;
883 }
884 
885 
887 {
888  return new MODULE( *this );
889 }
890 
891 
892 void MODULE::RunOnChildren( const std::function<void (BOARD_ITEM*)>& aFunction )
893 {
894  try
895  {
896  for( D_PAD* pad = m_Pads; pad; pad = pad->Next() )
897  aFunction( static_cast<BOARD_ITEM*>( pad ) );
898 
899  for( BOARD_ITEM* drawing = m_Drawings; drawing; drawing = drawing->Next() )
900  aFunction( drawing );
901 
902  aFunction( static_cast<BOARD_ITEM*>( m_Reference ) );
903  aFunction( static_cast<BOARD_ITEM*>( m_Value ) );
904  }
905  catch( std::bad_function_call& )
906  {
907  DisplayError( NULL, wxT( "Error running MODULE::RunOnChildren" ) );
908  }
909 }
910 
911 
912 void MODULE::GetAllDrawingLayers( int aLayers[], int& aCount, bool aIncludePads ) const
913 {
914  std::unordered_set<int> layers;
915 
916  for( BOARD_ITEM* item = m_Drawings; item; item = item->Next() )
917  {
918  layers.insert( static_cast<int>( item->GetLayer() ) );
919  }
920 
921  if( aIncludePads )
922  {
923  for( D_PAD* pad = m_Pads; pad; pad = pad->Next() )
924  {
925  int pad_layers[KIGFX::VIEW::VIEW_MAX_LAYERS], pad_layers_count;
926  pad->ViewGetLayers( pad_layers, pad_layers_count );
927 
928  for( int i = 0; i < pad_layers_count; i++ )
929  layers.insert( pad_layers[i] );
930  }
931  }
932 
933  aCount = layers.size();
934  int i = 0;
935 
936  for( auto layer : layers )
937  aLayers[i++] = layer;
938 }
939 
940 
941 void MODULE::ViewGetLayers( int aLayers[], int& aCount ) const
942 {
943  aCount = 2;
944  aLayers[0] = LAYER_ANCHOR;
945 
946  switch( m_Layer )
947  {
948 
949  default:
950  wxASSERT_MSG( false, "Illegal layer" ); // do you really have modules placed on other layers?
951  // pass through
952  case F_Cu:
953  aLayers[1] = LAYER_MOD_FR;
954  break;
955 
956  case B_Cu:
957  aLayers[1] = LAYER_MOD_BK;
958  break;
959  }
960 
961  // If there are no pads, and only drawings on a silkscreen layer, then
962  // report the silkscreen layer as well so that the component can be edited
963  // with the silkscreen layer
964  bool f_silk = false, b_silk = false, non_silk = false;
965 
966  for( BOARD_ITEM* item = m_Drawings; item; item = item->Next() )
967  {
968  if( item->GetLayer() == F_SilkS )
969  f_silk = true;
970  else if( item->GetLayer() == B_SilkS )
971  b_silk = true;
972  else
973  non_silk = true;
974  }
975 
976  if( ( f_silk || b_silk ) && !non_silk && m_Pads.GetCount() == 0 )
977  {
978  if( f_silk )
979  aLayers[ aCount++ ] = F_SilkS;
980 
981  if( b_silk )
982  aLayers[ aCount++ ] = B_SilkS;
983  }
984 }
985 
986 
987 unsigned int MODULE::ViewGetLOD( int aLayer, KIGFX::VIEW* aView ) const
988 {
989  int layer = ( m_Layer == F_Cu ) ? LAYER_MOD_FR :
991 
992  // Currently it is only for anchor layer
993  if( aView->IsLayerVisible( layer ) )
994  return 3;
995 
997 }
998 
999 
1001 {
1002  EDA_RECT area = GetFootprintRect();
1003 
1004  // Calculate extended area including text fields
1005  area.Merge( m_Reference->GetBoundingBox() );
1006  area.Merge( m_Value->GetBoundingBox() );
1007 
1008  // Add the Clearance shape size: (shape around the pads when the
1009  // clearance is shown. Not optimized, but the draw cost is small
1010  // (perhaps smaller than optimization).
1011  BOARD* board = GetBoard();
1012  if( board )
1013  {
1014  int biggest_clearance = board->GetDesignSettings().GetBiggestClearanceValue();
1015  area.Inflate( biggest_clearance );
1016  }
1017 
1018  return area;
1019 }
1020 
1021 
1022 bool MODULE::IsLibNameValid( const wxString & aName )
1023 {
1024  const wxChar * invalids = StringLibNameInvalidChars( false );
1025 
1026  if( aName.find_first_of( invalids ) != std::string::npos )
1027  return false;
1028 
1029  return true;
1030 }
1031 
1032 
1033 const wxChar* MODULE::StringLibNameInvalidChars( bool aUserReadable )
1034 {
1035  static const wxChar invalidChars[] = wxT("%$\t\n\r \"\\/:");
1036  static const wxChar invalidCharsReadable[] = wxT("% $ 'tab' 'return' 'line feed' 'space' \\ \" / :");
1037 
1038  if( aUserReadable )
1039  return invalidCharsReadable;
1040  else
1041  return invalidChars;
1042 }
1043 
1044 
1045 void MODULE::Move( const wxPoint& aMoveVector )
1046 {
1047  wxPoint newpos = m_Pos + aMoveVector;
1048  SetPosition( newpos );
1049 }
1050 
1051 
1052 void MODULE::Rotate( const wxPoint& aRotCentre, double aAngle )
1053 {
1054  double orientation = GetOrientation();
1055  double newOrientation = orientation + aAngle;
1056  wxPoint newpos = m_Pos;
1057  RotatePoint( &newpos, aRotCentre, aAngle );
1058  SetPosition( newpos );
1059  SetOrientation( newOrientation );
1060 
1061  m_Reference->KeepUpright( orientation, newOrientation );
1062  m_Value->KeepUpright( orientation, newOrientation );
1063 
1064  for( EDA_ITEM* item = m_Drawings; item; item = item->Next() )
1065  {
1066  if( item->Type() == PCB_MODULE_TEXT_T )
1067  static_cast<TEXTE_MODULE*>( item )->KeepUpright( orientation, newOrientation );
1068  }
1069 }
1070 
1071 
1072 void MODULE::Flip( const wxPoint& aCentre )
1073 {
1074  // Move module to its final position:
1075  wxPoint finalPos = m_Pos;
1076  MIRROR( finalPos.y, aCentre.y );
1077  SetPosition( finalPos );
1078 
1079  // Flip layer
1080  SetLayer( FlipLayer( GetLayer() ) );
1081 
1082  // Reverse mirror orientation.
1083  m_Orient = -m_Orient;
1085 
1086  // Mirror pads to other side of board about the x axis, i.e. vertically.
1087  for( D_PAD* pad = m_Pads; pad; pad = pad->Next() )
1088  pad->Flip( m_Pos );
1089 
1090  // Mirror reference and value.
1091  m_Reference->Flip( m_Pos );
1092  m_Value->Flip( m_Pos );
1093 
1094  // Reverse mirror module graphics and texts.
1095  for( EDA_ITEM* item = m_Drawings; item; item = item->Next() )
1096  {
1097  switch( item->Type() )
1098  {
1099  case PCB_MODULE_EDGE_T:
1100  ( (EDGE_MODULE*) item )->Flip( m_Pos );
1101  break;
1102 
1103  case PCB_MODULE_TEXT_T:
1104  static_cast<TEXTE_MODULE*>( item )->Flip( m_Pos );
1105  break;
1106 
1107  default:
1108  wxMessageBox( wxT( "MODULE::Flip() error: Unknown Draw Type" ) );
1109  break;
1110  }
1111  }
1112 
1114 }
1115 
1116 
1117 void MODULE::SetPosition( const wxPoint& newpos )
1118 {
1119  wxPoint delta = newpos - m_Pos;
1120 
1121  m_Pos += delta;
1122 
1123  m_Reference->EDA_TEXT::Offset( delta );
1124  m_Value->EDA_TEXT::Offset( delta );
1125 
1126  for( D_PAD* pad = m_Pads; pad; pad = pad->Next() )
1127  {
1128  pad->SetPosition( pad->GetPosition() + delta );
1129  }
1130 
1131  for( EDA_ITEM* item = m_Drawings; item; item = item->Next() )
1132  {
1133  switch( item->Type() )
1134  {
1135  case PCB_MODULE_EDGE_T:
1136  {
1137  EDGE_MODULE* pt_edgmod = (EDGE_MODULE*) item;
1138  pt_edgmod->SetDrawCoord();
1139  break;
1140  }
1141 
1142  case PCB_MODULE_TEXT_T:
1143  {
1144  TEXTE_MODULE* text = static_cast<TEXTE_MODULE*>( item );
1145  text->EDA_TEXT::Offset( delta );
1146  break;
1147  }
1148 
1149  default:
1150  wxMessageBox( wxT( "Draw type undefined." ) );
1151  break;
1152  }
1153  }
1154 
1156 }
1157 
1158 
1159 void MODULE::MoveAnchorPosition( const wxPoint& aMoveVector )
1160 {
1161  /* Move the reference point of the footprint
1162  * the footprints elements (pads, outlines, edges .. ) are moved
1163  * but:
1164  * - the footprint position is not modified.
1165  * - the relative (local) coordinates of these items are modified
1166  * - Draw coordinates are updated
1167  */
1168 
1169 
1170  // Update (move) the relative coordinates relative to the new anchor point.
1171  wxPoint moveVector = aMoveVector;
1172  RotatePoint( &moveVector, -GetOrientation() );
1173 
1174  // Update of the reference and value.
1175  m_Reference->SetPos0( m_Reference->GetPos0() + moveVector );
1177  m_Value->SetPos0( m_Value->GetPos0() + moveVector );
1178  m_Value->SetDrawCoord();
1179 
1180  // Update the pad local coordinates.
1181  for( D_PAD* pad = PadsList(); pad; pad = pad->Next() )
1182  {
1183  pad->SetPos0( pad->GetPos0() + moveVector );
1184  pad->SetDrawCoord();
1185  }
1186 
1187  // Update the draw element coordinates.
1188  for( EDA_ITEM* item = GraphicalItemsList(); item; item = item->Next() )
1189  {
1190  switch( item->Type() )
1191  {
1192  case PCB_MODULE_EDGE_T:
1193  {
1194  EDGE_MODULE* edge = static_cast<EDGE_MODULE*>( item );
1195  edge->Move( moveVector );
1196  }
1197  break;
1198 
1199  case PCB_MODULE_TEXT_T:
1200  {
1201  TEXTE_MODULE* text = static_cast<TEXTE_MODULE*>( item );
1202  text->SetPos0( text->GetPos0() + moveVector );
1203  text->SetDrawCoord();
1204  }
1205  break;
1206 
1207  default:
1208  break;
1209  }
1210  }
1211 
1213 }
1214 
1215 
1216 void MODULE::SetOrientation( double newangle )
1217 {
1218  double angleChange = newangle - m_Orient; // change in rotation
1219 
1220  NORMALIZE_ANGLE_POS( newangle );
1221 
1222  m_Orient = newangle;
1223 
1224  for( D_PAD* pad = m_Pads; pad; pad = pad->Next() )
1225  {
1226  pad->SetOrientation( pad->GetOrientation() + angleChange );
1227  pad->SetDrawCoord();
1228  }
1229 
1230  // Update of the reference and value.
1232  m_Value->SetDrawCoord();
1233 
1234  // Displace contours and text of the footprint.
1235  for( BOARD_ITEM* item = m_Drawings; item; item = item->Next() )
1236  {
1237  if( item->Type() == PCB_MODULE_EDGE_T )
1238  {
1239  static_cast<EDGE_MODULE*>( item )->SetDrawCoord();
1240  }
1241  else if( item->Type() == PCB_MODULE_TEXT_T )
1242  {
1243  static_cast<TEXTE_MODULE*>( item )->SetDrawCoord();
1244  }
1245  }
1246 
1248 }
1249 
1251  bool aIncrementPadNumbers,
1252  bool aAddToModule )
1253 {
1254  BOARD_ITEM* new_item = NULL;
1255  D_PAD* new_pad = NULL;
1256 
1257  switch( aItem->Type() )
1258  {
1259  case PCB_PAD_T:
1260  {
1261  new_pad = new D_PAD( *static_cast<const D_PAD*>( aItem ) );
1262 
1263  if( aAddToModule )
1264  PadsList().PushBack( new_pad );
1265 
1266  new_item = new_pad;
1267  break;
1268  }
1269 
1270  case PCB_MODULE_TEXT_T:
1271  {
1272  const TEXTE_MODULE* old_text = static_cast<const TEXTE_MODULE*>( aItem );
1273 
1274  // do not duplicate value or reference fields
1275  // (there can only be one of each)
1276  if( old_text->GetType() == TEXTE_MODULE::TEXT_is_DIVERS )
1277  {
1278  TEXTE_MODULE* new_text = new TEXTE_MODULE( *old_text );
1279 
1280  if( aAddToModule )
1281  GraphicalItemsList().PushBack( new_text );
1282 
1283  new_item = new_text;
1284  }
1285  break;
1286  }
1287 
1288  case PCB_MODULE_EDGE_T:
1289  {
1290  EDGE_MODULE* new_edge = new EDGE_MODULE(
1291  *static_cast<const EDGE_MODULE*>(aItem) );
1292 
1293  if( aAddToModule )
1294  GraphicalItemsList().PushBack( new_edge );
1295 
1296  new_item = new_edge;
1297  break;
1298  }
1299 
1300  case PCB_MODULE_T:
1301  // Ignore the module itself
1302  break;
1303 
1304  default:
1305  // Un-handled item for duplication
1306  wxASSERT_MSG( false, "Duplication not supported for items of class "
1307  + aItem->GetClass() );
1308  break;
1309  }
1310 
1311  if( aIncrementPadNumbers && new_pad && !new_pad->IsAperturePad() )
1312  {
1313  new_pad->IncrementPadName( true, true );
1314  }
1315 
1316  return new_item;
1317 }
1318 
1319 
1320 wxString MODULE::GetNextPadName( bool aFillSequenceGaps ) const
1321 {
1322  std::set<int> usedNumbers;
1323 
1324  // Create a set of used pad numbers
1325  for( D_PAD* pad = PadsList(); pad; pad = pad->Next() )
1326  {
1327  int padNumber = GetTrailingInt( pad->GetName() );
1328  usedNumbers.insert( padNumber );
1329  }
1330 
1331  const int nextNum = getNextNumberInSequence( usedNumbers, aFillSequenceGaps );
1332 
1333  return wxString::Format( wxT( "%i" ), nextNum );
1334 }
1335 
1336 
1337 void MODULE::IncrementReference( int aDelta )
1338 {
1339  const auto& refdes = GetReference();
1340  SetReference( wxString::Format( wxT( "%s%i" ), UTIL::GetReferencePrefix( refdes ),
1341  GetTrailingInt( refdes ) + aDelta ) );
1342 }
1343 
1344 
1345 // Calculate the area of aPolySet, after fracturation, because
1346 // polygons with no hole are expected.
1347 static double polygonArea( SHAPE_POLY_SET& aPolySet )
1348 {
1349  double area = 0.0;
1350  for( int ii = 0; ii < aPolySet.OutlineCount(); ii++ )
1351  {
1352  SHAPE_LINE_CHAIN& outline = aPolySet.Outline( ii );
1353  // Ensure the curr outline is closed, to calculate area
1354  outline.SetClosed( true );
1355 
1356  area += outline.Area();
1357  }
1358 
1359  return area;
1360 }
1361 
1362 // a helper function to add a rectangular polygon aRect to aPolySet
1363 static void addRect( SHAPE_POLY_SET& aPolySet, wxRect aRect )
1364 {
1365  aPolySet.NewOutline();
1366 
1367  aPolySet.Append( aRect.GetX(), aRect.GetY() );
1368  aPolySet.Append( aRect.GetX()+aRect.width, aRect.GetY() );
1369  aPolySet.Append( aRect.GetX()+aRect.width, aRect.GetY()+aRect.height );
1370  aPolySet.Append( aRect.GetX(), aRect.GetY()+aRect.height );
1371 }
1372 
1373 double MODULE::CoverageRatio( const GENERAL_COLLECTOR& aCollector ) const
1374 {
1375  double moduleArea = GetFootprintRect().GetArea();
1376  SHAPE_POLY_SET coveredRegion;
1377  addRect( coveredRegion, GetFootprintRect() );
1378 
1379  // build list of holes (covered areas not available for selection)
1380  SHAPE_POLY_SET holes;
1381 
1382  for( D_PAD* pad = m_Pads; pad; pad = pad->Next() )
1383  addRect( holes, pad->GetBoundingBox() );
1384 
1385  addRect( holes, m_Reference->GetBoundingBox() );
1386  addRect( holes, m_Value->GetBoundingBox() );
1387 
1388  for( int i = 0; i < aCollector.GetCount(); ++i )
1389  {
1390  BOARD_ITEM* item = aCollector[i];
1391 
1392  switch( item->Type() )
1393  {
1394  case PCB_TEXT_T:
1395  case PCB_MODULE_TEXT_T:
1396  case PCB_TRACE_T:
1397  case PCB_VIA_T:
1398  addRect( holes, item->GetBoundingBox() );
1399  break;
1400  default:
1401  break;
1402  }
1403  }
1404 
1405  SHAPE_POLY_SET uncoveredRegion;
1406  uncoveredRegion.BooleanSubtract( coveredRegion, holes, SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
1407  uncoveredRegion.Simplify( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
1408  uncoveredRegion.Fracture( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
1409 
1410  double uncoveredRegionArea = polygonArea( uncoveredRegion );
1411  double coveredArea = moduleArea - uncoveredRegionArea;
1412  double ratio = ( coveredArea / moduleArea );
1413 
1414  return std::min( ratio, 1.0 );
1415 }
1416 
1417 
1418 // see convert_drawsegment_list_to_polygon.cpp:
1419 extern bool ConvertOutlineToPolygon( std::vector<DRAWSEGMENT*>& aSegList, SHAPE_POLY_SET& aPolygons,
1420  wxString* aErrorText, unsigned int aTolerance, wxPoint* aErrorLocation = nullptr );
1421 
1423 {
1426  // Build the courtyard area from graphic items on the courtyard.
1427  // Only PCB_MODULE_EDGE_T have meaning, graphic texts are ignored.
1428  // Collect items:
1429  std::vector< DRAWSEGMENT* > list_front;
1430  std::vector< DRAWSEGMENT* > list_back;
1431 
1432  for( BOARD_ITEM* item = GraphicalItemsList(); item; item = item->Next() )
1433  {
1434  if( item->GetLayer() == B_CrtYd && item->Type() == PCB_MODULE_EDGE_T )
1435  list_back.push_back( static_cast< DRAWSEGMENT* > ( item ) );
1436 
1437  if( item->GetLayer() == F_CrtYd && item->Type() == PCB_MODULE_EDGE_T )
1438  list_front.push_back( static_cast< DRAWSEGMENT* > ( item ) );
1439  }
1440 
1441  // Note: if no item found on courtyard layers, return true.
1442  // false is returned only when the shape defined on courtyard layers
1443  // is not convertible to a polygon
1444  if( !list_front.size() && !list_back.size() )
1445  return true;
1446 
1447  wxString error_msg;
1448 
1449  bool success = ConvertOutlineToPolygon( list_front, m_poly_courtyard_front,
1450  &error_msg, (unsigned) Millimeter2iu( 0.05 ) );
1451 
1452  if( success )
1453  {
1454  success = ConvertOutlineToPolygon( list_back, m_poly_courtyard_back,
1455  &error_msg, (unsigned) Millimeter2iu( 0.05 ) );
1456  }
1457 
1458  if( !error_msg.IsEmpty() )
1459  {
1460  wxLogMessage( wxString::Format( _( "Processing courtyard of \"%s\": %s" ),
1461  GetChars( GetFPID().Format() ),
1462  error_msg) );
1463  }
1464 
1465  return success;
1466 }
1467 
1469 {
1470  assert( aImage->Type() == PCB_MODULE_T );
1471 
1472  std::swap( *((MODULE*) this), *((MODULE*) aImage) );
1473 }
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
The LIB_ID of the MODULE.
Definition: class_module.h:728
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:676
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:577
wxString GetSelectMenuText(EDA_UNITS_T aUnits) const override
Function GetSelectMenuText returns the text to display to be used in the selection clarification cont...
bool Contains(const VECTOR2I &aP, int aSubpolyIndex=-1, bool aIgnoreHoles=false) const
Returns true if a given subpolygon contains the point aP.
double GetOrientation() const
Definition: class_module.h:188
static SEARCH_RESULT IterateForward(EDA_ITEM *listStart, INSPECTOR inspector, void *testData, const KICAD_T scanTypes[])
Function IterateForward walks through the object tree calling the inspector() on each object type req...
double GetArea(int aPadding=0) const
void SetThermalGap(int aGap)
Definition: class_module.h:222
int m_CntRot90
Horizontal automatic placement cost ( 0..10 ).
Definition: class_module.h:743
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:761
T * Remove(T *aElement)
Function Remove removes aElement from the list, but does not delete it.
Definition: dlist.h:211
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:61
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 GRSetDrawMode(wxDC *DC, GR_DRAWMODE draw_mode)
Definition: gr_basic.cpp:223
void SetLocalClearance(int aClearance)
Definition: class_module.h:208
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.
void PushFront(T *aNewElement)
Function PushFront puts aNewElement at front of list sequence.
Definition: dlist.h:240
bool IsFlipped() const
function IsFlipped
Definition: class_module.h:258
wxString m_KeyWord
Search keywords to find module in library.
Definition: class_module.h:737
wxString m_Path
Definition: class_module.h:738
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:188
Class 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:734
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.
void Draw(EDA_DRAW_PANEL *aPanel, wxDC *aDC, GR_DRAWMODE aDrawMode, const wxPoint &aOffset=ZeroOffset) override
Function Draw draws the footprint to the aDC.
double m_LocalSolderPasteMarginRatio
Solder mask margin ratio value of pad size.
Definition: class_module.h:752
void Flip(const wxPoint &aCentre) override
Function Flip Flip this object, i.e.
Class BOARD to handle a board.
Definition: colors.h:61
bool IsMoving() const
Definition: base_struct.h:224
PCB_LAYER_ID FlipLayer(PCB_LAYER_ID aLayerId, int aCopperLayersCount)
Function FlippedLayerNumber.
Definition: lset.cpp:475
BOARD_ITEM * Duplicate(const BOARD_ITEM *aItem, bool aIncrementPadNumbers, bool aAddToModule=false)
Function Duplicate Duplicate a given item within the module, without adding to the board.
unsigned GetCount() const
Function GetCount returns the number of elements in the list.
Definition: dlist.h:126
int m_LocalSolderPasteMargin
Solder paste margin absolute value.
Definition: class_module.h:751
int m_ThermalGap
Definition: class_module.h:735
Collection of utility functions for component reference designators (refdes)
int GetWidth() const
Definition: eda_rect.h:117
Set for modules listed in the automatic insertion list (usually SMD footprints)
Definition: class_module.h:76
class TEXTE_PCB, text on a layer
Definition: typeinfo.h:92
coord_type GetRight() const
Definition: box2.h:197
void SetOrigin(const wxPoint &pos)
Definition: eda_rect.h:124
show modules values (when texts are visibles)
void GRDrawAnchor(EDA_RECT *aClipBox, wxDC *aDC, int x, int y, int aSize, COLOR4D aColor)
Definition: gr_basic.cpp:1193
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Function GetDesignSettings.
Definition: class_board.h:534
EDA_RECT GetFootprintRect() const
Function GetFootprintRect() Returns the area of the module footprint excluding any text.
void SetZoneConnection(ZoneConnection aType)
Definition: class_module.h:216
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:192
static const wxChar * StringLibNameInvalidChars(bool aUserReadable)
static function StringLibNameInvalidChars Test for validity of the name in a library of the footprint...
virtual EDA_RECT * GetClipBox()
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:216
coord_type GetBottom() const
Definition: box2.h:198
void NORMALIZE_ANGLE_POS(T &Angle)
Definition: trigo.h:250
void DeleteAll()
Function DeleteAll deletes all items on the list and leaves the list empty.
Definition: dlist.cpp:44
virtual wxString GetShownText() const override
Returns the string actually shown after processing of the base text.
int GetLocalSolderMaskMargin() const
Definition: class_module.h:204
void MoveAnchorPosition(const wxPoint &aMoveVector)
Function MoveAnchorPosition Move the reference point of the footprint It looks like a move footprint:...
#define abs(a)
Definition: auxiliary.h:84
wxArrayString * m_initial_comments
leading s-expression comments in the module, lazily allocated only if needed for speed
Definition: class_module.h:755
void SetLocalSolderPasteMarginRatio(double aRatio)
Definition: class_module.h:214
class EDGE_MODULE, a footprint edge
Definition: typeinfo.h:94
void DrawAncre(EDA_DRAW_PANEL *panel, wxDC *DC, const wxPoint &offset, int dim_ancre, GR_DRAWMODE draw_mode)
Function DrawAncre Draw the anchor cross (vertical) Must be done after the pads, because drawing the ...
bool Contains(const wxPoint &aPoint) const
Function Contains.
#define MODULE_PADS_LOCKED
In autoplace: module waiting for autoplace.
Definition: class_module.h:264
static const int delta[8][2]
Definition: solve.cpp:112
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:712
class TRACK, a track segment (segment on a copper layer)
Definition: typeinfo.h:95
wxString m_Doc
File name and path for documentation file.
Definition: class_module.h:736
timestamp_t m_LastEditTime
Definition: class_module.h:740
#define DIM_ANCRE_MODULE
Definition: pcbnew.h:57
This file contains miscellaneous commonly used macros and functions.
const wxString GetReference() const
Function GetReference.
Definition: class_module.h:462
const char * c_str() const
Definition: utf8.h:107
#define MODULE_is_PLACED
In autoplace: module automatically placed.
Definition: class_module.h:262
EDA_ITEM * Next() const
Definition: base_struct.h:212
void PushBack(T *aNewElement)
Function PushBack puts aNewElement at the end of the list sequence.
Definition: dlist.h:250
show modules on front
int m_LocalClearance
Definition: class_module.h:749
virtual EDA_DRAW_FRAME * GetParent() const =0
const INSPECTOR_FUNC & INSPECTOR
Definition: base_struct.h:102
PCB_LAYER_ID m_Layer
double m_Orient
Orientation in tenths of a degree, 900=90.0 degrees.
Definition: class_module.h:724
void MIRROR(T &aPoint, const T &aMirrorRef)
Definition: macros.h:122
int GetCount() const
Function GetCount returns the number of objects in the list.
Definition: collector.h:114
static void addRect(SHAPE_POLY_SET &aPolySet, wxRect aRect)
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.
void GRRect(EDA_RECT *aClipBox, wxDC *aDC, int x1, int y1, int x2, int y2, COLOR4D aColor)
Definition: gr_basic.cpp:1003
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_INSERT) override
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
Bounding box : coordinates on board, real orientation.
Definition: class_module.h:731
Class LSET is a set of PCB_LAYER_IDs.
void Inflate(int aFactor, int aCircleSegmentsCount)
Performs outline inflation/deflation, using round corners.
int GetLocalClearance() const
Definition: class_module.h:207
void SetParent(EDA_ITEM *aParent)
Definition: base_struct.h:219
GR_DRAWMODE
Drawmode. Compositing mode plus a flag or two.
Definition: gr_basic.h:37
Class 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:134
TEXT_TYPE GetType() const
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.
timestamp_t m_Link
Temporary logical link used during editing.
Definition: class_module.h:742
void SetThermalWidth(int aWidth)
Definition: class_module.h:219
int m_LocalSolderMaskMargin
Solder mask margin.
Definition: class_module.h:750
std::list< MODULE_3D_SETTINGS > m_3D_Drawings
Linked list of 3D models.
Definition: class_module.h:723
double GetOrientationRadians() const
Definition: class_module.h:190
int m_arflag
Use to trace ratsnest and auto routing.
Definition: class_module.h:741
double GetOrientationDegrees() const
Definition: class_module.h:189
Definition: colors.h:60
void Flip(const wxPoint &aCentre) override
Flip entity during module flip.
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:472
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
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:760
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.
T * GetFirst() const
Function GetFirst returns the first T* in the list without removing it, or NULL if the list is empty.
Definition: dlist.h:163
void DrawEdgesOnly(EDA_DRAW_PANEL *panel, wxDC *DC, const wxPoint &offset, GR_DRAWMODE draw_mode)
Function DrawEdgesOnly Draws the footprint edges only to the current Device Context.
void Draw(EDA_DRAW_PANEL *aPanel, wxDC *aDC, GR_DRAWMODE aDrawMode, const wxPoint &aOffset=ZeroOffset) override
Function Draw Draw the text according to the footprint pos and orient.
int NewOutline()
Creates a new empty polygon in the set and returns its index
bool IsLocked() const override
Function IsLocked.
Definition: class_module.h:267
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...
void SetLocalSolderMaskMargin(int aMargin)
Definition: class_module.h:205
int GetHeight() const
Definition: eda_rect.h:118
D_PAD * GetTopLeftPad()
void SetPos0(const wxPoint &aPos)
UTF8 Format() const
Definition: lib_id.cpp:237
int GetLocalSolderPasteMargin() const
Definition: class_module.h:210
static const int ORPHANED
Constant that forces initialization of a netinfo item to the NETINFO_ITEM ORPHANED (typically -1) whe...
Definition: netinfo.h:469
MODULE & operator=(const MODULE &aOther)
double Area() const
wxString m_Filename
The 3D shape filename in 3D library.
Definition: class_module.h:102
default
Definition: class_module.h:75
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:192
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.
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:211
double GetLocalSolderPasteMarginRatio() const
Definition: class_module.h:213
void GetMsgPanelInfo(EDA_UNITS_T aUnits, std::vector< MSG_PANEL_ITEM > &aList) override
int m_CntRot180
Vertical automatic placement cost ( 0..10 ).
Definition: class_module.h:744
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:100
virtual wxString GetClass() const =0
Function GetClass returns the class name.
BOARD_ITEM * Next() const
void SetLocked(bool isLocked) override
Function SetLocked sets the MODULE_is_LOCKED bit in the m_ModuleStatus.
Definition: class_module.h:277
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...
DLIST< BOARD_ITEM > m_Drawings
Linked list of graphical items.
Definition: class_module.h:722
#define max(a, b)
Definition: auxiliary.h:86
Class BOARD holds information pertinent to a Pcbnew printed circuit board.
Definition: class_board.h:170
int m_ModuleStatus
For autoplace: flags (LOCKED, AUTOPLACED)
Definition: class_module.h:730
Class 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:78
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.
STATUS_FLAGS m_Flags
Flag bits for editing and other uses.
Definition: base_struct.h:181
size_t i
Definition: json11.cpp:597
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.
Class EDA_RECT handles the component boundary box.
Definition: eda_rect.h:44
Class PCB_EDIT_FRAME is the main frame for Pcbnew.
TEXTE_MODULE * m_Value
Component value (74LS00, 22K..)
Definition: class_module.h:727
bool IsAperturePad() const
Definition: class_pad.h:421
Class EDA_ITEM is a base class for most all the KiCad significant classes, used in schematics and boa...
Definition: base_struct.h:157
wxPoint m_Pos
Position of module on the board in internal units.
Definition: class_module.h:725
int GetTrailingInt(const wxString &aStr)
Gets the trailing int, if any, from a string.
Definition: string.cpp:638
bool Intersects(const EDA_RECT &aRect) const
Function Intersects tests for a common area between rectangles.
DLIST< BOARD_ITEM > & GraphicalItemsList()
Definition: class_module.h:165
class VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:96
TEXTE_MODULE * m_Reference
Component reference designator value (U34, R18..)
Definition: class_module.h:726
void CopyNetlistSettings(MODULE *aModule, bool aCopyLocalSettings)
Function CopyNetlistSettings copies the netlist settings to aModule.
DLIST< D_PAD > & PadsList()
Definition: class_module.h:162
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 EDA_MSG_ITEM is used EDA_MSG_PANEL as the item type for displaying messages.
Definition: msgpanel.h:53
Class VIEW.
Definition: view.h:61
SEARCH_RESULT
Definition: base_struct.h:66
DLIST< D_PAD > m_Pads
Linked list of pads.
Definition: class_module.h:721
const wxPoint GetPosition() const override
Definition: class_pad.h:222
int GetThermalWidth() const
Definition: class_module.h:220
EDGE_MODULE class definition.
ZoneConnection m_ZoneConnection
Definition: class_module.h:739
Message panel definition file.
void Rotate(double aAngle, const VECTOR2I &aCenter)
Function Rotate rotates all vertices by a given angle.
wxString GetLayerName() const
Function GetLayerName returns the name of the PCB layer on which the item resides.
INCLUDE_NPTH_T
Definition: class_module.h:61
virtual PCB_LAYER_ID GetLayer() const
Function GetLayer returns the primary layer this item is on.
void DisplayError(wxWindow *parent, const wxString &text, int displaytime)
Function DisplayError displays an error or warning message box with aMessage.
Definition: confirm.cpp:244
const wxPoint GetPosition() const override
Definition: class_module.h:183
int GetThermalGap() const
Definition: class_module.h:223
void CopyNetlistSettings(D_PAD *aPad, bool aCopyLocalSettings)
Function CopyNetlistSettings copies the netlist settings to aPad, and the net name.
Definition: class_pad.cpp:588
EDA_UNITS_T
Definition: common.h:157
show modules references (when texts are visibles)
ZoneConnection GetZoneConnection() const
Definition: class_module.h:217
#define DO_NOT_DRAW
Used to disable draw function.
Definition: base_struct.h:126
EDA_RECT & Inflate(wxCoord dx, wxCoord dy)
Function Inflate inflates the rectangle horizontally by dx and vertically by dy.
KICAD_T Type() const
Function Type()
Definition: base_struct.h:204
#define min(a, b)
Definition: auxiliary.h:85
int m_Attributs
Flag bits ( see Mod_Attribut )
Definition: class_module.h:729
bool IsLayerVisible(int aLayer) const
Function IsLayerVisible() Returns information about visibility of a particular layer.
Definition: view.h:427
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