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