Implement shape routines for DIMENSION_Ts.

This allows them to participate in DRC and PNS.

Fixes https://gitlab.com/kicad/code/kicad/issues/5712
This commit is contained in:
Jeff Young 2020-09-19 12:47:43 +01:00
parent ece2ae9805
commit d402d93487
6 changed files with 42 additions and 20 deletions

View File

@ -617,7 +617,7 @@ void EDA_TEXT::TransformTextShapeToSegmentList( std::vector<wxPoint>& aCornerBuf
}
std::shared_ptr<SHAPE> EDA_TEXT::GetEffectiveTextShape( ) const
std::shared_ptr<SHAPE_COMPOUND> EDA_TEXT::GetEffectiveTextShape( ) const
{
std::shared_ptr<SHAPE_COMPOUND> shape ( new SHAPE_COMPOUND );
int penWidth = GetEffectiveTextPenWidth();

View File

@ -32,7 +32,7 @@
#include "kicad_string.h"
#include "painter.h"
class SHAPE;
class SHAPE_COMPOUND;
class SHAPE_POLY_SET;
using KIGFX::RENDER_SETTINGS;
@ -293,7 +293,7 @@ public:
void TransformBoundingBoxWithClearanceToPolygon( SHAPE_POLY_SET* aCornerBuffer,
int aClearanceValue ) const;
std::shared_ptr<SHAPE> GetEffectiveTextShape( ) const;
std::shared_ptr<SHAPE_COMPOUND> GetEffectiveTextShape( ) const;
/**
* Test if \a aPoint is within the bounds of this object.

View File

@ -617,7 +617,7 @@ static bool collideSingleShapes( const SHAPE* aA, const SHAPE* aB, int aClearanc
bool unsupported_collision = true;
(void) unsupported_collision; // make gcc quiet
assert( unsupported_collision == false );
wxASSERT( unsupported_collision == false );
return false;
}
@ -635,10 +635,9 @@ static bool collideShapes( const SHAPE* aA, const SHAPE* aB, int aClearance, int
int actual;
VECTOR2I mtv;
bool c = collideSingleShapes( elemA, elemB,
clearance,
aActual ? &actual : nullptr,
aMTV ? &mtv : nullptr );
bool c = collideSingleShapes( elemA, elemB, clearance,
aActual ? &actual : nullptr,
aMTV ? &mtv : nullptr );
if(c)
{
if (aActual)
@ -655,7 +654,7 @@ static bool collideShapes( const SHAPE* aA, const SHAPE* aB, int aClearance, int
return c;
};
if (aA->Type() == SH_COMPOUND && aB->Type() == SH_COMPOUND )
if( aA->Type() == SH_COMPOUND && aB->Type() == SH_COMPOUND )
{
auto cmpA = static_cast<const SHAPE_COMPOUND*>( aA );
auto cmpB = static_cast<const SHAPE_COMPOUND*>( aB );
@ -675,7 +674,7 @@ static bool collideShapes( const SHAPE* aA, const SHAPE* aB, int aClearance, int
break;
}
}
else if ( aA->Type() == SH_COMPOUND )
else if( aA->Type() == SH_COMPOUND )
{
auto cmpA = static_cast<const SHAPE_COMPOUND*>( aA );
for( auto elemA : cmpA->Shapes() )

View File

@ -311,6 +311,26 @@ void DIMENSION::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_I
}
std::vector<SHAPE*> DIMENSION::MakeEffectiveShapes() const
{
std::vector<SHAPE*> effectiveShapes;
for( SHAPE* shape : Text().GetEffectiveTextShape()->Shapes() )
effectiveShapes.emplace_back( shape->Clone() );
for( const std::shared_ptr<SHAPE>& shape : GetShapes() )
effectiveShapes.emplace_back( shape->Clone() );
return effectiveShapes;
}
std::shared_ptr<SHAPE> DIMENSION::GetEffectiveShape( PCB_LAYER_ID aLayer ) const
{
return std::shared_ptr<SHAPE>( new SHAPE_COMPOUND( MakeEffectiveShapes() ) );
}
bool DIMENSION::HitTest( const wxPoint& aPosition, int aAccuracy ) const
{
if( m_text.TextHitTest( aPosition ) )

View File

@ -226,6 +226,12 @@ public:
*/
const std::vector<std::shared_ptr<SHAPE>>& GetShapes() const { return m_shapes; }
/**
* @return create a caller-owned list of *all* shapes (including any text).
* Used for collision calculations (DRC, PNS, etc.).
*/
std::vector<SHAPE*> MakeEffectiveShapes() const;
// BOARD_ITEM overrides
void Move( const wxPoint& offset ) override;
@ -247,6 +253,8 @@ public:
const EDA_RECT GetBoundingBox() const override;
std::shared_ptr<SHAPE> GetEffectiveShape( PCB_LAYER_ID aLayer ) const override;
wxString GetSelectMenuText( EDA_UNITS aUnits ) const override;
const BOX2I ViewBBox() const override;

View File

@ -37,6 +37,7 @@
#include <drc/drc_item.h>
#include <drc/drc_rule.h>
#include <drc/drc_test_provider_clearance_base.h>
#include <class_dimension.h>
/*
Copper clearance test. Checks all copper items (pads, vias, tracks, drawings, zones) for their electrical clearance.
@ -189,24 +190,18 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testCopperDrawItem( BOARD_ITEM* aItem )
{
EDA_RECT bbox;
std::shared_ptr<SHAPE> itemShape;
DRAWSEGMENT* drawItem = dynamic_cast<DRAWSEGMENT*>( aItem );
EDA_TEXT* textItem = dynamic_cast<EDA_TEXT*>( aItem );
PCB_LAYER_ID layer = aItem->GetLayer();
if( drawItem )
{
bbox = drawItem->GetBoundingBox();
itemShape = drawItem->GetEffectiveShape();
}
else if( textItem )
if( textItem )
{
bbox = textItem->GetTextBox();
itemShape = textItem->GetEffectiveTextShape();
}
else
{
wxFAIL_MSG( "unknown item type in testCopperDrawItem()" );
return;
bbox = aItem->GetBoundingBox();
itemShape = aItem->GetEffectiveShape( layer );
}
SHAPE_RECT bboxShape( bbox.GetX(), bbox.GetY(), bbox.GetWidth(), bbox.GetHeight() );
@ -260,7 +255,7 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testCopperDrawItem( BOARD_ITEM* aItem )
continue;
// Graphic items are allowed to act as net-ties within their own footprint
if( drawItem && pad->GetParent() == drawItem->GetParent() )
if( aItem->Type() == PCB_MODULE_EDGE_T && pad->GetParent() == aItem->GetParent() )
continue;
auto constraint = m_drcEngine->EvalRulesForItems( DRC_CONSTRAINT_TYPE_CLEARANCE,