Beware of infinite recursion on colliding hatched shapes.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/20264
This commit is contained in:
@@ -656,7 +656,7 @@ void BOARD_ADAPTER::addShape( const PCB_SHAPE* aShape, CONTAINER_2D_BASE* aConta
|
||||
{
|
||||
SHAPE_POLY_SET polyList;
|
||||
|
||||
aShape->TransformShapeToPolygon( polyList, UNDEFINED_LAYER, 0, ARC_HIGH_DEF,
|
||||
aShape->TransformShapeToPolySet( polyList, UNDEFINED_LAYER, 0, ARC_HIGH_DEF,
|
||||
ERROR_INSIDE );
|
||||
|
||||
polyList.Simplify();
|
||||
|
||||
@@ -97,7 +97,7 @@ void transformFPShapesToPolySet( const FOOTPRINT* aFootprint, PCB_LAYER_ID aLaye
|
||||
if( item->Type() == PCB_SHAPE_T || BaseType( item->Type() ) == PCB_DIMENSION_T )
|
||||
{
|
||||
if( item->GetLayer() == aLayer )
|
||||
item->TransformShapeToPolygon( aBuffer, aLayer, 0, aMaxError, aErrorLoc );
|
||||
item->TransformShapeToPolySet( aBuffer, aLayer, 0, aMaxError, aErrorLoc );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -716,20 +716,22 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
|
||||
{
|
||||
PCB_TEXTBOX* text_box = static_cast<PCB_TEXTBOX*>( item );
|
||||
text_box->TransformTextToPolySet( *platedCopperPolys,
|
||||
0, maxError, ERROR_INSIDE );
|
||||
0, maxError, ERROR_INSIDE );
|
||||
// Add box outlines
|
||||
text_box->PCB_SHAPE::TransformShapeToPolygon( *platedCopperPolys, layer,
|
||||
0, maxError, ERROR_INSIDE );
|
||||
}
|
||||
else if( item->Type() == PCB_TEXT_T )
|
||||
{
|
||||
static_cast<PCB_TEXT*>( item )->TransformTextToPolySet(
|
||||
*platedCopperPolys,
|
||||
0, maxError, ERROR_INSIDE );
|
||||
static_cast<PCB_TEXT*>( item )->TransformTextToPolySet( *platedCopperPolys,
|
||||
0, maxError,
|
||||
ERROR_INSIDE );
|
||||
}
|
||||
else
|
||||
item->TransformShapeToPolygon( *platedCopperPolys, layer,
|
||||
0, maxError, ERROR_INSIDE );
|
||||
{
|
||||
item->TransformShapeToPolySet( *platedCopperPolys, layer,
|
||||
0, maxError, ERROR_INSIDE );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -753,7 +755,7 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
|
||||
switch( item->Type() )
|
||||
{
|
||||
case PCB_SHAPE_T:
|
||||
item->TransformShapeToPolygon( *layerPoly, layer, 0, maxError, ERROR_INSIDE );
|
||||
item->TransformShapeToPolySet( *layerPoly, layer, 0, maxError, ERROR_INSIDE );
|
||||
break;
|
||||
|
||||
case PCB_TEXT_T:
|
||||
@@ -1026,7 +1028,7 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
|
||||
switch( item->Type() )
|
||||
{
|
||||
case PCB_SHAPE_T:
|
||||
item->TransformShapeToPolygon( *layerPoly, layer, 0, maxError, ERROR_INSIDE );
|
||||
item->TransformShapeToPolySet( *layerPoly, layer, 0, maxError, ERROR_INSIDE );
|
||||
break;
|
||||
|
||||
case PCB_TEXT_T:
|
||||
|
||||
@@ -2083,7 +2083,8 @@ int EDA_SHAPE::Compare( const EDA_SHAPE* aOther ) const
|
||||
|
||||
|
||||
void EDA_SHAPE::TransformShapeToPolygon( SHAPE_POLY_SET& aBuffer, int aClearance, int aError,
|
||||
ERROR_LOC aErrorLoc, bool ignoreLineWidth ) const
|
||||
ERROR_LOC aErrorLoc, bool ignoreLineWidth,
|
||||
bool includeFill ) const
|
||||
{
|
||||
int width = ignoreLineWidth ? 0 : GetWidth();
|
||||
|
||||
@@ -2200,7 +2201,7 @@ void EDA_SHAPE::TransformShapeToPolygon( SHAPE_POLY_SET& aBuffer, int aClearance
|
||||
break;
|
||||
}
|
||||
|
||||
if( IsHatchedFill() )
|
||||
if( IsHatchedFill() && includeFill )
|
||||
{
|
||||
for( int ii = 0; ii < GetHatching().OutlineCount(); ++ii )
|
||||
aBuffer.AddOutline( GetHatching().COutline( ii ) );
|
||||
|
||||
@@ -416,6 +416,23 @@ public:
|
||||
int aClearance, int aError, ERROR_LOC aErrorLoc,
|
||||
bool ignoreLineWidth = false ) const;
|
||||
|
||||
/**
|
||||
* Convert the item shape to a polyset. Circles and arcs are approximated by segments; hatched
|
||||
* fills will be included.
|
||||
*
|
||||
* @param aBuffer a buffer to store the polygon.
|
||||
* @param aClearance the clearance around the pad.
|
||||
* @param aError the maximum deviation from true circle.
|
||||
* @param aErrorLoc should the approximation error be placed outside or inside the polygon?
|
||||
* @param ignoreLineWidth used for edge cut items where the line width is only
|
||||
* for visualization.
|
||||
*/
|
||||
virtual void TransformShapeToPolySet( SHAPE_POLY_SET& aBuffer, PCB_LAYER_ID aLayer,
|
||||
int aClearance, int aError, ERROR_LOC aErrorLoc ) const
|
||||
{
|
||||
TransformShapeToPolygon( aBuffer, aLayer, aClearance, aError, aErrorLoc );
|
||||
}
|
||||
|
||||
enum COMPARE_FLAGS : int
|
||||
{
|
||||
DRC = 0x01
|
||||
|
||||
+2
-1
@@ -415,7 +415,8 @@ public:
|
||||
* visualization
|
||||
*/
|
||||
void TransformShapeToPolygon( SHAPE_POLY_SET& aBuffer, int aClearance, int aError,
|
||||
ERROR_LOC aErrorLoc, bool ignoreLineWidth = false ) const;
|
||||
ERROR_LOC aErrorLoc, bool ignoreLineWidth = false,
|
||||
bool includeFill = false ) const;
|
||||
|
||||
int Compare( const EDA_SHAPE* aOther ) const;
|
||||
|
||||
|
||||
@@ -519,7 +519,7 @@ bool EXPORTER_STEP::buildGraphic3DShape( BOARD_ITEM* aItem, VECTOR2D aOrigin )
|
||||
return true;
|
||||
}
|
||||
|
||||
graphic->TransformShapeToPolygon( m_poly_shapes[pcblayer], pcblayer, 0, maxError,
|
||||
graphic->TransformShapeToPolySet( m_poly_shapes[pcblayer], pcblayer, 0, maxError,
|
||||
ERROR_INSIDE );
|
||||
|
||||
break;
|
||||
|
||||
@@ -3944,10 +3944,10 @@ void FOOTPRINT::TransformFPShapesToPolySet( SHAPE_POLY_SET& aBuffer, PCB_LAYER_I
|
||||
|
||||
if( item->Type() == PCB_SHAPE_T && aIncludeShapes )
|
||||
{
|
||||
const PCB_SHAPE* outline = static_cast<PCB_SHAPE*>( item );
|
||||
const PCB_SHAPE* shape = static_cast<PCB_SHAPE*>( item );
|
||||
|
||||
if( aLayer != UNDEFINED_LAYER && outline->GetLayer() == aLayer )
|
||||
outline->TransformShapeToPolygon( aBuffer, aLayer, 0, aError, aErrorLoc );
|
||||
if( aLayer != UNDEFINED_LAYER && shape->GetLayer() == aLayer )
|
||||
shape->TransformShapeToPolySet( aBuffer, aLayer, 0, aError, aErrorLoc );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -838,7 +838,15 @@ void PCB_SHAPE::TransformShapeToPolygon( SHAPE_POLY_SET& aBuffer, PCB_LAYER_ID a
|
||||
int aClearance, int aError, ERROR_LOC aErrorLoc,
|
||||
bool ignoreLineWidth ) const
|
||||
{
|
||||
EDA_SHAPE::TransformShapeToPolygon( aBuffer, aClearance, aError, aErrorLoc, ignoreLineWidth );
|
||||
EDA_SHAPE::TransformShapeToPolygon( aBuffer, aClearance, aError, aErrorLoc, ignoreLineWidth,
|
||||
false );
|
||||
}
|
||||
|
||||
|
||||
void PCB_SHAPE::TransformShapeToPolySet( SHAPE_POLY_SET& aBuffer, PCB_LAYER_ID aLayer,
|
||||
int aClearance, int aError, ERROR_LOC aErrorLoc ) const
|
||||
{
|
||||
EDA_SHAPE::TransformShapeToPolygon( aBuffer, aClearance, aError, aErrorLoc, false, true );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -161,6 +161,9 @@ public:
|
||||
int aError, ERROR_LOC aErrorLoc,
|
||||
bool ignoreLineWidth = false ) const override;
|
||||
|
||||
void TransformShapeToPolySet( SHAPE_POLY_SET& aBuffer, PCB_LAYER_ID aLayer, int aClearance,
|
||||
int aError, ERROR_LOC aErrorLoc ) const override;
|
||||
|
||||
wxString GetItemDescription( UNITS_PROVIDER* aUnitsProvider, bool aFull ) const override;
|
||||
|
||||
BITMAPS GetMenuImage() const override;
|
||||
|
||||
@@ -1006,9 +1006,9 @@ void GenerateLayerPoly( SHAPE_POLY_SET* aResult, BOARD *aBoard, PCB_LAYER_ID aLa
|
||||
else
|
||||
{
|
||||
if( inflate != 0 )
|
||||
item->TransformShapeToPolygon( exactPolys, aLayer, 0, ERROR );
|
||||
item->TransformShapeToPolySet( exactPolys, aLayer, 0, ERROR );
|
||||
|
||||
item->TransformShapeToPolygon( *aResult, aLayer, inflate, ERROR );
|
||||
item->TransformShapeToPolySet( *aResult, aLayer, inflate, ERROR );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user