summaryrefslogtreecommitdiff
path: root/pcbnew/pcad2kicadpcb_plugin/pcb_pad.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'pcbnew/pcad2kicadpcb_plugin/pcb_pad.cpp')
-rw-r--r--pcbnew/pcad2kicadpcb_plugin/pcb_pad.cpp363
1 files changed, 363 insertions, 0 deletions
diff --git a/pcbnew/pcad2kicadpcb_plugin/pcb_pad.cpp b/pcbnew/pcad2kicadpcb_plugin/pcb_pad.cpp
new file mode 100644
index 0000000..f1e9b91
--- /dev/null
+++ b/pcbnew/pcad2kicadpcb_plugin/pcb_pad.cpp
@@ -0,0 +1,363 @@
+/*
+ * 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_pad.cpp
+ */
+
+#include <wx/wx.h>
+#include <wx/config.h>
+#include <trigo.h>
+
+#include <pcb_pad.h>
+
+namespace PCAD2KICAD {
+
+PCB_PAD::PCB_PAD( PCB_CALLBACKS* aCallbacks, BOARD* aBoard ) : PCB_COMPONENT( aCallbacks, aBoard )
+{
+ m_objType = wxT( 'P' );
+ m_number = 0;
+ m_hole = 0;
+ m_isHolePlated = true;
+ m_defaultPinDes = wxEmptyString;
+}
+
+
+PCB_PAD::~PCB_PAD()
+{
+ int i;
+
+ for( i = 0; i < (int) m_shapes.GetCount(); i++ )
+ {
+ delete m_shapes[i];
+ }
+}
+
+
+void PCB_PAD::Parse( XNODE* aNode, wxString aDefaultMeasurementUnit,
+ wxString aActualConversion )
+{
+ XNODE* lNode, *cNode;
+ long num;
+ wxString propValue, str, emsg;
+ PCB_PAD_SHAPE* padShape;
+
+ m_rotation = 0;
+ lNode = FindNode( aNode, wxT( "padNum" ) );
+
+ if( lNode )
+ {
+ lNode->GetNodeContent().ToLong( &num );
+ m_number = (int) num;
+ }
+
+ lNode = FindNode( aNode, wxT( "padStyleRef" ) );
+
+ if( lNode )
+ {
+ lNode->GetAttribute( wxT( "Name" ), &propValue );
+ propValue.Trim( false );
+ m_name.text = propValue;
+ }
+
+ lNode = FindNode( aNode, wxT( "pt" ) );
+
+ if( lNode )
+ SetPosition( lNode->GetNodeContent(), aDefaultMeasurementUnit,
+ &m_positionX, &m_positionY, aActualConversion );
+
+ lNode = FindNode( aNode, wxT( "rotation" ) );
+
+ if( lNode )
+ {
+ str = lNode->GetNodeContent();
+ str.Trim( false );
+ m_rotation = StrToInt1Units( str );
+ }
+
+ lNode = FindNode( aNode, wxT( "netNameRef" ) );
+
+ if( lNode )
+ {
+ lNode->GetAttribute( wxT( "Name" ), &propValue );
+ propValue.Trim( false );
+ propValue.Trim( true );
+ m_net = propValue;
+ m_netCode = GetNetCode( m_net );
+ }
+
+ lNode = FindNode( aNode, wxT( "defaultPinDes" ) );
+
+ if( lNode )
+ {
+ lNode->GetAttribute( wxT( "Name" ), &propValue );
+ //propValue.Trim( false );
+ m_defaultPinDes = propValue;
+ }
+
+ lNode = aNode;
+
+ while( lNode && lNode->GetName() != wxT( "www.lura.sk" ) )
+ lNode = lNode->GetParent();
+
+ lNode = FindNode( lNode, wxT( "library" ) );
+ if ( !lNode )
+ THROW_IO_ERROR( wxT( "Unable to find library section" ) );
+
+ lNode = FindNode( lNode, wxT( "padStyleDef" ) );
+
+ while( lNode )
+ {
+ lNode->GetAttribute( wxT( "Name" ), &propValue );
+
+ if( propValue.IsSameAs( m_name.text, false) )
+ break;
+
+ lNode = lNode->GetNext();
+ }
+
+ if ( !lNode )
+ THROW_IO_ERROR( wxString::Format( wxT( "Unable to find padStyleDef " ) + m_name.text ) );
+
+ cNode = FindNode( lNode, wxT( "holeDiam" ) );
+
+ if( cNode )
+ SetWidth( cNode->GetNodeContent(), aDefaultMeasurementUnit, &m_hole, aActualConversion );
+
+ if( FindNodeGetContent( lNode, wxT( "isHolePlated" ) ) == wxT( "False" ) )
+ m_isHolePlated = false;
+
+ cNode = FindNode( lNode, wxT( "padShape" ) );
+
+ while( cNode )
+ {
+ if( cNode->GetName() == wxT( "padShape" ) )
+ {
+ // we support only Pads on specific layers......
+ // we do not support pads on "Plane", "NonSignal" , "Signal" ... layerr
+ if( FindNode( cNode, wxT( "layerNumRef" ) ) )
+ {
+ padShape = new PCB_PAD_SHAPE( m_callbacks, m_board );
+ padShape->Parse( cNode, aDefaultMeasurementUnit, aActualConversion );
+ m_shapes.Add( padShape );
+ }
+ }
+
+ cNode = cNode->GetNext();
+ }
+}
+
+
+void PCB_PAD::Flip()
+{
+ int i;
+
+ PCB_COMPONENT::Flip();
+
+ if( m_objType == wxT( 'P' ) )
+ m_rotation = -m_rotation;
+
+ for( i = 0; i < (int)m_shapes.GetCount(); i++ )
+ m_shapes[i]->m_KiCadLayer = FlipLayer( m_shapes[i]->m_KiCadLayer );
+}
+
+
+void PCB_PAD::AddToModule( MODULE* aModule, int aRotation, bool aEncapsulatedPad )
+{
+ PCB_PAD_SHAPE* padShape;
+ wxString padShapeName = wxT( "Ellipse" );
+ PAD_ATTR_T padType;
+ int i;
+ int width = 0;
+ int height = 0;
+
+ D_PAD* pad = new D_PAD( aModule );
+
+ if( !m_isHolePlated && m_hole )
+ {
+ // mechanical hole
+ pad->SetShape( PAD_SHAPE_CIRCLE );
+ pad->SetAttribute( PAD_ATTRIB_HOLE_NOT_PLATED );
+
+ pad->SetDrillShape( PAD_DRILL_SHAPE_CIRCLE );
+ pad->SetDrillSize( wxSize( m_hole, m_hole ) );
+ pad->SetSize( wxSize( m_hole, m_hole ) );
+
+ pad->SetLayerSet( LSET::AllCuMask() | LSET( 2, B_Mask, F_Mask ) );
+ }
+ else
+ {
+ ( m_hole ) ? padType = PAD_ATTRIB_STANDARD : padType = PAD_ATTRIB_SMD;
+
+ // form layer mask
+ for( i = 0; i < (int) m_shapes.GetCount(); i++ )
+ {
+ padShape = m_shapes[i];
+
+ if( padShape->m_width > 0 && padShape->m_height > 0 )
+ {
+ if( padShape->m_KiCadLayer == F_Cu ||
+ padShape->m_KiCadLayer == B_Cu )
+ {
+ padShapeName = padShape->m_shape;
+ width = padShape->m_width;
+ height = padShape->m_height;
+
+ // assume this is SMD pad
+ if( padShape->m_KiCadLayer == F_Cu )
+ pad->SetLayerSet( LSET( 3, F_Cu, F_Paste, F_Mask ) );
+ else
+ pad->SetLayerSet( LSET( 3, B_Cu, B_Paste, B_Mask ) );
+ break;
+ }
+ }
+ }
+
+ if( width == 0 || height == 0 )
+ {
+ delete pad;
+ return;
+ }
+
+ if( padType == PAD_ATTRIB_STANDARD )
+ // actually this is a thru-hole pad
+ pad->SetLayerSet( LSET::AllCuMask() | LSET( 2, B_Mask, F_Mask ) );
+
+ pad->SetPadName( m_name.text );
+
+ if( padShapeName == wxT( "Oval" )
+ || padShapeName == wxT( "Ellipse" )
+ || padShapeName == wxT( "MtHole" ) )
+ {
+ if( width != height )
+ pad->SetShape( PAD_SHAPE_OVAL );
+ else
+ pad->SetShape( PAD_SHAPE_CIRCLE );
+ }
+ else if( padShapeName == wxT( "Rect" )
+ || padShapeName == wxT( "RndRect" ) )
+ pad->SetShape( PAD_SHAPE_RECT );
+ else if( padShapeName == wxT( "Polygon" ) )
+ pad->SetShape( PAD_SHAPE_RECT ); // approximation
+
+ pad->SetSize( wxSize( width, height ) );
+ pad->SetDelta( wxSize( 0, 0 ) );
+ pad->SetOrientation( m_rotation + aRotation );
+
+ pad->SetDrillShape( PAD_DRILL_SHAPE_CIRCLE );
+ pad->SetOffset( wxPoint( 0, 0 ) );
+ pad->SetDrillSize( wxSize( m_hole, m_hole ) );
+
+ pad->SetAttribute( padType );
+
+ // Set the proper net code
+ NETINFO_ITEM* netinfo = m_board->FindNet( m_net );
+ if( netinfo == NULL ) // I believe this should not happen, but just in case
+ {
+ // It is a new net
+ netinfo = new NETINFO_ITEM( m_board, m_net );
+ m_board->AppendNet( netinfo );
+ }
+
+ pad->SetNetCode( netinfo->GetNet() );
+ }
+
+ if( !aEncapsulatedPad )
+ {
+ // pad's "Position" is not relative to the module's,
+ // whereas Pos0 is relative to the module's but is the unrotated coordinate.
+ wxPoint padpos( m_positionX, m_positionY );
+ pad->SetPos0( padpos );
+ RotatePoint( &padpos, aModule->GetOrientation() );
+ pad->SetPosition( padpos + aModule->GetPosition() );
+ }
+
+ aModule->Pads().PushBack( pad );
+}
+
+
+void PCB_PAD::AddToBoard()
+{
+ PCB_PAD_SHAPE* padShape;
+ int i;
+ int width = 0;
+ int height = 0;
+
+ if( m_objType == wxT( 'V' ) ) // via
+ {
+ // choose one of the shapes
+ for( i = 0; i < (int) m_shapes.GetCount(); i++ )
+ {
+ padShape = m_shapes[i];
+
+ if( padShape->m_width > 0 && padShape->m_height > 0 )
+ {
+ if( padShape->m_KiCadLayer == F_Cu
+ || padShape->m_KiCadLayer == B_Cu )
+ {
+ width = padShape->m_width;
+ height = padShape->m_height;
+
+ break;
+ }
+ }
+ }
+
+ if( width == 0 || height == 0 )
+ return;
+
+ if( IsCopperLayer( m_KiCadLayer ) )
+ {
+ VIA* via = new VIA( m_board );
+ m_board->m_Track.Append( via );
+
+ via->SetTimeStamp( 0 );
+
+ via->SetPosition( wxPoint( m_positionX, m_positionY ) );
+ via->SetEnd( wxPoint( m_positionX, m_positionY ) );
+
+ via->SetWidth( height );
+ via->SetViaType( VIA_THROUGH );
+ via->SetLayerPair( F_Cu, B_Cu );
+ via->SetDrill( m_hole );
+
+ via->SetLayer( m_KiCadLayer );
+ via->SetNetCode( m_netCode );
+ }
+ }
+ else // pad
+ {
+ MODULE* module = new MODULE( m_board );
+ m_board->Add( module, ADD_APPEND );
+
+ m_name.text = m_defaultPinDes;
+
+ module->SetPosition( wxPoint( m_positionX, m_positionY ) );
+ AddToModule( module, 0, true );
+
+ }
+}
+
+} // namespace PCAD2KICAD