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