KiCad PCB EDA Suite
pcb.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) 2007, 2008 Lubo Racko <developer@lura.sk>
5  * Copyright (C) 2007, 2008, 2012-2013 Alexander Lunev <al.lunev@yahoo.com>
6  * Copyright (C) 2012-2020 KiCad Developers, see CHANGELOG.TXT for contributors.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, you may find one here:
20  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
21  * or you may search the http://www.gnu.org website for the version 2 license,
22  * or you may write to the Free Software Foundation, Inc.,
23  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24  */
25 
30 #include <wx/wx.h>
31 
32 #include <common.h>
33 
34 #include <pcb.h>
35 #include <pcb_keepout.h>
36 #include <pcb_footprint.h>
37 #include <pcb_pad.h>
38 #include <pcb_text.h>
39 #include <pcb_via.h>
40 #include <s_expr_loader.h>
41 
42 namespace PCAD2KICAD {
43 
44 PCB_LAYER_ID PCB::GetKiCadLayer( int aPCadLayer ) const
45 {
46  auto it = m_LayersMap.find( aPCadLayer );
47 
48  if( it == m_LayersMap.end() )
49  THROW_IO_ERROR( wxString::Format( _( "Unknown PCad layer %u" ), unsigned( aPCadLayer ) ) );
50 
51  return it->second.KiCadLayer;
52 }
53 
54 LAYER_TYPE_T PCB::GetLayerType( int aPCadLayer ) const
55 {
56  auto it = m_LayersMap.find( aPCadLayer );
57 
58  if( it == m_LayersMap.end() )
59  THROW_IO_ERROR( wxString::Format( _( "Unknown PCad layer %u" ), unsigned( aPCadLayer ) ) );
60 
61  return it->second.layerType;
62 }
63 
64 wxString PCB::GetLayerNetNameRef( int aPCadLayer ) const
65 {
66  auto it = m_LayersMap.find( aPCadLayer );
67 
68  if( it == m_LayersMap.end() )
69  THROW_IO_ERROR( wxString::Format( _( "Unknown PCad layer %u" ), unsigned( aPCadLayer ) ) );
70 
71  return it->second.netNameRef;
72 }
73 
74 PCB::PCB( BOARD* aBoard ) :
75  PCB_FOOTPRINT( this, aBoard )
76 {
77  m_DefaultMeasurementUnit = wxT( "mil" );
78 
79  for( size_t i = 0; i < 8; ++i )
80  {
81  TLAYER layer;
82  layer.KiCadLayer = F_Mask; // default
83  layer.layerType = LAYER_TYPE_NONSIGNAL; // default
84  layer.netNameRef = wxT( "" ); // default
85 
86  m_LayersMap.insert( std::make_pair( i, layer ) );
87  }
88 
89  m_SizeX = 0;
90  m_SizeY = 0;
91 
92  m_LayersMap[1].KiCadLayer = F_Cu;
93  m_LayersMap[1].layerType = LAYER_TYPE_SIGNAL;
94 
95  m_LayersMap[2].KiCadLayer = B_Cu;
96  m_LayersMap[2].layerType = LAYER_TYPE_SIGNAL;
97 
98  m_LayersMap[3].KiCadLayer = Eco2_User;
99  m_LayersMap[6].KiCadLayer = F_SilkS;
100  m_LayersMap[7].KiCadLayer = B_SilkS;
101 }
102 
103 
105 {
106  int i;
107 
108  for( i = 0; i < (int) m_PcbComponents.GetCount(); i++ )
109  {
110  delete m_PcbComponents[i];
111  }
112 
113  for( i = 0; i < (int) m_PcbNetlist.GetCount(); i++ )
114  {
115  delete m_PcbNetlist[i];
116  }
117 }
118 
119 
120 int PCB::GetNetCode( const wxString& aNetName ) const
121 {
122  const PCB_NET* net;
123 
124  for( int i = 0; i < (int) m_PcbNetlist.GetCount(); i++ )
125  {
126  net = m_PcbNetlist[i];
127 
128  if( net->m_Name == aNetName )
129  {
130  return net->m_NetCode;
131  }
132  }
133 
134  return 0;
135 }
136 
137 XNODE* PCB::FindCompDefName( XNODE* aNode, const wxString& aName ) const
138 {
139  XNODE* result = NULL, * lNode;
140  wxString propValue;
141 
142  lNode = FindNode( aNode, wxT( "compDef" ) );
143 
144  while( lNode )
145  {
146  if( lNode->GetName() == wxT( "compDef" ) )
147  {
148  lNode->GetAttribute( wxT( "Name" ), &propValue );
149 
150  if( propValue == aName )
151  {
152  result = lNode;
153  lNode = NULL;
154  }
155  }
156 
157  if( lNode )
158  lNode = lNode->GetNext();
159  }
160 
161  return result;
162 }
163 
164 
165 void PCB::SetTextProperty( XNODE* aNode, TTEXTVALUE* aTextValue,
166  const wxString& aPatGraphRefName,
167  const wxString& aXmlName,
168  const wxString& aActualConversion )
169 {
170  XNODE* tNode, * t1Node;
171  wxString n, nnew, pn, propValue, str;
172 
173  // aNode is pattern now
174  tNode = aNode;
175  t1Node = aNode;
176  n = aXmlName;
177 
178  // new file format version
179  if( FindNode( tNode, wxT( "patternGraphicsNameRef" ) ) )
180  {
181  FindNode( tNode,
182  wxT( "patternGraphicsNameRef" ) )->GetAttribute( wxT( "Name" ),
183  &pn );
184  pn.Trim( false );
185  pn.Trim( true );
186  tNode = FindNode( tNode, wxT( "patternGraphicsRef" ) );
187 
188  while( tNode )
189  {
190  if( tNode->GetName() == wxT( "patternGraphicsRef" ) )
191  {
192  if( FindNode( tNode, wxT( "patternGraphicsNameRef" ) ) )
193  {
194  FindNode( tNode,
195  wxT( "patternGraphicsNameRef" ) )->GetAttribute( wxT( "Name" ),
196  &propValue );
197 
198  if( propValue == pn )
199  {
200  t1Node = tNode; // find correct section with same name.
201  str = aTextValue->text;
202  str.Trim( false );
203  str.Trim( true );
204  nnew = n; // new file version
205  n = n + wxT( ' ' ) + str; // old file version
206  tNode = NULL;
207  }
208  }
209  }
210 
211  if( tNode )
212  tNode = tNode->GetNext();
213  }
214  }
215 
216  // old version and compatibile fr both from this point
217  tNode = FindNode( t1Node, wxT( "attr" ) );
218 
219  while( tNode )
220  {
221  tNode->GetAttribute( wxT( "Name" ), &propValue );
222  propValue.Trim( false );
223  propValue.Trim( true );
224 
225  if( propValue == n || propValue == nnew )
226  break;
227 
228  tNode = tNode->GetNext();
229  }
230 
231  if( tNode )
232  SetTextParameters( tNode, aTextValue, m_DefaultMeasurementUnit, aActualConversion );
233 }
234 
235 
237  wxXmlDocument* aXmlDoc,
238  const wxString& aActualConversion,
239  wxStatusBar* aStatusBar )
240 {
241  XNODE* lNode, * tNode, * mNode;
242  PCB_FOOTPRINT* fp;
243  PCB_PAD* pad;
244  PCB_VIA* via;
245  PCB_KEEPOUT* keepOut;
246  wxString cn, str, propValue;
247 
248  lNode = aNode->GetChildren();
249 
250  while( lNode )
251  {
252  fp = NULL;
253 
254  if( lNode->GetName() == wxT( "pattern" ) )
255  {
256  FindNode( lNode, wxT( "patternRef" ) )->GetAttribute( wxT( "Name" ),
257  &cn );
258  cn = ValidateName( cn );
259  tNode = FindNode( (XNODE *)aXmlDoc->GetRoot(), wxT( "library" ) );
260 
261  if( tNode && cn.Len() > 0 )
262  {
263  tNode = FindModulePatternDefName( tNode, cn );
264 
265  if( tNode )
266  {
267  fp = new PCB_FOOTPRINT( this, m_board );
268 
269  mNode = FindNode( lNode, wxT( "patternGraphicsNameRef" ) );
270  if( mNode )
271  mNode->GetAttribute( wxT( "Name" ), &fp->m_patGraphRefName );
272 
273  fp->Parse( tNode, aStatusBar, m_DefaultMeasurementUnit, aActualConversion );
274  }
275  }
276 
277  if( fp )
278  {
279  fp->m_compRef = cn; // default - in new version of file it is updated later....
280  tNode = FindNode( lNode, wxT( "refDesRef" ) );
281 
282  if( tNode )
283  {
284  tNode->GetAttribute( wxT( "Name" ), &fp->m_name.text );
285  SetTextProperty( lNode, &fp->m_name, fp->m_patGraphRefName, wxT( "RefDes" ),
286  aActualConversion );
287  SetTextProperty( lNode, &fp->m_Value, fp->m_patGraphRefName, wxT( "Value" ),
288  aActualConversion );
289  }
290 
291  tNode = FindNode( lNode, wxT( "pt" ) );
292 
293  if( tNode )
294  {
295  SetPosition( tNode->GetNodeContent(), m_DefaultMeasurementUnit,
296  &fp->m_positionX, &fp->m_positionY, aActualConversion );
297  }
298 
299  tNode = FindNode( lNode, wxT( "rotation" ) );
300 
301  if( tNode )
302  {
303  str = tNode->GetNodeContent();
304  str.Trim( false );
305  fp->m_rotation = StrToInt1Units( str );
306  }
307 
308  str = FindNodeGetContent( lNode, wxT( "isFlipped" ) );
309 
310  if( str == wxT( "True" ) )
311  fp->m_Mirror = 1;
312 
313  tNode = aNode;
314 
315  while( tNode->GetName() != wxT( "www.lura.sk" ) )
316  tNode = tNode->GetParent();
317 
318  tNode = FindNode( tNode, wxT( "netlist" ) );
319 
320  if( tNode )
321  {
322  tNode = FindNode( tNode, wxT( "compInst" ) );
323 
324  while( tNode )
325  {
326  tNode->GetAttribute( wxT( "Name" ), &propValue );
327 
328  if( propValue == fp->m_name.text )
329  {
330  if( FindNode( tNode, wxT( "compValue" ) ) )
331  {
332  FindNode( tNode,
333  wxT( "compValue" ) )->GetAttribute( wxT( "Name" ),
334  &fp->m_Value.text );
335  fp->m_Value.text.Trim( false );
336  fp->m_Value.text.Trim( true );
337  }
338 
339  if( FindNode( tNode, wxT( "compRef" ) ) )
340  {
341  FindNode( tNode,
342  wxT( "compRef" ) )->GetAttribute( wxT( "Name" ),
343  &fp->m_compRef );
344  fp->m_compRef.Trim( false );
345  fp->m_compRef.Trim( true );
346  }
347 
348  tNode = NULL;
349  }
350  else
351  tNode = tNode->GetNext();
352  }
353  }
354 
355  // map pins
356  tNode = FindNode( (XNODE *)aXmlDoc->GetRoot(), wxT( "library" ) );
357  tNode = FindCompDefName( tNode, fp->m_compRef );
358 
359  if( tNode )
360  {
361  tNode = FindPinMap( tNode );
362 
363  if( tNode )
364  {
365  mNode = tNode->GetChildren();
366 
367  while( mNode )
368  {
369  if( mNode->GetName() == wxT( "padNum" ) )
370  {
371  str = mNode->GetNodeContent();
372  mNode = mNode->GetNext();
373 
374  if( !mNode )
375  break;
376 
377  mNode->GetAttribute( wxT( "Name" ), &propValue );
378  fp->SetName( str, propValue );
379  mNode = mNode->GetNext();
380  }
381  else
382  {
383  mNode = mNode->GetNext();
384 
385  if( !mNode )
386  break;
387 
388  mNode = mNode->GetNext();
389  }
390  }
391  }
392  }
393 
394  m_PcbComponents.Add( fp );
395  }
396  }
397  else if( lNode->GetName() == wxT( "pad" ) )
398  {
399  pad = new PCB_PAD( this, m_board );
400  pad->Parse( lNode, m_DefaultMeasurementUnit, aActualConversion );
401  m_PcbComponents.Add( pad );
402  }
403  else if( lNode->GetName() == wxT( "via" ) )
404  {
405  via = new PCB_VIA( this, m_board );
406  via->Parse( lNode, m_DefaultMeasurementUnit, aActualConversion );
407  m_PcbComponents.Add( via );
408  }
409  else if( lNode->GetName() == wxT( "polyKeepOut" ) )
410  {
411  keepOut = new PCB_KEEPOUT( m_callbacks, m_board, 0 );
412 
413  if( keepOut->Parse( lNode, m_DefaultMeasurementUnit, aActualConversion ) )
414  m_PcbComponents.Add( keepOut );
415  else
416  delete keepOut;
417  }
418 
419  lNode = lNode->GetNext();
420  }
421 }
422 
423 
424 void PCB::ConnectPinToNet( const wxString& aCompRef, const wxString& aPinRef,
425  const wxString& aNetName )
426 {
427  PCB_FOOTPRINT* footprint;
428  PCB_PAD* cp;
429  int i, j;
430 
431  for( i = 0; i < (int) m_PcbComponents.GetCount(); i++ )
432  {
433  footprint = (PCB_FOOTPRINT*) m_PcbComponents[i];
434 
435  if( footprint->m_objType == wxT( 'M' ) && footprint->m_name.text == aCompRef )
436  {
437  for( j = 0; j < (int) footprint->m_FootprintItems.GetCount(); j++ )
438  {
439  if( footprint->m_FootprintItems[j]->m_objType == wxT( 'P' ) )
440  {
441  cp = (PCB_PAD*) footprint->m_FootprintItems[j];
442 
443  if( cp->m_name.text == aPinRef )
444  cp->m_net = aNetName;
445  }
446  }
447  }
448  }
449 }
450 
451 
452 int PCB::FindLayer( const wxString& aLayerName ) const
453 {
454  for( LAYER_NUM i = 0; i < (int)m_layersStackup.GetCount(); ++i )
455  {
456  if( m_layersStackup[i] == aLayerName )
457  return i;
458  }
459 
460  return -1;
461 }
462 
463 
464 /* KiCad layers
465  * 0 Copper layer
466  * 1 to 14 Inner layers
467  * 15 Component layer
468  * 16 Copper side adhesive layer Technical layers
469  * 17 Component side adhesive layer
470  * 18 Copper side Solder paste layer
471  * 19 Component Solder paste layer
472  * 20 Copper side Silk screen layer
473  * 21 Component Silk screen layer
474  * 22 Copper side Solder mask layer
475  * 23 Component Solder mask layer
476  * 24 Draw layer (Used for general drawings)
477  * 25 Comment layer (Other layer used for general drawings)
478  * 26 ECO1 layer (Other layer used for general drawings) // BUG
479  * 26 ECO2 layer (Other layer used for general drawings) // BUG 27
480  * 27 Edge layer. Items on Edge layer are seen on all layers // BUG 28
481  */
482 void PCB::MapLayer( XNODE* aNode )
483 {
484  wxString lName, layerType;
485  PCB_LAYER_ID KiCadLayer;
486  long num = 0;
487 
488  aNode->GetAttribute( wxT( "Name" ), &lName );
489  lName = lName.MakeUpper();
490 
491  if( lName == wxT( "TOP ASSY" ) )
492  KiCadLayer = F_Fab;
493  else if( lName == wxT( "TOP SILK" ) )
494  KiCadLayer = F_SilkS;
495  else if( lName == wxT( "TOP PASTE" ) )
496  KiCadLayer = F_Paste;
497  else if( lName == wxT( "TOP MASK" ) )
498  KiCadLayer = F_Mask;
499  else if( lName == wxT( "TOP" ) )
500  KiCadLayer = F_Cu;
501  else if( lName == wxT( "BOTTOM" ) )
502  KiCadLayer = B_Cu;
503  else if( lName == wxT( "BOT MASK" ) )
504  KiCadLayer = B_Mask;
505  else if( lName == wxT( "BOT PASTE" ) )
506  KiCadLayer = B_Paste;
507  else if( lName == wxT( "BOT SILK" ) )
508  KiCadLayer = B_SilkS;
509  else if( lName == wxT( "BOT ASSY" ) )
510  KiCadLayer = B_Fab;
511  else if( lName == wxT( "BOARD" ) )
512  KiCadLayer = Edge_Cuts;
513  else
514  {
515  int layernum = FindLayer( lName );
516 
517  if( layernum == -1 )
518  KiCadLayer = Dwgs_User; // default
519  else
520 #if 0 // was:
521  KiCadLayer = FIRST_COPPER_LAYER + m_layersStackup.GetCount() - 1 - layernum;
522 #else
523  KiCadLayer = ToLAYER_ID( layernum );
524 #endif
525  }
526 
527  if( FindNode( aNode, wxT( "layerNum" ) ) )
528  FindNode( aNode, wxT( "layerNum" ) )->GetNodeContent().ToLong( &num );
529 
530  if( num < 0 )
531  THROW_IO_ERROR( wxString::Format( wxT( "layerNum = %ld is out of range" ), num ) );
532 
533  TLAYER newlayer;
534  newlayer.KiCadLayer = KiCadLayer;
535 
536  if( FindNode( aNode, wxT( "layerType" ) ) )
537  {
538  layerType = FindNode( aNode, wxT( "layerType" ) )->GetNodeContent().Trim( false );
539 
540  if( layerType == wxT( "NonSignal" ) )
541  newlayer.layerType = LAYER_TYPE_NONSIGNAL;
542  if( layerType == wxT( "Signal" ) )
543  newlayer.layerType = LAYER_TYPE_SIGNAL;
544  if( layerType == wxT( "Plane" ) )
545  newlayer.layerType = LAYER_TYPE_PLANE;
546  }
547 
548  m_LayersMap.insert( std::make_pair( num, newlayer ) );
549 
550  if( FindNode( aNode, wxT( "netNameRef" ) ) )
551  {
552  FindNode( aNode, wxT( "netNameRef" ) )->GetAttribute( wxT( "Name" ),
553  &m_LayersMap[(int) num].netNameRef );
554  }
555 }
556 
557 int PCB::FindOutlinePoint( const VERTICES_ARRAY* aOutline, wxRealPoint aPoint ) const
558 {
559  int i;
560 
561  for( i = 0; i < (int) aOutline->GetCount(); i++ )
562  if( *((*aOutline)[i]) == aPoint )
563  return i;
564 
565  return -1;
566 }
567 
568 /*int cmpFunc( wxRealPoint **first, wxRealPoint **second )
569 {
570  return sqrt( pow( (double) aPointA.x - (double) aPointB.x, 2 ) +
571  pow( (double) aPointA.y - (double) aPointB.y, 2 ) );
572 
573  return 0;
574 }*/
575 double PCB::GetDistance( const wxRealPoint* aPoint1, const wxRealPoint* aPoint2 ) const
576 {
577  return sqrt( ( aPoint1->x - aPoint2->x ) *
578  ( aPoint1->x - aPoint2->x ) +
579  ( aPoint1->y - aPoint2->y ) *
580  ( aPoint1->y - aPoint2->y ) );
581 }
582 
583 void PCB::GetBoardOutline( wxXmlDocument* aXmlDoc, const wxString& aActualConversion )
584 {
585  XNODE* iNode, *lNode, *pNode;
586  long PCadLayer = 0;
587  int x, y, i, j, targetInd;
588  wxRealPoint* xchgPoint;
589  double minDistance, distance;
590 
591  iNode = FindNode( (XNODE *)aXmlDoc->GetRoot(), wxT( "pcbDesign" ) );
592 
593  if( iNode )
594  {
595  // COMPONENTS AND OBJECTS
596  iNode = iNode->GetChildren();
597 
598  while( iNode )
599  {
600  // objects
601  if( iNode->GetName() == wxT( "layerContents" ) )
602  {
603  if( FindNode( iNode, wxT( "layerNumRef" ) ) )
604  FindNode( iNode, wxT( "layerNumRef" ) )->GetNodeContent().ToLong( &PCadLayer );
605 
606  if( GetKiCadLayer( PCadLayer ) == Edge_Cuts )
607  {
608  lNode = iNode->GetChildren();
609  while( lNode )
610  {
611  if( lNode->GetName() == wxT( "line" ) )
612  {
613  pNode = FindNode( lNode, wxT( "pt" ) );
614 
615  if( pNode )
616  {
617  SetPosition( pNode->GetNodeContent(), m_DefaultMeasurementUnit,
618  &x, &y, aActualConversion );
619 
620  if( FindOutlinePoint( &m_BoardOutline, wxRealPoint( x, y) ) == -1 )
621  m_BoardOutline.Add( new wxRealPoint( x, y ) );
622  }
623 
624  if( pNode )
625  pNode = pNode->GetNext();
626 
627  if( pNode )
628  {
629  SetPosition( pNode->GetNodeContent(), m_DefaultMeasurementUnit,
630  &x, &y, aActualConversion );
631 
632  if( FindOutlinePoint( &m_BoardOutline, wxRealPoint( x, y) ) == -1 )
633  m_BoardOutline.Add( new wxRealPoint( x, y ) );
634  }
635  }
636 
637  lNode = lNode->GetNext();
638  }
639 
640  //m_boardOutline.Sort( cmpFunc );
641  // sort vertices according to the distances between them
642  if( m_BoardOutline.GetCount() > 3 )
643  {
644  for( i = 0; i < (int) m_BoardOutline.GetCount() - 1; i++ )
645  {
646  minDistance = GetDistance( m_BoardOutline[i], m_BoardOutline[ i + 1] );
647  targetInd = i + 1;
648 
649  for( j = i + 2; j < (int) m_BoardOutline.GetCount(); j++ )
650  {
652  if( distance < minDistance )
653  {
654  minDistance = distance;
655  targetInd = j;
656  }
657  }
658 
659  xchgPoint = m_BoardOutline[ i + 1];
660  m_BoardOutline[ i + 1] = m_BoardOutline[targetInd];
661  m_BoardOutline[targetInd] = xchgPoint;
662  }
663  }
664 
665  break;
666  }
667  }
668 
669  iNode = iNode->GetNext();
670  }
671  }
672 }
673 
674 void PCB::ParseBoard( wxStatusBar* aStatusBar, wxXmlDocument* aXmlDoc, const wxString& aActualConversion )
675 {
676  XNODE* aNode;//, *aaNode;
677  PCB_NET* net;
678  PCB_COMPONENT* comp;
679  PCB_FOOTPRINT* footprint;
680  wxString compRef, pinRef, layerName, layerType;
681  int i, j, netCode;
682 
683  // Defaut measurement units
684  aNode = FindNode( (XNODE *)aXmlDoc->GetRoot(), wxT( "asciiHeader" ) );
685 
686  if( aNode )
687  {
688  aNode = FindNode( aNode, wxT( "fileUnits" ) );
689 
690  if( aNode )
691  {
692  m_DefaultMeasurementUnit = aNode->GetNodeContent().Lower();
693  m_DefaultMeasurementUnit.Trim( true );
694  m_DefaultMeasurementUnit.Trim( false );
695  }
696  }
697 
698  // Determine layers stackup
699  aNode = FindNode( (XNODE *)aXmlDoc->GetRoot(), wxT( "pcbDesign" ) );
700 
701  /*if( aNode )
702  {
703  aNode = FindNode( aNode, wxT( "layersStackup" ) );
704 
705  if( aNode )
706  {
707  aNode = FindNode( aNode, wxT( "layerStackupData" ) );
708 
709  while( aNode )
710  {
711  if( aNode->GetName() == wxT( "layerStackupData" ) )
712  {
713  aaNode = FindNode( aNode, wxT( "layerStackupName" ) );
714 
715  if( aaNode ) {
716  aaNode->GetAttribute( wxT( "Name" ), &layerName );
717  layerName = layerName.MakeUpper();
718  m_layersStackup.Add( layerName );
719  }
720  }
721 
722  aNode = aNode->GetNext();
723  }
724  }
725  }*/
726 
727  if( aNode )
728  {
729  aNode = FindNode( aNode, wxT( "layerDef" ) );
730 
731  while( aNode )
732  {
733  if( aNode->GetName() == wxT( "layerDef" ) )
734  {
735  if( FindNode( aNode, wxT( "layerType" ) ) )
736  {
737  layerType = FindNode( aNode,
738  wxT( "layerType" ) )->GetNodeContent().Trim( false );
739 
740  if( layerType == wxT( "Signal" ) || layerType == wxT( "Plane" ) )
741  {
742  aNode->GetAttribute( wxT( "Name" ), &layerName );
743  layerName = layerName.MakeUpper();
744  m_layersStackup.Add( layerName );
745 
746  if( m_layersStackup.size() > 32 )
747  THROW_IO_ERROR( _( "KiCad only supports 32 signal layers" ) );
748  }
749  }
750  }
751 
752  aNode = aNode->GetNext();
753  }
754  }
755 
756  // Layers mapping
757  aNode = FindNode( (XNODE *)aXmlDoc->GetRoot(), wxT( "pcbDesign" ) );
758 
759  if( aNode )
760  {
761  aNode = FindNode( aNode, wxT( "layerDef" ) );
762 
763  while( aNode )
764  {
765  if( aNode->GetName() == wxT( "layerDef" ) )
766  MapLayer( aNode );
767 
768  aNode = aNode->GetNext();
769  }
770  }
771 
772  GetBoardOutline( aXmlDoc, aActualConversion );
773 
774  // NETLIST
775  // aStatusBar->SetStatusText( wxT( "Loading NETLIST " ) );
776 
777  aNode = FindNode( (XNODE *)aXmlDoc->GetRoot(), wxT( "netlist" ) );
778 
779  if( aNode )
780  {
781  aNode = FindNode( aNode, wxT( "net" ) );
782 
783  netCode = 1;
784 
785  while( aNode )
786  {
787  net = new PCB_NET( netCode++ );
788  net->Parse( aNode );
789  m_PcbNetlist.Add( net );
790 
791  aNode = aNode->GetNext();
792  }
793  }
794 
795  // BOARD FILE
796  // aStatusBar->SetStatusText( wxT( "Loading BOARD DEFINITION " ) );
797 
798  aNode = FindNode( (XNODE *)aXmlDoc->GetRoot(), wxT( "pcbDesign" ) );
799 
800  if( aNode )
801  {
802  // COMPONENTS AND OBJECTS
803  aNode = aNode->GetChildren();
804 
805  while( aNode )
806  {
807  // Components/footprints
808  if( aNode->GetName() == wxT( "multiLayer" ) )
809  DoPCBComponents( aNode, aXmlDoc, aActualConversion, aStatusBar );
810 
811  // objects
812  if( aNode->GetName() == wxT( "layerContents" ) )
813  DoLayerContentsObjects( aNode, NULL, &m_PcbComponents, aStatusBar,
814  m_DefaultMeasurementUnit, aActualConversion );
815 
816  aNode = aNode->GetNext();
817  }
818 
819  // POSTPROCESS -- SET NETLIST REFERENCES
820  // aStatusBar->SetStatusText( wxT( "Processing NETLIST " ) );
821 
822  for( i = 0; i < (int) m_PcbNetlist.GetCount(); i++ )
823  {
824  net = m_PcbNetlist[i];
825 
826  for( j = 0; j < (int) net->m_NetNodes.GetCount(); j++ )
827  {
828  compRef = net->m_NetNodes[j]->m_CompRef;
829  compRef.Trim( false );
830  compRef.Trim( true );
831  pinRef = net->m_NetNodes[j]->m_PinRef;
832  pinRef.Trim( false );
833  pinRef.Trim( true );
834  ConnectPinToNet( compRef, pinRef, net->m_Name );
835  }
836  }
837 
838  // POSTPROCESS -- FLIP COMPONENTS
839  for( i = 0; i < (int) m_PcbComponents.GetCount(); i++ )
840  {
841  if( m_PcbComponents[i]->m_objType == wxT( 'M' ) )
842  ( (PCB_FOOTPRINT*) m_PcbComponents[i] )->Flip();
843  }
844 
845  // POSTPROCESS -- SET/OPTIMIZE NEW PCB POSITION
846  // aStatusBar->SetStatusText( wxT( "Optimizing BOARD POSITION " ) );
847 
848  m_SizeX = 10000000;
849  m_SizeY = 0;
850 
851  for( i = 0; i < (int) m_PcbComponents.GetCount(); i++ )
852  {
853  comp = m_PcbComponents[i];
854 
855  if( comp->m_positionY < m_SizeY )
856  m_SizeY = comp->m_positionY; // max Y
857 
858  if( comp->m_positionX < m_SizeX && comp->m_positionX > 0 )
859  m_SizeX = comp->m_positionX; // Min X
860  }
861 
862  m_SizeY -= 10000;
863  m_SizeX -= 10000;
864  // aStatusBar->SetStatusText( wxT( " POSITIONING POSTPROCESS " ) );
865 
866  for( i = 0; i < (int) m_PcbComponents.GetCount(); i++ )
868 
869  m_SizeX = 0;
870  m_SizeY = 0;
871 
872  for( i = 0; i < (int) m_PcbComponents.GetCount(); i++ )
873  {
874  comp = m_PcbComponents[i];
875 
876  if( comp->m_positionY < m_SizeY )
877  m_SizeY = comp->m_positionY; // max Y
878 
879  if( comp->m_positionX > m_SizeX )
880  m_SizeX = comp->m_positionX; // Min X
881  }
882 
883  // SHEET SIZE CALCULATION
884  m_SizeY = -m_SizeY; // it is in absolute units
885  m_SizeX += 10000;
886  m_SizeY += 10000;
887 
888  // A4 is minimum $Descr A4 11700 8267
889  if( m_SizeX < 11700 )
890  m_SizeX = 11700;
891 
892  if( m_SizeY < 8267 )
893  m_SizeY = 8267;
894  }
895  else
896  {
897  // LIBRARY FILE
898  // aStatusBar->SetStatusText( wxT( "Processing LIBRARY FILE " ) );
899 
900  aNode = FindNode( (XNODE *)aXmlDoc->GetRoot(), wxT( "library" ) );
901 
902  if( aNode )
903  {
904  aNode = FindNode( aNode, wxT( "compDef" ) );
905 
906  while( aNode )
907  {
908  // aStatusBar->SetStatusText( wxT( "Processing COMPONENTS " ) );
909 
910  if( aNode->GetName() == wxT( "compDef" ) )
911  {
912  footprint = new PCB_FOOTPRINT( this, m_board );
913  footprint->Parse( aNode, aStatusBar, m_DefaultMeasurementUnit,
914  aActualConversion );
915  m_PcbComponents.Add( footprint );
916  }
917 
918  aNode = aNode->GetNext();
919  }
920  }
921  }
922 }
923 
924 
926 {
927  int i;
928  PCB_NET* net;
929 
931 
932  for( i = 0; i < (int) m_PcbNetlist.GetCount(); i++ )
933  {
934  net = m_PcbNetlist[i];
935 
936  m_board->Add( new NETINFO_ITEM( m_board, net->m_Name, net->m_NetCode ) );
937  }
938 
939  for( i = 0; i < (int) m_PcbComponents.GetCount(); i++ )
940  {
941  m_PcbComponents[i]->AddToBoard();
942  }
943 }
944 
945 } // namespace PCAD2KICAD
int m_SizeX
Definition: pcb.h:49
int GetNetCode(const wxString &aNetName) const override
Definition: pcb.cpp:120
LAYER_TYPE_T GetLayerType(int aPCadLayer) const override
Definition: pcb.cpp:54
wxString netNameRef
Definition: pcb_callbacks.h:47
void ParseBoard(wxStatusBar *aStatusBar, wxXmlDocument *aXmlDoc, const wxString &aActualConversion)
Definition: pcb.cpp:674
void SetPosition(wxString aStr, const wxString &aDefaultMeasurementUnit, int *aX, int *aY, const wxString &aActualConversion)
virtual void Parse(XNODE *aNode, wxStatusBar *aStatusBar, const wxString &aDefaultMeasurementUnit, const wxString &aActualConversion)
int FindOutlinePoint(const VERTICES_ARRAY *aOutline, wxRealPoint aPoint) const
Definition: pcb.cpp:557
void DoLayerContentsObjects(XNODE *aNode, PCB_FOOTPRINT *aFootprint, PCB_COMPONENTS_ARRAY *aList, wxStatusBar *aStatusBar, const wxString &aDefaultMeasurementUnit, const wxString &aActualConversion)
void SetCopperLayerCount(int aCount)
Definition: board.cpp:441
virtual void Parse(XNODE *aNode, const wxString &aDefaultMeasurementUnit, const wxString &aActualConversion)
Definition: pcb_pad.cpp:57
XNODE * FindModulePatternDefName(XNODE *aNode, const wxString &aName)
PCB_NET_NODES_ARRAY m_NetNodes
Definition: pcb_net.h:56
PCB_COMPONENTS_ARRAY m_PcbComponents
Definition: pcb.h:45
void SetTextProperty(XNODE *aNode, TTEXTVALUE *aTextValue, const wxString &aPatGraphRefName, const wxString &aXmlName, const wxString &aActualConversion)
Definition: pcb.cpp:165
int FindLayer(const wxString &aLayerName) const
Definition: pcb.cpp:452
PCB_NETS_ARRAY m_PcbNetlist
Definition: pcb.h:46
virtual void SetPosOffset(int aX_offs, int aY_offs)
virtual void Flip() override
PCB(BOARD *aBoard)
Definition: pcb.cpp:74
void ConnectPinToNet(const wxString &aCr, const wxString &aPr, const wxString &aNetName)
Definition: pcb.cpp:424
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT) override
Adds an item to the container.
Definition: board.cpp:563
std::map< int, TLAYER > m_LayersMap
Definition: pcb.h:48
wxString ValidateName(wxString aName)
PCB_LAYER_ID
A quick note on layer IDs:
void SetName(const wxString &aPin, const wxString &aName)
void AddToBoard() override
Definition: pcb.cpp:925
wxString m_DefaultMeasurementUnit
Definition: pcb.h:47
XNODE * GetChildren() const
Definition: xnode.h:62
wxArrayString m_layersStackup
Definition: pcb.h:66
#define NULL
void DoPCBComponents(XNODE *aNode, wxXmlDocument *aXmlDoc, const wxString &aActualConversion, wxStatusBar *aStatusBar)
Definition: pcb.cpp:236
XNODE * GetParent() const
Definition: xnode.h:72
wxString FindNodeGetContent(XNODE *aChild, const wxString &aTag)
void SetTextParameters(XNODE *aNode, TTEXTVALUE *aTextValue, const wxString &aDefaultMeasurementUnit, const wxString &aActualConversion)
VERTICES_ARRAY m_BoardOutline
Definition: pcb_footprint.h:42
int m_SizeY
Definition: pcb.h:50
double GetDistance(const wxRealPoint *aPoint1, const wxRealPoint *aPoint2) const
Definition: pcb.cpp:575
XNODE * FindCompDefName(XNODE *aNode, const wxString &aName) const
Definition: pcb.cpp:137
void GetBoardOutline(wxXmlDocument *aXmlDoc, const wxString &aActualConversion)
Definition: pcb.cpp:583
wxString GetLayerNetNameRef(int aPCadLayer) const override
Definition: pcb.cpp:64
static float distance(const SFVEC2UI &a, const SFVEC2UI &b)
PCB_LAYER_ID KiCadLayer
Definition: pcb_callbacks.h:45
int LAYER_NUM
This can be replaced with int and removed.
PCB_LAYER_ID GetKiCadLayer() const
Definition: pcb_component.h:70
virtual bool Parse(XNODE *aNode, const wxString &aDefaultMeasurementUnit, const wxString &aActualConversion) override
Definition: pcb_keepout.cpp:51
Hold an XML or S-expression element.
Definition: xnode.h:43
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
Handle the data for a net.
Definition: netinfo.h:64
PCB_COMPONENTS_ARRAY m_FootprintItems
Definition: pcb_footprint.h:40
XNODE * GetNext() const
Definition: xnode.h:67
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:190
#define _(s)
Definition: 3d_actions.cpp:33
PCB_FOOTPRINT(PCB_CALLBACKS *aCallbacks, BOARD *aBoard)
void MapLayer(XNODE *aNode)
Definition: pcb.cpp:482
XNODE * FindNode(XNODE *aChild, const wxString &aTag)
The common library.
wxString m_Name
Definition: pcb_net.h:54
PCB_CALLBACKS * m_callbacks
Definition: pcb_component.h:74
LAYER_TYPE_T
Definition: pcb_callbacks.h:36
virtual void Parse(XNODE *aNode, const wxString &aDefaultMeasurementUnit, const wxString &aActualConversion) override
Definition: pcb_via.cpp:48
void Parse(XNODE *aNode)
Definition: pcb_net.cpp:65
LAYER_TYPE_T layerType
Definition: pcb_callbacks.h:46
XNODE * FindPinMap(XNODE *aNode)
#define FIRST_COPPER_LAYER
int StrToInt1Units(const wxString &aStr)
#define THROW_IO_ERROR(msg)
Definition: ki_exception.h:38
PCB_LAYER_ID ToLAYER_ID(int aLayer)
Definition: lset.cpp:905