diff options
Diffstat (limited to 'pcbnew/pcad2kicadpcb_plugin/pcb.cpp')
-rw-r--r-- | pcbnew/pcad2kicadpcb_plugin/pcb.cpp | 937 |
1 files changed, 937 insertions, 0 deletions
diff --git a/pcbnew/pcad2kicadpcb_plugin/pcb.cpp b/pcbnew/pcad2kicadpcb_plugin/pcb.cpp new file mode 100644 index 0000000..feedb83 --- /dev/null +++ b/pcbnew/pcad2kicadpcb_plugin/pcb.cpp @@ -0,0 +1,937 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2007, 2008 Lubo Racko <developer@lura.sk> + * Copyright (C) 2007, 2008, 2012-2013 Alexander Lunev <al.lunev@yahoo.com> + * Copyright (C) 2012 KiCad Developers, see CHANGELOG.TXT for contributors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +/** + * @file pcb.cpp + */ + +#include <wx/wx.h> +#include <wx/config.h> + +#include <common.h> + +#include <pcb.h> +#include <pcb_arc.h> +#include <pcb_copper_pour.h> +#include <pcb_cutout.h> +#include <pcb_keepout.h> +#include <pcb_line.h> +#include <pcb_module.h> +#include <pcb_pad_shape.h> +#include <pcb_via_shape.h> +#include <pcb_pad.h> +#include <pcb_text.h> +#include <pcb_via.h> +#include <s_expr_loader.h> + +namespace PCAD2KICAD { + +LAYER_ID PCB::GetKiCadLayer( int aPCadLayer ) +{ + wxASSERT( aPCadLayer >= 0 && aPCadLayer < MAX_PCAD_LAYER_QTY ); + return m_layersMap[aPCadLayer].KiCadLayer; +} + +LAYER_TYPE_T PCB::GetLayerType( int aPCadLayer ) +{ + wxASSERT( aPCadLayer >= 0 && aPCadLayer < MAX_PCAD_LAYER_QTY ); + return m_layersMap[aPCadLayer].layerType; +} + +wxString PCB::GetLayerNetNameRef( int aPCadLayer ) +{ + wxASSERT( aPCadLayer >= 0 && aPCadLayer < MAX_PCAD_LAYER_QTY ); + return m_layersMap[aPCadLayer].netNameRef; +} + +PCB::PCB( BOARD* aBoard ) : PCB_MODULE( this, aBoard ) +{ + int i; + + m_defaultMeasurementUnit = wxT( "mil" ); + + for( i = 0; i < MAX_PCAD_LAYER_QTY; i++ ) + { + m_layersMap[i].KiCadLayer = F_Mask; // default + m_layersMap[i].layerType = LAYER_TYPE_NONSIGNAL; // default + m_layersMap[i].netNameRef = wxT( "" ); // default + } + + m_sizeX = 0; + m_sizeY = 0; + + m_layersMap[1].KiCadLayer = F_Cu; + m_layersMap[1].layerType = LAYER_TYPE_SIGNAL; + + m_layersMap[2].KiCadLayer = B_Cu; + m_layersMap[2].layerType = LAYER_TYPE_SIGNAL; + + m_layersMap[3].KiCadLayer = Eco2_User; + m_layersMap[6].KiCadLayer = F_SilkS; + m_layersMap[7].KiCadLayer = B_SilkS; + m_timestamp_cnt = 0x10000000; +} + + +PCB::~PCB() +{ + int i; + + for( i = 0; i < (int) m_pcbComponents.GetCount(); i++ ) + { + delete m_pcbComponents[i]; + } + + for( i = 0; i < (int) m_pcbNetlist.GetCount(); i++ ) + { + delete m_pcbNetlist[i]; + } +} + + +int PCB::GetNewTimestamp() +{ + return m_timestamp_cnt++; +} + +int PCB::GetNetCode( wxString aNetName ) +{ + PCB_NET* net; + + for( int i = 0; i < (int) m_pcbNetlist.GetCount(); i++ ) + { + net = m_pcbNetlist[i]; + + if( net->m_name == aNetName ) + { + return net->m_netCode; + } + } + + return 0; +} + +XNODE* PCB::FindCompDefName( XNODE* aNode, wxString aName ) +{ + XNODE* result = NULL, * lNode; + wxString propValue; + + lNode = FindNode( aNode, wxT( "compDef" ) ); + + while( lNode ) + { + if( lNode->GetName() == wxT( "compDef" ) ) + { + lNode->GetAttribute( wxT( "Name" ), &propValue ); + + if( propValue == aName ) + { + result = lNode; + lNode = NULL; + } + } + + if( lNode ) + lNode = lNode->GetNext(); + } + + return result; +} + + +void PCB::SetTextProperty( XNODE* aNode, TTEXTVALUE* aTextValue, + wxString aPatGraphRefName, wxString aXmlName, + wxString aActualConversion ) +{ + XNODE* tNode, * t1Node; + wxString n, nnew, pn, propValue, str; + + // aNode is pattern now + tNode = aNode; + t1Node = aNode; + n = aXmlName; + + // new file format version + if( FindNode( tNode, wxT( "patternGraphicsNameRef" ) ) ) + { + FindNode( tNode, + wxT( "patternGraphicsNameRef" ) )->GetAttribute( wxT( "Name" ), + &pn ); + pn.Trim( false ); + pn.Trim( true ); + tNode = FindNode( tNode, wxT( "patternGraphicsRef" ) ); + + while( tNode ) + { + if( tNode->GetName() == wxT( "patternGraphicsRef" ) ) + { + if( FindNode( tNode, wxT( "patternGraphicsNameRef" ) ) ) + { + FindNode( tNode, + wxT( "patternGraphicsNameRef" ) )->GetAttribute( wxT( "Name" ), + &propValue ); + + if( propValue == pn ) + { + t1Node = tNode; // find correct section with same name. + str = aTextValue->text; + str.Trim( false ); + str.Trim( true ); + nnew = n; // new file version + n = n + wxT( ' ' ) + str; // old file version + tNode = NULL; + } + } + } + + if( tNode ) + tNode = tNode->GetNext(); + } + } + + // old version and compatibile fr both from this point + tNode = FindNode( t1Node, wxT( "attr" ) ); + + while( tNode ) + { + tNode->GetAttribute( wxT( "Name" ), &propValue ); + propValue.Trim( false ); + propValue.Trim( true ); + + if( propValue == n || propValue == nnew ) + break; + + tNode = tNode->GetNext(); + } + + if( tNode ) + SetTextParameters( tNode, aTextValue, m_defaultMeasurementUnit, aActualConversion ); +} + + +void PCB::DoPCBComponents( XNODE* aNode, + wxXmlDocument* aXmlDoc, + wxString aActualConversion, + wxStatusBar* aStatusBar ) +{ + XNODE* lNode, * tNode, * mNode; + PCB_MODULE* mc; + PCB_PAD* pad; + PCB_VIA* via; + PCB_KEEPOUT* keepOut; + wxString cn, str, propValue; + + lNode = aNode->GetChildren(); + + while( lNode ) + { + mc = NULL; + + if( lNode->GetName() == wxT( "pattern" ) ) + { + FindNode( lNode, wxT( "patternRef" ) )->GetAttribute( wxT( "Name" ), + &cn ); + cn = ValidateName( cn ); + tNode = FindNode( (XNODE *)aXmlDoc->GetRoot(), wxT( "library" ) ); + + if( tNode && cn.Len() > 0 ) + { + tNode = FindModulePatternDefName( tNode, cn ); + + if( tNode ) + { + mc = new PCB_MODULE( this, m_board ); + + mNode = FindNode( lNode, wxT( "patternGraphicsNameRef" ) ); + if( mNode ) + mNode->GetAttribute( wxT( "Name" ), &mc->m_patGraphRefName ); + + mc->Parse( tNode, aStatusBar, m_defaultMeasurementUnit, aActualConversion ); + } + } + + if( mc ) + { + mc->m_compRef = cn; // default - in new version of file it is updated later.... + tNode = FindNode( lNode, wxT( "refDesRef" ) ); + + if( tNode ) + { + tNode->GetAttribute( wxT( "Name" ), &mc->m_name.text ); + SetTextProperty( lNode, &mc->m_name, mc->m_patGraphRefName, wxT( + "RefDes" ), aActualConversion ); + SetTextProperty( lNode, &mc->m_value, mc->m_patGraphRefName, wxT( + "Value" ), aActualConversion ); + } + + tNode = FindNode( lNode, wxT( "pt" ) ); + + if( tNode ) + SetPosition( tNode->GetNodeContent(), + m_defaultMeasurementUnit, + &mc->m_positionX, + &mc->m_positionY, + aActualConversion ); + + tNode = FindNode( lNode, wxT( "rotation" ) ); + + if( tNode ) + { + str = tNode->GetNodeContent(); + str.Trim( false ); + mc->m_rotation = StrToInt1Units( str ); + } + + str = FindNodeGetContent( lNode, wxT( "isFlipped" ) ); + + if( str == wxT( "True" ) ) + mc->m_mirror = 1; + + tNode = aNode; + + while( tNode->GetName() != wxT( "www.lura.sk" ) ) + tNode = tNode->GetParent(); + + tNode = FindNode( tNode, wxT( "netlist" ) ); + + if( tNode ) + { + tNode = FindNode( tNode, wxT( "compInst" ) ); + + while( tNode ) + { + tNode->GetAttribute( wxT( "Name" ), &propValue ); + + if( propValue == mc->m_name.text ) + { + if( FindNode( tNode, wxT( "compValue" ) ) ) + { + FindNode( tNode, + wxT( "compValue" ) )->GetAttribute( wxT( "Name" ), + &mc->m_value.text ); + mc->m_value.text.Trim( false ); + mc->m_value.text.Trim( true ); + } + + if( FindNode( tNode, wxT( "compRef" ) ) ) + { + FindNode( tNode, + wxT( "compRef" ) )->GetAttribute( wxT( "Name" ), + &mc->m_compRef ); + mc->m_compRef.Trim( false ); + mc->m_compRef.Trim( true ); + } + + tNode = NULL; + } + else + tNode = tNode->GetNext(); + } + } + + // map pins + tNode = FindNode( (XNODE *)aXmlDoc->GetRoot(), wxT( "library" ) ); + tNode = FindCompDefName( tNode, mc->m_compRef ); + + if( tNode ) + { + tNode = FindPinMap( tNode ); + + if( tNode ) + { + mNode = tNode->GetChildren(); + + while( mNode ) + { + if( mNode->GetName() == wxT( "padNum" ) ) + { + str = mNode->GetNodeContent(); + mNode = mNode->GetNext(); + + if( !mNode ) + break; + + mNode->GetAttribute( wxT( "Name" ), &propValue ); + mc->SetPadName( str, propValue ); + mNode = mNode->GetNext(); + } + else + { + mNode = mNode->GetNext(); + + if( !mNode ) + break; + + mNode = mNode->GetNext(); + } + } + } + } + + m_pcbComponents.Add( mc ); + } + } + else if( lNode->GetName() == wxT( "pad" ) ) + { + pad = new PCB_PAD( this, m_board ); + pad->Parse( lNode, m_defaultMeasurementUnit, aActualConversion ); + m_pcbComponents.Add( pad ); + } + else if( lNode->GetName() == wxT( "via" ) ) + { + via = new PCB_VIA( this, m_board ); + via->Parse( lNode, m_defaultMeasurementUnit, aActualConversion ); + m_pcbComponents.Add( via ); + } + else if( lNode->GetName() == wxT( "polyKeepOut" ) ) + { + keepOut = new PCB_KEEPOUT( m_callbacks, m_board, 0 ); + + if( keepOut->Parse( lNode, m_defaultMeasurementUnit, aActualConversion ) ) + m_pcbComponents.Add( keepOut ); + else + delete keepOut; + } + + lNode = lNode->GetNext(); + } +} + + +void PCB::ConnectPinToNet( wxString aCompRef, wxString aPinRef, wxString aNetName ) +{ + PCB_MODULE* module; + PCB_PAD* cp; + int i, j; + + for( i = 0; i < (int) m_pcbComponents.GetCount(); i++ ) + { + module = (PCB_MODULE*) m_pcbComponents[i]; + + if( module->m_objType == wxT( 'M' ) && module->m_name.text == aCompRef ) + { + for( j = 0; j < (int) module->m_moduleObjects.GetCount(); j++ ) + { + if( module->m_moduleObjects[j]->m_objType == wxT( 'P' ) ) + { + cp = (PCB_PAD*) module->m_moduleObjects[j]; + + if( cp->m_name.text == aPinRef ) + cp->m_net = aNetName; + } + } + } + } +} + + +int PCB::FindLayer( wxString aLayerName ) +{ + for( LAYER_NUM i = 0; i < (int)m_layersStackup.GetCount(); ++i ) + { + if( m_layersStackup[i] == aLayerName ) + return i; + } + + return -1; +} + + +/* KiCad layers + * 0 Copper layer + * 1 to 14 Inner layers + * 15 Component layer + * 16 Copper side adhesive layer Technical layers + * 17 Component side adhesive layer + * 18 Copper side Solder paste layer + * 19 Component Solder paste layer + * 20 Copper side Silk screen layer + * 21 Component Silk screen layer + * 22 Copper side Solder mask layer + * 23 Component Solder mask layer + * 24 Draw layer (Used for general drawings) + * 25 Comment layer (Other layer used for general drawings) + * 26 ECO1 layer (Other layer used for general drawings) // BUG + * 26 ECO2 layer (Other layer used for general drawings) // BUG 27 + * 27 Edge layer. Items on Edge layer are seen on all layers // BUG 28 + */ +void PCB::MapLayer( XNODE* aNode ) +{ + wxString lName, layerType; + LAYER_ID KiCadLayer; + long num = 0; + + aNode->GetAttribute( wxT( "Name" ), &lName ); + lName = lName.MakeUpper(); + + if( lName == wxT( "TOP ASSY" ) ) + KiCadLayer = Cmts_User; + else if( lName == wxT( "TOP SILK" ) ) + KiCadLayer = F_SilkS; + else if( lName == wxT( "TOP PASTE" ) ) + KiCadLayer = F_Paste; + else if( lName == wxT( "TOP MASK" ) ) + KiCadLayer = F_Mask; + else if( lName == wxT( "TOP" ) ) + KiCadLayer = F_Cu; + else if( lName == wxT( "BOTTOM" ) ) + KiCadLayer = B_Cu; + else if( lName == wxT( "BOT MASK" ) ) + KiCadLayer = B_Mask; + else if( lName == wxT( "BOT PASTE" ) ) + KiCadLayer = B_Paste; + else if( lName == wxT( "BOT SILK" ) ) + KiCadLayer = B_SilkS; + else if( lName == wxT( "BOT ASSY" ) ) + KiCadLayer = Dwgs_User; + else if( lName == wxT( "BOARD" ) ) + KiCadLayer = Edge_Cuts; + else + { + int layernum = FindLayer( lName ); + + if( layernum == -1 ) + KiCadLayer = Dwgs_User; // default + else +#if 0 // was: + KiCadLayer = FIRST_COPPER_LAYER + m_layersStackup.GetCount() - 1 - layernum; +#else + KiCadLayer = ToLAYER_ID( layernum ); +#endif + } + + if( FindNode( aNode, wxT( "layerNum" ) ) ) + FindNode( aNode, wxT( "layerNum" ) )->GetNodeContent().ToLong( &num ); + + if( num < 0 || num >= MAX_PCAD_LAYER_QTY ) + THROW_IO_ERROR( wxString::Format( wxT( "layerNum = %ld is out of range" ), num ) ); + + m_layersMap[(int) num].KiCadLayer = KiCadLayer; + + if( FindNode( aNode, wxT( "layerType" ) ) ) + { + layerType = FindNode( aNode, wxT( "layerType" ) )->GetNodeContent().Trim( false ); + + if( layerType == wxT( "NonSignal" ) ) + m_layersMap[(int) num].layerType = LAYER_TYPE_NONSIGNAL; + if( layerType == wxT( "Signal" ) ) + m_layersMap[(int) num].layerType = LAYER_TYPE_SIGNAL; + if( layerType == wxT( "Plane" ) ) + m_layersMap[(int) num].layerType = LAYER_TYPE_PLANE; + } + + if( FindNode( aNode, wxT( "netNameRef" ) ) ) + { + FindNode( aNode, wxT( "netNameRef" ) )->GetAttribute( wxT( "Name" ), + &m_layersMap[(int) num].netNameRef ); + } +} + +int PCB::FindOutlinePoint( VERTICES_ARRAY* aOutline, wxRealPoint aPoint ) +{ + int i; + + for( i = 0; i < (int) aOutline->GetCount(); i++ ) + if( *((*aOutline)[i]) == aPoint ) + return i; + + return -1; +} + +/*int cmpFunc( wxRealPoint **first, wxRealPoint **second ) +{ + return sqrt( pow( (double) aPointA.x - (double) aPointB.x, 2 ) + + pow( (double) aPointA.y - (double) aPointB.y, 2 ) ); + + return 0; +}*/ +double PCB::GetDistance( wxRealPoint* aPoint1, wxRealPoint* aPoint2 ) +{ + return sqrt( ( aPoint1->x - aPoint2->x ) * + ( aPoint1->x - aPoint2->x ) + + ( aPoint1->y - aPoint2->y ) * + ( aPoint1->y - aPoint2->y ) ); +} + +void PCB::GetBoardOutline( wxXmlDocument* aXmlDoc, wxString aActualConversion ) +{ + XNODE* iNode, *lNode, *pNode; + long PCadLayer = 0; + int x, y, i, j, targetInd; + wxRealPoint* xchgPoint; + double minDistance, distance; + + iNode = FindNode( (XNODE *)aXmlDoc->GetRoot(), wxT( "pcbDesign" ) ); + + if( iNode ) + { + // COMPONENTS AND OBJECTS + iNode = iNode->GetChildren(); + + while( iNode ) + { + // objects + if( iNode->GetName() == wxT( "layerContents" ) ) + { + if( FindNode( iNode, wxT( "layerNumRef" ) ) ) + FindNode( iNode, wxT( "layerNumRef" ) )->GetNodeContent().ToLong( &PCadLayer ); + + if( GetKiCadLayer( PCadLayer ) == Edge_Cuts ) + { + lNode = iNode->GetChildren(); + while( lNode ) + { + if( lNode->GetName() == wxT( "line" ) ) + { + pNode = FindNode( lNode, wxT( "pt" ) ); + + if( pNode ) + { + SetPosition( pNode->GetNodeContent(), m_defaultMeasurementUnit, + &x, &y, aActualConversion ); + + if( FindOutlinePoint( &m_boardOutline, wxRealPoint( x, y) ) == -1 ) + m_boardOutline.Add( new wxRealPoint( x, y ) ); + } + + if( pNode ) + pNode = pNode->GetNext(); + + if( pNode ) + { + SetPosition( pNode->GetNodeContent(), m_defaultMeasurementUnit, + &x, &y, aActualConversion ); + + if( FindOutlinePoint( &m_boardOutline, wxRealPoint( x, y) ) == -1 ) + m_boardOutline.Add( new wxRealPoint( x, y ) ); + } + } + + lNode = lNode->GetNext(); + } + + //m_boardOutline.Sort( cmpFunc ); + // sort vertices according to the distances between them + if( m_boardOutline.GetCount() > 3 ) + { + for( i = 0; i < (int) m_boardOutline.GetCount() - 1; i++ ) + { + minDistance = GetDistance( m_boardOutline[i], m_boardOutline[i + 1] ); + targetInd = i + 1; + + for( j = i + 2; j < (int) m_boardOutline.GetCount(); j++ ) + { + distance = GetDistance( m_boardOutline[i], m_boardOutline[j] ); + if( distance < minDistance ) + { + minDistance = distance; + targetInd = j; + } + } + + xchgPoint = m_boardOutline[i + 1]; + m_boardOutline[i + 1] = m_boardOutline[targetInd]; + m_boardOutline[targetInd] = xchgPoint; + } + } + + break; + } + } + + iNode = iNode->GetNext(); + } + } +} + +void PCB::Parse( wxStatusBar* aStatusBar, wxXmlDocument* aXmlDoc, wxString aActualConversion ) +{ + XNODE* aNode;//, *aaNode; + PCB_NET* net; + PCB_COMPONENT* comp; + PCB_MODULE* module; + wxString compRef, pinRef, layerName, layerType; + int i, j, netCode; + + // Defaut measurement units + aNode = FindNode( (XNODE *)aXmlDoc->GetRoot(), wxT( "asciiHeader" ) ); + + if( aNode ) + { + aNode = FindNode( aNode, wxT( "fileUnits" ) ); + + if( aNode ) + { + m_defaultMeasurementUnit = aNode->GetNodeContent().Lower(); + m_defaultMeasurementUnit.Trim( true ); + m_defaultMeasurementUnit.Trim( false ); + } + } + + // Determine layers stackup + aNode = FindNode( (XNODE *)aXmlDoc->GetRoot(), wxT( "pcbDesign" ) ); + + /*if( aNode ) + { + aNode = FindNode( aNode, wxT( "layersStackup" ) ); + + if( aNode ) + { + aNode = FindNode( aNode, wxT( "layerStackupData" ) ); + + while( aNode ) + { + if( aNode->GetName() == wxT( "layerStackupData" ) ) + { + aaNode = FindNode( aNode, wxT( "layerStackupName" ) ); + + if( aaNode ) { + aaNode->GetAttribute( wxT( "Name" ), &layerName ); + layerName = layerName.MakeUpper(); + m_layersStackup.Add( layerName ); + } + } + + aNode = aNode->GetNext(); + } + } + }*/ + + if( aNode ) + { + aNode = FindNode( aNode, wxT( "layerDef" ) ); + + while( aNode ) + { + if( aNode->GetName() == wxT( "layerDef" ) ) + { + if( FindNode( aNode, wxT( "layerType" ) ) ) + { + layerType = FindNode( aNode, + wxT( "layerType" ) )->GetNodeContent().Trim( false ); + + if( layerType == wxT( "Signal" ) || layerType == wxT( "Plane" ) ) + { + aNode->GetAttribute( wxT( "Name" ), &layerName ); + layerName = layerName.MakeUpper(); + m_layersStackup.Add( layerName ); + } + } + } + + aNode = aNode->GetNext(); + } + } + + // Layers mapping + aNode = FindNode( (XNODE *)aXmlDoc->GetRoot(), wxT( "pcbDesign" ) ); + + if( aNode ) + { + aNode = FindNode( aNode, wxT( "layerDef" ) ); + + while( aNode ) + { + if( aNode->GetName() == wxT( "layerDef" ) ) + MapLayer( aNode ); + + aNode = aNode->GetNext(); + } + } + + GetBoardOutline( aXmlDoc, aActualConversion ); + + // NETLIST + // aStatusBar->SetStatusText( wxT( "Loading NETLIST " ) ); + + aNode = FindNode( (XNODE *)aXmlDoc->GetRoot(), wxT( "netlist" ) ); + + if( aNode ) + { + aNode = FindNode( aNode, wxT( "net" ) ); + + netCode = 1; + + while( aNode ) + { + net = new PCB_NET( netCode++ ); + net->Parse( aNode ); + m_pcbNetlist.Add( net ); + + aNode = aNode->GetNext(); + } + } + + // BOARD FILE + // aStatusBar->SetStatusText( wxT( "Loading BOARD DEFINITION " ) ); + + aNode = FindNode( (XNODE *)aXmlDoc->GetRoot(), wxT( "pcbDesign" ) ); + + if( aNode ) + { + // COMPONENTS AND OBJECTS + aNode = aNode->GetChildren(); + + while( aNode ) + { + // Components/modules + if( aNode->GetName() == wxT( "multiLayer" ) ) + DoPCBComponents( aNode, aXmlDoc, aActualConversion, aStatusBar ); + + // objects + if( aNode->GetName() == wxT( "layerContents" ) ) + DoLayerContentsObjects( aNode, NULL, &m_pcbComponents, aStatusBar, + m_defaultMeasurementUnit, aActualConversion ); + + aNode = aNode->GetNext(); + } + + // POSTPROCESS -- SET NETLIST REFERENCES + // aStatusBar->SetStatusText( wxT( "Processing NETLIST " ) ); + + for( i = 0; i < (int) m_pcbNetlist.GetCount(); i++ ) + { + net = m_pcbNetlist[i]; + + for( j = 0; j < (int) net->m_netNodes.GetCount(); j++ ) + { + compRef = net->m_netNodes[j]->m_compRef; + compRef.Trim( false ); + compRef.Trim( true ); + pinRef = net->m_netNodes[j]->m_pinRef; + pinRef.Trim( false ); + pinRef.Trim( true ); + ConnectPinToNet( compRef, pinRef, net->m_name ); + } + } + + // POSTPROCESS -- FLIP COMPONENTS + for( i = 0; i < (int) m_pcbComponents.GetCount(); i++ ) + { + if( m_pcbComponents[i]->m_objType == wxT( 'M' ) ) + ( (PCB_MODULE*) m_pcbComponents[i] )->Flip(); + } + + // POSTPROCESS -- SET/OPTIMIZE NEW PCB POSITION + // aStatusBar->SetStatusText( wxT( "Optimizing BOARD POSITION " ) ); + + m_sizeX = 10000000; + m_sizeY = 0; + + for( i = 0; i < (int) m_pcbComponents.GetCount(); i++ ) + { + comp = m_pcbComponents[i]; + + if( comp->m_positionY < m_sizeY ) + m_sizeY = comp->m_positionY; // max Y + + if( comp->m_positionX < m_sizeX && comp->m_positionX > 0 ) + m_sizeX = comp->m_positionX; // Min X + } + + m_sizeY -= 10000; + m_sizeX -= 10000; + // aStatusBar->SetStatusText( wxT( " POSITIONING POSTPROCESS " ) ); + + for( i = 0; i < (int) m_pcbComponents.GetCount(); i++ ) + m_pcbComponents[i]->SetPosOffset( -m_sizeX, -m_sizeY ); + + m_sizeX = 0; + m_sizeY = 0; + + for( i = 0; i < (int) m_pcbComponents.GetCount(); i++ ) + { + comp = m_pcbComponents[i]; + + if( comp->m_positionY < m_sizeY ) + m_sizeY = comp->m_positionY; // max Y + + if( comp->m_positionX > m_sizeX ) + m_sizeX = comp->m_positionX; // Min X + } + + // SHEET SIZE CALCULATION + m_sizeY = -m_sizeY; // it is in absolute units + m_sizeX += 10000; + m_sizeY += 10000; + + // A4 is minimum $Descr A4 11700 8267 + if( m_sizeX < 11700 ) + m_sizeX = 11700; + + if( m_sizeY < 8267 ) + m_sizeY = 8267; + } + else + { + // LIBRARY FILE + // aStatusBar->SetStatusText( wxT( "Processing LIBRARY FILE " ) ); + + aNode = FindNode( (XNODE *)aXmlDoc->GetRoot(), wxT( "library" ) ); + + if( aNode ) + { + aNode = FindNode( aNode, wxT( "compDef" ) ); + + while( aNode ) + { + // aStatusBar->SetStatusText( wxT( "Processing COMPONENTS " ) ); + + if( aNode->GetName() == wxT( "compDef" ) ) + { + module = new PCB_MODULE( this, m_board ); + module->Parse( aNode, aStatusBar, m_defaultMeasurementUnit, + aActualConversion ); + m_pcbComponents.Add( module ); + } + + aNode = aNode->GetNext(); + } + } + } +} + + +void PCB::AddToBoard() +{ + int i; + PCB_NET* net; + + m_board->SetCopperLayerCount( m_layersStackup.GetCount() ); + + for( i = 0; i < (int) m_pcbNetlist.GetCount(); i++ ) + { + net = m_pcbNetlist[i]; + + m_board->AppendNet( new NETINFO_ITEM( m_board, net->m_name, net->m_netCode ) ); + } + + for( i = 0; i < (int) m_pcbComponents.GetCount(); i++ ) + { + m_pcbComponents[i]->AddToBoard(); + } +} + +} // namespace PCAD2KICAD |