Migrated GetEffectiveShape(s) to SHAPE_COMPOUND
This commit is contained in:
parent
85aecc15ee
commit
89a953e039
|
@ -329,13 +329,14 @@ void BOARD_ADAPTER::createNewPadWithClearance( const D_PAD* aPad,
|
|||
}
|
||||
else
|
||||
{
|
||||
for( const std::shared_ptr<SHAPE>& shape : aPad->GetEffectiveShapes() )
|
||||
auto padShapes = std::static_pointer_cast<SHAPE_COMPOUND>( aPad->GetEffectiveShape() );
|
||||
for( const SHAPE* shape : padShapes->Shapes() )
|
||||
{
|
||||
switch( shape->Type() )
|
||||
{
|
||||
case SH_SEGMENT:
|
||||
{
|
||||
const SHAPE_SEGMENT* seg = (SHAPE_SEGMENT*) shape.get();
|
||||
const SHAPE_SEGMENT* seg = (SHAPE_SEGMENT*) shape;
|
||||
const SFVEC2F start3DU( seg->GetSeg().A.x * m_biuTo3Dunits,
|
||||
-seg->GetSeg().A.y * m_biuTo3Dunits );
|
||||
const SFVEC2F end3DU ( seg->GetSeg().B.x * m_biuTo3Dunits,
|
||||
|
@ -360,7 +361,7 @@ void BOARD_ADAPTER::createNewPadWithClearance( const D_PAD* aPad,
|
|||
|
||||
case SH_CIRCLE:
|
||||
{
|
||||
const SHAPE_CIRCLE* circle = (SHAPE_CIRCLE*) shape.get();
|
||||
const SHAPE_CIRCLE* circle = (SHAPE_CIRCLE*) shape;
|
||||
const int radius = circle->GetRadius() + aClearanceValue.x;
|
||||
const SFVEC2F center( circle->GetCenter().x * m_biuTo3Dunits,
|
||||
-circle->GetCenter().y * m_biuTo3Dunits );
|
||||
|
@ -371,7 +372,7 @@ void BOARD_ADAPTER::createNewPadWithClearance( const D_PAD* aPad,
|
|||
|
||||
case SH_RECT:
|
||||
{
|
||||
SHAPE_RECT* rect = (SHAPE_RECT*) shape.get();
|
||||
SHAPE_RECT* rect = (SHAPE_RECT*) shape;
|
||||
|
||||
poly.NewOutline();
|
||||
poly.Append( rect->GetPosition() );
|
||||
|
@ -382,11 +383,11 @@ void BOARD_ADAPTER::createNewPadWithClearance( const D_PAD* aPad,
|
|||
break;
|
||||
|
||||
case SH_SIMPLE:
|
||||
poly.AddOutline( static_cast<SHAPE_SIMPLE*>( shape.get() )->Vertices() );
|
||||
poly.AddOutline( static_cast<const SHAPE_SIMPLE*>( shape )->Vertices() );
|
||||
break;
|
||||
|
||||
case SH_POLY_SET:
|
||||
poly = *(SHAPE_POLY_SET*) shape.get();
|
||||
poly = *(SHAPE_POLY_SET*) shape;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
|
@ -156,7 +156,20 @@ public:
|
|||
*/
|
||||
static wxPoint ZeroOffset;
|
||||
|
||||
virtual std::shared_ptr<SHAPE> GetEffectiveShape( PCB_LAYER_ID aLayer = UNDEFINED_LAYER );
|
||||
/**
|
||||
* Function GetEffectiveShape
|
||||
* Some pad shapes can be complex (rounded/chamfered rectangle), even without considering
|
||||
* custom shapes. This routine returns a COMPOUND shape (set of simple shapes which make
|
||||
* up the pad fod use with routing, collision determiniation, etc).
|
||||
*
|
||||
* Note that this list can contain a SHAPE_SIMPLE (a simple single-outline non-intersecting
|
||||
* polygon), but should never contain a SHAPE_POLY_SET (a complex polygon consisting of
|
||||
* multiple outlines and/or holes).
|
||||
*
|
||||
* @param aLayer in case of items spanning multiple layers, only the shapes belonging to aLayer
|
||||
* will be returned. Pass UNDEFINED_LAYER to return shapes for all layers.
|
||||
*/
|
||||
virtual std::shared_ptr<SHAPE> GetEffectiveShape( PCB_LAYER_ID aLayer = UNDEFINED_LAYER ) const;
|
||||
|
||||
BOARD_ITEM_CONTAINER* GetParent() const { return (BOARD_ITEM_CONTAINER*) m_Parent; }
|
||||
|
||||
|
|
|
@ -151,7 +151,7 @@ bool BOARD_ITEM::ptr_cmp::operator() ( const BOARD_ITEM* a, const BOARD_ITEM* b
|
|||
}
|
||||
|
||||
|
||||
std::shared_ptr<SHAPE> BOARD_ITEM::GetEffectiveShape( PCB_LAYER_ID aLayer )
|
||||
std::shared_ptr<SHAPE> BOARD_ITEM::GetEffectiveShape( PCB_LAYER_ID aLayer ) const
|
||||
{
|
||||
std::shared_ptr<SHAPE> shape;
|
||||
|
||||
|
|
|
@ -296,10 +296,21 @@ void DRAWSEGMENT::RebuildBezierToSegmentsPointsList( int aMinSegLen )
|
|||
m_BezierPoints.clear();
|
||||
return;
|
||||
}
|
||||
// Rebuild the m_BezierPoints vertex list that approximate the Bezier curve
|
||||
m_BezierPoints = buildBezierToSegmentsPointsList( aMinSegLen );
|
||||
}
|
||||
|
||||
|
||||
const std::vector<wxPoint> DRAWSEGMENT::buildBezierToSegmentsPointsList( int aMinSegLen ) const
|
||||
{
|
||||
std::vector<wxPoint> bezierPoints;
|
||||
|
||||
// Rebuild the m_BezierPoints vertex list that approximate the Bezier curve
|
||||
std::vector<wxPoint> ctrlPoints = { m_Start, m_BezierC1, m_BezierC2, m_End };
|
||||
BEZIER_POLY converter( ctrlPoints );
|
||||
converter.GetPoly( m_BezierPoints, aMinSegLen );
|
||||
converter.GetPoly( bezierPoints, aMinSegLen );
|
||||
|
||||
return bezierPoints;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1015,7 +1026,7 @@ void DRAWSEGMENT::SetPolyPoints( const std::vector<wxPoint>& aPoints )
|
|||
}
|
||||
|
||||
|
||||
std::vector<SHAPE*> DRAWSEGMENT::MakeEffectiveShapes()
|
||||
std::vector<SHAPE*> DRAWSEGMENT::MakeEffectiveShapes() const
|
||||
{
|
||||
std::vector<SHAPE*> effectiveShapes;
|
||||
|
||||
|
@ -1082,12 +1093,12 @@ std::vector<SHAPE*> DRAWSEGMENT::MakeEffectiveShapes()
|
|||
|
||||
case S_CURVE:
|
||||
{
|
||||
RebuildBezierToSegmentsPointsList( GetWidth() );
|
||||
wxPoint start_pt = GetBezierPoints()[0];
|
||||
auto bezierPoints = buildBezierToSegmentsPointsList( GetWidth() );
|
||||
wxPoint start_pt = bezierPoints[0];
|
||||
|
||||
for( unsigned int jj = 1; jj < GetBezierPoints().size(); jj++ )
|
||||
for( unsigned int jj = 1; jj < bezierPoints.size(); jj++ )
|
||||
{
|
||||
wxPoint end_pt = GetBezierPoints()[jj];
|
||||
wxPoint end_pt = bezierPoints[jj];
|
||||
effectiveShapes.emplace_back( new SHAPE_SEGMENT( start_pt, end_pt, m_Width ) );
|
||||
start_pt = end_pt;
|
||||
}
|
||||
|
@ -1097,7 +1108,7 @@ std::vector<SHAPE*> DRAWSEGMENT::MakeEffectiveShapes()
|
|||
|
||||
case S_POLYGON:
|
||||
{
|
||||
SHAPE_LINE_CHAIN l = GetPolyShape().Outline( 0 );
|
||||
SHAPE_LINE_CHAIN l = GetPolyShape().COutline( 0 );
|
||||
|
||||
if( IsPolygonFilled() )
|
||||
{
|
||||
|
@ -1121,7 +1132,7 @@ std::vector<SHAPE*> DRAWSEGMENT::MakeEffectiveShapes()
|
|||
}
|
||||
|
||||
|
||||
std::shared_ptr<SHAPE> DRAWSEGMENT::GetEffectiveShape( PCB_LAYER_ID aLayer )
|
||||
std::shared_ptr<SHAPE> DRAWSEGMENT::GetEffectiveShape( PCB_LAYER_ID aLayer ) const
|
||||
{
|
||||
return std::shared_ptr<SHAPE>( new SHAPE_COMPOUND( MakeEffectiveShapes() ) );
|
||||
}
|
||||
|
|
|
@ -64,6 +64,8 @@ protected:
|
|||
// Computes the bounding box for an arc
|
||||
void computeArcBBox( EDA_RECT& aBBox ) const;
|
||||
|
||||
const std::vector<wxPoint> buildBezierToSegmentsPointsList( int aMinSegLen ) const;
|
||||
|
||||
public:
|
||||
DRAWSEGMENT( BOARD_ITEM* aParent = NULL, KICAD_T idtype = PCB_LINE_T );
|
||||
|
||||
|
@ -244,8 +246,8 @@ public:
|
|||
/**
|
||||
* Makes a set of SHAPE objects representing the DRAWSEGMENT. Caller owns the objects.
|
||||
*/
|
||||
std::vector<SHAPE*> MakeEffectiveShapes(); // fixme: move to shape_compound
|
||||
virtual std::shared_ptr<SHAPE> GetEffectiveShape( PCB_LAYER_ID aLayer = UNDEFINED_LAYER ) override;
|
||||
std::vector<SHAPE*> MakeEffectiveShapes() const; // fixme: move to shape_compound
|
||||
virtual std::shared_ptr<SHAPE> GetEffectiveShape( PCB_LAYER_ID aLayer = UNDEFINED_LAYER ) const override;
|
||||
|
||||
void GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList ) override;
|
||||
|
||||
|
|
|
@ -222,7 +222,7 @@ const std::shared_ptr<SHAPE_POLY_SET>& D_PAD::GetEffectivePolygon() const
|
|||
}
|
||||
|
||||
|
||||
std::shared_ptr<SHAPE> D_PAD::GetEffectiveShape( PCB_LAYER_ID aLayer )
|
||||
std::shared_ptr<SHAPE> D_PAD::GetEffectiveShape( PCB_LAYER_ID aLayer ) const
|
||||
{
|
||||
std::shared_ptr<SHAPE_COMPOUND> shape( new SHAPE_COMPOUND );
|
||||
|
||||
|
@ -865,53 +865,14 @@ bool D_PAD::Collide( const D_PAD* aPad, int aMinClearance, int* aActual )
|
|||
if( center2center - GetBoundingRadius() - aPad->GetBoundingRadius() >= aMinClearance )
|
||||
return false;
|
||||
|
||||
int actual = INT_MAX;
|
||||
|
||||
for( const std::shared_ptr<SHAPE>& aShape : GetEffectiveShapes() )
|
||||
{
|
||||
for( const std::shared_ptr<SHAPE>& bShape : aPad->GetEffectiveShapes() )
|
||||
{
|
||||
int this_dist;
|
||||
|
||||
if( aShape->Collide( bShape.get(), aMinClearance, &this_dist ) )
|
||||
actual = std::min( actual, this_dist );
|
||||
}
|
||||
}
|
||||
|
||||
if( actual < INT_MAX )
|
||||
{
|
||||
// returns the actual clearance (clearance < aMinClearance) for diags:
|
||||
if( aActual )
|
||||
*aActual = std::max( 0, actual );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
return GetEffectiveShape()->Collide( aPad->GetEffectiveShape().get(), aMinClearance, aActual );
|
||||
}
|
||||
|
||||
|
||||
bool D_PAD::Collide( const SHAPE_SEGMENT* aSeg, int aMinClearance, int* aActual )
|
||||
{
|
||||
int actual = INT_MAX;
|
||||
|
||||
for( const std::shared_ptr<SHAPE>& shape : GetEffectiveShapes() )
|
||||
{
|
||||
int this_dist;
|
||||
|
||||
if( shape->Collide( aSeg, aMinClearance, &this_dist ) )
|
||||
actual = std::min( actual, this_dist );
|
||||
}
|
||||
|
||||
if( actual < INT_MAX )
|
||||
{
|
||||
if( aActual )
|
||||
*aActual = std::max( 0, actual );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
return aSeg->Collide( GetEffectiveShape().get(), aMinClearance, aActual );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include <class_board_item.h>
|
||||
#include <convert_to_biu.h>
|
||||
#include <geometry/shape_poly_set.h>
|
||||
#include <geometry/shape_compound.h>
|
||||
#include <pad_shapes.h>
|
||||
#include <pcbnew.h>
|
||||
|
||||
|
@ -381,18 +382,8 @@ public:
|
|||
bool TransformHoleWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer, int aInflateValue,
|
||||
int aError = ARC_HIGH_DEF ) const;
|
||||
|
||||
/**
|
||||
* Function GetEffectiveShapes
|
||||
* Some pad shapes can be complex (rounded/chamfered rectangle), even without considering
|
||||
* custom shapes. This routine returns a list of simple shapes which make up the pad for
|
||||
* use with routing, collision determiniation, etc.
|
||||
*
|
||||
* Note that this list can contain a SHAPE_SIMPLE (a simple single-outline non-intersecting
|
||||
* polygon), but should never contain a SHAPE_POLY_LIST (a complex polygon consisting of
|
||||
* multiple outlines and/or holes).
|
||||
*/
|
||||
const std::vector<std::shared_ptr<SHAPE>>& GetEffectiveShapes() const;
|
||||
virtual std::shared_ptr<SHAPE> GetEffectiveShape( PCB_LAYER_ID aLayer = UNDEFINED_LAYER ) override;
|
||||
// @copydoc BOARD_ITEM::GetEffectiveShape
|
||||
virtual std::shared_ptr<SHAPE> GetEffectiveShape( PCB_LAYER_ID aLayer = UNDEFINED_LAYER ) const override;
|
||||
|
||||
const std::shared_ptr<SHAPE_POLY_SET>& GetEffectivePolygon() const;
|
||||
|
||||
|
|
|
@ -973,16 +973,13 @@ void DRC::testCopperDrawItem( BOARD_COMMIT& aCommit, BOARD_ITEM* aItem )
|
|||
if( !bboxShape.Collide( SEG( pad->GetPosition(), pad->GetPosition() ), bb_radius ) )
|
||||
continue;
|
||||
|
||||
for( const std::shared_ptr<SHAPE>& aShape : pad->GetEffectiveShapes() )
|
||||
{
|
||||
for( const SHAPE* bShape : itemShapes )
|
||||
{
|
||||
int this_dist;
|
||||
|
||||
if( aShape->Collide( bShape, minClearance, &this_dist ) )
|
||||
if( pad->GetEffectiveShape()->Collide( bShape, minClearance, &this_dist ) )
|
||||
actual = std::min( actual, this_dist );
|
||||
}
|
||||
}
|
||||
|
||||
if( actual < INT_MAX )
|
||||
{
|
||||
|
|
|
@ -842,16 +842,16 @@ void PCB_PAINTER::draw( const D_PAD* aPad, int aLayer )
|
|||
margin.x = margin.y = 0;
|
||||
}
|
||||
|
||||
const std::vector<std::shared_ptr<SHAPE>>& shapes = aPad->GetEffectiveShapes();
|
||||
const std::shared_ptr<SHAPE_COMPOUND> shapes = std::dynamic_pointer_cast<SHAPE_COMPOUND>( aPad->GetEffectiveShape() );
|
||||
|
||||
if( shapes.size() == 1 && shapes[0]->Type() == SH_SEGMENT )
|
||||
if( shapes && shapes->Size() == 1 && shapes->Shapes()[0]->Type() == SH_SEGMENT )
|
||||
{
|
||||
const SHAPE_SEGMENT* seg = (SHAPE_SEGMENT*) shapes[0].get();
|
||||
const SHAPE_SEGMENT* seg = (SHAPE_SEGMENT*) shapes->Shapes()[0];
|
||||
m_gal->DrawSegment( seg->GetSeg().A, seg->GetSeg().B, seg->GetWidth() + 2 * margin.x );
|
||||
}
|
||||
else if( shapes.size() == 1 && shapes[0]->Type() == SH_CIRCLE )
|
||||
else if( shapes && shapes->Size() == 1 && shapes->Shapes()[0]->Type() == SH_CIRCLE )
|
||||
{
|
||||
const SHAPE_CIRCLE* circle = (SHAPE_CIRCLE*) shapes[0].get();
|
||||
const SHAPE_CIRCLE* circle = (SHAPE_CIRCLE*) shapes->Shapes()[0];
|
||||
m_gal->DrawCircle( circle->GetCenter(), circle->GetRadius() + margin.x );
|
||||
}
|
||||
else
|
||||
|
@ -879,16 +879,16 @@ void PCB_PAINTER::draw( const D_PAD* aPad, int aLayer )
|
|||
m_gal->SetStrokeColor( color );
|
||||
int clearance = aPad->GetClearance();
|
||||
|
||||
const std::vector<std::shared_ptr<SHAPE>>& shapes = aPad->GetEffectiveShapes();
|
||||
const std::shared_ptr<SHAPE_COMPOUND> shapes = std::dynamic_pointer_cast<SHAPE_COMPOUND>( aPad->GetEffectiveShape() );
|
||||
|
||||
if( shapes.size() == 1 && shapes[0]->Type() == SH_SEGMENT )
|
||||
if( shapes && shapes->Size() == 1 && shapes->Shapes()[0]->Type() == SH_SEGMENT )
|
||||
{
|
||||
const SHAPE_SEGMENT* seg = (SHAPE_SEGMENT*) shapes[0].get();
|
||||
const SHAPE_SEGMENT* seg = (SHAPE_SEGMENT*) shapes->Shapes()[0];
|
||||
m_gal->DrawSegment( seg->GetSeg().A, seg->GetSeg().B, seg->GetWidth() + 2 * clearance );
|
||||
}
|
||||
else if( shapes.size() == 1 && shapes[0]->Type() == SH_CIRCLE )
|
||||
else if( shapes && shapes->Size() == 1 && shapes->Shapes()[0]->Type() == SH_CIRCLE )
|
||||
{
|
||||
const SHAPE_CIRCLE* circle = (SHAPE_CIRCLE*) shapes[0].get();
|
||||
const SHAPE_CIRCLE* circle = (SHAPE_CIRCLE*) shapes->Shapes()[0];
|
||||
m_gal->DrawCircle( circle->GetCenter(), circle->GetRadius() + clearance );
|
||||
}
|
||||
else
|
||||
|
|
|
@ -634,9 +634,12 @@ std::unique_ptr<PNS::SOLID> PNS_KICAD_IFACE_BASE::syncPad( D_PAD* aPad )
|
|||
solid->SetPos( VECTOR2I( c.x - offset.x, c.y - offset.y ) );
|
||||
solid->SetOffset( VECTOR2I( offset.x, offset.y ) );
|
||||
|
||||
if( aPad->GetEffectiveShapes().size() == 1 )
|
||||
|
||||
auto shapes = std::dynamic_pointer_cast<SHAPE_COMPOUND>( aPad->GetEffectiveShape() );
|
||||
|
||||
if( shapes && shapes->Size() == 1 )
|
||||
{
|
||||
solid->SetShape( aPad->GetEffectiveShapes()[0]->Clone() );
|
||||
solid->SetShape( shapes->Shapes()[0]->Clone() );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue