diff options
Diffstat (limited to 'pcbnew/pcad2kicadpcb_plugin/pcb_module.cpp')
-rw-r--r-- | pcbnew/pcad2kicadpcb_plugin/pcb_module.cpp | 640 |
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 |