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 <[email protected]>
5 * Copyright (C) 2007, 2008, 2012-2013 Alexander Lunev <[email protected]>
6 * Copyright (C) 2012-2021 KiCad Developers, see AUTHORS.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/string.h>
41
42namespace PCAD2KICAD {
43
44
45PCB_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
56LAYER_TYPE_T PCB::GetLayerType( int aPCadLayer ) const
57{
58 auto it = m_LayersMap.find( aPCadLayer );
59
60 if( it == m_LayersMap.end() )
61 THROW_IO_ERROR( wxString::Format( _( "Unknown PCad layer %u" ), unsigned( aPCadLayer ) ) );
62
63 return it->second.layerType;
64}
65
66
67wxString PCB::GetLayerNetNameRef( int aPCadLayer ) const
68{
69 auto it = m_LayersMap.find( aPCadLayer );
70
71 if( it == m_LayersMap.end() )
72 THROW_IO_ERROR( wxString::Format( _( "Unknown PCad layer %u" ), unsigned( aPCadLayer ) ) );
73
74 return it->second.netNameRef;
75}
76
77
78PCB::PCB( BOARD* aBoard ) :
79 PCB_FOOTPRINT( this, aBoard )
80{
81 m_DefaultMeasurementUnit = wxT( "mil" );
82
83 for( size_t i = 0; i < 8; ++i )
84 {
85 TLAYER layer;
86 layer.KiCadLayer = F_Mask; // default
87 layer.layerType = LAYER_TYPE_NONSIGNAL; // default
88 layer.netNameRef = wxT( "" ); // default
89
90 m_LayersMap.insert( std::make_pair( i, layer ) );
91 }
92
93 m_SizeX = 0;
94 m_SizeY = 0;
95
96 m_LayersMap[1].KiCadLayer = F_Cu;
97 m_LayersMap[1].layerType = LAYER_TYPE_SIGNAL;
98
99 m_LayersMap[2].KiCadLayer = B_Cu;
100 m_LayersMap[2].layerType = LAYER_TYPE_SIGNAL;
101
102 m_LayersMap[3].KiCadLayer = Eco2_User;
103 m_LayersMap[6].KiCadLayer = F_SilkS;
104 m_LayersMap[7].KiCadLayer = B_SilkS;
105}
106
107
109{
110 int i;
111
112 for( i = 0; i < (int) m_PcbComponents.GetCount(); i++ )
113 {
114 delete m_PcbComponents[i];
115 }
116
117 for( i = 0; i < (int) m_PcbNetlist.GetCount(); i++ )
118 {
119 delete m_PcbNetlist[i];
120 }
121}
122
123
124int PCB::GetNetCode( const wxString& aNetName ) const
125{
126 const PCB_NET* net;
127
128 for( int i = 0; i < (int) m_PcbNetlist.GetCount(); i++ )
129 {
130 net = m_PcbNetlist[i];
131
132 if( net->m_Name == aNetName )
133 {
134 return net->m_NetCode;
135 }
136 }
137
138 return 0;
139}
140
141XNODE* PCB::FindCompDefName( XNODE* aNode, const wxString& aName ) const
142{
143 XNODE* result = nullptr, * lNode;
144 wxString propValue;
145
146 lNode = FindNode( aNode, wxT( "compDef" ) );
147
148 while( lNode )
149 {
150 if( lNode->GetName().IsSameAs( wxT( "compDef" ), false ) )
151 {
152 lNode->GetAttribute( wxT( "Name" ), &propValue );
153
154 if( propValue == aName )
155 {
156 result = lNode;
157 lNode = nullptr;
158 }
159 }
160
161 if( lNode )
162 lNode = lNode->GetNext();
163 }
164
165 return result;
166}
167
168
169void PCB::SetTextProperty( XNODE* aNode, TTEXTVALUE* aTextValue, const wxString& aPatGraphRefName,
170 const wxString& aXmlName, const wxString& aActualConversion )
171{
172 XNODE* tNode, * t1Node;
173 wxString n, nnew, pn, propValue, str;
174
175 // aNode is pattern now
176 tNode = aNode;
177 t1Node = aNode;
178 n = aXmlName;
179
180 // new file format version
181 if( FindNode( tNode, wxT( "patternGraphicsNameRef" ) ) )
182 {
183 FindNode( tNode,
184 wxT( "patternGraphicsNameRef" ) )->GetAttribute( wxT( "Name" ),
185 &pn );
186 pn.Trim( false );
187 pn.Trim( true );
188 tNode = FindNode( tNode, wxT( "patternGraphicsRef" ) );
189
190 while( tNode )
191 {
192 if( tNode->GetName().IsSameAs( wxT( "patternGraphicsRef" ), false ) )
193 {
194 if( FindNode( tNode, wxT( "patternGraphicsNameRef" ) ) )
195 {
196 FindNode( tNode,
197 wxT( "patternGraphicsNameRef" ) )->GetAttribute( wxT( "Name" ),
198 &propValue );
199
200 if( propValue == pn )
201 {
202 t1Node = tNode; // find correct section with same name.
203 str = aTextValue->text;
204 str.Trim( false );
205 str.Trim( true );
206 nnew = n; // new file version
207 n = n + wxT( ' ' ) + str; // old file version
208 tNode = nullptr;
209 }
210 }
211 }
212
213 if( tNode )
214 tNode = tNode->GetNext();
215 }
216 }
217
218 // old version and compatible for both from this point
219 tNode = FindNode( t1Node, wxT( "attr" ) );
220
221 while( tNode )
222 {
223 tNode->GetAttribute( wxT( "Name" ), &propValue );
224 propValue.Trim( false );
225 propValue.Trim( true );
226
227 if( propValue == n || propValue == nnew )
228 break;
229
230 tNode = tNode->GetNext();
231 }
232
233 if( tNode )
234 SetTextParameters( tNode, aTextValue, m_DefaultMeasurementUnit, aActualConversion );
235}
236
237
238void PCB::DoPCBComponents( XNODE* aNode, wxXmlDocument* aXmlDoc, 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 = nullptr;
253
254 if( lNode->GetName().IsSameAs( wxT( "pattern" ), false ) )
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
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 );
307 }
308
309 str = FindNodeGetContent( lNode, wxT( "isFlipped" ) );
310
311 if( str.IsSameAs( wxT( "True" ), false ) )
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 = nullptr;
350 }
351 else
352 {
353 tNode = tNode->GetNext();
354 }
355 }
356 }
357
358 // map pins
359 tNode = FindNode( (XNODE *)aXmlDoc->GetRoot(), wxT( "library" ) );
360 tNode = FindCompDefName( tNode, fp->m_compRef );
361
362 if( tNode )
363 {
364 tNode = FindPinMap( tNode );
365
366 if( tNode )
367 {
368 mNode = tNode->GetChildren();
369
370 while( mNode )
371 {
372 if( mNode->GetName().IsSameAs( wxT( "padNum" ), false ) )
373 {
374 str = mNode->GetNodeContent();
375 mNode = mNode->GetNext();
376
377 if( !mNode )
378 break;
379
380 mNode->GetAttribute( wxT( "Name" ), &propValue );
381 fp->SetName( str, propValue );
382 mNode = mNode->GetNext();
383 }
384 else
385 {
386 mNode = mNode->GetNext();
387
388 if( !mNode )
389 break;
390
391 mNode = mNode->GetNext();
392 }
393 }
394 }
395 }
396
397 m_PcbComponents.Add( fp );
398 }
399 }
400 else if( lNode->GetName().IsSameAs( wxT( "pad" ), false ) )
401 {
402 pad = new PCB_PAD( this, m_board );
403 pad->Parse( lNode, m_DefaultMeasurementUnit, aActualConversion );
404 m_PcbComponents.Add( pad );
405 }
406 else if( lNode->GetName().IsSameAs( wxT( "via" ), false ) )
407 {
408 via = new PCB_VIA( this, m_board );
409 via->Parse( lNode, m_DefaultMeasurementUnit, aActualConversion );
410 m_PcbComponents.Add( via );
411 }
412 else if( lNode->GetName().IsSameAs( wxT( "polyKeepOut" ), false ) )
413 {
414 keepOut = new PCB_KEEPOUT( m_callbacks, m_board, 0 );
415
416 if( keepOut->Parse( lNode, m_DefaultMeasurementUnit, aActualConversion ) )
417 m_PcbComponents.Add( keepOut );
418 else
419 delete keepOut;
420 }
421
422 lNode = lNode->GetNext();
423 }
424}
425
426
427void PCB::ConnectPinToNet( const wxString& aCompRef, const wxString& aPinRef,
428 const wxString& aNetName )
429{
430 PCB_FOOTPRINT* footprint;
431 PCB_PAD* cp;
432 int i, j;
433
434 for( i = 0; i < (int) m_PcbComponents.GetCount(); i++ )
435 {
436 footprint = (PCB_FOOTPRINT*) m_PcbComponents[i];
437
438 if( footprint->m_objType == wxT( 'M' ) && footprint->m_name.text == aCompRef )
439 {
440 for( j = 0; j < (int) footprint->m_FootprintItems.GetCount(); j++ )
441 {
442 if( footprint->m_FootprintItems[j]->m_objType == wxT( 'P' ) )
443 {
444 cp = (PCB_PAD*) footprint->m_FootprintItems[j];
445
446 if( cp->m_name.text == aPinRef )
447 cp->m_net = aNetName;
448 }
449 }
450 }
451 }
452}
453
454
455int PCB::FindLayer( const wxString& aLayerName ) const
456{
457 for( int i = 0; i < (int) m_layersStackup.size(); ++i )
458 {
459 if( m_layersStackup[i].first == aLayerName )
460 return i;
461 }
462
463 return -1;
464}
465
466
467void PCB::MapLayer( XNODE* aNode )
468{
469 wxString lName, layerType;
470 PCB_LAYER_ID KiCadLayer;
471 long num = 0;
472
473 aNode->GetAttribute( wxT( "Name" ), &lName );
474 lName = lName.MakeUpper();
475
476 if( lName == wxT( "TOP ASSY" ) )
477 {
478 KiCadLayer = F_Fab;
479 }
480 else if( lName == wxT( "TOP SILK" ) )
481 {
482 KiCadLayer = F_SilkS;
483 }
484 else if( lName == wxT( "TOP PASTE" ) )
485 {
486 KiCadLayer = F_Paste;
487 }
488 else if( lName == wxT( "TOP MASK" ) )
489 {
490 KiCadLayer = F_Mask;
491 }
492 else if( lName == wxT( "TOP" ) )
493 {
494 KiCadLayer = F_Cu;
495 }
496 else if( lName == wxT( "BOTTOM" ) )
497 {
498 KiCadLayer = B_Cu;
499 }
500 else if( lName == wxT( "BOT MASK" ) )
501 {
502 KiCadLayer = B_Mask;
503 }
504 else if( lName == wxT( "BOT PASTE" ) )
505 {
506 KiCadLayer = B_Paste;
507 }
508 else if( lName == wxT( "BOT SILK" ) )
509 {
510 KiCadLayer = B_SilkS;
511 }
512 else if( lName == wxT( "BOT ASSY" ) )
513 {
514 KiCadLayer = B_Fab;
515 }
516 else if( lName == wxT( "BOARD" ) )
517 {
518 KiCadLayer = Edge_Cuts;
519 }
520 else
521 {
522 int layernum = FindLayer( lName );
523
524 if( layernum == -1 )
525 KiCadLayer = Dwgs_User; // default
526 else
527 KiCadLayer = ToLAYER_ID( layernum );
528 }
529
530 if( FindNode( aNode, wxT( "layerNum" ) ) )
531 FindNode( aNode, wxT( "layerNum" ) )->GetNodeContent().ToLong( &num );
532
533 if( num < 0 )
534 THROW_IO_ERROR( wxString::Format( wxT( "layerNum = %ld is out of range" ), num ) );
535
536 TLAYER newlayer;
537 newlayer.KiCadLayer = KiCadLayer;
538
539 if( FindNode( aNode, wxT( "layerType" ) ) )
540 {
541 layerType = FindNode( aNode, wxT( "layerType" ) )->GetNodeContent().Trim( false );
542
543 if( layerType.IsSameAs( wxT( "NonSignal" ), false ) )
545
546 if( layerType.IsSameAs( wxT( "Signal" ), false ) )
547 newlayer.layerType = LAYER_TYPE_SIGNAL;
548
549 if( layerType.IsSameAs( wxT( "Plane" ), false ) )
550 newlayer.layerType = LAYER_TYPE_PLANE;
551 }
552
553 m_LayersMap.insert( std::make_pair( num, newlayer ) );
554
555 if( FindNode( aNode, wxT( "netNameRef" ) ) )
556 {
557 FindNode( aNode, wxT( "netNameRef" ) )->GetAttribute( wxT( "Name" ),
558 &m_LayersMap[(int) num].netNameRef );
559 }
560}
561
562int PCB::FindOutlinePoint( const VERTICES_ARRAY* aOutline, wxRealPoint aPoint ) const
563{
564 int i;
565
566 for( i = 0; i < (int) aOutline->GetCount(); i++ )
567 {
568 if( *((*aOutline)[i]) == aPoint )
569 return i;
570 }
571
572 return -1;
573}
574
575
576double PCB::GetDistance( const wxRealPoint* aPoint1, const wxRealPoint* aPoint2 ) const
577{
578 return sqrt( ( aPoint1->x - aPoint2->x ) * ( aPoint1->x - aPoint2->x ) +
579 ( aPoint1->y - aPoint2->y ) * ( aPoint1->y - aPoint2->y ) );
580}
581
582void PCB::GetBoardOutline( wxXmlDocument* aXmlDoc, const wxString& aActualConversion )
583{
584 XNODE* iNode, *lNode, *pNode;
585 long PCadLayer = 0;
586 int x, y, i, j, targetInd;
587 wxRealPoint* xchgPoint;
588 double minDistance, distance;
589
590 iNode = FindNode( (XNODE *)aXmlDoc->GetRoot(), wxT( "pcbDesign" ) );
591
592 if( iNode )
593 {
594 // COMPONENTS AND OBJECTS
595 iNode = iNode->GetChildren();
596
597 while( iNode )
598 {
599 // objects
600 if( iNode->GetName().IsSameAs( wxT( "layerContents" ), false ) )
601 {
602 if( FindNode( iNode, wxT( "layerNumRef" ) ) )
603 FindNode( iNode, wxT( "layerNumRef" ) )->GetNodeContent().ToLong( &PCadLayer );
604
605 if( GetKiCadLayer( PCadLayer ) == Edge_Cuts )
606 {
607 lNode = iNode->GetChildren();
608
609 while( lNode )
610 {
611 if( lNode->GetName().IsSameAs( wxT( "line" ), false ) )
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
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
676void PCB::ParseBoard( wxStatusBar* aStatusBar, wxXmlDocument* aXmlDoc,
677 const wxString& aActualConversion )
678{
679 XNODE* aNode;//, *aaNode;
680 PCB_NET* net;
681 PCB_COMPONENT* comp;
682 PCB_FOOTPRINT* footprint;
683 wxString compRef, pinRef, layerName, layerType;
684 int i, j, netCode;
685
686 // Default measurement units
687 aNode = FindNode( (XNODE *)aXmlDoc->GetRoot(), wxT( "asciiHeader" ) );
688
689 if( aNode )
690 {
691 aNode = FindNode( aNode, wxT( "fileUnits" ) );
692
693 if( aNode )
694 {
695 m_DefaultMeasurementUnit = aNode->GetNodeContent().Lower();
696 m_DefaultMeasurementUnit.Trim( true );
697 m_DefaultMeasurementUnit.Trim( false );
698 }
699 }
700
701 // Determine layers stackup
702 aNode = FindNode( (XNODE *)aXmlDoc->GetRoot(), wxT( "pcbDesign" ) );
703
704 /*if( aNode )
705 {
706 aNode = FindNode( aNode, wxT( "layersStackup" ) );
707
708 if( aNode )
709 {
710 aNode = FindNode( aNode, wxT( "layerStackupData" ) );
711
712 while( aNode )
713 {
714 if( aNode->GetName() == wxT( "layerStackupData" ) )
715 {
716 aaNode = FindNode( aNode, wxT( "layerStackupName" ) );
717
718 if( aaNode ) {
719 aaNode->GetAttribute( wxT( "Name" ), &layerName );
720 layerName = layerName.MakeUpper();
721 m_layersStackup.Add( layerName );
722 }
723 }
724
725 aNode = aNode->GetNext();
726 }
727 }
728 }*/
729
730 if( aNode )
731 {
732 aNode = FindNode( aNode, wxT( "layerDef" ) );
733
734 while( aNode )
735 {
736 if( aNode->GetName().IsSameAs( wxT( "layerDef" ), false ) )
737 {
738 if( FindNode( aNode, wxT( "layerType" ) ) )
739 {
740 long num = -1;
741
742 if( FindNode( aNode, wxT( "layerNum" ) ) )
743 FindNode( aNode, wxT( "layerNum" ) )->GetNodeContent().ToLong( &num );
744
745 layerType = FindNode( aNode, wxT( "layerType" ) )->GetNodeContent().Trim(
746 false );
747
748 if( num > 0 && ( layerType.IsSameAs( wxT( "Signal" ), false )
749 || layerType.IsSameAs( wxT( "Plane" ), false ) ) )
750 {
751 aNode->GetAttribute( wxT( "Name" ), &layerName );
752 layerName = layerName.MakeUpper();
753 m_layersStackup.emplace_back( layerName, num );
754
755 if( m_layersStackup.size() > 32 )
756 THROW_IO_ERROR( _( "KiCad only supports 32 signal layers." ) );
757 }
758 }
759 }
760
761 aNode = aNode->GetNext();
762 }
763
764 // Ensure that the layers are properly mapped to their order with the bottom
765 // copper (layer 2 in PCAD) at the end
766 std::sort( m_layersStackup.begin(), m_layersStackup.end(),
767 [&]( const std::pair<wxString, long>& a, const std::pair<wxString, long>& b ) {
768 long lhs = a.second == 2 ? std::numeric_limits<long>::max() : a.second;
769 long rhs = b.second == 2 ? std::numeric_limits<long>::max() : b.second;
770
771 return lhs < rhs;
772 } );
773 }
774
775 // Layers mapping
776 aNode = FindNode( (XNODE *)aXmlDoc->GetRoot(), wxT( "pcbDesign" ) );
777
778 if( aNode )
779 {
780 aNode = FindNode( aNode, wxT( "layerDef" ) );
781
782 while( aNode )
783 {
784 if( aNode->GetName().IsSameAs( wxT( "layerDef" ), false ) )
785 MapLayer( aNode );
786
787 aNode = aNode->GetNext();
788 }
789 }
790
791 GetBoardOutline( aXmlDoc, aActualConversion );
792
793 // NETLIST
794 // aStatusBar->SetStatusText( wxT( "Loading NETLIST " ) );
795
796 aNode = FindNode( (XNODE *)aXmlDoc->GetRoot(), wxT( "netlist" ) );
797
798 if( aNode )
799 {
800 aNode = FindNode( aNode, wxT( "net" ) );
801
802 netCode = 1;
803
804 while( aNode )
805 {
806 net = new PCB_NET( netCode++ );
807 net->Parse( aNode );
808 m_PcbNetlist.Add( net );
809
810 aNode = aNode->GetNext();
811 }
812 }
813
814 // BOARD FILE
815 // aStatusBar->SetStatusText( wxT( "Loading BOARD DEFINITION " ) );
816
817 aNode = FindNode( (XNODE *)aXmlDoc->GetRoot(), wxT( "pcbDesign" ) );
818
819 if( aNode )
820 {
821 // COMPONENTS AND OBJECTS
822 aNode = aNode->GetChildren();
823
824 while( aNode )
825 {
826 // Components/footprints
827 if( aNode->GetName().IsSameAs( wxT( "multiLayer" ), false ) )
828 DoPCBComponents( aNode, aXmlDoc, aActualConversion, aStatusBar );
829
830 // objects
831 if( aNode->GetName().IsSameAs( wxT( "layerContents" ), false ) )
832 DoLayerContentsObjects( aNode, nullptr, &m_PcbComponents, aStatusBar,
833 m_DefaultMeasurementUnit, aActualConversion );
834
835 aNode = aNode->GetNext();
836 }
837
838 // POSTPROCESS -- SET NETLIST REFERENCES
839 // aStatusBar->SetStatusText( wxT( "Processing NETLIST " ) );
840
841 for( i = 0; i < (int) m_PcbNetlist.GetCount(); i++ )
842 {
843 net = m_PcbNetlist[i];
844
845 for( j = 0; j < (int) net->m_NetNodes.GetCount(); j++ )
846 {
847 compRef = net->m_NetNodes[j]->m_CompRef;
848 compRef.Trim( false );
849 compRef.Trim( true );
850 pinRef = net->m_NetNodes[j]->m_PinRef;
851 pinRef.Trim( false );
852 pinRef.Trim( true );
853 ConnectPinToNet( compRef, pinRef, net->m_Name );
854 }
855 }
856
857 // POSTPROCESS -- FLIP COMPONENTS
858 for( i = 0; i < (int) m_PcbComponents.GetCount(); i++ )
859 {
860 if( m_PcbComponents[i]->m_objType == wxT( 'M' ) )
862 }
863
864 // POSTPROCESS -- SET/OPTIMIZE NEW PCB POSITION
865 // aStatusBar->SetStatusText( wxT( "Optimizing BOARD POSITION " ) );
866
867 m_SizeX = 10000000;
868 m_SizeY = 0;
869
870 for( i = 0; i < (int) m_PcbComponents.GetCount(); i++ )
871 {
872 comp = m_PcbComponents[i];
873
874 if( comp->m_positionY < m_SizeY )
875 m_SizeY = comp->m_positionY; // max Y
876
877 if( comp->m_positionX < m_SizeX && comp->m_positionX > 0 )
878 m_SizeX = comp->m_positionX; // Min X
879 }
880
881 m_SizeY -= 10000;
882 m_SizeX -= 10000;
883 // aStatusBar->SetStatusText( wxT( " POSITIONING POSTPROCESS " ) );
884
885 for( i = 0; i < (int) m_PcbComponents.GetCount(); i++ )
887
888 m_SizeX = 0;
889 m_SizeY = 0;
890
891 for( i = 0; i < (int) m_PcbComponents.GetCount(); i++ )
892 {
893 comp = m_PcbComponents[i];
894
895 if( comp->m_positionY < m_SizeY )
896 m_SizeY = comp->m_positionY; // max Y
897
898 if( comp->m_positionX > m_SizeX )
899 m_SizeX = comp->m_positionX; // Min X
900 }
901
902 // SHEET SIZE CALCULATION
903 m_SizeY = -m_SizeY; // it is in absolute units
904 m_SizeX += 10000;
905 m_SizeY += 10000;
906
907 // A4 is minimum $Descr A4 11700 8267
908 if( m_SizeX < 11700 )
909 m_SizeX = 11700;
910
911 if( m_SizeY < 8267 )
912 m_SizeY = 8267;
913 }
914 else
915 {
916 // LIBRARY FILE
917 // aStatusBar->SetStatusText( wxT( "Processing LIBRARY FILE " ) );
918
919 aNode = FindNode( (XNODE *)aXmlDoc->GetRoot(), wxT( "library" ) );
920
921 if( aNode )
922 {
923 aNode = FindNode( aNode, wxT( "compDef" ) );
924
925 while( aNode )
926 {
927 // aStatusBar->SetStatusText( wxT( "Processing COMPONENTS " ) );
928
929 if( aNode->GetName().IsSameAs( wxT( "compDef" ), false ) )
930 {
931 footprint = new PCB_FOOTPRINT( this, m_board );
932 footprint->Parse( aNode, aStatusBar, m_DefaultMeasurementUnit,
933 aActualConversion );
934 m_PcbComponents.Add( footprint );
935 }
936
937 aNode = aNode->GetNext();
938 }
939 }
940 }
941}
942
943
945{
946 int i;
947 PCB_NET* net;
948
950
951 for( i = 0; i < (int) m_PcbNetlist.GetCount(); i++ )
952 {
953 net = m_PcbNetlist[i];
954
955 m_board->Add( new NETINFO_ITEM( m_board, net->m_Name, net->m_NetCode ) );
956 }
957
958 for( i = 0; i < (int) m_PcbComponents.GetCount(); i++ )
959 {
960 m_PcbComponents[i]->AddToBoard();
961 }
962}
963
964} // namespace PCAD2KICAD
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:269
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT, bool aSkipConnectivity=false) override
Removes an item from the container.
Definition: board.cpp:772
void SetCopperLayerCount(int aCount)
Definition: board.cpp:569
Handle the data for a net.
Definition: netinfo.h:67
PCB_LAYER_ID GetKiCadLayer() const
Definition: pcb_component.h:56
virtual void SetPosOffset(int aX_offs, int aY_offs)
PCB_CALLBACKS * m_callbacks
Definition: pcb_component.h:78
void SetName(const wxString &aPin, const wxString &aName)
virtual void Flip() override
VERTICES_ARRAY m_BoardOutline
Definition: pcb_footprint.h:66
PCB_COMPONENTS_ARRAY m_FootprintItems
Definition: pcb_footprint.h:64
virtual void Parse(XNODE *aNode, wxStatusBar *aStatusBar, const wxString &aDefaultMeasurementUnit, const wxString &aActualConversion)
XNODE * FindModulePatternDefName(XNODE *aNode, const wxString &aName)
PCB_FOOTPRINT(PCB_CALLBACKS *aCallbacks, BOARD *aBoard)
void DoLayerContentsObjects(XNODE *aNode, PCB_FOOTPRINT *aFootprint, PCB_COMPONENTS_ARRAY *aList, wxStatusBar *aStatusBar, const wxString &aDefaultMeasurementUnit, const wxString &aActualConversion)
virtual bool Parse(XNODE *aNode, const wxString &aDefaultMeasurementUnit, const wxString &aActualConversion) override
Definition: pcb_keepout.cpp:48
wxString m_Name
Definition: pcb_net.h:56
void Parse(XNODE *aNode)
Definition: pcb_net.cpp:63
PCB_NET_NODES_ARRAY m_NetNodes
Definition: pcb_net.h:58
void SetTextProperty(XNODE *aNode, TTEXTVALUE *aTextValue, const wxString &aPatGraphRefName, const wxString &aXmlName, const wxString &aActualConversion)
Definition: pcb.cpp:169
wxString GetLayerNetNameRef(int aPCadLayer) const override
Definition: pcb.cpp:67
int FindLayer(const wxString &aLayerName) const
Definition: pcb.cpp:455
void ParseBoard(wxStatusBar *aStatusBar, wxXmlDocument *aXmlDoc, const wxString &aActualConversion)
Definition: pcb.cpp:676
int FindOutlinePoint(const VERTICES_ARRAY *aOutline, wxRealPoint aPoint) const
Definition: pcb.cpp:562
void ConnectPinToNet(const wxString &aCr, const wxString &aPr, const wxString &aNetName)
Definition: pcb.cpp:427
int m_SizeY
Definition: pcb.h:67
void AddToBoard() override
Definition: pcb.cpp:944
int GetNetCode(const wxString &aNetName) const override
Definition: pcb.cpp:124
double GetDistance(const wxRealPoint *aPoint1, const wxRealPoint *aPoint2) const
Definition: pcb.cpp:576
void DoPCBComponents(XNODE *aNode, wxXmlDocument *aXmlDoc, const wxString &aActualConversion, wxStatusBar *aStatusBar)
Definition: pcb.cpp:238
void GetBoardOutline(wxXmlDocument *aXmlDoc, const wxString &aActualConversion)
Definition: pcb.cpp:582
void MapLayer(XNODE *aNode)
Definition: pcb.cpp:467
std::vector< std::pair< wxString, long > > m_layersStackup
Definition: pcb.h:86
PCB_NETS_ARRAY m_PcbNetlist
Definition: pcb.h:63
wxString m_DefaultMeasurementUnit
Definition: pcb.h:64
XNODE * FindCompDefName(XNODE *aNode, const wxString &aName) const
Definition: pcb.cpp:141
std::map< int, TLAYER > m_LayersMap
Definition: pcb.h:65
PCB(BOARD *aBoard)
Definition: pcb.cpp:78
PCB_COMPONENTS_ARRAY m_PcbComponents
Definition: pcb.h:62
int m_SizeX
Definition: pcb.h:66
LAYER_TYPE_T GetLayerType(int aPCadLayer) const override
Definition: pcb.cpp:56
Hold an XML or S-expression element.
Definition: xnode.h:44
XNODE * GetParent() const
Definition: xnode.h:72
XNODE * GetChildren() const
Definition: xnode.h:62
XNODE * GetNext() const
Definition: xnode.h:67
The common library.
#define _(s)
@ TENTHS_OF_A_DEGREE_T
Definition: eda_angle.h:30
#define THROW_IO_ERROR(msg)
Definition: ki_exception.h:38
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:59
@ Edge_Cuts
Definition: layer_ids.h:113
@ Dwgs_User
Definition: layer_ids.h:109
@ F_Paste
Definition: layer_ids.h:101
@ B_Mask
Definition: layer_ids.h:106
@ B_Cu
Definition: layer_ids.h:95
@ F_Mask
Definition: layer_ids.h:107
@ B_Paste
Definition: layer_ids.h:100
@ F_Fab
Definition: layer_ids.h:120
@ F_SilkS
Definition: layer_ids.h:104
@ Eco2_User
Definition: layer_ids.h:112
@ B_SilkS
Definition: layer_ids.h:103
@ F_Cu
Definition: layer_ids.h:64
@ B_Fab
Definition: layer_ids.h:119
PCB_LAYER_ID ToLAYER_ID(int aLayer)
Definition: lset.cpp:932
wxString ValidateName(const wxString &aName)
int StrToInt1Units(const wxString &aStr)
XNODE * FindNode(XNODE *aChild, const wxString &aTag)
void SetPosition(const wxString &aStr, const wxString &aDefaultMeasurementUnit, int *aX, int *aY, const wxString &aActualConversion)
XNODE * FindPinMap(XNODE *aNode)
wxString FindNodeGetContent(XNODE *aChild, const wxString &aTag)
void SetTextParameters(XNODE *aNode, TTEXTVALUE *aTextValue, const wxString &aDefaultMeasurementUnit, const wxString &aActualConversion)
LAYER_TYPE_T
Definition: pcb_callbacks.h:38
@ LAYER_TYPE_NONSIGNAL
Definition: pcb_callbacks.h:40
@ LAYER_TYPE_PLANE
Definition: pcb_callbacks.h:41
@ LAYER_TYPE_SIGNAL
Definition: pcb_callbacks.h:39
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
static float distance(const SFVEC2UI &a, const SFVEC2UI &b)
LAYER_TYPE_T layerType
Definition: pcb_callbacks.h:47
PCB_LAYER_ID KiCadLayer
Definition: pcb_callbacks.h:46
wxString netNameRef
Definition: pcb_callbacks.h:48