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_Surface = 0.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  // Update relative coordinates, it can be done only after there is a parent object assigned
291  switch( aBoardItem->Type() )
292  {
293  case PCB_MODULE_TEXT_T:
294  static_cast<TEXTE_MODULE*>( aBoardItem )->SetLocalCoord();
295  break;
296 
297  case PCB_MODULE_EDGE_T:
298  static_cast<EDGE_MODULE*>( aBoardItem )->SetLocalCoord();
299  break;
300 
301  case PCB_PAD_T:
302  static_cast<D_PAD*>( aBoardItem )->SetLocalCoord();
303  break;
304 
305  default:
306  // Huh? It should have been filtered out by the previous switch
307  assert(false);
308  break;
309  }
310 }
311 
312 
313 void MODULE::Remove( BOARD_ITEM* aBoardItem )
314 {
315  switch( aBoardItem->Type() )
316  {
317  case PCB_MODULE_TEXT_T:
318  // Only user texts can be removed this way. Reference and value are not hold in the DLIST.
319  assert( static_cast<TEXTE_MODULE*>( aBoardItem )->GetType() == TEXTE_MODULE::TEXT_is_DIVERS );
320 
321  // no break
322 
323  case PCB_MODULE_EDGE_T:
324  m_Drawings.Remove( aBoardItem );
325  break;
326 
327  case PCB_PAD_T:
328  m_Pads.Remove( static_cast<D_PAD*>( aBoardItem ) );
329  break;
330 
331  default:
332  {
333  wxString msg;
334  msg.Printf( wxT( "MODULE::Remove() needs work: BOARD_ITEM type (%d) not handled" ),
335  aBoardItem->Type() );
336  wxFAIL_MSG( msg );
337  }
338  }
339 }
340 
341 
342 void MODULE::CopyNetlistSettings( MODULE* aModule, bool aCopyLocalSettings )
343 {
344  // Don't do anything foolish like trying to copy to yourself.
345  wxCHECK_RET( aModule != NULL && aModule != this, wxT( "Cannot copy to NULL or yourself." ) );
346 
347  // Not sure what to do with the value field. Use netlist for now.
348  aModule->SetPosition( GetPosition() );
349 
350  if( aModule->GetLayer() != GetLayer() )
351  aModule->Flip( aModule->GetPosition() );
352 
353  if( aModule->GetOrientation() != GetOrientation() )
354  aModule->Rotate( aModule->GetPosition(), GetOrientation() );
355 
356  aModule->SetLocked( IsLocked() );
357 
358  if( aCopyLocalSettings )
359  {
361  aModule->SetLocalClearance( GetLocalClearance() );
364  aModule->SetZoneConnection( GetZoneConnection() );
365  aModule->SetThermalWidth( GetThermalWidth() );
366  aModule->SetThermalGap( GetThermalGap() );
367  }
368 
369  for( D_PAD* pad = aModule->PadsList(); pad; pad = pad->Next() )
370  {
371  // Fix me: if aCopyLocalSettings == true, for "multiple" pads
372  // (set of pads having the same name/number) this is broken
373  // because we copy settings from the first pad found.
374  // When old and new footprints have very few differences, a better
375  // algo can be used.
376  D_PAD* oldPad = FindPadByName( pad->GetName() );
377 
378  if( oldPad )
379  oldPad->CopyNetlistSettings( pad, aCopyLocalSettings );
380  }
381 
382  // Not sure about copying description, keywords, 3D models or any other
383  // local user changes to footprint. Stick with the new footprint settings
384  // called out in the footprint loaded in the netlist.
385  aModule->CalculateBoundingBox();
386 }
387 
388 
389 void MODULE::Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, GR_DRAWMODE aDrawMode,
390  const wxPoint& aOffset )
391 {
392  if( (m_Flags & DO_NOT_DRAW) || (IsMoving()) )
393  return;
394 
395  for( D_PAD* pad = m_Pads; pad; pad = pad->Next() )
396  {
397  if( pad->IsMoving() )
398  continue;
399 
400  pad->Draw( aPanel, aDC, aDrawMode, aOffset );
401  }
402 
403  BOARD* brd = GetBoard();
404 
405  // Draws footprint anchor
406  DrawAncre( aPanel, aDC, aOffset, DIM_ANCRE_MODULE, aDrawMode );
407 
408  // Draw graphic items
410  {
411  if( !(m_Reference->IsMoving()) )
412  m_Reference->Draw( aPanel, aDC, aDrawMode, aOffset );
413  }
414 
415  if( brd->IsElementVisible( LAYER_MOD_VALUES ) )
416  {
417  if( !(m_Value->IsMoving()) )
418  m_Value->Draw( aPanel, aDC, aDrawMode, aOffset );
419  }
420 
421  for( BOARD_ITEM* item = m_Drawings; item; item = item->Next() )
422  {
423  if( item->IsMoving() )
424  continue;
425 
426  switch( item->Type() )
427  {
428  case PCB_MODULE_TEXT_T:
429  case PCB_MODULE_EDGE_T:
430  item->Draw( aPanel, aDC, aDrawMode, aOffset );
431  break;
432 
433  default:
434  break;
435  }
436  }
437 
438  // Enable these line to draw m_BoundaryBox (debug tests purposes only)
439 #if 0
440  GRRect( aPanel->GetClipBox(), aDC, m_BoundaryBox, 0, BROWN );
441 #endif
442 
443 }
444 
445 
446 void MODULE::DrawEdgesOnly( EDA_DRAW_PANEL* panel, wxDC* DC, const wxPoint& offset,
447  GR_DRAWMODE draw_mode )
448 {
449  for( BOARD_ITEM* item = m_Drawings; item; item = item->Next() )
450  {
451  switch( item->Type() )
452  {
453  case PCB_MODULE_EDGE_T:
454  item->Draw( panel, DC, draw_mode, offset );
455  break;
456 
457  default:
458  break;
459  }
460  }
461 }
462 
463 
465 {
468 }
469 
470 
472 {
473  EDA_RECT area;
474 
475  area.SetOrigin( m_Pos );
476  area.SetEnd( m_Pos );
477  area.Inflate( Millimeter2iu( 0.25 ) ); // Give a min size to the area
478 
479  for( const BOARD_ITEM* item = m_Drawings.GetFirst(); item; item = item->Next() )
480  {
481  const EDGE_MODULE* edge = dyn_cast<const EDGE_MODULE*>( item );
482 
483  if( edge )
484  area.Merge( edge->GetBoundingBox() );
485  }
486 
487  for( D_PAD* pad = m_Pads; pad; pad = pad->Next() )
488  area.Merge( pad->GetBoundingBox() );
489 
490  return area;
491 }
492 
493 
495 {
496  EDA_RECT area = GetFootprintRect();
497 
498  // Calculate extended area including text fields
499  area.Merge( m_Reference->GetBoundingBox() );
500  area.Merge( m_Value->GetBoundingBox() );
501 
502  // Add the Clearance shape size: (shape around the pads when the
503  // clearance is shown. Not optimized, but the draw cost is small
504  // (perhaps smaller than optimization).
505  BOARD* board = GetBoard();
506  if( board )
507  {
508  int biggest_clearance = board->GetDesignSettings().GetBiggestClearanceValue();
509  area.Inflate( biggest_clearance );
510  }
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( 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 
887 {
888  wxString text;
889  text.Printf( _( "Footprint %s on %s" ),
890  GetChars ( GetReference() ),
891  GetChars ( GetLayerName() ) );
892 
893  return text;
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 fpRect = GetFootprintRect();
1020 
1021  return BOX2I( VECTOR2I( fpRect.GetOrigin() ), VECTOR2I( fpRect.GetSize() ) );
1022 }
1023 
1024 
1025 bool MODULE::IsLibNameValid( const wxString & aName )
1026 {
1027  const wxChar * invalids = StringLibNameInvalidChars( false );
1028 
1029  if( aName.find_first_of( invalids ) != std::string::npos )
1030  return false;
1031 
1032  return true;
1033 }
1034 
1035 
1036 const wxChar* MODULE::StringLibNameInvalidChars( bool aUserReadable )
1037 {
1038  static const wxChar invalidChars[] = wxT("%$\t\n\r \"\\/:");
1039  static const wxChar invalidCharsReadable[] = wxT("% $ 'tab' 'return' 'line feed' 'space' \\ \" / :");
1040 
1041  if( aUserReadable )
1042  return invalidCharsReadable;
1043  else
1044  return invalidChars;
1045 }
1046 
1047 
1048 void MODULE::Move( const wxPoint& aMoveVector )
1049 {
1050  wxPoint newpos = m_Pos + aMoveVector;
1051  SetPosition( newpos );
1052 }
1053 
1054 
1055 void MODULE::Rotate( const wxPoint& aRotCentre, double aAngle )
1056 {
1057  wxPoint newpos = m_Pos;
1058  RotatePoint( &newpos, aRotCentre, aAngle );
1059  SetPosition( newpos );
1060  SetOrientation( GetOrientation() + aAngle );
1061 }
1062 
1063 
1064 void MODULE::Flip( const wxPoint& aCentre )
1065 {
1066  // Move module to its final position:
1067  wxPoint finalPos = m_Pos;
1068  MIRROR( finalPos.y, aCentre.y );
1069  SetPosition( finalPos );
1070 
1071  // Flip layer
1072  SetLayer( FlipLayer( GetLayer() ) );
1073 
1074  // Reverse mirror orientation.
1075  m_Orient = -m_Orient;
1077 
1078  // Mirror pads to other side of board about the x axis, i.e. vertically.
1079  for( D_PAD* pad = m_Pads; pad; pad = pad->Next() )
1080  pad->Flip( m_Pos );
1081 
1082  // Mirror reference and value.
1083  m_Reference->Flip( m_Pos );
1084  m_Value->Flip( m_Pos );
1085 
1086  // Reverse mirror module graphics and texts.
1087  for( EDA_ITEM* item = m_Drawings; item; item = item->Next() )
1088  {
1089  switch( item->Type() )
1090  {
1091  case PCB_MODULE_EDGE_T:
1092  ( (EDGE_MODULE*) item )->Flip( m_Pos );
1093  break;
1094 
1095  case PCB_MODULE_TEXT_T:
1096  static_cast<TEXTE_MODULE*>( item )->Flip( m_Pos );
1097  break;
1098 
1099  default:
1100  wxMessageBox( wxT( "MODULE::Flip() error: Unknown Draw Type" ) );
1101  break;
1102  }
1103  }
1104 
1106 }
1107 
1108 
1109 void MODULE::SetPosition( const wxPoint& newpos )
1110 {
1111  wxPoint delta = newpos - m_Pos;
1112 
1113  m_Pos += delta;
1114 
1115  m_Reference->EDA_TEXT::Offset( delta );
1116  m_Value->EDA_TEXT::Offset( delta );
1117 
1118  for( D_PAD* pad = m_Pads; pad; pad = pad->Next() )
1119  {
1120  pad->SetPosition( pad->GetPosition() + delta );
1121  }
1122 
1123  for( EDA_ITEM* item = m_Drawings; item; item = item->Next() )
1124  {
1125  switch( item->Type() )
1126  {
1127  case PCB_MODULE_EDGE_T:
1128  {
1129  EDGE_MODULE* pt_edgmod = (EDGE_MODULE*) item;
1130  pt_edgmod->SetDrawCoord();
1131  break;
1132  }
1133 
1134  case PCB_MODULE_TEXT_T:
1135  {
1136  TEXTE_MODULE* text = static_cast<TEXTE_MODULE*>( item );
1137  text->EDA_TEXT::Offset( delta );
1138  break;
1139  }
1140 
1141  default:
1142  wxMessageBox( wxT( "Draw type undefined." ) );
1143  break;
1144  }
1145  }
1146 
1148 }
1149 
1150 
1151 void MODULE::MoveAnchorPosition( const wxPoint& aMoveVector )
1152 {
1153  /* Move the reference point of the footprint
1154  * the footprints elements (pads, outlines, edges .. ) are moved
1155  * but:
1156  * - the footprint position is not modified.
1157  * - the relative (local) coordinates of these items are modified
1158  * - Draw coordinates are updated
1159  */
1160 
1161 
1162  // Update (move) the relative coordinates relative to the new anchor point.
1163  wxPoint moveVector = aMoveVector;
1164  RotatePoint( &moveVector, -GetOrientation() );
1165 
1166  // Update of the reference and value.
1167  m_Reference->SetPos0( m_Reference->GetPos0() + moveVector );
1169  m_Value->SetPos0( m_Value->GetPos0() + moveVector );
1170  m_Value->SetDrawCoord();
1171 
1172  // Update the pad local coordinates.
1173  for( D_PAD* pad = PadsList(); pad; pad = pad->Next() )
1174  {
1175  pad->SetPos0( pad->GetPos0() + moveVector );
1176  pad->SetDrawCoord();
1177  }
1178 
1179  // Update the draw element coordinates.
1180  for( EDA_ITEM* item = GraphicalItemsList(); item; item = item->Next() )
1181  {
1182  switch( item->Type() )
1183  {
1184  case PCB_MODULE_EDGE_T:
1185  {
1186  EDGE_MODULE* edge = static_cast<EDGE_MODULE*>( item );
1187 
1188  // Polygonal shape coordinates are specific:
1189  // m_Start0 and m_End0 have no meaning. So we have to move corner positions
1190  if( edge->GetShape() == S_POLYGON )
1191  {
1192  for( auto iter = edge->GetPolyShape().Iterate(); iter; iter++ )
1193  {
1194  (*iter) += VECTOR2I( moveVector );
1195  }
1196  }
1197  else
1198  {
1199  edge->m_Start0 += moveVector;
1200  edge->m_End0 += moveVector;
1201  edge->SetDrawCoord();
1202  }
1203  break;
1204  }
1205 
1206  case PCB_MODULE_TEXT_T:
1207  {
1208  TEXTE_MODULE* text = static_cast<TEXTE_MODULE*>( item );
1209  text->SetPos0( text->GetPos0() + moveVector );
1210  text->SetDrawCoord();
1211  break;
1212  }
1213 
1214  default:
1215  break;
1216  }
1217  }
1218 
1220 }
1221 
1222 
1223 void MODULE::SetOrientation( double newangle )
1224 {
1225  double angleChange = newangle - m_Orient; // change in rotation
1226 
1227  NORMALIZE_ANGLE_POS( newangle );
1228 
1229  m_Orient = newangle;
1230 
1231  for( D_PAD* pad = m_Pads; pad; pad = pad->Next() )
1232  {
1233  pad->SetOrientation( pad->GetOrientation() + angleChange );
1234  pad->SetDrawCoord();
1235  }
1236 
1237  // Update of the reference and value.
1239  m_Value->SetDrawCoord();
1240 
1241  // Displace contours and text of the footprint.
1242  for( BOARD_ITEM* item = m_Drawings; item; item = item->Next() )
1243  {
1244  if( item->Type() == PCB_MODULE_EDGE_T )
1245  {
1246  static_cast<EDGE_MODULE*>( item )->SetDrawCoord();
1247  }
1248  else if( item->Type() == PCB_MODULE_TEXT_T )
1249  {
1250  static_cast<TEXTE_MODULE*>( item )->SetDrawCoord();
1251  }
1252  }
1253 
1255 }
1256 
1258  bool aIncrementPadNumbers,
1259  bool aAddToModule )
1260 {
1261  BOARD_ITEM* new_item = NULL;
1262  D_PAD* new_pad = NULL;
1263 
1264  switch( aItem->Type() )
1265  {
1266  case PCB_PAD_T:
1267  {
1268  new_pad = new D_PAD( *static_cast<const D_PAD*>( aItem ) );
1269 
1270  if( aAddToModule )
1271  PadsList().PushBack( new_pad );
1272 
1273  new_item = new_pad;
1274  break;
1275  }
1276 
1277  case PCB_MODULE_TEXT_T:
1278  {
1279  const TEXTE_MODULE* old_text = static_cast<const TEXTE_MODULE*>( aItem );
1280 
1281  // do not duplicate value or reference fields
1282  // (there can only be one of each)
1283  if( old_text->GetType() == TEXTE_MODULE::TEXT_is_DIVERS )
1284  {
1285  TEXTE_MODULE* new_text = new TEXTE_MODULE( *old_text );
1286 
1287  if( aAddToModule )
1288  GraphicalItemsList().PushBack( new_text );
1289 
1290  new_item = new_text;
1291  }
1292  break;
1293  }
1294 
1295  case PCB_MODULE_EDGE_T:
1296  {
1297  EDGE_MODULE* new_edge = new EDGE_MODULE(
1298  *static_cast<const EDGE_MODULE*>(aItem) );
1299 
1300  if( aAddToModule )
1301  GraphicalItemsList().PushBack( new_edge );
1302 
1303  new_item = new_edge;
1304  break;
1305  }
1306 
1307  case PCB_MODULE_T:
1308  // Ignore the module itself
1309  break;
1310 
1311  default:
1312  // Un-handled item for duplication
1313  wxASSERT_MSG( false, "Duplication not supported for items of class "
1314  + aItem->GetClass() );
1315  break;
1316  }
1317 
1318  if( aIncrementPadNumbers && new_pad )
1319  {
1320  new_pad->IncrementPadName( true, true );
1321  }
1322 
1323  return new_item;
1324 }
1325 
1326 
1327 wxString MODULE::GetNextPadName( bool aFillSequenceGaps ) const
1328 {
1329  std::set<int> usedNumbers;
1330 
1331  // Create a set of used pad numbers
1332  for( D_PAD* pad = PadsList(); pad; pad = pad->Next() )
1333  {
1334  int padNumber = getTrailingInt( pad->GetName() );
1335  usedNumbers.insert( padNumber );
1336  }
1337 
1338  const int nextNum = getNextNumberInSequence( usedNumbers, aFillSequenceGaps );
1339 
1340  return wxString::Format( wxT( "%i" ), nextNum );
1341 }
1342 
1343 
1345 {
1346  wxString prefix = GetReference();
1347 
1348  int strIndex = prefix.length() - 1;
1349  while( strIndex >= 0 )
1350  {
1351  const wxUniChar chr = prefix.GetChar( strIndex );
1352 
1353  // numeric suffix
1354  if( chr >= '0' && chr <= '9' )
1355  break;
1356 
1357  strIndex--;
1358  }
1359 
1360  prefix = prefix.Mid( 0, strIndex );
1361 
1362  return prefix;
1363 }
1364 
1365 
1366 // Calculate the area of aPolySet, after fracturation, because
1367 // polygons with no hole are expected.
1368 static double polygonArea( SHAPE_POLY_SET& aPolySet )
1369 {
1370  double area = 0.0;
1371  for( int ii = 0; ii < aPolySet.OutlineCount(); ii++ )
1372  {
1373  SHAPE_LINE_CHAIN& outline = aPolySet.Outline( ii );
1374  // Ensure the curr outline is closed, to calculate area
1375  outline.SetClosed( true );
1376 
1377  area += outline.Area();
1378  }
1379 
1380  return area;
1381 }
1382 
1383 // a helper function to add a rectangular polygon aRect to aPolySet
1384 static void addRect( SHAPE_POLY_SET& aPolySet, wxRect aRect )
1385 {
1386  aPolySet.NewOutline();
1387 
1388  aPolySet.Append( aRect.GetX(), aRect.GetY() );
1389  aPolySet.Append( aRect.GetX()+aRect.width, aRect.GetY() );
1390  aPolySet.Append( aRect.GetX()+aRect.width, aRect.GetY()+aRect.height );
1391  aPolySet.Append( aRect.GetX(), aRect.GetY()+aRect.height );
1392 }
1393 
1394 double MODULE::CoverageRatio( const GENERAL_COLLECTOR& aCollector ) const
1395 {
1396  double moduleArea = GetFootprintRect().GetArea();
1397  SHAPE_POLY_SET coveredRegion;
1398  addRect( coveredRegion, GetFootprintRect() );
1399 
1400  // build list of holes (covered areas not available for selection)
1401  SHAPE_POLY_SET holes;
1402 
1403  for( D_PAD* pad = m_Pads; pad; pad = pad->Next() )
1404  addRect( holes, pad->GetBoundingBox() );
1405 
1406  addRect( holes, m_Reference->GetBoundingBox() );
1407  addRect( holes, m_Value->GetBoundingBox() );
1408 
1409  for( int i = 0; i < aCollector.GetCount(); ++i )
1410  {
1411  BOARD_ITEM* item = aCollector[i];
1412 
1413  switch( item->Type() )
1414  {
1415  case PCB_TEXT_T:
1416  case PCB_MODULE_TEXT_T:
1417  case PCB_TRACE_T:
1418  case PCB_VIA_T:
1419  addRect( holes, item->GetBoundingBox() );
1420  break;
1421  default:
1422  break;
1423  }
1424  }
1425 
1426  SHAPE_POLY_SET uncoveredRegion;
1427  uncoveredRegion.BooleanSubtract( coveredRegion, holes, SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
1428  uncoveredRegion.Simplify( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
1429  uncoveredRegion.Fracture( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
1430 
1431  double uncoveredRegionArea = polygonArea( uncoveredRegion );
1432  double coveredArea = moduleArea - uncoveredRegionArea;
1433  double ratio = ( coveredArea / moduleArea );
1434 
1435  return std::min( ratio, 1.0 );
1436 }
1437 
1438 
1439 // see convert_drawsegment_list_to_polygon.cpp:
1440 extern bool ConvertOutlineToPolygon( std::vector< DRAWSEGMENT* >& aSegList,
1441  SHAPE_POLY_SET& aPolygons, wxString* aErrorText);
1442 
1444 {
1447  // Build the courtyard area from graphic items on the courtyard.
1448  // Only PCB_MODULE_EDGE_T have meaning, graphic texts are ignored.
1449  // Collect items:
1450  std::vector< DRAWSEGMENT* > list_front;
1451  std::vector< DRAWSEGMENT* > list_back;
1452 
1453  for( BOARD_ITEM* item = GraphicalItemsList(); item; item = item->Next() )
1454  {
1455  if( item->GetLayer() == B_CrtYd && item->Type() == PCB_MODULE_EDGE_T )
1456  list_back.push_back( static_cast< DRAWSEGMENT* > ( item ) );
1457 
1458  if( item->GetLayer() == F_CrtYd && item->Type() == PCB_MODULE_EDGE_T )
1459  list_front.push_back( static_cast< DRAWSEGMENT* > ( item ) );
1460  }
1461 
1462  // Note: if no item found on courtyard layers, return true.
1463  // false is returned only when the shape defined on courtyard layers
1464  // is not convertible to a polygon
1465  if( !list_front.size() && !list_back.size() )
1466  return true;
1467 
1468  wxString error_msg;
1469 
1470  bool success = ConvertOutlineToPolygon( list_front, m_poly_courtyard_front, &error_msg );
1471 
1472  if( success )
1473  success = ConvertOutlineToPolygon( list_back, m_poly_courtyard_back, &error_msg );
1474 
1475  if( !error_msg.IsEmpty() )
1476  {
1477  error_msg.Prepend( GetReference() + ": " );
1478  wxLogMessage( error_msg );
1479  }
1480 
1481  return success;
1482 }
1483 
1485 {
1486  assert( aImage->Type() == PCB_MODULE_T );
1487 
1488  std::swap( *((MODULE*) this), *((MODULE*) aImage) );
1489 }
LIB_ID m_fpid
The LIB_ID of the MODULE.
Definition: class_module.h:727
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:515
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:209
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...
BOX2< VECTOR2I > BOX2I
Definition: box2.h:468
bool IsMoving() const
Definition: base_struct.h:229
wxString GetReferencePrefix() const
Function GetReference prefix Gets the alphabetic prefix of the module reference - e...
void SetThermalGap(int aGap)
Definition: class_module.h:221
int m_CntRot90
Horizontal automatic placement cost ( 0..10 ).
Definition: class_module.h:743
int GetThermalGap() const
Definition: class_module.h:222
const wxPoint GetOrigin() const
Definition: eda_rect.h:112
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:761
bool ConvertOutlineToPolygon(std::vector< DRAWSEGMENT * > &aSegList, SHAPE_POLY_SET &aPolygons, wxString *aErrorText)
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.
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:207
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:736
bool IsLayerVisible(int aLayer) const
Function IsLayerVisible() Returns information about visibility of a particular layer.
Definition: view.h:404
wxString m_Path
Definition: class_module.h:737
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:206
int m_ThermalWidth
Definition: class_module.h:733
const wxSize GetSize() const
Definition: eda_rect.h:101
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:752
void Flip(const wxPoint &aCentre) override
Function Flip Flip this object, i.e.
Class BOARD to handle a board.
Definition: colors.h:61
polygon (not yet used for tracks, but could be in microwave apps)
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:751
int m_ThermalGap
Definition: class_module.h:734
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:187
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:215
wxString GetSelectMenuText() const override
Function GetSelectMenuText returns the text to display to be used in the selection clarification cont...
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:217
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:216
double m_Surface
Bounding box area.
Definition: class_module.h:741
ZoneConnection GetZoneConnection() const
Definition: class_module.h:216
ITERATOR Iterate(int aFirst, int aLast, bool aIterateHoles=false)
Function Iterate returns an object to iterate through the points of the polygons between aFirst and a...
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:41
virtual wxString GetShownText() const override
Returns the string actually shown after processing of the base text.
VECTOR2< int > VECTOR2I
Definition: vector2d.h:589
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:213
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:212
#define MODULE_PADS_LOCKED
In autoplace: module waiting for autoplace.
Definition: class_module.h:260
static const int delta[8][2]
Definition: solve.cpp:112
Casted dyn_cast(From aObject)
Function dyn_cast()
Definition: typeinfo.h:61
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:735
timestamp_t m_LastEditTime
Definition: class_module.h:739
#define DIM_ANCRE_MODULE
Definition: pcbnew.h:63
wxPoint m_End0
This file contains miscellaneous commonly used macros and functions.
#define MODULE_is_PLACED
In autoplace: module automatically placed.
Definition: class_module.h:258
void PushBack(T *aNewElement)
Function PushBack puts aNewElement at the end of the list sequence.
Definition: dlist.h:250
void GetMsgPanelInfo(std::vector< MSG_PANEL_ITEM > &aList) override
>
show modules on front
BOARD_ITEM * Next() const
int m_LocalClearance
Definition: class_module.h:749
const INSPECTOR_FUNC & INSPECTOR
Definition: base_struct.h:100
PCB_LAYER_ID m_Layer
double m_Orient
Orientation in tenths of a degree, 900=90.0 degrees.
Definition: class_module.h:723
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.
STROKE_T GetShape() const
EDA_RECT m_BoundaryBox
Bounding box : coordinates on board, real orientation.
Definition: class_module.h:730
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:188
void SetParent(EDA_ITEM *aParent)
Definition: base_struct.h:224
double GetOrientation() const
Definition: class_module.h:187
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:254
static const int VIEW_MAX_LAYERS
maximum number of layers that may be shown
Definition: view.h:675
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:182
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:188
D_PAD * Next() const
Definition: class_pad.h:160
timestamp_t m_Link
Temporary logical link used in edition.
Definition: class_module.h:742
void SetThermalWidth(int aWidth)
Definition: class_module.h:218
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:722
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Function GetDesignSettings.
Definition: class_board.h:532
int m_arflag
Use to trace ratsnest and auto routing.
Definition: class_module.h:740
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...
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:180
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
SHAPE_POLY_SET & GetPolyShape()
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:203
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:189
bool IsLocked() const override
Function IsLocked.
Definition: class_module.h:263
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:204
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:209
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:102
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:210
bool HitTestAccurate(const wxPoint &aPosition) const
Tests if a point is inside the bounding polygon of the module.
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: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:273
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
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:721
#define max(a, b)
Definition: auxiliary.h:86
Class BOARD holds information pertinent to a Pcbnew printed circuit board.
Definition: class_board.h:169
const wxString & GetReference() const
Function GetReference.
Definition: class_module.h:458
int m_ModuleStatus
For autoplace: flags (LOCKED, AUTOPLACED)
Definition: class_module.h:729
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
STATUS_FLAGS m_Flags
Flag bits for editing and other uses.
Definition: base_struct.h:186
size_t i
Definition: json11.cpp:597
wxString GetClass() const override
Function GetClass returns the class name.
Definition: class_module.h:594
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
TEXTE_MODULE * m_Value
Component value (74LS00, 22K..)
Definition: class_module.h:726
Class EDA_ITEM is a base class for most all the KiCad significant classes, used in schematics and boa...
Definition: base_struct.h:162
int GetWidth() const
Definition: eda_rect.h:117
wxPoint m_Pos
Position of module on the board in internal units.
Definition: class_module.h:724
UTF8 Format() const
Definition: lib_id.cpp:263
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:164
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:725
void CopyNetlistSettings(MODULE *aModule, bool aCopyLocalSettings)
Function CopyNetlistSettings copies the netlist settings to aModule.
DLIST< D_PAD > & PadsList()
Definition: class_module.h:161
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.
wxPoint m_Start0
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:58
SEARCH_RESULT
Definition: base_struct.h:64
DLIST< D_PAD > m_Pads
Linked list of pads.
Definition: class_module.h:720
const wxPoint GetPosition() const override
Definition: class_pad.h:220
coord_type GetX() const
Definition: box2.h:178
EDGE_MODULE class definition.
ZoneConnection m_ZoneConnection
Definition: class_module.h:738
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:185
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:182
void CopyNetlistSettings(D_PAD *aPad, bool aCopyLocalSettings)
Function CopyNetlistSettings copies the netlist settings to aPad, and the net name.
Definition: class_pad.cpp:526
show modules references (when texts are visibles)
int GetThermalWidth() const
Definition: class_module.h:219
#define DO_NOT_DRAW
Used to disable draw function.
Definition: base_struct.h:121
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:728
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) ...
virtual const EDA_RECT GetBoundingBox() const override
Function GetBoundingBox returns the orthogonal, bounding box of this object for display purposes...
bool HitTest(const wxPoint &aPosition) const override
Function HitTest tests if aPosition is contained within or on the bounding area of an item...
Definition: colors.h:62