summaryrefslogtreecommitdiff
path: root/pcbnew/pcad2kicadpcb_plugin/pcb_module.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'pcbnew/pcad2kicadpcb_plugin/pcb_module.cpp')
-rw-r--r--pcbnew/pcad2kicadpcb_plugin/pcb_module.cpp640
1 files changed, 640 insertions, 0 deletions
diff --git a/pcbnew/pcad2kicadpcb_plugin/pcb_module.cpp b/pcbnew/pcad2kicadpcb_plugin/pcb_module.cpp
new file mode 100644
index 0000000..5bcf7d9
--- /dev/null
+++ b/pcbnew/pcad2kicadpcb_plugin/pcb_module.cpp
@@ -0,0 +1,640 @@
+/*
+ * 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_module.cpp
+ */
+
+#include <wx/wx.h>
+#include <wx/config.h>
+
+#include <common.h>
+
+#include <pcb_arc.h>
+#include <pcb_copper_pour.h>
+#include <pcb_cutout.h>
+#include <pcb_plane.h>
+#include <pcb_line.h>
+#include <pcb_module.h>
+#include <pcb_pad.h>
+#include <pcb_polygon.h>
+#include <pcb_text.h>
+#include <pcb_via.h>
+
+#include <trigo.h>
+
+namespace PCAD2KICAD {
+
+PCB_MODULE::PCB_MODULE( PCB_CALLBACKS* aCallbacks, BOARD* aBoard ) : PCB_COMPONENT( aCallbacks,
+ aBoard )
+{
+ InitTTextValue( &m_value );
+ m_mirror = 0;
+ m_objType = wxT( 'M' ); // MODULE
+ m_KiCadLayer = F_SilkS; // default
+}
+
+
+PCB_MODULE::~PCB_MODULE()
+{
+ int i;
+
+ for( i = 0; i < (int) m_moduleObjects.GetCount(); i++ )
+ {
+ delete m_moduleObjects[i];
+ }
+}
+
+
+XNODE* PCB_MODULE::FindModulePatternDefName( XNODE* aNode, wxString aName )
+{
+ XNODE* result, * lNode;
+ wxString propValue1, propValue2;
+
+ result = NULL;
+ lNode = FindNode( aNode, wxT( "patternDef" ) );
+
+ while( lNode )
+ {
+ if( lNode->GetName() == wxT( "patternDef" ) )
+ {
+ lNode->GetAttribute( wxT( "Name" ), &propValue1 );
+ FindNode( lNode,
+ wxT( "originalName" ) )->GetAttribute( wxT( "Name" ), &propValue2 );
+
+ if( ValidateName( propValue1 ) == aName
+ || ValidateName( propValue2 ) == aName )
+ {
+ result = lNode;
+ lNode = NULL;
+ }
+ }
+
+ if( lNode )
+ lNode = lNode->GetNext();
+ }
+
+ if( result == NULL )
+ {
+ lNode = FindNode( aNode, wxT( "patternDefExtended" ) ); // New file format
+
+ while( lNode )
+ {
+ if( lNode->GetName() == wxT( "patternDefExtended" ) )
+ {
+ lNode->GetAttribute( wxT( "Name" ), &propValue1 );
+
+ if( ValidateName( propValue1 ) == aName )
+ {
+ result = lNode;
+ lNode = NULL;
+ }
+ }
+
+ if( lNode )
+ lNode = lNode->GetNext();
+ }
+ }
+
+ return result;
+}
+
+
+XNODE* PCB_MODULE::FindPatternMultilayerSection( XNODE* aNode, wxString* aPatGraphRefName )
+{
+ XNODE* result, * pNode, * lNode;
+ wxString propValue, patName;
+
+ result = NULL;
+ pNode = aNode; // pattern;
+ lNode = aNode;
+
+ // calling from library conversion we need to find pattern
+ if( lNode->GetName() == wxT( "compDef" ) )
+ {
+ lNode->GetAttribute( wxT( "Name" ), &propValue );
+ propValue.Trim( false );
+ patName = ValidateName( propValue );
+
+ if( FindNode( lNode, wxT( "attachedPattern" ) ) )
+ {
+ FindNode( FindNode( lNode, wxT( "attachedPattern" ) ),
+ wxT( "patternName" ) )->GetAttribute( wxT( "Name" ), &propValue );
+ propValue.Trim( false );
+ propValue.Trim( true );
+ patName = ValidateName( propValue );
+ }
+
+ lNode = FindModulePatternDefName( lNode->GetParent(), patName );
+ pNode = lNode; // pattern;
+ }
+
+ lNode = NULL;
+
+ if( pNode )
+ lNode = FindNode( pNode, wxT( "multiLayer" ) ); // Old file format
+
+ if( lNode )
+ {
+ *aPatGraphRefName = wxEmptyString; // default
+ result = lNode;
+ }
+ else
+ {
+ // New file format
+
+ if( *aPatGraphRefName == wxEmptyString ) // default
+ {
+ if( FindNode( aNode, wxT( "patternGraphicsNameRef" ) ) )
+ {
+ FindNode( aNode,
+ wxT( "patternGraphicsNameRef" ) )->GetAttribute( wxT( "Name" ),
+ aPatGraphRefName );
+ }
+ }
+
+ if( FindNode( aNode, wxT( "patternGraphicsDef" ) ) )
+ lNode = FindNode( aNode, wxT( "patternGraphicsDef" ) );
+ else
+ lNode = FindNode( pNode, wxT( "patternGraphicsDef" ) );
+
+ if( *aPatGraphRefName == wxEmptyString ) // no patern delection, the first is actual...
+ {
+ if( lNode )
+ {
+ result = FindNode( lNode, wxT( "multiLayer" ) );
+ lNode = NULL;
+ }
+ }
+
+ while( lNode ) // selected by name
+ {
+ if( lNode->GetName() == wxT( "patternGraphicsDef" ) )
+ {
+ FindNode( lNode,
+ wxT( "patternGraphicsNameDef" ) )->GetAttribute( wxT( "Name" ),
+ &propValue );
+
+ if( propValue == *aPatGraphRefName )
+ {
+ result = FindNode( lNode, wxT( "multiLayer" ) );
+ lNode = NULL;
+ }
+ else
+ lNode = lNode->GetNext();
+ }
+ else
+ lNode = lNode->GetNext();
+ }
+ }
+
+ return result;
+}
+
+
+void PCB_MODULE::DoLayerContentsObjects( XNODE* aNode,
+ PCB_MODULE* aPCBModule,
+ PCB_COMPONENTS_ARRAY* aList,
+ wxStatusBar* aStatusBar,
+ wxString aDefaultMeasurementUnit,
+ wxString aActualConversion )
+{
+ PCB_ARC* arc;
+ PCB_POLYGON* polygon;
+ PCB_POLYGON *plane_layer = NULL;
+ PCB_COPPER_POUR* copperPour;
+ PCB_CUTOUT* cutout;
+ PCB_PLANE* plane;
+ VERTICES_ARRAY* plane_layer_polygon;
+ PCB_LINE* line;
+ PCB_TEXT* text;
+ XNODE* lNode, * tNode;
+ wxString propValue;
+ long long i;
+ int PCadLayer;
+ long num = 0;
+
+ i = 0;
+ // aStatusBar->SetStatusText( wxT( "Processing LAYER CONTENT OBJECTS " ) );
+ if( FindNode( aNode, wxT( "layerNumRef" ) ) )
+ FindNode( aNode, wxT( "layerNumRef" ) )->GetNodeContent().ToLong( &num );
+
+ PCadLayer = (int) num;
+
+ if( m_callbacks->GetLayerType( PCadLayer ) == LAYER_TYPE_PLANE )
+ {
+ plane_layer = new PCB_POLYGON( m_callbacks, m_board, PCadLayer );
+ plane_layer->AssignNet( m_callbacks->GetLayerNetNameRef( PCadLayer ) );
+ plane_layer->SetOutline( &m_boardOutline );
+ aList->Add( plane_layer );
+
+ // fill the polygon with the same contour as its outline is
+ //plane_layer->AddIsland( &m_boardOutline );
+ }
+
+ lNode = aNode->GetChildren();
+
+ while( lNode )
+ {
+ i++;
+ // aStatusBar->SetStatusText( wxString::Format( "Processing LAYER CONTENT OBJECTS :%lld",
+ // i ) );
+
+ if( lNode->GetName() == wxT( "line" ) )
+ {
+ line = new PCB_LINE( m_callbacks, m_board );
+ line->Parse( lNode, PCadLayer, aDefaultMeasurementUnit, aActualConversion );
+ aList->Add( line );
+ }
+
+ if( lNode->GetName() == wxT( "text" ) )
+ {
+ text = new PCB_TEXT( m_callbacks, m_board );
+ text->Parse( lNode, PCadLayer, aDefaultMeasurementUnit, aActualConversion );
+ aList->Add( text );
+ }
+
+ // added as Sergeys request 02/2008
+ if( lNode->GetName() == wxT( "attr" ) )
+ {
+ // assign fonts to Module Name,Value,Type,....s
+ lNode->GetAttribute( wxT( "Name" ), &propValue );
+ propValue.Trim( false );
+ propValue.Trim( true );
+
+ if( propValue == wxT( "RefDes" ) )
+ {
+ tNode = FindNode( lNode, wxT( "textStyleRef" ) );
+
+ if( tNode && aPCBModule )
+ {
+ // TODO: to understand and may be repair
+ // Alexander Lunev: originally in Delphi version of the project there was
+ // a strange access to pcbModule->m_name (it was global variable). This access
+ // is necessary when the function DoLayerContentsObjects() is called from
+ // function CreatePCBModule(). However it is not clear whether the access is
+ // required when the function DoLayerContentsObjects() is called from
+ // function ProcessXMLtoPCBLib().
+ SetFontProperty( tNode,
+ &aPCBModule->m_name,
+ aDefaultMeasurementUnit,
+ aActualConversion );
+ }
+ }
+ }
+
+ // added as Sergeys request 02/2008
+ if( lNode->GetName() == wxT( "arc" ) || lNode->GetName() == wxT( "triplePointArc" ) )
+ {
+ arc = new PCB_ARC( m_callbacks, m_board );
+ arc->Parse( lNode, PCadLayer, aDefaultMeasurementUnit, aActualConversion );
+ aList->Add( arc );
+ }
+
+ if( lNode->GetName() == wxT( "pcbPoly" ) )
+ {
+ if( m_callbacks->GetLayerType( PCadLayer ) == LAYER_TYPE_PLANE )
+ {
+ plane_layer_polygon = new VERTICES_ARRAY;
+ wxASSERT( plane_layer );
+ plane_layer->FormPolygon( lNode, plane_layer_polygon, aDefaultMeasurementUnit, aActualConversion );
+ plane_layer->m_cutouts.Add( plane_layer_polygon );
+ }
+ else
+ {
+ polygon = new PCB_POLYGON( m_callbacks, m_board, PCadLayer );
+ if( polygon->Parse( lNode,
+ aDefaultMeasurementUnit,
+ aActualConversion,
+ aStatusBar ) )
+ aList->Add( polygon );
+ else
+ delete polygon;
+ }
+ }
+
+ if( lNode->GetName() == wxT( "copperPour95" ) )
+ {
+ copperPour = new PCB_COPPER_POUR( m_callbacks, m_board, PCadLayer );
+
+ if( copperPour->Parse( lNode, aDefaultMeasurementUnit, aActualConversion,
+ aStatusBar ) )
+ aList->Add( copperPour );
+ else
+ delete copperPour;
+ }
+
+ if( lNode->GetName() == wxT( "polyCutOut" ) )
+ {
+ cutout = new PCB_CUTOUT( m_callbacks, m_board, PCadLayer );
+
+ if( cutout->Parse( lNode, aDefaultMeasurementUnit, aActualConversion ) )
+ aList->Add( cutout );
+ else
+ delete cutout;
+ }
+
+ if( lNode->GetName() == wxT( "planeObj" ) )
+ {
+ plane = new PCB_PLANE( m_callbacks, m_board, PCadLayer );
+
+ if( plane->Parse( lNode, aDefaultMeasurementUnit, aActualConversion,
+ aStatusBar ) )
+ aList->Add( plane );
+ else
+ delete plane;
+ }
+
+ lNode = lNode->GetNext();
+ }
+}
+
+
+void PCB_MODULE::SetPadName( wxString aPin, wxString aName )
+{
+ int i;
+ long num;
+
+ aPin.ToLong( &num );
+
+ for( i = 0; i < (int) m_moduleObjects.GetCount(); i++ )
+ {
+ if( m_moduleObjects[i]->m_objType == wxT( 'P' ) )
+ if( ( (PCB_PAD*) m_moduleObjects[i] )->m_number == num )
+ ( (PCB_PAD*) m_moduleObjects[i] )->m_name.text = aName;
+
+
+ }
+}
+
+
+void PCB_MODULE::Parse( XNODE* aNode, wxStatusBar* aStatusBar,
+ wxString aDefaultMeasurementUnit, wxString aActualConversion )
+{
+ XNODE* lNode, * tNode, * mNode;
+ PCB_PAD* pad;
+ PCB_VIA* via;
+ wxString propValue, str;
+
+ FindNode( aNode, wxT( "originalName" ) )->GetAttribute( wxT( "Name" ),
+ &propValue );
+ propValue.Trim( false );
+ m_name.text = propValue;
+
+ // aStatusBar->SetStatusText( wxT( "Creating Component : " ) + m_name.text );
+ lNode = aNode;
+ lNode = FindPatternMultilayerSection( lNode, &m_patGraphRefName );
+
+ if( lNode )
+ {
+ tNode = lNode;
+ tNode = tNode->GetChildren();
+
+ while( tNode )
+ {
+ if( tNode->GetName() == wxT( "pad" ) )
+ {
+ pad = new PCB_PAD( m_callbacks, m_board );
+ pad->Parse( tNode, aDefaultMeasurementUnit, aActualConversion );
+ m_moduleObjects.Add( pad );
+ }
+
+ if( tNode->GetName() == wxT( "via" ) )
+ {
+ via = new PCB_VIA( m_callbacks, m_board );
+ via->Parse( tNode, aDefaultMeasurementUnit, aActualConversion );
+ m_moduleObjects.Add( via );
+ }
+
+ tNode = tNode->GetNext();
+ }
+ }
+
+ if( lNode )
+ lNode = lNode->GetParent();
+
+ if( lNode )
+ lNode = FindNode( lNode, wxT( "layerContents" ) );
+
+ while( lNode )
+ {
+ if( lNode->GetName() == wxT( "layerContents" ) )
+ DoLayerContentsObjects( lNode, this, &m_moduleObjects, aStatusBar,
+ aDefaultMeasurementUnit, aActualConversion );
+
+ lNode = lNode->GetNext();
+ }
+
+ // map pins
+ lNode = FindPinMap( aNode );
+
+ if( lNode )
+ {
+ mNode = lNode->GetChildren();
+
+ while( mNode )
+ {
+ if( mNode->GetName() == wxT( "padNum" ) )
+ {
+ str = mNode->GetNodeContent();
+ mNode = mNode->GetNext();
+
+ if( !mNode )
+ break;
+
+ mNode->GetAttribute( wxT( "Name" ), &propValue );
+ SetPadName( str, propValue );
+ mNode = mNode->GetNext();
+ }
+ else
+ {
+ mNode = mNode->GetNext();
+
+ if( !mNode )
+ break;
+
+ mNode = mNode->GetNext();
+ }
+ }
+ }
+}
+
+
+wxString PCB_MODULE::ModuleLayer( int aMirror )
+{
+ wxString result;
+
+ // ///NOT ! {IntToStr(KiCadLayer)} NOT !
+ // / MODULES ARE HARD PLACED ON COMPONENT OR COPPER LAYER.
+ // / IsFLIPPED--> MIRROR attribute is decision Point!!!
+
+ if( aMirror == 0 )
+ result = wxT( "15" ); // Components side
+ else
+ result = wxT( "0" ); // Copper side
+
+ return result;
+}
+
+
+void PCB_MODULE::AddToBoard()
+{
+ int i;
+ int r;
+
+ // transform text positions
+ CorrectTextPosition( &m_name );
+ RotatePoint( &m_name.correctedPositionX, &m_name.correctedPositionY,
+ (double) -m_rotation );
+
+ CorrectTextPosition( &m_value );
+ RotatePoint( &m_value.correctedPositionX, &m_value.correctedPositionY,
+ (double) -m_rotation );
+
+ MODULE* module = new MODULE( m_board );
+ m_board->Add( module, ADD_APPEND );
+
+ module->SetPosition( wxPoint( m_positionX, m_positionY ) );
+ module->SetLayer( m_mirror ? B_Cu : F_Cu );
+ module->SetOrientation( m_rotation );
+ module->SetTimeStamp( 0 );
+ module->SetLastEditTime( 0 );
+
+ module->SetFPID( FPID( m_compRef ) );
+
+ module->SetAttributes( MOD_DEFAULT | MOD_CMS );
+
+ // reference text
+ TEXTE_MODULE* ref_text = &module->Reference();
+
+ ref_text->SetText( m_name.text );
+ ref_text->SetType( TEXTE_MODULE::TEXT_is_REFERENCE );
+
+ ref_text->SetPos0( wxPoint( m_name.correctedPositionX, m_name.correctedPositionY ) );
+ ref_text->SetSize( wxSize( KiROUND( m_name.textHeight / 2 ),
+ KiROUND( m_name.textHeight / 1.5 ) ) );
+
+ r = m_name.textRotation - m_rotation;
+ ref_text->SetOrientation( r );
+
+ ref_text->SetThickness( m_name.textstrokeWidth );
+
+ ref_text->SetMirrored( m_name.mirror );
+ ref_text->SetVisible( m_name.textIsVisible );
+
+ ref_text->SetLayer( m_KiCadLayer );
+
+ // Calculate the actual position.
+ ref_text->SetDrawCoord();
+
+ // value text
+ TEXTE_MODULE* val_text = &module->Value();
+
+ val_text->SetText( m_value.text );
+ val_text->SetType( TEXTE_MODULE::TEXT_is_VALUE );
+
+ val_text->SetPos0( wxPoint( m_value.correctedPositionX, m_value.correctedPositionY ) );
+ val_text->SetSize( wxSize( KiROUND( m_value.textHeight / 2 ),
+ KiROUND( m_value.textHeight / 1.5 ) ) );
+
+ r = m_value.textRotation - m_rotation;
+ val_text->SetOrientation( r );
+
+ val_text->SetThickness( m_value.textstrokeWidth );
+
+ val_text->SetMirrored( m_value.mirror );
+ val_text->SetVisible( m_value.textIsVisible );
+
+ val_text->SetLayer( m_KiCadLayer );
+
+ // Calculate the actual position.
+ val_text->SetDrawCoord();
+
+ // TEXTS
+ for( i = 0; i < (int) m_moduleObjects.GetCount(); i++ )
+ {
+ if( m_moduleObjects[i]->m_objType == wxT( 'T' ) )
+ {
+ ( (PCB_TEXT*) m_moduleObjects[i] )->m_tag = i + 2;
+ m_moduleObjects[i]->AddToModule( module );
+ }
+ }
+
+ // MODULE LINES
+ for( i = 0; i < (int) m_moduleObjects.GetCount(); i++ )
+ {
+ if( m_moduleObjects[i]->m_objType == wxT( 'L' ) )
+ m_moduleObjects[i]->AddToModule( module );
+ }
+
+ // MODULE Arcs
+ for( i = 0; i < (int) m_moduleObjects.GetCount(); i++ )
+ {
+ if( m_moduleObjects[i]->m_objType == wxT( 'A' ) )
+ m_moduleObjects[i]->AddToModule( module );
+ }
+
+ // PADS
+ for( i = 0; i < (int) m_moduleObjects.GetCount(); i++ )
+ {
+ if( m_moduleObjects[i]->m_objType == wxT( 'P' ) )
+ ( (PCB_PAD*) m_moduleObjects[i] )->AddToModule( module, m_rotation, false );
+ }
+
+ // VIAS
+ for( i = 0; i < (int) m_moduleObjects.GetCount(); i++ )
+ {
+ if( m_moduleObjects[i]->m_objType == wxT( 'V' ) )
+ ( (PCB_VIA*) m_moduleObjects[i] )->AddToModule( module, m_rotation, false );
+ }
+
+ module->CalculateBoundingBox();
+}
+
+
+void PCB_MODULE::Flip()
+{
+ int i;
+
+ if( m_mirror == 1 )
+ {
+ // Flipped
+ m_KiCadLayer = FlipLayer( m_KiCadLayer );
+ m_rotation = -m_rotation;
+
+ for( i = 0; i < (int) m_moduleObjects.GetCount(); i++ )
+ {
+ if( m_moduleObjects[i]->m_objType == wxT( 'L' ) || // lines
+ m_moduleObjects[i]->m_objType == wxT( 'A' ) || // arcs
+ m_moduleObjects[i]->m_objType == wxT( 'P' ) || // pads
+ m_moduleObjects[i]->m_objType == wxT( 'V' ) ) // vias
+ {
+ m_moduleObjects[i]->Flip();
+ }
+ }
+ }
+}
+
+} // namespace PCAD2KICAD