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