From 0ab583cf72317f119abde971440f87456dcd3bbf Mon Sep 17 00:00:00 2001 From: Jeff Young Date: Wed, 7 Oct 2020 16:13:31 +0100 Subject: [PATCH] Special-case clearances of NPTH pads with no copper on layer. These should get the hole clearance, not the copper clearance. Fixes https://gitlab.com/kicad/code/kicad/issues/4017 --- pcbnew/class_pad.cpp | 29 +++++++++++++++++++++++++++++ pcbnew/class_pad.h | 14 ++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/pcbnew/class_pad.cpp b/pcbnew/class_pad.cpp index c131ff7ee4..0a3a5b3a7c 100644 --- a/pcbnew/class_pad.cpp +++ b/pcbnew/class_pad.cpp @@ -641,6 +641,35 @@ int D_PAD::GetLocalClearance( wxString* aSource ) const } +int D_PAD::GetClearance( PCB_LAYER_ID aLayer, BOARD_ITEM* aItem, wxString* aSource ) const +{ + DRC_CONSTRAINT constraint; + + if( GetBoard() && GetBoard()->GetDesignSettings().m_DRCEngine ) + { + BOARD_DESIGN_SETTINGS& bds = GetBoard()->GetDesignSettings(); + DRC_CONSTRAINT_TYPE_T constraintType = DRC_CONSTRAINT_TYPE_CLEARANCE; + + // A PTH pad has a plated cylinder around the hole so copper clearances apply + // whether or not there's a flashed pad. Not true for NPTHs. + if( GetAttribute() == PAD_ATTRIB_NPTH && !FlashLayer( aLayer ) ) + constraintType = DRC_CONSTRAINT_TYPE_HOLE_CLEARANCE; + + constraint = bds.m_DRCEngine->EvalRulesForItems( constraintType, this, aItem, aLayer ); + } + + if( constraint.Value().HasMin() ) + { + if( aSource ) + *aSource = constraint.GetName(); + + return constraint.Value().Min(); + } + + return 0; +} + + // Mask margins handling: int D_PAD::GetSolderMaskMargin() const diff --git a/pcbnew/class_pad.h b/pcbnew/class_pad.h index 195e73f1e8..03b6e7690a 100644 --- a/pcbnew/class_pad.h +++ b/pcbnew/class_pad.h @@ -366,6 +366,20 @@ public: double GetLocalSolderPasteMarginRatio() const { return m_localSolderPasteMarginRatio; } void SetLocalSolderPasteMarginRatio( double aRatio ) { m_localSolderPasteMarginRatio = aRatio; } + /** + * Function GetClearance + * returns the clearance in internal units. If \a aItem is not NULL then the + * returned clearance is the greater of this object's NETCLASS clearance and + * aItem's NETCLASS clearance. If \a aItem is NULL, then this objects clearance + * is returned. + * @param aLayer the layer in question + * @param aItem is an optional BOARD_ITEM + * @param aSource [out] optionally reports the source as a user-readable string + * @return int - the clearance in internal units. + */ + int GetClearance( PCB_LAYER_ID aLayer, BOARD_ITEM* aItem = nullptr, + wxString* aSource = nullptr ) const override; + /** * Function TransformShapeWithClearanceToPolygon * Convert the pad shape to a closed polygon. Circles and arcs are approximated by segments.