From f2518a51204ee927b2ade7551164f290deb02ef8 Mon Sep 17 00:00:00 2001 From: jean-pierre charras Date: Wed, 11 Dec 2019 11:36:45 +0100 Subject: [PATCH] ADDED: pad fabrication property, as required in latest Gerber file specification. Property is a pad info used mainly for fabrication or test. Currently, supported properties are: BGA property (variant of SMD pad) Fiducial (global to the board or local to the footprint) Test Point Heat sink Castellated. And are used in Gerber files (copper layers and drill files) Increment BOARD_FILE_VERSION to 20200104 --- common/gbr_metadata.cpp | 27 +- common/pcb.keywords | 7 + include/gbr_metadata.h | 9 +- include/pad_shapes.h | 17 ++ pcbnew/class_pad.cpp | 29 +- pcbnew/class_pad.h | 5 + pcbnew/dialogs/dialog_pad_properties.cpp | 75 +++++- pcbnew/dialogs/dialog_pad_properties.h | 3 + pcbnew/dialogs/dialog_pad_properties_base.cpp | 27 +- pcbnew/dialogs/dialog_pad_properties_base.fbp | 255 +++++++++++++----- pcbnew/dialogs/dialog_pad_properties_base.h | 4 +- pcbnew/exporters/gendrill_gerber_writer.cpp | 17 +- pcbnew/kicad_plugin.cpp | 21 ++ pcbnew/kicad_plugin.h | 3 +- pcbnew/pcb_parser.cpp | 46 ++++ pcbnew/plot_brditems_plotter.cpp | 38 ++- 16 files changed, 485 insertions(+), 98 deletions(-) diff --git a/common/gbr_metadata.cpp b/common/gbr_metadata.cpp index 83d373a92d..d80d7a09d8 100644 --- a/common/gbr_metadata.cpp +++ b/common/gbr_metadata.cpp @@ -223,7 +223,32 @@ std::string GBR_APERTURE_METADATA::FormatAttribute( GBR_APERTURE_ATTRIB aAttribu attribute_string = "TA.AperFunction,HeatsinkPad"; break; - case GBR_APERTURE_ATTRIB_VIADRILL: // print info associated to a via hole in drill files + case GBR_APERTURE_ATTRIB_TESTPOINT: // print info associated to a flashed test point pad + // (typically for SMDs) + attribute_string = "TA.AperFunction,TestPad"; + break; + + case GBR_APERTURE_ATTRIB_FIDUCIAL_GLBL: // print info associated to a flashed fiducial pad + // (typically for SMDs) + attribute_string = "TA.AperFunction,FiducialPad,Global"; + break; + + case GBR_APERTURE_ATTRIB_FIDUCIAL_LOCAL: // print info associated to a flashed fiducial pad + // (typically for SMDs) + attribute_string = "TA.AperFunction,FiducialPad,Local"; + break; + + case GBR_APERTURE_ATTRIB_CASTELLATEDPAD: // print info associated to a flashed castellated pad + // (typically for SMDs) + attribute_string = "TA.AperFunction,CastellatedPad"; + break; + + case GBR_APERTURE_ATTRIB_CASTELLATEDDRILL: // print info associated to a flashed castellated pad + // in drill files + attribute_string = "TA.AperFunction,CastellatedDrill"; + break; + + case GBR_APERTURE_ATTRIB_VIADRILL: // print info associated to a via hole in drill files attribute_string = "TA.AperFunction,ViaDrill"; break; diff --git a/common/pcb.keywords b/common/pcb.keywords index 8000e090b7..af41b7c704 100644 --- a/common/pcb.keywords +++ b/common/pcb.keywords @@ -163,6 +163,13 @@ pad_size pad_to_mask_clearance pad_to_paste_clearance pad_to_paste_clearance_ratio +pad_prop_bga +pad_prop_fiducial_loc +pad_prop_fiducial_glob +pad_prop_castellated +pad_prop_testpoint +pad_prop_heatsink +property page path pcb_text_size diff --git a/include/gbr_metadata.h b/include/gbr_metadata.h index 26ac5ddcb7..10671f8388 100644 --- a/include/gbr_metadata.h +++ b/include/gbr_metadata.h @@ -85,14 +85,21 @@ public: GBR_APERTURE_ATTRIB_EDGECUT, ///< aperture used for board cutout GBR_APERTURE_ATTRIB_NONCONDUCTOR, ///< aperture used for not connected items (texts, outlines on copper) GBR_APERTURE_ATTRIB_VIAPAD, ///< aperture used for vias + GBR_APERTURE_ATTRIB_COMPONENTPAD, ///< aperture used for through hole component on outer layer GBR_APERTURE_ATTRIB_SMDPAD_SMDEF, ///< aperture used for SMD pad. Excluded BGA pads which have their own type GBR_APERTURE_ATTRIB_SMDPAD_CUDEF, ///< aperture used for SMD pad with a solder mask defined by the solder mask GBR_APERTURE_ATTRIB_BGAPAD_SMDEF, ///< aperture used for BGA pads with a solder mask defined by the copper shape GBR_APERTURE_ATTRIB_BGAPAD_CUDEF, ///< aperture used for BGA pad with a solder mask defined by the solder mask - GBR_APERTURE_ATTRIB_CONNECTORPAD, ///< aperture used for edge connecto pad (outer layers) + GBR_APERTURE_ATTRIB_CONNECTORPAD, ///< aperture used for edge connector pad (outer layers) GBR_APERTURE_ATTRIB_WASHERPAD, ///< aperture used for mechanical pads (NPTH) + GBR_APERTURE_ATTRIB_TESTPOINT, ///< aperture used for test point pad (outer layers) + GBR_APERTURE_ATTRIB_FIDUCIAL_GLBL, ///< aperture used for fiducial pad (outer layers), at board level + GBR_APERTURE_ATTRIB_FIDUCIAL_LOCAL, ///< aperture used for fiducial pad (outer layers), at footprint level GBR_APERTURE_ATTRIB_HEATSINKPAD, ///< aperture used for heat sink pad (typically for SMDs) + GBR_APERTURE_ATTRIB_CASTELLATEDPAD, ///< aperture used for castellated pads in copper layer files + GBR_APERTURE_ATTRIB_CASTELLATEDDRILL, ///< aperture used for castellated pads in drill files + GBR_APERTURE_ATTRIB_VIADRILL, ///< aperture used for via holes in drill files GBR_APERTURE_ATTRIB_CMP_DRILL, ///< aperture used for pad holes in drill files GBR_APERTURE_ATTRIB_CMP_OBLONG_DRILL, ///< aperture used for pads oblong holes in drill files diff --git a/include/pad_shapes.h b/include/pad_shapes.h index 8878b3646e..c435a12f57 100644 --- a/include/pad_shapes.h +++ b/include/pad_shapes.h @@ -68,4 +68,21 @@ enum PAD_ATTR_T }; +/** + * Enum PAD_PROP_T + * is the set of pad properties used in Gerber files (Draw files, and P&P files) + * to define some properties in fabrication or test files + */ +enum PAD_PROP_T +{ + PAD_PROP_NONE, ///< no special fabrication property + PAD_PROP_BGA, ///< Smd pad, used in BGA footprints + PAD_PROP_FIDUCIAL_GLBL, ///< a fiducial (usually a smd) for the full board + PAD_PROP_FIDUCIAL_LOCAL, ///< a fiducial (usually a smd) local to the parent footprint + PAD_PROP_TESTPOINT, ///< a test point pad + PAD_PROP_HEATSINK, ///< a pad used as heat sink, usually in SMD footprints + PAD_PROP_CASTELLATED ///< a pad with a castellated through hole +}; + + #endif // PAD_SHAPES_H_ diff --git a/pcbnew/class_pad.cpp b/pcbnew/class_pad.cpp index d6ea0b7732..496c8f9fd4 100644 --- a/pcbnew/class_pad.cpp +++ b/pcbnew/class_pad.cpp @@ -74,6 +74,7 @@ D_PAD::D_PAD( MODULE* parent ) : // is PAD_CIRCLE. SetDrillShape( PAD_DRILL_SHAPE_CIRCLE ); // Default pad drill shape is a circle. m_Attribute = PAD_ATTRIB_STANDARD; // Default pad type is NORMAL (thru hole) + SetProperty( PAD_PROP_NONE ); // no special fabrication property m_LocalClearance = 0; m_LocalSolderMaskMargin = 0; m_LocalSolderPasteMargin = 0; @@ -427,6 +428,12 @@ void D_PAD::SetAttribute( PAD_ATTR_T aAttribute ) } +void D_PAD::SetProperty( PAD_PROP_T aProperty ) +{ + m_Property = aProperty; +} + + void D_PAD::SetOrientation( double aAngle ) { NORMALIZE_ANGLE_POS( aAngle ); @@ -770,9 +777,26 @@ void D_PAD::GetMsgPanelInfo( EDA_UNITS aUnits, std::vector& aLis board = GetBoard(); aList.emplace_back( _( "Layer" ), - LayerMaskDescribe( board, m_layerMask ), DARKGREEN ); + LayerMaskDescribe( board, m_layerMask ), DARKGREEN ); - aList.emplace_back( ShowPadShape(), ShowPadAttr(), DARKGREEN ); + // Show the pad shape, attribute and property + wxString props = ShowPadAttr(); + + if( GetProperty() != PAD_PROP_NONE ) + props += ','; + + switch( GetProperty() ) + { + case PAD_PROP_NONE: break; + case PAD_PROP_BGA: props += _("BGA" ); break; + case PAD_PROP_FIDUCIAL_GLBL: props += _("Fiducial global" ); break; + case PAD_PROP_FIDUCIAL_LOCAL: props += _("Fiducial local" ); break; + case PAD_PROP_TESTPOINT: props += _("Test point" ); break; + case PAD_PROP_HEATSINK: props += _("Heat sink" ); break; + case PAD_PROP_CASTELLATED: props += _("Castellated" ); break; + } + + aList.emplace_back( ShowPadShape(), props, DARKGREEN ); msg = MessageTextFromValue( aUnits, m_Size.x, true ); aList.emplace_back( _( "Width" ), msg, RED ); @@ -1465,6 +1489,7 @@ void D_PAD::ImportSettingsFrom( const D_PAD& aMasterPad ) SetShape( aMasterPad.GetShape() ); SetLayerSet( aMasterPad.GetLayerSet() ); SetAttribute( aMasterPad.GetAttribute() ); + SetProperty( aMasterPad.GetProperty() ); // The pad orientation, for historical reasons is the // pad rotation + parent rotation. diff --git a/pcbnew/class_pad.h b/pcbnew/class_pad.h index f1de75915d..4f50762b8e 100644 --- a/pcbnew/class_pad.h +++ b/pcbnew/class_pad.h @@ -444,6 +444,9 @@ public: void SetAttribute( PAD_ATTR_T aAttribute ); PAD_ATTR_T GetAttribute() const { return m_Attribute; } + void SetProperty( PAD_PROP_T aProperty ); + PAD_PROP_T GetProperty() const { return m_Property; } + // We don't currently have an attribute for APERTURE, and adding one will change the file // format, so for now just infer a copper-less pad to be an APERTURE pad. bool IsAperturePad() const { return ( m_layerMask & LSET::AllCuMask() ).none(); } @@ -921,6 +924,8 @@ private: // Private variable members: PAD_ATTR_T m_Attribute; ///< PAD_ATTRIB_NORMAL, PAD_ATTRIB_SMD, ///< PAD_ATTRIB_CONN, PAD_ATTRIB_HOLE_NOT_PLATED + PAD_PROP_T m_Property; ///< property in fab files (BGA, FIDUCIAL, TEST POINT, CASTELLATED) + double m_Orient; ///< in 1/10 degrees int m_LengthPadToDie; ///< Length net from pad to die, inside the package diff --git a/pcbnew/dialogs/dialog_pad_properties.cpp b/pcbnew/dialogs/dialog_pad_properties.cpp index 57e2433bc1..189162cb35 100644 --- a/pcbnew/dialogs/dialog_pad_properties.cpp +++ b/pcbnew/dialogs/dialog_pad_properties.cpp @@ -24,12 +24,8 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ -#include -#include -#include #include #include -#include #include #include #include @@ -157,10 +153,10 @@ DIALOG_PAD_PROPERTIES::DIALOG_PAD_PROPERTIES( PCB_BASE_FRAME* aParent, D_PAD* aP m_techLayersLabel->SetFont( infoFont ); m_parentInfoLine1->SetFont( infoFont ); m_parentInfoLine2->SetFont( infoFont ); - m_nonCopperNote->SetFont( infoFont ); - m_staticTextInfoPaste->SetFont( infoFont ); infoFont.SetStyle( wxFONTSTYLE_ITALIC ); + m_nonCopperNote->SetFont( infoFont ); + m_staticTextInfoPaste->SetFont( infoFont ); m_staticTextInfoNegVal->SetFont( infoFont ); m_staticTextInfoPosValue->SetFont( infoFont ); @@ -765,6 +761,25 @@ void DIALOG_PAD_PROPERTIES::initValues() } } + switch( m_dummyPad->GetProperty() ) + { + case PAD_PROP_NONE: m_choiceFabProperty->SetSelection( 0 ); break; + case PAD_PROP_BGA: m_choiceFabProperty->SetSelection( 1 ); break; + case PAD_PROP_FIDUCIAL_LOCAL: m_choiceFabProperty->SetSelection( 2 ); break; + case PAD_PROP_FIDUCIAL_GLBL: m_choiceFabProperty->SetSelection( 3 ); break; + case PAD_PROP_TESTPOINT: m_choiceFabProperty->SetSelection( 4 ); break; + case PAD_PROP_HEATSINK: m_choiceFabProperty->SetSelection( 5 ); break; + case PAD_PROP_CASTELLATED: m_choiceFabProperty->SetSelection( 6 ); break; + } + + // Ensure the pad property is compatible with the pad type + if( m_dummyPad->GetAttribute() == PAD_ATTRIB_HOLE_NOT_PLATED ) + { + m_choiceFabProperty->SetSelection( 0 ); + m_choiceFabProperty->Enable( false ); + } + + // Disable Pad name,and pad to die length for mechanical and aperture pads m_PadNumText->Enable( !mechanical && !aperture ); m_PadNumCtrl->Enable( !mechanical && !aperture ); @@ -1017,6 +1032,7 @@ void DIALOG_PAD_PROPERTIES::PadTypeSelected( wxCommandEvent& event ) ii = 0; bool hasHole, hasConnection; + bool hasProperty = true; switch( ii ) { @@ -1024,7 +1040,12 @@ void DIALOG_PAD_PROPERTIES::PadTypeSelected( wxCommandEvent& event ) case 0: /* PTH */ hasHole = true; hasConnection = true; break; case 1: /* SMD */ hasHole = false; hasConnection = true; break; case 2: /* CONN */ hasHole = false; hasConnection = true; break; - case 3: /* NPTH */ hasHole = true; hasConnection = false; break; + case 3: /* NPTH */ + hasHole = true; + hasConnection = false; + hasProperty = false; + break; + case 4: /* Aperture */ hasHole = false; hasConnection = false; break; } @@ -1054,6 +1075,11 @@ void DIALOG_PAD_PROPERTIES::PadTypeSelected( wxCommandEvent& event ) m_PadNetSelector->SetSelectedNetcode( m_currentPad->GetNetCode() ); } + if( !hasProperty ) + m_choiceFabProperty->SetSelection( 0 ); + + m_choiceFabProperty->Enable( hasProperty ); + transferDataToPad( m_dummyPad ); redraw(); } @@ -1259,6 +1285,17 @@ bool DIALOG_PAD_PROPERTIES::padValuesOK() break; } + if( m_dummyPad->GetProperty() != PAD_PROP_NONE && + m_dummyPad->GetAttribute() == PAD_ATTRIB_HOLE_NOT_PLATED ) + error_msgs.Add( _( "Property cannot be set for NPTH" ) ); + + if( m_dummyPad->GetProperty() == PAD_PROP_CASTELLATED && + m_dummyPad->GetAttribute() != PAD_ATTRIB_STANDARD ) + error_msgs.Add( _( "Castellated property can be set only for PTH" ) ); + + if( m_dummyPad->GetProperty() == PAD_PROP_BGA && + m_dummyPad->GetAttribute() != PAD_ATTRIB_SMD ) + error_msgs.Add( _( "BGA property can be set only for SMD pads" ) ); if( m_dummyPad->GetShape() == PAD_SHAPE_ROUNDRECT || m_dummyPad->GetShape() == PAD_SHAPE_CHAMFERED_RECT ) @@ -1523,6 +1560,9 @@ bool DIALOG_PAD_PROPERTIES::TransferDataFromWindow() m_currentPad->SetShape( PAD_SHAPE_RECT ); } + // Set the fabrication property: + m_currentPad->SetProperty( getSelectedProperty() ); + // define the way the clearance area is defined in zones m_currentPad->SetCustomShapeInZoneOpt( m_padMaster->GetCustomShapeInZoneOpt() ); @@ -1540,6 +1580,25 @@ bool DIALOG_PAD_PROPERTIES::TransferDataFromWindow() } +PAD_PROP_T DIALOG_PAD_PROPERTIES::getSelectedProperty() +{ + PAD_PROP_T prop = PAD_PROP_NONE; + + switch( m_choiceFabProperty->GetSelection() ) + { + case 0: prop = PAD_PROP_NONE; break; + case 1: prop = PAD_PROP_BGA; break; + case 2: prop = PAD_PROP_FIDUCIAL_LOCAL; break; + case 3: prop = PAD_PROP_FIDUCIAL_GLBL; break; + case 4: prop = PAD_PROP_TESTPOINT; break; + case 5: prop = PAD_PROP_HEATSINK; break; + case 6: prop = PAD_PROP_CASTELLATED; break; + } + + return prop; +} + + bool DIALOG_PAD_PROPERTIES::transferDataToPad( D_PAD* aPad ) { wxString msg; @@ -1773,6 +1832,8 @@ bool DIALOG_PAD_PROPERTIES::transferDataToPad( D_PAD* aPad ) aPad->SetChamferRectRatio( ratioPercent / 100.0 ); } + aPad->SetProperty( getSelectedProperty() ); + LSET padLayerMask; switch( m_rbCopperLayersSel->GetSelection() ) diff --git a/pcbnew/dialogs/dialog_pad_properties.h b/pcbnew/dialogs/dialog_pad_properties.h index cc1721695b..3dab9dfa50 100644 --- a/pcbnew/dialogs/dialog_pad_properties.h +++ b/pcbnew/dialogs/dialog_pad_properties.h @@ -152,6 +152,9 @@ private: void onPrimitiveDClick( wxMouseEvent& event ) override; /// Called on selection/deselection of a basic shape void OnPrimitiveSelection( wxListEvent& event ) override; + + /// Return the pad property currently selected + PAD_PROP_T getSelectedProperty(); }; /** diff --git a/pcbnew/dialogs/dialog_pad_properties_base.cpp b/pcbnew/dialogs/dialog_pad_properties_base.cpp index 5ea9b335b7..8b1743ea89 100644 --- a/pcbnew/dialogs/dialog_pad_properties_base.cpp +++ b/pcbnew/dialogs/dialog_pad_properties_base.cpp @@ -392,7 +392,19 @@ DIALOG_PAD_PROPERTIES_BASE::DIALOG_PAD_PROPERTIES_BASE( wxWindow* parent, wxWind m_LayersSizer->Add( m_PadLayerECO2, 0, wxALL, 4 ); - m_middleBoxSizer->Add( m_LayersSizer, 1, wxEXPAND|wxLEFT|wxRIGHT|wxTOP, 5 ); + m_middleBoxSizer->Add( m_LayersSizer, 0, wxLEFT|wxRIGHT|wxTOP|wxEXPAND, 5 ); + + m_staticTextFabProperty = new wxStaticText( m_panelGeneral, wxID_ANY, _("Fabrication Property:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticTextFabProperty->Wrap( -1 ); + m_staticTextFabProperty->SetToolTip( _("Optional property to specify a special purpose or constraint in fabrication files:\nBGA attribute is for pads in BGA footprints\nFiducial local is a fiducial for the parent footprint\nFiducial global is a fiducial for the whole board\nTest pad is useful to specify test points in Gerber files\nHeatsink pad specify a thermal pad\nCastellated specify castellated through hole pads on a board edge\nThis property is specified in Gerber X2 files.") ); + + m_middleBoxSizer->Add( m_staticTextFabProperty, 0, wxTOP|wxRIGHT|wxLEFT, 5 ); + + wxString m_choiceFabPropertyChoices[] = { _("None"), _("BGA pad"), _("Fiducial, local to footprint"), _("Fiducial, global to board"), _("Test Point Pad"), _("Heatsink pad"), _("Castellated pad (through hole only)") }; + int m_choiceFabPropertyNChoices = sizeof( m_choiceFabPropertyChoices ) / sizeof( wxString ); + m_choiceFabProperty = new wxChoice( m_panelGeneral, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_choiceFabPropertyNChoices, m_choiceFabPropertyChoices, 0 ); + m_choiceFabProperty->SetSelection( 0 ); + m_middleBoxSizer->Add( m_choiceFabProperty, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 ); bGeneralSizer->Add( m_middleBoxSizer, 0, wxEXPAND|wxALL, 3 ); @@ -421,13 +433,13 @@ DIALOG_PAD_PROPERTIES_BASE::DIALOG_PAD_PROPERTIES_BASE( wxWindow* parent, wxWind m_staticTextInfoPosValue = new wxStaticText( sbClearancesSizer->GetStaticBox(), wxID_ANY, _("Positive clearance means area bigger than the pad (usual for mask clearance)."), wxDefaultPosition, wxDefaultSize, 0 ); m_staticTextInfoPosValue->Wrap( -1 ); - m_staticTextInfoPosValue->SetFont( wxFont( 12, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_ITALIC, wxFONTWEIGHT_NORMAL, false, wxEmptyString ) ); + m_staticTextInfoPosValue->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), wxFONTFAMILY_DEFAULT, wxFONTSTYLE_ITALIC, wxFONTWEIGHT_NORMAL, false, wxEmptyString ) ); sbClearancesSizer->Add( m_staticTextInfoPosValue, 0, wxTOP|wxRIGHT, 10 ); m_staticTextInfoNegVal = new wxStaticText( sbClearancesSizer->GetStaticBox(), wxID_ANY, _("Negative clearance means area smaller than the pad (usual for paste clearance)."), wxDefaultPosition, wxDefaultSize, 0 ); m_staticTextInfoNegVal->Wrap( -1 ); - m_staticTextInfoNegVal->SetFont( wxFont( 12, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_ITALIC, wxFONTWEIGHT_NORMAL, false, wxEmptyString ) ); + m_staticTextInfoNegVal->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), wxFONTFAMILY_DEFAULT, wxFONTSTYLE_ITALIC, wxFONTWEIGHT_NORMAL, false, wxEmptyString ) ); sbClearancesSizer->Add( m_staticTextInfoNegVal, 0, wxBOTTOM|wxRIGHT, 10 ); @@ -500,13 +512,13 @@ DIALOG_PAD_PROPERTIES_BASE::DIALOG_PAD_PROPERTIES_BASE( wxWindow* parent, wxWind m_nonCopperNote = new wxStaticText( notePanel, wxID_ANY, _("Note: solder mask and paste values are used only for pads on copper layers."), wxDefaultPosition, wxDefaultSize, 0 ); m_nonCopperNote->Wrap( -1 ); - m_nonCopperNote->SetFont( wxFont( 12, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false, wxEmptyString ) ); + m_nonCopperNote->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), wxFONTFAMILY_DEFAULT, wxFONTSTYLE_ITALIC, wxFONTWEIGHT_NORMAL, false, wxEmptyString ) ); bNoteSizer->Add( m_nonCopperNote, 0, wxTOP|wxRIGHT, 5 ); m_staticTextInfoPaste = new wxStaticText( notePanel, wxID_ANY, _("Note: solder paste clearances (absolute and relative) are added to determine the final clearance."), wxDefaultPosition, wxDefaultSize, 0 ); m_staticTextInfoPaste->Wrap( -1 ); - m_staticTextInfoPaste->SetFont( wxFont( 12, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false, wxEmptyString ) ); + m_staticTextInfoPaste->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), wxFONTFAMILY_DEFAULT, wxFONTSTYLE_ITALIC, wxFONTWEIGHT_NORMAL, false, wxEmptyString ) ); bNoteSizer->Add( m_staticTextInfoPaste, 0, wxBOTTOM|wxRIGHT, 5 ); @@ -671,13 +683,13 @@ DIALOG_PAD_PROPERTIES_BASE::DIALOG_PAD_PROPERTIES_BASE( wxWindow* parent, wxWind m_parentInfoLine1 = new wxStaticText( this, wxID_ANY, _("Footprint name"), wxDefaultPosition, wxDefaultSize, 0 ); m_parentInfoLine1->Wrap( -1 ); - m_parentInfoLine1->SetFont( wxFont( 11, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false, wxEmptyString ) ); + m_parentInfoLine1->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false, wxEmptyString ) ); bSizerDisplayPad->Add( m_parentInfoLine1, 0, wxTOP, 8 ); m_parentInfoLine2 = new wxStaticText( this, wxID_ANY, _("side and rotation"), wxDefaultPosition, wxDefaultSize, 0 ); m_parentInfoLine2->Wrap( -1 ); - m_parentInfoLine2->SetFont( wxFont( 11, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false, wxEmptyString ) ); + m_parentInfoLine2->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false, wxEmptyString ) ); bSizerDisplayPad->Add( m_parentInfoLine2, 0, wxRIGHT, 3 ); @@ -722,7 +734,6 @@ DIALOG_PAD_PROPERTIES_BASE::DIALOG_PAD_PROPERTIES_BASE( wxWindow* parent, wxWind this->SetSizer( m_MainSizer ); this->Layout(); - m_MainSizer->Fit( this ); this->Centre( wxBOTH ); diff --git a/pcbnew/dialogs/dialog_pad_properties_base.fbp b/pcbnew/dialogs/dialog_pad_properties_base.fbp index 1671b11524..346e425a33 100644 --- a/pcbnew/dialogs/dialog_pad_properties_base.fbp +++ b/pcbnew/dialogs/dialog_pad_properties_base.fbp @@ -47,7 +47,7 @@ -1,-1 DIALOG_PAD_PROPERTIES_BASE - -1,-1 + 764,581 wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER DIALOG_SHIM; dialog_shim.h Pad Properties @@ -130,7 +130,7 @@ General - 1 + 0 1 1 @@ -192,7 +192,7 @@ 5 wxALL|wxEXPAND 0 - + m_LeftBoxSizer wxVERTICAL @@ -3286,20 +3286,20 @@ - + 3 wxEXPAND|wxALL 0 - + m_middleBoxSizer wxVERTICAL protected - + 5 wxEXPAND 0 - + 3 wxBOTH 1 @@ -4062,8 +4062,8 @@ 5 - wxEXPAND|wxLEFT|wxRIGHT|wxTOP - 1 + wxLEFT|wxRIGHT|wxTOP|wxEXPAND + 0 wxID_ANY @@ -5117,6 +5117,131 @@ + + 5 + wxTOP|wxRIGHT|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Fabrication Property: + 0 + + 0 + + + 0 + + 1 + m_staticTextFabProperty + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + Optional property to specify a special purpose or constraint in fabrication files: BGA attribute is for pads in BGA footprints Fiducial local is a fiducial for the parent footprint Fiducial global is a fiducial for the whole board Test pad is useful to specify test points in Gerber files Heatsink pad specify a thermal pad Castellated specify castellated through hole pads on a board edge This property is specified in Gerber X2 files. + + + + -1 + + + + 5 + wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + "None" "BGA pad" "Fiducial, local to footprint" "Fiducial, global to board" "Test Point Pad" "Heatsink pad" "Castellated pad (through hole only)" + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + 0 + + 1 + m_choiceFabProperty + 1 + + + protected + 1 + + Resizable + 0 + 1 + + + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + @@ -5125,7 +5250,7 @@ Local Clearance and Settings - 0 + 1 1 1 @@ -5292,7 +5417,7 @@ 1 1 - ,93,90,12,70,0 + ,93,90,-1,70,0 0 0 wxID_ANY @@ -5353,7 +5478,7 @@ 1 1 - ,93,90,12,70,0 + ,93,90,-1,70,0 0 0 wxID_ANY @@ -6292,7 +6417,7 @@ 1 1 - ,90,90,12,70,0 + ,93,90,-1,70,0 0 0 wxID_ANY @@ -6325,11 +6450,11 @@ -1 - + 5 wxBOTTOM|wxRIGHT 0 - + 1 1 1 @@ -6353,7 +6478,7 @@ 1 1 - ,90,90,12,70,0 + ,93,90,-1,70,0 0 0 wxID_ANY @@ -7243,11 +7368,11 @@ - + Custom Shape Primitives 0 - + 1 1 1 @@ -7882,30 +8007,30 @@ - + 10 wxEXPAND|wxTOP|wxRIGHT 1 - + -1,-1 bSizerDisplayPad wxVERTICAL none - + 3 wxBOTTOM|wxEXPAND|wxTOP 0 - + 0 protected 0 - + 8 wxTOP 0 - + 1 1 1 @@ -7929,7 +8054,7 @@ 1 1 - ,90,90,11,70,0 + ,90,90,-1,70,0 0 0 wxID_ANY @@ -7962,11 +8087,11 @@ -1 - + 3 wxRIGHT 0 - + 1 1 1 @@ -7990,7 +8115,7 @@ 1 1 - ,90,90,11,70,0 + ,90,90,-1,70,0 0 0 wxID_ANY @@ -8023,11 +8148,11 @@ -1 - + 5 wxEXPAND 1 - + 0 protected 0 @@ -8218,11 +8343,11 @@ onChangePadMode - + 5 wxEXPAND 1 - + 0 protected 0 @@ -8311,7 +8436,7 @@ - + 0 wxAUI_MGR_DEFAULT @@ -8337,16 +8462,16 @@ - + bSizermain wxVERTICAL none - + 10 wxEXPAND|wxALL 1 - + 7 wxBOTH 2,4 @@ -8791,11 +8916,11 @@ -1 - + 5 wxALIGN_CENTER_VERTICAL|wxLEFT 0 - + 1 1 1 @@ -8852,11 +8977,11 @@ -1 - + 5 wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxLEFT 0 - + 1 1 1 @@ -8913,11 +9038,11 @@ -1 - + 5 wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT 0 - + 1 1 1 @@ -8977,11 +9102,11 @@ - + 5 wxALIGN_CENTER_VERTICAL|wxRIGHT 0 - + 1 1 1 @@ -9038,11 +9163,11 @@ -1 - + 5 wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxLEFT 0 - + 1 1 1 @@ -9099,11 +9224,11 @@ -1 - + 5 wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT 0 - + 1 1 1 @@ -9163,11 +9288,11 @@ - + 5 wxALIGN_CENTER_VERTICAL|wxRIGHT 0 - + 1 1 1 @@ -9224,11 +9349,11 @@ -1 - + 5 wxALIGN_CENTER_VERTICAL|wxLEFT 0 - + 1 1 1 @@ -9285,11 +9410,11 @@ -1 - + 5 wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxLEFT 0 - + 1 1 1 @@ -9346,11 +9471,11 @@ -1 - + 5 wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT 0 - + 1 1 1 @@ -9410,11 +9535,11 @@ - + 5 wxALIGN_CENTER_VERTICAL|wxRIGHT 0 - + 1 1 1 @@ -9471,11 +9596,11 @@ -1 - + 5 wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxLEFT 0 - + 1 1 1 @@ -9532,11 +9657,11 @@ -1 - + 5 wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT 0 - + 1 1 1 @@ -9596,11 +9721,11 @@ - + 5 wxALIGN_CENTER_VERTICAL|wxRIGHT 0 - + 1 1 1 @@ -11793,7 +11918,7 @@ - + bSizerMain wxVERTICAL diff --git a/pcbnew/dialogs/dialog_pad_properties_base.h b/pcbnew/dialogs/dialog_pad_properties_base.h index 9218828c28..69e948e66a 100644 --- a/pcbnew/dialogs/dialog_pad_properties_base.h +++ b/pcbnew/dialogs/dialog_pad_properties_base.h @@ -142,6 +142,8 @@ class DIALOG_PAD_PROPERTIES_BASE : public DIALOG_SHIM wxCheckBox* m_PadLayerDraft; wxCheckBox* m_PadLayerECO1; wxCheckBox* m_PadLayerECO2; + wxStaticText* m_staticTextFabProperty; + wxChoice* m_choiceFabProperty; wxPanel* m_localSettingsPanel; wxStaticText* m_staticTextInfoPosValue; wxStaticText* m_staticTextInfoNegVal; @@ -220,7 +222,7 @@ class DIALOG_PAD_PROPERTIES_BASE : public DIALOG_SHIM public: - DIALOG_PAD_PROPERTIES_BASE( wxWindow* parent, wxWindowID id = wxID_DIALOG_EDIT_PAD, const wxString& title = _("Pad Properties"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER ); + DIALOG_PAD_PROPERTIES_BASE( wxWindow* parent, wxWindowID id = wxID_DIALOG_EDIT_PAD, const wxString& title = _("Pad Properties"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 764,581 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER ); ~DIALOG_PAD_PROPERTIES_BASE(); }; diff --git a/pcbnew/exporters/gendrill_gerber_writer.cpp b/pcbnew/exporters/gendrill_gerber_writer.cpp index 5270570560..85ae95b6e5 100644 --- a/pcbnew/exporters/gendrill_gerber_writer.cpp +++ b/pcbnew/exporters/gendrill_gerber_writer.cpp @@ -191,16 +191,21 @@ int GERBER_WRITER::createDrillFile( wxString& aFullFilename, bool aIsNpth, else if( dyn_cast( hole_descr.m_ItemParent ) ) { last_item_is_via = false; + const D_PAD* pad = dyn_cast( hole_descr.m_ItemParent ); - // Good practice of oblong pad holes (slots) is to use a specific aperture for routing, not used - // in drill commands - if( hole_descr.m_Hole_Shape ) - gbr_metadata.SetApertureAttrib( GBR_APERTURE_METADATA::GBR_APERTURE_ATTRIB_CMP_OBLONG_DRILL ); + if( pad->GetProperty() == PAD_PROP_CASTELLATED ) + gbr_metadata.SetApertureAttrib( GBR_APERTURE_METADATA::GBR_APERTURE_ATTRIB_CASTELLATEDDRILL ); else - gbr_metadata.SetApertureAttrib( GBR_APERTURE_METADATA::GBR_APERTURE_ATTRIB_CMP_DRILL ); + { + // Good practice of oblong pad holes (slots) is to use a specific aperture for routing, not used + // in drill commands + if( hole_descr.m_Hole_Shape ) + gbr_metadata.SetApertureAttrib( GBR_APERTURE_METADATA::GBR_APERTURE_ATTRIB_CMP_OBLONG_DRILL ); + else + gbr_metadata.SetApertureAttrib( GBR_APERTURE_METADATA::GBR_APERTURE_ATTRIB_CMP_DRILL ); + } // Add object attribute: component reference to pads (mainly usefull for users) - const D_PAD* pad = dyn_cast( hole_descr.m_ItemParent ); wxString ref = pad->GetParent()->GetReference(); gbr_metadata.SetCmpReference( ref ); diff --git a/pcbnew/kicad_plugin.cpp b/pcbnew/kicad_plugin.cpp index a42c9ef2b0..0897f05eee 100644 --- a/pcbnew/kicad_plugin.cpp +++ b/pcbnew/kicad_plugin.cpp @@ -1327,6 +1327,22 @@ void PCB_IO::format( D_PAD* aPad, int aNestLevel ) const THROW_IO_ERROR( wxString::Format( "unknown pad attribute: %d", aPad->GetAttribute() ) ); } + const char* property = nullptr; + + switch( aPad->GetProperty() ) + { + case PAD_PROP_NONE: break; + case PAD_PROP_BGA: property = "pad_prop_bga"; break; + case PAD_PROP_FIDUCIAL_GLBL: property = "pad_prop_fiducial_glob"; break; + case PAD_PROP_FIDUCIAL_LOCAL: property = "pad_prop_fiducial_loc"; break; + case PAD_PROP_TESTPOINT: property = "pad_prop_testpoint"; break; + case PAD_PROP_HEATSINK: property = "pad_prop_heatsink"; break; + case PAD_PROP_CASTELLATED: property = "pad_prop_castellated"; break; + + default: + THROW_IO_ERROR( wxString::Format( "unknown pad property: %d", aPad->GetProperty() ) ); + } + m_out->Print( aNestLevel, "(pad %s %s %s", m_out->Quotew( aPad->GetName() ).c_str(), type, shape ); @@ -1364,6 +1380,11 @@ void PCB_IO::format( D_PAD* aPad, int aNestLevel ) const m_out->Print( 0, ")" ); } + if( property ) + { + m_out->Print( 0, " (property %s)", property ); + } + formatLayers( aPad->GetLayerSet() ); // Output the radius ratio for rounded and chamfered rect pads diff --git a/pcbnew/kicad_plugin.h b/pcbnew/kicad_plugin.h index 7b67dab2dc..ae99bd98cf 100644 --- a/pcbnew/kicad_plugin.h +++ b/pcbnew/kicad_plugin.h @@ -64,7 +64,8 @@ class TEXTE_PCB; //#define SEXPR_BOARD_FILE_VERSION 20190605 // Add layer defaults //#define SEXPR_BOARD_FILE_VERSION 20190905 // Add board physical stackup info in setup section //#define SEXPR_BOARD_FILE_VERSION 20190907 // Keepout areas in footprints -#define SEXPR_BOARD_FILE_VERSION 20191123 // pin function in pads +//#define SEXPR_BOARD_FILE_VERSION 20191123 // pin function in pads +#define SEXPR_BOARD_FILE_VERSION 20200104 // pad property for fabrication #define CTL_STD_LAYER_NAMES (1 << 0) ///< Use English Standard layer names #define CTL_OMIT_NETS (1 << 1) ///< Omit pads net names (useless in library) diff --git a/pcbnew/pcb_parser.cpp b/pcbnew/pcb_parser.cpp index 45009fb680..749ce6a5d3 100644 --- a/pcbnew/pcb_parser.cpp +++ b/pcbnew/pcb_parser.cpp @@ -3144,6 +3144,52 @@ D_PAD* PCB_PARSER::parseD_PAD( MODULE* aParent ) } break; + case T_property: + { + while( token != T_RIGHT ) + { + token = NextTok(); + + switch( token ) + { + case T_pad_prop_bga: + pad->SetProperty( PAD_PROP_BGA ); + break; + + case T_pad_prop_fiducial_glob: + pad->SetProperty( PAD_PROP_FIDUCIAL_GLBL ); + break; + + case T_pad_prop_fiducial_loc: + pad->SetProperty( PAD_PROP_FIDUCIAL_LOCAL ); + break; + + case T_pad_prop_testpoint: + pad->SetProperty( PAD_PROP_TESTPOINT ); + break; + + case T_pad_prop_castellated: + pad->SetProperty( PAD_PROP_CASTELLATED ); + break; + + case T_pad_prop_heatsink: + pad->SetProperty( PAD_PROP_HEATSINK ); + break; + + case T_RIGHT: + break; + + default: +#if 0 // Currently: skip unknown property + Expecting( "pad_prop_bga pad_prop_fiducial_glob pad_prop_fiducial_loc" + " pad_prop_heatsink or pad_prop_castellated" ); +#endif + break; + } + } + } + break; + case T_options: parseD_PAD_option( pad.get() ); break; diff --git a/pcbnew/plot_brditems_plotter.cpp b/pcbnew/plot_brditems_plotter.cpp index e09755134f..fd11d6a6ad 100644 --- a/pcbnew/plot_brditems_plotter.cpp +++ b/pcbnew/plot_brditems_plotter.cpp @@ -142,12 +142,38 @@ void BRDITEMS_PLOTTER::PlotPad( D_PAD* aPad, COLOR4D aColor, EDA_DRAW_MODE_T aPl break; case PAD_ATTRIB_SMD: // SMD pads (One external copper layer only) with solder paste - // If round shape, perhaps a BGA pad but not sure: so use currently SMDPAD attribute, - // until an explicit BGA pad attribute is added in Pcbnew -// if( aPad->GetShape() == PAD_SHAPE_CIRCLE ) -// gbr_metadata.SetApertureAttrib( GBR_APERTURE_METADATA::GBR_APERTURE_ATTRIB_BGAPAD_CUDEF ); -// else - gbr_metadata.SetApertureAttrib( GBR_APERTURE_METADATA::GBR_APERTURE_ATTRIB_SMDPAD_CUDEF ); + gbr_metadata.SetApertureAttrib( GBR_APERTURE_METADATA::GBR_APERTURE_ATTRIB_SMDPAD_CUDEF ); + break; + } + + // Fabrication properties can have specific GBR_APERTURE_METADATA options: + switch( aPad->GetProperty() ) + { + case PAD_PROP_BGA: + gbr_metadata.SetApertureAttrib( GBR_APERTURE_METADATA::GBR_APERTURE_ATTRIB_BGAPAD_CUDEF ); + break; + + case PAD_PROP_FIDUCIAL_GLBL: + gbr_metadata.SetApertureAttrib( GBR_APERTURE_METADATA::GBR_APERTURE_ATTRIB_FIDUCIAL_GLBL ); + break; + + case PAD_PROP_FIDUCIAL_LOCAL: + gbr_metadata.SetApertureAttrib( GBR_APERTURE_METADATA::GBR_APERTURE_ATTRIB_FIDUCIAL_LOCAL ); + break; + + case PAD_PROP_TESTPOINT: // Only on outer layers + gbr_metadata.SetApertureAttrib( GBR_APERTURE_METADATA::GBR_APERTURE_ATTRIB_TESTPOINT ); + break; + + case PAD_PROP_HEATSINK: + gbr_metadata.SetApertureAttrib( GBR_APERTURE_METADATA::GBR_APERTURE_ATTRIB_HEATSINKPAD ); + break; + + case PAD_PROP_CASTELLATED: + gbr_metadata.SetApertureAttrib( GBR_APERTURE_METADATA::GBR_APERTURE_ATTRIB_CASTELLATEDPAD ); + break; + + case PAD_PROP_NONE: break; } }