Use SCOPED_FLAGS_CLEANER more carefully.

Other methods used ConvertOutlineToPolygon's SKIP_STRUCT state.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/16321
This commit is contained in:
Alex Shvartzkop 2023-12-09 19:24:47 +03:00
parent d8bb9b1e66
commit a161829f86

View File

@ -180,9 +180,10 @@ static bool isCopperOutside( const FOOTPRINT* aFootprint, SHAPE_POLY_SET& aShape
} }
bool ConvertOutlineToPolygon( std::vector<PCB_SHAPE*>& aShapeList, SHAPE_POLY_SET& aPolygons, bool doConvertOutlineToPolygon( std::vector<PCB_SHAPE*>& aShapeList, SHAPE_POLY_SET& aPolygons,
int aErrorMax, int aChainingEpsilon, bool aAllowDisjoint, int aErrorMax, int aChainingEpsilon, bool aAllowDisjoint,
OUTLINE_ERROR_HANDLER* aErrorHandler, bool aAllowUseArcsInPolygons ) OUTLINE_ERROR_HANDLER* aErrorHandler, bool aAllowUseArcsInPolygons,
SCOPED_FLAGS_CLEANER& aCleaner )
{ {
if( aShapeList.size() == 0 ) if( aShapeList.size() == 0 )
return true; return true;
@ -209,7 +210,6 @@ bool ConvertOutlineToPolygon( std::vector<PCB_SHAPE*>& aShapeList, SHAPE_POLY_SE
VECTOR2I prevPt; VECTOR2I prevPt;
std::vector<SHAPE_LINE_CHAIN> contours; std::vector<SHAPE_LINE_CHAIN> contours;
SCOPED_FLAGS_CLEANER cleaner( SKIP_STRUCT );
for( PCB_SHAPE* shape : startCandidates ) for( PCB_SHAPE* shape : startCandidates )
shape->ClearFlags( SKIP_STRUCT ); shape->ClearFlags( SKIP_STRUCT );
@ -218,7 +218,7 @@ bool ConvertOutlineToPolygon( std::vector<PCB_SHAPE*>& aShapeList, SHAPE_POLY_SE
{ {
graphic = (PCB_SHAPE*) *startCandidates.begin(); graphic = (PCB_SHAPE*) *startCandidates.begin();
graphic->SetFlags( SKIP_STRUCT ); graphic->SetFlags( SKIP_STRUCT );
cleaner.insert( graphic ); aCleaner.insert( graphic );
startCandidates.erase( startCandidates.begin() ); startCandidates.erase( startCandidates.begin() );
contours.emplace_back(); contours.emplace_back();
@ -438,7 +438,7 @@ bool ConvertOutlineToPolygon( std::vector<PCB_SHAPE*>& aShapeList, SHAPE_POLY_SE
prevGraphic = graphic; prevGraphic = graphic;
graphic = nextGraphic; graphic = nextGraphic;
graphic->SetFlags( SKIP_STRUCT ); graphic->SetFlags( SKIP_STRUCT );
cleaner.insert( graphic ); aCleaner.insert( graphic );
startCandidates.erase( graphic ); startCandidates.erase( graphic );
continue; continue;
} }
@ -587,6 +587,18 @@ bool ConvertOutlineToPolygon( std::vector<PCB_SHAPE*>& aShapeList, SHAPE_POLY_SE
} }
bool ConvertOutlineToPolygon( std::vector<PCB_SHAPE*>& aShapeList, SHAPE_POLY_SET& aPolygons,
int aErrorMax, int aChainingEpsilon, bool aAllowDisjoint,
OUTLINE_ERROR_HANDLER* aErrorHandler, bool aAllowUseArcsInPolygons )
{
SCOPED_FLAGS_CLEANER cleaner( SKIP_STRUCT );
return doConvertOutlineToPolygon( aShapeList, aPolygons, aErrorMax, aChainingEpsilon,
aAllowDisjoint, aErrorHandler, aAllowUseArcsInPolygons,
cleaner );
}
bool TestBoardOutlinesGraphicItems( BOARD* aBoard, int aMinDist, bool TestBoardOutlinesGraphicItems( BOARD* aBoard, int aMinDist,
OUTLINE_ERROR_HANDLER* aErrorHandler ) OUTLINE_ERROR_HANDLER* aErrorHandler )
{ {
@ -725,9 +737,10 @@ bool BuildBoardPolygonOutlines( BOARD* aBoard, SHAPE_POLY_SET& aOutlines, int aE
bool aAllowUseArcsInPolygons ) bool aAllowUseArcsInPolygons )
{ {
PCB_TYPE_COLLECTOR items; PCB_TYPE_COLLECTOR items;
SHAPE_POLY_SET fpHoles;
bool success = false; bool success = false;
SHAPE_POLY_SET fpHoles; SCOPED_FLAGS_CLEANER cleaner( SKIP_STRUCT );
// Get all the shapes into 'items', then keep only those on layer == Edge_Cuts. // Get all the shapes into 'items', then keep only those on layer == Edge_Cuts.
items.Collect( aBoard, { PCB_SHAPE_T } ); items.Collect( aBoard, { PCB_SHAPE_T } );
@ -753,11 +766,11 @@ bool BuildBoardPolygonOutlines( BOARD* aBoard, SHAPE_POLY_SET& aOutlines, int aE
if( !fpSegList.empty() ) if( !fpSegList.empty() )
{ {
SHAPE_POLY_SET fpOutlines; SHAPE_POLY_SET fpOutlines;
success = ConvertOutlineToPolygon( fpSegList, fpOutlines, aErrorMax, aChainingEpsilon, success = doConvertOutlineToPolygon( fpSegList, fpOutlines, aErrorMax, aChainingEpsilon,
false, false,
// don't report errors here; the second pass also // don't report errors here; the second pass also
// gets an opportunity to use these segments // gets an opportunity to use these segments
nullptr, aAllowUseArcsInPolygons ); nullptr, aAllowUseArcsInPolygons, cleaner );
// Test to see if we should make holes or outlines. Holes are made if the footprint // Test to see if we should make holes or outlines. Holes are made if the footprint
// has copper outside of a single, closed outline. If there are multiple outlines, // has copper outside of a single, closed outline. If there are multiple outlines,
@ -795,8 +808,8 @@ bool BuildBoardPolygonOutlines( BOARD* aBoard, SHAPE_POLY_SET& aOutlines, int aE
if( segList.size() ) if( segList.size() )
{ {
success = ConvertOutlineToPolygon( segList, aOutlines, aErrorMax, aChainingEpsilon, success = doConvertOutlineToPolygon( segList, aOutlines, aErrorMax, aChainingEpsilon, true,
true, aErrorHandler, aAllowUseArcsInPolygons ); aErrorHandler, aAllowUseArcsInPolygons, cleaner );
} }
if( !success || !aOutlines.OutlineCount() ) if( !success || !aOutlines.OutlineCount() )
@ -980,6 +993,8 @@ bool BuildFootprintPolygonOutlines( BOARD* aBoard, SHAPE_POLY_SET& aOutlines, in
SHAPE_POLY_SET outlines; SHAPE_POLY_SET outlines;
bool success = false; bool success = false;
SCOPED_FLAGS_CLEANER cleaner( SKIP_STRUCT );
// Get all the SHAPEs into 'items', then keep only those on layer == Edge_Cuts. // Get all the SHAPEs into 'items', then keep only those on layer == Edge_Cuts.
items.Collect( aBoard, { PCB_SHAPE_T } ); items.Collect( aBoard, { PCB_SHAPE_T } );
@ -994,8 +1009,8 @@ bool BuildFootprintPolygonOutlines( BOARD* aBoard, SHAPE_POLY_SET& aOutlines, in
if( !segList.empty() ) if( !segList.empty() )
{ {
success = ConvertOutlineToPolygon( segList, outlines, aErrorMax, aChainingEpsilon, success = doConvertOutlineToPolygon( segList, outlines, aErrorMax, aChainingEpsilon, true,
true, aErrorHandler ); aErrorHandler, false, cleaner );
} }
// A closed outline was found on Edge_Cuts // A closed outline was found on Edge_Cuts