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  return GetFootprintRect();
497 }
498 
499 
515 {
516  SHAPE_POLY_SET poly;
517 
518  double orientation = GetOrientationRadians();
519 
520  MODULE temp = *this;
521  temp.SetOrientation( 0.0 );
522  BOX2I area = temp.GetFootprintRect();
523 
524  poly.NewOutline();
525 
526  VECTOR2I p = area.GetPosition();
527  poly.Append( p );
528  p.x = area.GetRight();
529  poly.Append( p );
530  p.y = area.GetBottom();
531  poly.Append( p );
532  p.x = area.GetX();
533  poly.Append( p );
534 
535  BOARD* board = GetBoard();
536  if( board )
537  {
538  int biggest_clearance = board->GetDesignSettings().GetBiggestClearanceValue();
539  poly.Inflate( biggest_clearance, 4 );
540  }
541 
542  poly.Inflate( Millimeter2iu( 0.01 ), 4 );
543  poly.Rotate( -orientation, m_Pos );
544 
545  return poly;
546 }
547 
548 
549 void MODULE::GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList )
550 {
551  int nbpad;
552  wxString msg;
553 
554  aList.push_back( MSG_PANEL_ITEM( m_Reference->GetShownText(), m_Value->GetShownText(), DARKCYAN ) );
555 
556  // Display last date the component was edited (useful in Module Editor).
557  wxDateTime date( static_cast<time_t>( m_LastEditTime ) );
558 
559  if( m_LastEditTime && date.IsValid() )
560  // Date format: see http://www.cplusplus.com/reference/ctime/strftime
561  msg = date.Format( wxT( "%b %d, %Y" ) ); // Abbreviated_month_name Day, Year
562  else
563  msg = _( "Unknown" );
564 
565  aList.push_back( MSG_PANEL_ITEM( _( "Last Change" ), msg, BROWN ) );
566 
567  // display schematic path
568  aList.push_back( MSG_PANEL_ITEM( _( "Netlist Path" ), m_Path, BROWN ) );
569 
570  // display the board side placement
571  aList.push_back( MSG_PANEL_ITEM( _( "Board Side" ),
572  IsFlipped()? _( "Back (Flipped)" ) : _( "Front" ), RED ) );
573 
574  EDA_ITEM* PtStruct = m_Pads;
575  nbpad = 0;
576 
577  while( PtStruct )
578  {
579  nbpad++;
580  PtStruct = PtStruct->Next();
581  }
582 
583  msg.Printf( wxT( "%d" ), nbpad );
584  aList.push_back( MSG_PANEL_ITEM( _( "Pads" ), msg, BLUE ) );
585 
586  msg = wxT( ".." );
587 
588  if( IsLocked() )
589  msg[0] = 'L';
590 
592  msg[1] = 'P';
593 
594  aList.push_back( MSG_PANEL_ITEM( _( "Status" ), msg, MAGENTA ) );
595 
596  msg.Printf( wxT( "%.1f" ), GetOrientationDegrees() );
597  aList.push_back( MSG_PANEL_ITEM( _( "Rotation" ), msg, BROWN ) );
598 
599  // Controls on right side of the dialog
600  switch( m_Attributs & 255 )
601  {
602  case 0:
603  msg = _( "Normal" );
604  break;
605 
606  case MOD_CMS:
607  msg = _( "Insert" );
608  break;
609 
610  case MOD_VIRTUAL:
611  msg = _( "Virtual" );
612  break;
613 
614  default:
615  msg = wxT( "???" );
616  break;
617  }
618 
619  aList.push_back( MSG_PANEL_ITEM( _( "Attributes" ), msg, BROWN ) );
620  aList.push_back( MSG_PANEL_ITEM( _( "Footprint" ), FROM_UTF8( m_fpid.Format().c_str() ), BLUE ) );
621 
622  if( m_3D_Drawings.empty() )
623  msg = _( "No 3D shape" );
624  else
625  msg = m_3D_Drawings.front().m_Filename;
626 
627  // Search the first active 3D shape in list
628 
629  aList.push_back( MSG_PANEL_ITEM( _( "3D-Shape" ), msg, RED ) );
630 
631  wxString doc, keyword;
632  doc.Printf( _( "Doc: %s" ), GetChars( m_Doc ) );
633  keyword.Printf( _( "Key Words: %s" ), GetChars( m_KeyWord ) );
634  aList.push_back( MSG_PANEL_ITEM( doc, keyword, BLACK ) );
635 }
636 
637 
638 bool MODULE::HitTest( const wxPoint& aPosition ) const
639 {
640  return m_BoundaryBox.Contains( aPosition );
641 }
642 
643 
644 bool MODULE::HitTestAccurate( const wxPoint& aPosition ) const
645 {
646  auto shape = GetBoundingPoly();
647  return shape.Contains( aPosition, -1, true );
648 }
649 
650 
651 bool MODULE::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const
652 {
653  EDA_RECT arect = aRect;
654  arect.Inflate( aAccuracy );
655 
656  if( aContained )
657  return arect.Contains( m_BoundaryBox );
658  else
659  {
660  // If the rect does not intersect the bounding box, skip any tests
661  if( !aRect.Intersects( GetBoundingBox() ) )
662  return false;
663 
664  // Determine if any elements in the MODULE intersect the rect
665  for( D_PAD* pad = m_Pads; pad; pad = pad->Next() )
666  {
667  if( pad->HitTest( arect, false, 0 ) )
668  return true;
669  }
670 
671  for( BOARD_ITEM* item = m_Drawings; item; item = item->Next() )
672  {
673  if( item->HitTest( arect, false, 0 ) )
674  return true;
675  }
676 
677  // No items were hit
678  return false;
679  }
680 }
681 
682 
683 D_PAD* MODULE::FindPadByName( const wxString& aPadName ) const
684 {
685  for( D_PAD* pad = m_Pads; pad; pad = pad->Next() )
686  {
687  if( pad->GetName().CmpNoCase( aPadName ) == 0 ) // why case insensitive?
688  return pad;
689  }
690 
691  return NULL;
692 }
693 
694 
695 D_PAD* MODULE::GetPad( const wxPoint& aPosition, LSET aLayerMask )
696 {
697  for( D_PAD* pad = m_Pads; pad; pad = pad->Next() )
698  {
699  // ... and on the correct layer.
700  if( !( pad->GetLayerSet() & aLayerMask ).any() )
701  continue;
702 
703  if( pad->HitTest( aPosition ) )
704  return pad;
705  }
706 
707  return NULL;
708 }
709 
710 
712 {
713  D_PAD* topLeftPad = m_Pads;
714 
715  for( D_PAD* p = m_Pads->Next(); p; p = p->Next() )
716  {
717  wxPoint pnt = p->GetPosition(); // GetPosition() returns the center of the pad
718 
719  if( ( pnt.x < topLeftPad->GetPosition().x ) ||
720  ( ( topLeftPad->GetPosition().x == pnt.x ) &&
721  ( pnt.y < topLeftPad->GetPosition().y ) ) )
722  {
723  topLeftPad = p;
724  }
725  }
726 
727  return topLeftPad;
728 }
729 
730 
731 unsigned MODULE::GetPadCount( INCLUDE_NPTH_T aIncludeNPTH ) const
732 {
733  if( aIncludeNPTH )
734  return m_Pads.GetCount();
735 
736  unsigned cnt = 0;
737 
738  for( D_PAD* pad = m_Pads; pad; pad = pad->Next() )
739  {
740  if( pad->GetAttribute() == PAD_ATTRIB_HOLE_NOT_PLATED )
741  continue;
742 
743  cnt++;
744  }
745 
746  return cnt;
747 }
748 
749 
750 unsigned MODULE::GetUniquePadCount( INCLUDE_NPTH_T aIncludeNPTH ) const
751 {
752  std::set<wxString> usedNames;
753 
754  // Create a set of used pad numbers
755  for( D_PAD* pad = PadsList(); pad; pad = pad->Next() )
756  {
757  // Skip pads not on copper layers (used to build complex
758  // solder paste shapes for instance)
759  if( ( pad->GetLayerSet() & LSET::AllCuMask() ).none() )
760  continue;
761 
762  // Skip pads with no name, because they are usually "mechanical"
763  // pads, not "electrical" pads
764  if( pad->GetName().IsEmpty() )
765  continue;
766 
767  if( !aIncludeNPTH )
768  {
769  // skip NPTH
770  if( pad->GetAttribute() == PAD_ATTRIB_HOLE_NOT_PLATED )
771  {
772  continue;
773  }
774  }
775 
776  usedNames.insert( pad->GetName() );
777  }
778 
779  return usedNames.size();
780 }
781 
782 
784 {
785  if( NULL == a3DModel )
786  return;
787 
788  if( !a3DModel->m_Filename.empty() )
789  m_3D_Drawings.push_back( *a3DModel );
790 
791  delete a3DModel;
792 }
793 
794 
795 // see class_module.h
796 SEARCH_RESULT MODULE::Visit( INSPECTOR inspector, void* testData, const KICAD_T scanTypes[] )
797 {
798  KICAD_T stype;
800  const KICAD_T* p = scanTypes;
801  bool done = false;
802 
803 #if 0 && defined(DEBUG)
804  std::cout << GetClass().mb_str() << ' ';
805 #endif
806 
807  while( !done )
808  {
809  stype = *p;
810 
811  switch( stype )
812  {
813  case PCB_MODULE_T:
814  result = inspector( this, testData ); // inspect me
815  ++p;
816  break;
817 
818  case PCB_PAD_T:
819  result = IterateForward( m_Pads, inspector, testData, p );
820  ++p;
821  break;
822 
823  case PCB_MODULE_TEXT_T:
824  result = inspector( m_Reference, testData );
825 
826  if( result == SEARCH_QUIT )
827  break;
828 
829  result = inspector( m_Value, testData );
830 
831  if( result == SEARCH_QUIT )
832  break;
833 
834  // m_Drawings can hold TYPETEXTMODULE also, so fall thru
835 
836  case PCB_MODULE_EDGE_T:
837  result = IterateForward( m_Drawings, inspector, testData, p );
838 
839  // skip over any types handled in the above call.
840  for( ; ; )
841  {
842  switch( stype = *++p )
843  {
844  case PCB_MODULE_TEXT_T:
845  case PCB_MODULE_EDGE_T:
846  continue;
847 
848  default:
849  ;
850  }
851 
852  break;
853  }
854 
855  break;
856 
857  default:
858  done = true;
859  break;
860  }
861 
862  if( result == SEARCH_QUIT )
863  break;
864  }
865 
866  return result;
867 }
868 
869 
871 {
872  wxString text;
873  text.Printf( _( "Footprint %s on %s" ),
874  GetChars ( GetReference() ),
875  GetChars ( GetLayerName() ) );
876 
877  return text;
878 }
879 
880 
882 {
883  return module_xpm;
884 }
885 
886 
888 {
889  return new MODULE( *this );
890 }
891 
892 
893 void MODULE::RunOnChildren( const std::function<void (BOARD_ITEM*)>& aFunction )
894 {
895  try
896  {
897  for( D_PAD* pad = m_Pads; pad; pad = pad->Next() )
898  aFunction( static_cast<BOARD_ITEM*>( pad ) );
899 
900  for( BOARD_ITEM* drawing = m_Drawings; drawing; drawing = drawing->Next() )
901  aFunction( drawing );
902 
903  aFunction( static_cast<BOARD_ITEM*>( m_Reference ) );
904  aFunction( static_cast<BOARD_ITEM*>( m_Value ) );
905  }
906  catch( std::bad_function_call& )
907  {
908  DisplayError( NULL, wxT( "Error running MODULE::RunOnChildren" ) );
909  }
910 }
911 
912 
913 void MODULE::GetAllDrawingLayers( int aLayers[], int& aCount, bool aIncludePads ) const
914 {
915  std::unordered_set<int> layers;
916 
917  for( BOARD_ITEM* item = m_Drawings; item; item = item->Next() )
918  {
919  layers.insert( static_cast<int>( item->GetLayer() ) );
920  }
921 
922  if( aIncludePads )
923  {
924  for( D_PAD* pad = m_Pads; pad; pad = pad->Next() )
925  {
926  int pad_layers[KIGFX::VIEW::VIEW_MAX_LAYERS], pad_layers_count;
927  pad->ViewGetLayers( pad_layers, pad_layers_count );
928 
929  for( int i = 0; i < pad_layers_count; i++ )
930  layers.insert( pad_layers[i] );
931  }
932  }
933 
934  aCount = layers.size();
935  int i = 0;
936 
937  for( auto layer : layers )
938  aLayers[i++] = layer;
939 }
940 
941 
942 void MODULE::ViewGetLayers( int aLayers[], int& aCount ) const
943 {
944  aCount = 2;
945  aLayers[0] = LAYER_ANCHOR;
946 
947  switch( m_Layer )
948  {
949 
950  default:
951  wxASSERT_MSG( false, "Illegal layer" ); // do you really have modules placed on other layers?
952  // pass through
953  case F_Cu:
954  aLayers[1] = LAYER_MOD_FR;
955  break;
956 
957  case B_Cu:
958  aLayers[1] = LAYER_MOD_BK;
959  break;
960  }
961 
962  // If there are no pads, and only drawings on a silkscreen layer, then
963  // report the silkscreen layer as well so that the component can be edited
964  // with the silkscreen layer
965  bool f_silk = false, b_silk = false, non_silk = false;
966 
967  for( BOARD_ITEM* item = m_Drawings; item; item = item->Next() )
968  {
969  if( item->GetLayer() == F_SilkS )
970  f_silk = true;
971  else if( item->GetLayer() == B_SilkS )
972  b_silk = true;
973  else
974  non_silk = true;
975  }
976 
977  if( ( f_silk || b_silk ) && !non_silk && m_Pads.GetCount() == 0 )
978  {
979  if( f_silk )
980  aLayers[ aCount++ ] = F_SilkS;
981 
982  if( b_silk )
983  aLayers[ aCount++ ] = B_SilkS;
984  }
985 }
986 
987 
988 unsigned int MODULE::ViewGetLOD( int aLayer, KIGFX::VIEW* aView ) const
989 {
990  int layer = ( m_Layer == F_Cu ) ? LAYER_MOD_FR :
992 
993  // Currently it is only for anchor layer
994  if( aView->IsLayerVisible( layer ) )
995  return 30;
996 
998 }
999 
1000 
1002 {
1003  EDA_RECT area = GetFootprintRect();
1004 
1005  // Calculate extended area including text fields
1006  area.Merge( m_Reference->GetBoundingBox() );
1007  area.Merge( m_Value->GetBoundingBox() );
1008 
1009  // Add the Clearance shape size: (shape around the pads when the
1010  // clearance is shown. Not optimized, but the draw cost is small
1011  // (perhaps smaller than optimization).
1012  BOARD* board = GetBoard();
1013  if( board )
1014  {
1015  int biggest_clearance = board->GetDesignSettings().GetBiggestClearanceValue();
1016  area.Inflate( biggest_clearance );
1017  }
1018 
1019 
1020  return BOX2I( area );
1021 }
1022 
1023 
1024 bool MODULE::IsLibNameValid( const wxString & aName )
1025 {
1026  const wxChar * invalids = StringLibNameInvalidChars( false );
1027 
1028  if( aName.find_first_of( invalids ) != std::string::npos )
1029  return false;
1030 
1031  return true;
1032 }
1033 
1034 
1035 const wxChar* MODULE::StringLibNameInvalidChars( bool aUserReadable )
1036 {
1037  static const wxChar invalidChars[] = wxT("%$\t\n\r \"\\/:");
1038  static const wxChar invalidCharsReadable[] = wxT("% $ 'tab' 'return' 'line feed' 'space' \\ \" / :");
1039 
1040  if( aUserReadable )
1041  return invalidCharsReadable;
1042  else
1043  return invalidChars;
1044 }
1045 
1046 
1047 void MODULE::Move( const wxPoint& aMoveVector )
1048 {
1049  wxPoint newpos = m_Pos + aMoveVector;
1050  SetPosition( newpos );
1051 }
1052 
1053 
1054 void MODULE::Rotate( const wxPoint& aRotCentre, double aAngle )
1055 {
1056  wxPoint newpos = m_Pos;
1057  RotatePoint( &newpos, aRotCentre, aAngle );
1058  SetPosition( newpos );
1059  SetOrientation( GetOrientation() + aAngle );
1060 }
1061 
1062 
1063 void MODULE::Flip( const wxPoint& aCentre )
1064 {
1065  // Move module to its final position:
1066  wxPoint finalPos = m_Pos;
1067  MIRROR( finalPos.y, aCentre.y );
1068  SetPosition( finalPos );
1069 
1070  // Flip layer
1071  SetLayer( FlipLayer( GetLayer() ) );
1072 
1073  // Reverse mirror orientation.
1074  m_Orient = -m_Orient;
1076 
1077  // Mirror pads to other side of board about the x axis, i.e. vertically.
1078  for( D_PAD* pad = m_Pads; pad; pad = pad->Next() )
1079  pad->Flip( m_Pos );
1080 
1081  // Mirror reference and value.
1082  m_Reference->Flip( m_Pos );
1083  m_Value->Flip( m_Pos );
1084 
1085  // Reverse mirror module graphics and texts.
1086  for( EDA_ITEM* item = m_Drawings; item; item = item->Next() )
1087  {
1088  switch( item->Type() )
1089  {
1090  case PCB_MODULE_EDGE_T:
1091  ( (EDGE_MODULE*) item )->Flip( m_Pos );
1092  break;
1093 
1094  case PCB_MODULE_TEXT_T:
1095  static_cast<TEXTE_MODULE*>( item )->Flip( m_Pos );
1096  break;
1097 
1098  default:
1099  wxMessageBox( wxT( "MODULE::Flip() error: Unknown Draw Type" ) );
1100  break;
1101  }
1102  }
1103 
1105 }
1106 
1107 
1108 void MODULE::SetPosition( const wxPoint& newpos )
1109 {
1110  wxPoint delta = newpos - m_Pos;
1111 
1112  m_Pos += delta;
1113 
1114  m_Reference->EDA_TEXT::Offset( delta );
1115  m_Value->EDA_TEXT::Offset( delta );
1116 
1117  for( D_PAD* pad = m_Pads; pad; pad = pad->Next() )
1118  {
1119  pad->SetPosition( pad->GetPosition() + delta );
1120  }
1121 
1122  for( EDA_ITEM* item = m_Drawings; item; item = item->Next() )
1123  {
1124  switch( item->Type() )
1125  {
1126  case PCB_MODULE_EDGE_T:
1127  {
1128  EDGE_MODULE* pt_edgmod = (EDGE_MODULE*) item;
1129  pt_edgmod->SetDrawCoord();
1130  break;
1131  }
1132 
1133  case PCB_MODULE_TEXT_T:
1134  {
1135  TEXTE_MODULE* text = static_cast<TEXTE_MODULE*>( item );
1136  text->EDA_TEXT::Offset( delta );
1137  break;
1138  }
1139 
1140  default:
1141  wxMessageBox( wxT( "Draw type undefined." ) );
1142  break;
1143  }
1144  }
1145 
1147 }
1148 
1149 
1150 void MODULE::MoveAnchorPosition( const wxPoint& aMoveVector )
1151 {
1152  /* Move the reference point of the footprint
1153  * the footprints elements (pads, outlines, edges .. ) are moved
1154  * but:
1155  * - the footprint position is not modified.
1156  * - the relative (local) coordinates of these items are modified
1157  * - Draw coordinates are updated
1158  */
1159 
1160 
1161  // Update (move) the relative coordinates relative to the new anchor point.
1162  wxPoint moveVector = aMoveVector;
1163  RotatePoint( &moveVector, -GetOrientation() );
1164 
1165  // Update of the reference and value.
1166  m_Reference->SetPos0( m_Reference->GetPos0() + moveVector );
1168  m_Value->SetPos0( m_Value->GetPos0() + moveVector );
1169  m_Value->SetDrawCoord();
1170 
1171  // Update the pad local coordinates.
1172  for( D_PAD* pad = PadsList(); pad; pad = pad->Next() )
1173  {
1174  pad->SetPos0( pad->GetPos0() + moveVector );
1175  pad->SetDrawCoord();
1176  }
1177 
1178  // Update the draw element coordinates.
1179  for( EDA_ITEM* item = GraphicalItemsList(); item; item = item->Next() )
1180  {
1181  switch( item->Type() )
1182  {
1183  case PCB_MODULE_EDGE_T:
1184  {
1185  EDGE_MODULE* edge = static_cast<EDGE_MODULE*>( item );
1186 
1187  // Polygonal shape coordinates are specific:
1188  // m_Start0 and m_End0 have no meaning. So we have to move corner positions
1189  if( edge->GetShape() == S_POLYGON )
1190  {
1191  for( auto iter = edge->GetPolyShape().Iterate(); iter; iter++ )
1192  {
1193  (*iter) += VECTOR2I( moveVector );
1194  }
1195  }
1196  else
1197  {
1198  edge->m_Start0 += moveVector;
1199  edge->m_End0 += moveVector;
1200  edge->SetDrawCoord();
1201  }
1202  break;
1203  }
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  break;
1211  }
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 )
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 // Calculate the area of aPolySet, after fracturation, because
1366 // polygons with no hole are expected.
1367 static double polygonArea( SHAPE_POLY_SET& aPolySet )
1368 {
1369  double area = 0.0;
1370  for( int ii = 0; ii < aPolySet.OutlineCount(); ii++ )
1371  {
1372  SHAPE_LINE_CHAIN& outline = aPolySet.Outline( ii );
1373  // Ensure the curr outline is closed, to calculate area
1374  outline.SetClosed( true );
1375 
1376  area += outline.Area();
1377  }
1378 
1379  return area;
1380 }
1381 
1382 // a helper function to add a rectangular polygon aRect to aPolySet
1383 static void addRect( SHAPE_POLY_SET& aPolySet, wxRect aRect )
1384 {
1385  aPolySet.NewOutline();
1386 
1387  aPolySet.Append( aRect.GetX(), aRect.GetY() );
1388  aPolySet.Append( aRect.GetX()+aRect.width, aRect.GetY() );
1389  aPolySet.Append( aRect.GetX()+aRect.width, aRect.GetY()+aRect.height );
1390  aPolySet.Append( aRect.GetX(), aRect.GetY()+aRect.height );
1391 }
1392 
1393 double MODULE::CoverageRatio( const GENERAL_COLLECTOR& aCollector ) const
1394 {
1395  double moduleArea = GetFootprintRect().GetArea();
1396  SHAPE_POLY_SET coveredRegion;
1397  addRect( coveredRegion, GetFootprintRect() );
1398 
1399  // build list of holes (covered areas not available for selection)
1400  SHAPE_POLY_SET holes;
1401 
1402  for( D_PAD* pad = m_Pads; pad; pad = pad->Next() )
1403  addRect( holes, pad->GetBoundingBox() );
1404 
1405  addRect( holes, m_Reference->GetBoundingBox() );
1406  addRect( holes, m_Value->GetBoundingBox() );
1407 
1408  for( int i = 0; i < aCollector.GetCount(); ++i )
1409  {
1410  BOARD_ITEM* item = aCollector[i];
1411 
1412  switch( item->Type() )
1413  {
1414  case PCB_TEXT_T:
1415  case PCB_MODULE_TEXT_T:
1416  case PCB_TRACE_T:
1417  case PCB_VIA_T:
1418  addRect( holes, item->GetBoundingBox() );
1419  break;
1420  default:
1421  break;
1422  }
1423  }
1424 
1425  SHAPE_POLY_SET uncoveredRegion;
1426  uncoveredRegion.BooleanSubtract( coveredRegion, holes, SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
1427  uncoveredRegion.Simplify( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
1428  uncoveredRegion.Fracture( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
1429 
1430  double uncoveredRegionArea = polygonArea( uncoveredRegion );
1431  double coveredArea = moduleArea - uncoveredRegionArea;
1432  double ratio = ( coveredArea / moduleArea );
1433 
1434  return std::min( ratio, 1.0 );
1435 }
1436 
1437 
1438 // see convert_drawsegment_list_to_polygon.cpp:
1439 extern bool ConvertOutlineToPolygon( std::vector<DRAWSEGMENT*>& aSegList, SHAPE_POLY_SET& aPolygons,
1440  wxString* aErrorText, unsigned int aTolerance );
1441 
1443 {
1446  // Build the courtyard area from graphic items on the courtyard.
1447  // Only PCB_MODULE_EDGE_T have meaning, graphic texts are ignored.
1448  // Collect items:
1449  std::vector< DRAWSEGMENT* > list_front;
1450  std::vector< DRAWSEGMENT* > list_back;
1451 
1452  for( BOARD_ITEM* item = GraphicalItemsList(); item; item = item->Next() )
1453  {
1454  if( item->GetLayer() == B_CrtYd && item->Type() == PCB_MODULE_EDGE_T )
1455  list_back.push_back( static_cast< DRAWSEGMENT* > ( item ) );
1456 
1457  if( item->GetLayer() == F_CrtYd && item->Type() == PCB_MODULE_EDGE_T )
1458  list_front.push_back( static_cast< DRAWSEGMENT* > ( item ) );
1459  }
1460 
1461  // Note: if no item found on courtyard layers, return true.
1462  // false is returned only when the shape defined on courtyard layers
1463  // is not convertible to a polygon
1464  if( !list_front.size() && !list_back.size() )
1465  return true;
1466 
1467  wxString error_msg;
1468 
1469  bool success = ConvertOutlineToPolygon( list_front, m_poly_courtyard_front,
1470  &error_msg, Millimeter2iu( 0.05 ) );
1471 
1472  if( success )
1473  {
1474  success = ConvertOutlineToPolygon( list_back, m_poly_courtyard_back,
1475  &error_msg, Millimeter2iu( 0.05 ) );
1476  }
1477 
1478  if( !error_msg.IsEmpty() )
1479  {
1480  error_msg.Prepend( GetReference() + ": " );
1481  wxLogMessage( error_msg );
1482  }
1483 
1484  return success;
1485 }
1486 
1488 {
1489  assert( aImage->Type() == PCB_MODULE_T );
1490 
1491  std::swap( *((MODULE*) this), *((MODULE*) aImage) );
1492 }
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
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
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
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:44
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
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: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:535
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...
const EDA_RECT GetBoundingBox() const override
Function GetBoundingBox returns the orthogonal, bounding box of this object for display purposes...
EDA_ITEM * Clone() const override
Function Clone creates a duplicate of this item with linked list members set to NULL.
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
Class PCB_EDIT_FRAME is the main frame for Pcbnew.
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