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