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