mirror of
https://gitlab.com/kicad/code/kicad.git
synced 2025-09-14 10:13:19 +02:00
Give Clipper1 a Viking funeral
Clears out the last spot where we were only using Clipper1 (how'd I miss that?) and remove all calls to the Clipper1 structures
This commit is contained in:
parent
fd137279c8
commit
e9bc8cfe9d
@ -947,9 +947,7 @@ bool BOARD_ADAPTER::createBoardPolygon( wxString* aErrorMsg )
|
||||
success = BuildFootprintPolygonOutlines( m_board, m_board_poly,
|
||||
m_board->GetDesignSettings().m_MaxError,
|
||||
chainingEpsilon );
|
||||
|
||||
// Make polygon strictly simple to avoid issues (especially in 3D viewer)
|
||||
m_board_poly.Simplify( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
||||
m_board_poly.Simplify();
|
||||
|
||||
if( !success && aErrorMsg )
|
||||
{
|
||||
|
@ -650,7 +650,7 @@ void BOARD_ADAPTER::addShape( const PCB_SHAPE* aShape, CONTAINER_2D_BASE* aConta
|
||||
aShape->TransformShapeToPolygon( polyList, UNDEFINED_LAYER, 0, ARC_HIGH_DEF,
|
||||
ERROR_INSIDE );
|
||||
|
||||
polyList.Simplify( SHAPE_POLY_SET::PM_FAST );
|
||||
polyList.Simplify();
|
||||
|
||||
if( margin != 0 )
|
||||
{
|
||||
@ -700,7 +700,7 @@ void BOARD_ADAPTER::addShape( const PCB_SHAPE* aShape, CONTAINER_2D_BASE* aConta
|
||||
// Some polygons can be a bit complex (especially when coming from a
|
||||
// picture ot a text converted to a polygon
|
||||
// So call Simplify before calling ConvertPolygonToTriangles, just in case.
|
||||
polyList.Simplify( SHAPE_POLY_SET::PM_FAST );
|
||||
polyList.Simplify();
|
||||
|
||||
if( polyList.IsEmpty() ) // Just for caution
|
||||
break;
|
||||
|
@ -780,10 +780,10 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
|
||||
// End Build Copper layers
|
||||
|
||||
// This will make a union of all added contours
|
||||
m_TH_ODPolys.Simplify( SHAPE_POLY_SET::PM_FAST );
|
||||
m_NPTH_ODPolys.Simplify( SHAPE_POLY_SET::PM_FAST );
|
||||
m_viaTH_ODPolys.Simplify( SHAPE_POLY_SET::PM_FAST );
|
||||
m_viaAnnuliPolys.Simplify( SHAPE_POLY_SET::PM_FAST );
|
||||
m_TH_ODPolys.Simplify();
|
||||
m_NPTH_ODPolys.Simplify();
|
||||
m_viaTH_ODPolys.Simplify();
|
||||
m_viaAnnuliPolys.Simplify();
|
||||
|
||||
// Build Tech layers
|
||||
// Based on:
|
||||
@ -1022,7 +1022,7 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
|
||||
}
|
||||
|
||||
// This will make a union of all added contours
|
||||
layerPoly->Simplify( SHAPE_POLY_SET::PM_FAST );
|
||||
layerPoly->Simplify();
|
||||
}
|
||||
}
|
||||
// End Build Tech layers
|
||||
@ -1061,14 +1061,12 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
|
||||
// TRIM PLATED COPPER TO SOLDERMASK
|
||||
if( m_layers_poly.find( F_Mask ) != m_layers_poly.end() )
|
||||
{
|
||||
m_frontPlatedCopperPolys->BooleanIntersection( *m_layers_poly.at( F_Mask ),
|
||||
SHAPE_POLY_SET::PM_FAST );
|
||||
m_frontPlatedCopperPolys->BooleanIntersection( *m_layers_poly.at( F_Mask ) );
|
||||
}
|
||||
|
||||
if( m_layers_poly.find( B_Mask ) != m_layers_poly.end() )
|
||||
{
|
||||
m_backPlatedCopperPolys->BooleanIntersection( *m_layers_poly.at( B_Mask ),
|
||||
SHAPE_POLY_SET::PM_FAST );
|
||||
m_backPlatedCopperPolys->BooleanIntersection( *m_layers_poly.at( B_Mask ) );
|
||||
}
|
||||
|
||||
// Subtract plated copper from unplated copper
|
||||
@ -1077,15 +1075,15 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
|
||||
|
||||
if( m_layers_poly.find( F_Cu ) != m_layers_poly.end() )
|
||||
{
|
||||
m_layers_poly[F_Cu]->BooleanSubtract( *m_frontPlatedPadAndGraphicPolys, SHAPE_POLY_SET::PM_FAST );
|
||||
m_layers_poly[F_Cu]->BooleanSubtract( *m_frontPlatedCopperPolys, SHAPE_POLY_SET::PM_FAST );
|
||||
m_layers_poly[F_Cu]->BooleanSubtract( *m_frontPlatedPadAndGraphicPolys );
|
||||
m_layers_poly[F_Cu]->BooleanSubtract( *m_frontPlatedCopperPolys );
|
||||
hasF_Cu = true;
|
||||
}
|
||||
|
||||
if( m_layers_poly.find( B_Cu ) != m_layers_poly.end() )
|
||||
{
|
||||
m_layers_poly[B_Cu]->BooleanSubtract( *m_backPlatedPadAndGraphicPolys, SHAPE_POLY_SET::PM_FAST );
|
||||
m_layers_poly[B_Cu]->BooleanSubtract( *m_backPlatedCopperPolys, SHAPE_POLY_SET::PM_FAST );
|
||||
m_layers_poly[B_Cu]->BooleanSubtract( *m_backPlatedPadAndGraphicPolys );
|
||||
m_layers_poly[B_Cu]->BooleanSubtract( *m_backPlatedCopperPolys );
|
||||
hasB_Cu = true;
|
||||
}
|
||||
|
||||
@ -1096,10 +1094,10 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
|
||||
if( hasB_Cu && m_backPlatedCopperPolys->OutlineCount() )
|
||||
m_backPlatedPadAndGraphicPolys->Append( *m_backPlatedCopperPolys );
|
||||
|
||||
m_frontPlatedPadAndGraphicPolys->Simplify( SHAPE_POLY_SET::PM_FAST );
|
||||
m_backPlatedPadAndGraphicPolys->Simplify( SHAPE_POLY_SET::PM_FAST );
|
||||
m_frontPlatedCopperPolys->Simplify( SHAPE_POLY_SET::PM_FAST );
|
||||
m_backPlatedCopperPolys->Simplify( SHAPE_POLY_SET::PM_FAST );
|
||||
m_frontPlatedPadAndGraphicPolys->Simplify();
|
||||
m_backPlatedPadAndGraphicPolys->Simplify();
|
||||
m_frontPlatedCopperPolys->Simplify();
|
||||
m_backPlatedCopperPolys->Simplify();
|
||||
|
||||
// ADD PLATED PADS
|
||||
for( FOOTPRINT* footprint : m_board->Footprints() )
|
||||
@ -1168,7 +1166,7 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
|
||||
{
|
||||
// This will make a union of all added contours
|
||||
layerPoly->second->ClearArcs();
|
||||
layerPoly->second->Simplify( SHAPE_POLY_SET::PM_FAST );
|
||||
layerPoly->second->Simplify();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1193,12 +1191,12 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
|
||||
{
|
||||
// found
|
||||
SHAPE_POLY_SET *polyLayer = m_layerHoleOdPolys[layer];
|
||||
polyLayer->Simplify( SHAPE_POLY_SET::PM_FAST );
|
||||
polyLayer->Simplify();
|
||||
|
||||
wxASSERT( m_layerHoleIdPolys.find( layer ) != m_layerHoleIdPolys.end() );
|
||||
|
||||
polyLayer = m_layerHoleIdPolys[layer];
|
||||
polyLayer->Simplify( SHAPE_POLY_SET::PM_FAST );
|
||||
polyLayer->Simplify();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -476,13 +476,12 @@ void RENDER_3D_OPENGL::reload( REPORTER* aStatusReporter, REPORTER* aWarningRepo
|
||||
m_antiBoardPolys.Append( VECTOR2I( -INT_MAX/2, INT_MAX/2 ) );
|
||||
m_antiBoardPolys.Outline( 0 ).SetClosed( true );
|
||||
|
||||
m_antiBoardPolys.BooleanSubtract( m_boardAdapter.GetBoardPoly(),
|
||||
SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
||||
m_antiBoardPolys.BooleanSubtract( m_boardAdapter.GetBoardPoly() );
|
||||
m_antiBoard = createBoard( m_antiBoardPolys );
|
||||
|
||||
SHAPE_POLY_SET board_poly_with_holes = m_boardAdapter.GetBoardPoly().CloneDropTriangulation();
|
||||
board_poly_with_holes.BooleanSubtract( m_boardAdapter.GetTH_ODPolys(), SHAPE_POLY_SET::PM_FAST );
|
||||
board_poly_with_holes.BooleanSubtract( m_boardAdapter.GetNPTH_ODPolys(), SHAPE_POLY_SET::PM_FAST );
|
||||
board_poly_with_holes.BooleanSubtract( m_boardAdapter.GetTH_ODPolys() );
|
||||
board_poly_with_holes.BooleanSubtract( m_boardAdapter.GetNPTH_ODPolys() );
|
||||
|
||||
m_boardWithHoles = createBoard( board_poly_with_holes );
|
||||
|
||||
@ -495,8 +494,7 @@ void RENDER_3D_OPENGL::reload( REPORTER* aStatusReporter, REPORTER* aWarningRepo
|
||||
|
||||
SHAPE_POLY_SET outerPolyTHT = m_boardAdapter.GetTH_ODPolys().CloneDropTriangulation();
|
||||
|
||||
outerPolyTHT.BooleanIntersection( m_boardAdapter.GetBoardPoly(),
|
||||
SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
||||
outerPolyTHT.BooleanIntersection( m_boardAdapter.GetBoardPoly() );
|
||||
|
||||
m_outerThroughHoles = generateHoles( m_boardAdapter.GetTH_ODs().GetList(), outerPolyTHT,
|
||||
1.0f, 0.0f, false, &m_boardAdapter.GetTH_IDs() );
|
||||
@ -575,29 +573,24 @@ void RENDER_3D_OPENGL::reload( REPORTER* aStatusReporter, REPORTER* aWarningRepo
|
||||
|
||||
if( LSET::PhysicalLayersMask().test( layer ) )
|
||||
{
|
||||
polyListSubtracted.BooleanIntersection( m_boardAdapter.GetBoardPoly(),
|
||||
SHAPE_POLY_SET::PM_FAST );
|
||||
polyListSubtracted.BooleanIntersection( m_boardAdapter.GetBoardPoly() );
|
||||
}
|
||||
|
||||
if( layer != B_Mask && layer != F_Mask )
|
||||
{
|
||||
polyListSubtracted.BooleanSubtract( m_boardAdapter.GetTH_ODPolys(),
|
||||
SHAPE_POLY_SET::PM_FAST );
|
||||
polyListSubtracted.BooleanSubtract( m_boardAdapter.GetNPTH_ODPolys(),
|
||||
SHAPE_POLY_SET::PM_FAST );
|
||||
polyListSubtracted.BooleanSubtract( m_boardAdapter.GetTH_ODPolys() );
|
||||
polyListSubtracted.BooleanSubtract( m_boardAdapter.GetNPTH_ODPolys() );
|
||||
}
|
||||
|
||||
if( m_boardAdapter.m_Cfg->m_Render.subtract_mask_from_silk )
|
||||
{
|
||||
if( layer == B_SilkS && map_poly.find( B_Mask ) != map_poly.end() )
|
||||
{
|
||||
polyListSubtracted.BooleanSubtract( *map_poly.at( B_Mask ),
|
||||
SHAPE_POLY_SET::PM_FAST );
|
||||
polyListSubtracted.BooleanSubtract( *map_poly.at( B_Mask ) );
|
||||
}
|
||||
else if( layer == F_SilkS && map_poly.find( F_Mask ) != map_poly.end() )
|
||||
{
|
||||
polyListSubtracted.BooleanSubtract( *map_poly.at( F_Mask ),
|
||||
SHAPE_POLY_SET::PM_FAST );
|
||||
polyListSubtracted.BooleanSubtract( *map_poly.at( F_Mask ) );
|
||||
}
|
||||
}
|
||||
|
||||
@ -620,9 +613,9 @@ void RENDER_3D_OPENGL::reload( REPORTER* aStatusReporter, REPORTER* aWarningRepo
|
||||
if( frontPlatedPadAndGraphicPolys )
|
||||
{
|
||||
SHAPE_POLY_SET poly = frontPlatedPadAndGraphicPolys->CloneDropTriangulation();
|
||||
poly.BooleanIntersection( m_boardAdapter.GetBoardPoly(), SHAPE_POLY_SET::PM_FAST );
|
||||
poly.BooleanSubtract( m_boardAdapter.GetTH_ODPolys(), SHAPE_POLY_SET::PM_FAST );
|
||||
poly.BooleanSubtract( m_boardAdapter.GetNPTH_ODPolys(), SHAPE_POLY_SET::PM_FAST );
|
||||
poly.BooleanIntersection( m_boardAdapter.GetBoardPoly() );
|
||||
poly.BooleanSubtract( m_boardAdapter.GetTH_ODPolys() );
|
||||
poly.BooleanSubtract( m_boardAdapter.GetNPTH_ODPolys() );
|
||||
|
||||
m_platedPadsFront = generateLayerList( m_boardAdapter.GetPlatedPadsFront(), &poly, F_Cu );
|
||||
|
||||
@ -634,9 +627,9 @@ void RENDER_3D_OPENGL::reload( REPORTER* aStatusReporter, REPORTER* aWarningRepo
|
||||
if( backPlatedPadAndGraphicPolys )
|
||||
{
|
||||
SHAPE_POLY_SET poly = backPlatedPadAndGraphicPolys->CloneDropTriangulation();
|
||||
poly.BooleanIntersection( m_boardAdapter.GetBoardPoly(), SHAPE_POLY_SET::PM_FAST );
|
||||
poly.BooleanSubtract( m_boardAdapter.GetTH_ODPolys(), SHAPE_POLY_SET::PM_FAST );
|
||||
poly.BooleanSubtract( m_boardAdapter.GetNPTH_ODPolys(), SHAPE_POLY_SET::PM_FAST );
|
||||
poly.BooleanIntersection( m_boardAdapter.GetBoardPoly() );
|
||||
poly.BooleanSubtract( m_boardAdapter.GetTH_ODPolys() );
|
||||
poly.BooleanSubtract( m_boardAdapter.GetNPTH_ODPolys() );
|
||||
|
||||
m_platedPadsBack = generateLayerList( m_boardAdapter.GetPlatedPadsBack(), &poly, B_Cu );
|
||||
|
||||
@ -839,9 +832,9 @@ void RENDER_3D_OPENGL::generateViasAndPads()
|
||||
}
|
||||
|
||||
// Subtract the holes
|
||||
tht_outer_holes_poly.BooleanSubtract( tht_inner_holes_poly, SHAPE_POLY_SET::PM_FAST );
|
||||
tht_outer_holes_poly.BooleanSubtract( tht_inner_holes_poly );
|
||||
|
||||
tht_outer_holes_poly.BooleanSubtract( m_antiBoardPolys, SHAPE_POLY_SET::PM_FAST );
|
||||
tht_outer_holes_poly.BooleanSubtract( m_antiBoardPolys );
|
||||
|
||||
CONTAINER_2D holesContainer;
|
||||
|
||||
|
@ -415,8 +415,8 @@ void RENDER_3D_RAYTRACE_BASE::Reload( REPORTER* aStatusReporter, REPORTER* aWarn
|
||||
|
||||
buildBoardBoundingBoxPoly( m_boardAdapter.GetBoard(), antiboardPoly );
|
||||
|
||||
antiboardPoly.BooleanSubtract( boardPolyCopy, SHAPE_POLY_SET::PM_FAST );
|
||||
antiboardPoly.Fracture( SHAPE_POLY_SET::PM_FAST );
|
||||
antiboardPoly.BooleanSubtract( boardPolyCopy );
|
||||
antiboardPoly.Fracture();
|
||||
|
||||
for( int ii = 0; ii < antiboardPoly.OutlineCount(); ii++ )
|
||||
{
|
||||
@ -427,7 +427,7 @@ void RENDER_3D_RAYTRACE_BASE::Reload( REPORTER* aStatusReporter, REPORTER* aWarn
|
||||
|
||||
m_antioutlineBoard2dObjects->BuildBVH();
|
||||
|
||||
boardPolyCopy.Fracture( SHAPE_POLY_SET::PM_FAST );
|
||||
boardPolyCopy.Fracture();
|
||||
|
||||
for( int ii = 0; ii < outlineCount; ii++ )
|
||||
{
|
||||
|
@ -612,10 +612,9 @@ void ConvertPolygonToBlocks( const SHAPE_POLY_SET& aMainPath, CONTAINER_2D_BASE&
|
||||
|
||||
subBlockPoly.AddOutline( sb );
|
||||
|
||||
// We need here a strictly simple polygon with outlines and holes
|
||||
// We need here a simple polygon with outlines and holes
|
||||
SHAPE_POLY_SET solution;
|
||||
solution.BooleanIntersection( aMainPath, subBlockPoly,
|
||||
SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
||||
solution.BooleanIntersection( aMainPath, subBlockPoly );
|
||||
|
||||
OUTERS_AND_HOLES outersAndHoles;
|
||||
|
||||
@ -659,68 +658,3 @@ void ConvertPolygonToBlocks( const SHAPE_POLY_SET& aMainPath, CONTAINER_2D_BASE&
|
||||
topToBottom += topToBottom_inc;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
static void polygon_Convert( const ClipperLib::Path& aPath, SEGMENTS& aOutSegment,
|
||||
float aBiuTo3dUnitsScale )
|
||||
{
|
||||
aOutSegment.resize( aPath.size() );
|
||||
|
||||
for( unsigned i = 0; i < aPath.size(); i++ )
|
||||
{
|
||||
aOutSegment[i].m_Start = SFVEC2F(
|
||||
(float) aPath[i].X * aBiuTo3dUnitsScale, (float) -aPath[i].Y * aBiuTo3dUnitsScale );
|
||||
}
|
||||
|
||||
unsigned int i;
|
||||
unsigned int j = aOutSegment.size() - 1;
|
||||
|
||||
for( i = 0; i < aOutSegment.size(); j = i++ )
|
||||
{
|
||||
// Calculate constants for each segment
|
||||
aOutSegment[i].m_inv_JY_minus_IY =
|
||||
1.0f / ( aOutSegment[j].m_Start.y - aOutSegment[i].m_Start.y );
|
||||
aOutSegment[i].m_JX_minus_IX = ( aOutSegment[j].m_Start.x - aOutSegment[i].m_Start.x );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Polygon2d_TestModule()
|
||||
{
|
||||
// "This structure contains a sequence of IntPoint vertices defining a single contour"
|
||||
ClipperLib::Path aPath;
|
||||
|
||||
SEGMENTS aSegments;
|
||||
|
||||
aPath.resize( 4 );
|
||||
|
||||
aPath[0] = ClipperLib::IntPoint( -2, -2 );
|
||||
aPath[1] = ClipperLib::IntPoint( 2, -2 );
|
||||
aPath[2] = ClipperLib::IntPoint( 2, 2 );
|
||||
aPath[3] = ClipperLib::IntPoint( -2, 2 );
|
||||
|
||||
// It must be an outer polygon
|
||||
wxASSERT( ClipperLib::Orientation( aPath ) );
|
||||
|
||||
polygon_Convert( aPath, aSegments, 1.0f );
|
||||
|
||||
wxASSERT( aPath.size() == aSegments.size() );
|
||||
|
||||
wxASSERT( aSegments[0].m_Start == SFVEC2F( -2.0f, 2.0f ) );
|
||||
wxASSERT( aSegments[1].m_Start == SFVEC2F( 2.0f, 2.0f ) );
|
||||
wxASSERT( aSegments[2].m_Start == SFVEC2F( 2.0f, -2.0f ) );
|
||||
wxASSERT( aSegments[3].m_Start == SFVEC2F( -2.0f, -2.0f ) );
|
||||
|
||||
wxASSERT( polygon_IsPointInside( aSegments, SFVEC2F( 0.0f, 0.0f ) ) );
|
||||
wxASSERT( polygon_IsPointInside( aSegments, SFVEC2F( -1.9f, -1.9f ) ) );
|
||||
wxASSERT( polygon_IsPointInside( aSegments, SFVEC2F( -1.9f, 1.9f ) ) );
|
||||
wxASSERT( polygon_IsPointInside( aSegments, SFVEC2F( 1.9f, 1.9f ) ) );
|
||||
wxASSERT( polygon_IsPointInside( aSegments, SFVEC2F( 1.9f, -1.9f ) ) );
|
||||
|
||||
wxASSERT( polygon_IsPointInside( aSegments, SFVEC2F( -2.1f, -2.0f ) ) == false );
|
||||
wxASSERT( polygon_IsPointInside( aSegments, SFVEC2F( -2.1f, 2.0f ) ) == false );
|
||||
wxASSERT( polygon_IsPointInside( aSegments, SFVEC2F( 2.1f, 2.0f ) ) == false );
|
||||
wxASSERT( polygon_IsPointInside( aSegments, SFVEC2F( 2.1f, -2.0f ) ) == false );
|
||||
}
|
||||
#endif
|
||||
|
@ -152,6 +152,5 @@ void ConvertPolygonToBlocks( const SHAPE_POLY_SET& aMainPath, CONTAINER_2D_BASE&
|
||||
float aBiuTo3dUnitsScale, float aDivFactor,
|
||||
const BOARD_ITEM& aBoardItem, int aPolyIndex );
|
||||
|
||||
void Polygon2d_TestModule();
|
||||
|
||||
#endif // _CPOLYGON2D_H_
|
||||
|
@ -33,7 +33,6 @@
|
||||
#include "../accelerators/container_2d.h"
|
||||
#include <geometry/shape_line_chain.h>
|
||||
#include <geometry/shape_poly_set.h>
|
||||
#include <clipper.hpp>
|
||||
|
||||
class TRIANGLE_2D : public OBJECT_2D
|
||||
{
|
||||
|
@ -524,15 +524,15 @@ void BITMAPCONV_INFO::createOutputData( BMP2CMP_MOD_LAYER aModLayer )
|
||||
// at the end of a group of a positive path and its negative children, fill.
|
||||
if( paths->next == nullptr || paths->next->sign == '+' )
|
||||
{
|
||||
polyset_areas.Simplify( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
||||
polyset_holes.Simplify( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
||||
polyset_areas.BooleanSubtract( polyset_holes, SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
||||
polyset_areas.Simplify();
|
||||
polyset_holes.Simplify();
|
||||
polyset_areas.BooleanSubtract( polyset_holes );
|
||||
|
||||
// Ensure there are no self intersecting polygons
|
||||
if( polyset_areas.NormalizeAreaOutlines() )
|
||||
{
|
||||
// Convert polygon with holes to a unique polygon
|
||||
polyset_areas.Fracture( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
||||
polyset_areas.Fracture();
|
||||
|
||||
// Output current resulting polygon(s)
|
||||
for( int ii = 0; ii < polyset_areas.OutlineCount(); ii++ )
|
||||
|
@ -98,7 +98,6 @@ static const wxChar AllowManualCanvasScale[] = wxT( "AllowManualCanvasScale" );
|
||||
static const wxChar UpdateUIEventInterval[] = wxT( "UpdateUIEventInterval" );
|
||||
static const wxChar V3DRT_BevelHeight_um[] = wxT( "V3DRT_BevelHeight_um" );
|
||||
static const wxChar V3DRT_BevelExtentFactor[] = wxT( "V3DRT_BevelExtentFactor" );
|
||||
static const wxChar UseClipper2[] = wxT( "UseClipper2" );
|
||||
static const wxChar EnableDesignBlocks[] = wxT( "EnableDesignBlocks" );
|
||||
static const wxChar EnableGenerators[] = wxT( "EnableGenerators" );
|
||||
static const wxChar EnableGit[] = wxT( "EnableGit" );
|
||||
@ -263,7 +262,6 @@ ADVANCED_CFG::ADVANCED_CFG()
|
||||
m_3DRT_BevelHeight_um = 30;
|
||||
m_3DRT_BevelExtentFactor = 1.0 / 16.0;
|
||||
|
||||
m_UseClipper2 = true;
|
||||
m_EnableAPILogging = false;
|
||||
|
||||
m_Use3DConnexionDriver = true;
|
||||
@ -464,9 +462,6 @@ void ADVANCED_CFG::loadSettings( wxConfigBase& aCfg )
|
||||
m_3DRT_BevelExtentFactor, 0.0, 100.0,
|
||||
AC_GROUPS::V3D_RayTracing ) );
|
||||
|
||||
configParams.push_back( new PARAM_CFG_BOOL( true, AC_KEYS::UseClipper2,
|
||||
&m_UseClipper2, m_UseClipper2 ) );
|
||||
|
||||
configParams.push_back( new PARAM_CFG_BOOL( true, AC_KEYS::Use3DConnexionDriver,
|
||||
&m_Use3DConnexionDriver, m_Use3DConnexionDriver ) );
|
||||
|
||||
|
@ -71,7 +71,7 @@ void CALLBACK_GAL::DrawGlyph( const KIFONT::GLYPH& aGlyph, int aNth, int aTotal
|
||||
KIFONT::OUTLINE_GLYPH glyph = static_cast<const KIFONT::OUTLINE_GLYPH&>( aGlyph );
|
||||
|
||||
if( glyph.HasHoles() )
|
||||
glyph.Fracture( SHAPE_POLY_SET::POLYGON_MODE::PM_FAST );
|
||||
glyph.Fracture();
|
||||
|
||||
for( int ii = 0; ii < glyph.OutlineCount(); ++ii )
|
||||
m_outlineCallback( glyph.Outline( ii ) );
|
||||
|
@ -1022,9 +1022,9 @@ void EDA_DRAW_FRAME::FocusOnLocation( const VECTOR2I& aPos )
|
||||
{
|
||||
GetCanvas()->GetView()->SetCenter( aPos, dialogScreenRects );
|
||||
}
|
||||
catch( const ClipperLib::clipperException& e )
|
||||
catch( const Clipper2Lib::Clipper2Exception& e )
|
||||
{
|
||||
wxFAIL_MSG( wxString::Format( wxT( "Clipper exception occurred centering object: %s" ),
|
||||
wxFAIL_MSG( wxString::Format( wxT( "Clipper2 exception occurred centering object: %s" ),
|
||||
e.what() ) );
|
||||
}
|
||||
}
|
||||
|
@ -250,9 +250,9 @@ static void convertPolygon( std::list<std::unique_ptr<IMPORTED_SHAPE>>& aShapes,
|
||||
upscaledPaths.push_back( lc );
|
||||
}
|
||||
|
||||
SHAPE_POLY_SET result = SHAPE_POLY_SET::BuildPolysetFromOrientedPaths(
|
||||
upscaledPaths, false, aFillRule == GRAPHICS_IMPORTER::PF_EVEN_ODD );
|
||||
result.Fracture( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
||||
SHAPE_POLY_SET result;
|
||||
result.BuildPolysetFromOrientedPaths( upscaledPaths, aFillRule == GRAPHICS_IMPORTER::PF_EVEN_ODD );
|
||||
result.Fracture();
|
||||
|
||||
for( int outl = 0; outl < result.OutlineCount(); outl++ )
|
||||
{
|
||||
|
@ -574,8 +574,8 @@ void DXF_PLOTTER::PlotPoly( const std::vector<VECTOR2I>& aCornerList, FILL_T aFi
|
||||
// polygon and its thick outline
|
||||
|
||||
// create the outline which contains thick outline:
|
||||
bufferPolybase.BooleanAdd( bufferOutline, SHAPE_POLY_SET::PM_FAST );
|
||||
bufferPolybase.Fracture( SHAPE_POLY_SET::PM_FAST );
|
||||
bufferPolybase.BooleanAdd( bufferOutline );
|
||||
bufferPolybase.Fracture();
|
||||
|
||||
if( bufferPolybase.OutlineCount() < 1 ) // should not happen
|
||||
return;
|
||||
|
@ -622,7 +622,7 @@ void VIEW::SetCenter( const VECTOR2D& aCenter, const std::vector<BOX2D>& obscuri
|
||||
for( const BOX2D& obscuringScreenRect : obscuringScreenRects )
|
||||
{
|
||||
SHAPE_POLY_SET obscuringPoly( obscuringScreenRect );
|
||||
unobscuredPoly.BooleanSubtract( obscuringPoly, SHAPE_POLY_SET::PM_FAST );
|
||||
unobscuredPoly.BooleanSubtract( obscuringPoly );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -91,7 +91,7 @@ std::unordered_map<uint32_t, SHAPE_POLY_SET> ConvertImageToPolygons( wxImage im
|
||||
|
||||
for( auto& [color, polySet] : colorPolys )
|
||||
{
|
||||
polySet.Simplify( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
||||
polySet.Simplify();
|
||||
|
||||
for( int i = 0; i < polySet.OutlineCount(); i++ )
|
||||
{
|
||||
@ -114,7 +114,7 @@ void ConvertImageToLibShapes( LIB_SYMBOL* aSymbol, int unit, wxImage img, VECTOR
|
||||
|
||||
for( auto& [color, polySet] : colorPolys )
|
||||
{
|
||||
polySet.Fracture( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
||||
polySet.Fracture();
|
||||
|
||||
for( const SHAPE_POLY_SET::POLYGON& poly : polySet.CPolygons() )
|
||||
{
|
||||
|
@ -664,8 +664,8 @@ static void knockoutText( KIGFX::GAL& aGal, const wxString& aText, const VECTOR2
|
||||
finalPoly.Append( bbox.GetRight(), bbox.GetBottom() );
|
||||
finalPoly.Append( bbox.GetLeft(), bbox.GetBottom() );
|
||||
|
||||
finalPoly.BooleanSubtract( knockouts, SHAPE_POLY_SET::PM_FAST );
|
||||
finalPoly.Fracture( SHAPE_POLY_SET::PM_FAST );
|
||||
finalPoly.BooleanSubtract( knockouts );
|
||||
finalPoly.Fracture();
|
||||
|
||||
aGal.SetIsStroke( false );
|
||||
aGal.SetIsFill( true );
|
||||
|
@ -124,19 +124,19 @@ SHAPE_POLY_SET* APERTURE_MACRO::GetApertureMacroShape( const GERBER_DRAW_ITEM* a
|
||||
|
||||
if( holeBuffer.OutlineCount() ) // we have a new hole in shape: remove the hole
|
||||
{
|
||||
m_shape.BooleanSubtract( holeBuffer, SHAPE_POLY_SET::PM_FAST );
|
||||
m_shape.BooleanSubtract( holeBuffer );
|
||||
holeBuffer.RemoveAllContours();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Merge and cleanup basic shape polygons
|
||||
m_shape.Simplify( SHAPE_POLY_SET::PM_FAST );
|
||||
m_shape.Simplify();
|
||||
|
||||
// A hole can be is defined inside a polygon, or the polygons themselve can create
|
||||
// a hole when merged, so we must fracture the polygon to be able to drawn it
|
||||
// (i.e link holes by overlapping edges)
|
||||
m_shape.Fracture( SHAPE_POLY_SET::PM_FAST );
|
||||
m_shape.Fracture();
|
||||
|
||||
// Move m_shape to the actual draw position:
|
||||
for( int icnt = 0; icnt < m_shape.OutlineCount(); icnt++ )
|
||||
|
@ -448,6 +448,6 @@ static void addHoleToPolygon( SHAPE_POLY_SET* aPolygon, APERTURE_DEF_HOLETYPE aH
|
||||
holeBuffer.Append( VECTOR2I( currpos ) ); // close hole
|
||||
}
|
||||
|
||||
aPolygon->BooleanSubtract( holeBuffer, SHAPE_POLY_SET::PM_FAST );
|
||||
aPolygon->Fracture( SHAPE_POLY_SET::PM_FAST );
|
||||
aPolygon->BooleanSubtract( holeBuffer );
|
||||
aPolygon->Fracture();
|
||||
}
|
||||
|
@ -574,7 +574,7 @@ void GBR_TO_PCB_EXPORTER::writePcbPolygon( const SHAPE_POLY_SET& aPolys, int aLa
|
||||
void GBR_TO_PCB_EXPORTER::writePcbZoneItem( const GERBER_DRAW_ITEM* aGbrItem, int aLayer )
|
||||
{
|
||||
SHAPE_POLY_SET polys = aGbrItem->m_ShapeAsPolygon.CloneDropTriangulation();
|
||||
polys.Simplify( SHAPE_POLY_SET::PM_FAST );
|
||||
polys.Simplify();
|
||||
|
||||
if( polys.OutlineCount() == 0 )
|
||||
return;
|
||||
|
@ -428,15 +428,6 @@ public:
|
||||
*/
|
||||
double m_3DRT_BevelExtentFactor;
|
||||
|
||||
/**
|
||||
* Use Clipper2 instead of Clipper1.
|
||||
*
|
||||
* Setting name: "UseClipper2"
|
||||
* Valid values: 0 or 1
|
||||
* Default value: 1
|
||||
*/
|
||||
bool m_UseClipper2;
|
||||
|
||||
/**
|
||||
* Use the 3DConnexion Driver.
|
||||
*
|
||||
|
@ -299,7 +299,7 @@ public:
|
||||
{
|
||||
if( m_poly.HoleCount( ii ) )
|
||||
{
|
||||
m_poly.Fracture( SHAPE_POLY_SET::PM_FAST );
|
||||
m_poly.Fracture();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -51,7 +51,6 @@ add_library( kimath STATIC
|
||||
|
||||
target_link_libraries( kimath
|
||||
core
|
||||
clipper
|
||||
clipper2
|
||||
othermath
|
||||
rtree
|
||||
|
@ -51,7 +51,6 @@
|
||||
#include <cmath>
|
||||
|
||||
#include <advanced_config.h>
|
||||
#include <clipper.hpp>
|
||||
#include <geometry/shape_line_chain.h>
|
||||
#include <geometry/shape_poly_set.h>
|
||||
#include <geometry/vertex_set.h>
|
||||
|
@ -27,7 +27,6 @@
|
||||
#define __SHAPE_LINE_CHAIN
|
||||
|
||||
|
||||
#include <clipper.hpp>
|
||||
#include <clipper2/clipper.h>
|
||||
#include <geometry/seg.h>
|
||||
#include <geometry/shape.h>
|
||||
@ -37,7 +36,7 @@
|
||||
|
||||
/**
|
||||
* Holds information on each point of a SHAPE_LINE_CHAIN that is retrievable
|
||||
* after an operation with ClipperLib
|
||||
* after an operation with Clipper2Lib
|
||||
*/
|
||||
struct CLIPPER_Z_VALUE
|
||||
{
|
||||
@ -176,10 +175,6 @@ public:
|
||||
|
||||
SHAPE_LINE_CHAIN( const SHAPE_ARC& aArc, bool aClosed = false );
|
||||
|
||||
SHAPE_LINE_CHAIN( const ClipperLib::Path& aPath,
|
||||
const std::vector<CLIPPER_Z_VALUE>& aZValueBuffer,
|
||||
const std::vector<SHAPE_ARC>& aArcBuffer );
|
||||
|
||||
SHAPE_LINE_CHAIN( const Clipper2Lib::Path64& aPath,
|
||||
const std::vector<CLIPPER_Z_VALUE>& aZValueBuffer,
|
||||
const std::vector<SHAPE_ARC>& aArcBuffer );
|
||||
@ -920,13 +915,6 @@ protected:
|
||||
return m_shapes[aSegment].second;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new Clipper path from the SHAPE_LINE_CHAIN in a given orientation
|
||||
*/
|
||||
ClipperLib::Path convertToClipper( bool aRequiredOrientation,
|
||||
std::vector<CLIPPER_Z_VALUE>& aZValueBuffer,
|
||||
std::vector<SHAPE_ARC>& aArcBuffer ) const;
|
||||
|
||||
/**
|
||||
* Create a new Clipper2 path from the SHAPE_LINE_CHAIN in a given orientation
|
||||
*/
|
||||
|
@ -39,7 +39,6 @@
|
||||
#include <stdlib.h> // for abs
|
||||
#include <vector>
|
||||
|
||||
#include <clipper.hpp> // for ClipType, PolyTree (ptr only)
|
||||
#include <clipper2/clipper.h>
|
||||
#include <core/mirror.h> // for FLIP_DIRECTION
|
||||
#include <geometry/corner_strategy.h>
|
||||
@ -986,55 +985,30 @@ public:
|
||||
return CIterateSegments( aOutline, aOutline, true );
|
||||
}
|
||||
|
||||
/**
|
||||
* Operations on polygons use a \a aFastMode param
|
||||
* if aFastMode is #PM_FAST (true) the result can be a weak polygon
|
||||
* if aFastMode is #PM_STRICTLY_SIMPLE (false) (default) the result is (theoretically) a
|
||||
* strictly simple polygon, but calculations can be really significantly time consuming
|
||||
* Most of time #PM_FAST is preferable.
|
||||
* #PM_STRICTLY_SIMPLE can be used in critical cases (Gerber output for instance)
|
||||
*/
|
||||
enum POLYGON_MODE
|
||||
{
|
||||
PM_FAST = true,
|
||||
PM_STRICTLY_SIMPLE = false
|
||||
};
|
||||
|
||||
/// Perform boolean polyset union
|
||||
/// For \a aFastMode meaning, see function booleanOp
|
||||
void BooleanAdd( const SHAPE_POLY_SET& b, POLYGON_MODE aFastMode );
|
||||
void BooleanAdd( const SHAPE_POLY_SET& b );
|
||||
|
||||
/// Perform boolean polyset difference
|
||||
/// For \a aFastMode meaning, see function booleanOp
|
||||
void BooleanSubtract( const SHAPE_POLY_SET& b, POLYGON_MODE aFastMode );
|
||||
void BooleanSubtract( const SHAPE_POLY_SET& b );
|
||||
|
||||
/// Perform boolean polyset intersection
|
||||
/// For \a aFastMode meaning, see function booleanOp
|
||||
void BooleanIntersection( const SHAPE_POLY_SET& b, POLYGON_MODE aFastMode );
|
||||
void BooleanIntersection( const SHAPE_POLY_SET& b );
|
||||
|
||||
/// Perform boolean polyset exclusive or
|
||||
/// For \a aFastMode meaning, see function booleanOp
|
||||
void BooleanXor( const SHAPE_POLY_SET& b, POLYGON_MODE aFastMode );
|
||||
void BooleanXor( const SHAPE_POLY_SET& b );
|
||||
|
||||
/// Perform boolean polyset union between a and b, store the result in it self
|
||||
/// For \a aFastMode meaning, see function booleanOp
|
||||
void BooleanAdd( const SHAPE_POLY_SET& a, const SHAPE_POLY_SET& b,
|
||||
POLYGON_MODE aFastMode );
|
||||
void BooleanAdd( const SHAPE_POLY_SET& a, const SHAPE_POLY_SET& b );
|
||||
|
||||
/// Perform boolean polyset difference between a and b, store the result in it self
|
||||
/// For \a aFastMode meaning, see function booleanOp
|
||||
void BooleanSubtract( const SHAPE_POLY_SET& a, const SHAPE_POLY_SET& b,
|
||||
POLYGON_MODE aFastMode );
|
||||
void BooleanSubtract( const SHAPE_POLY_SET& a, const SHAPE_POLY_SET& b );
|
||||
|
||||
/// Perform boolean polyset intersection between a and b, store the result in it self
|
||||
/// For \a aFastMode meaning, see function booleanOp
|
||||
void BooleanIntersection( const SHAPE_POLY_SET& a, const SHAPE_POLY_SET& b,
|
||||
POLYGON_MODE aFastMode );
|
||||
void BooleanIntersection( const SHAPE_POLY_SET& a, const SHAPE_POLY_SET& b );
|
||||
|
||||
/// Perform boolean polyset exclusive or between a and b, store the result in it self
|
||||
/// For \a aFastMode meaning, see function booleanOp
|
||||
void BooleanXor( const SHAPE_POLY_SET& a, const SHAPE_POLY_SET& b,
|
||||
POLYGON_MODE aFastMode );
|
||||
void BooleanXor( const SHAPE_POLY_SET& a, const SHAPE_POLY_SET& b );
|
||||
|
||||
/**
|
||||
* Extract all contours from this polygon set, then recreate polygons with holes.
|
||||
@ -1085,20 +1059,17 @@ public:
|
||||
* Perform outline inflation/deflation, using round corners.
|
||||
*
|
||||
* Polygons can have holes and/or linked holes with main outlines. The resulting
|
||||
* polygons are also polygons with linked holes to main outlines. For \a aFastMode
|
||||
* meaning, see function booleanOp .
|
||||
* polygons are also polygons with linked holes to main outlines.
|
||||
*/
|
||||
void InflateWithLinkedHoles( int aFactor, CORNER_STRATEGY aCornerStrategy, int aMaxError,
|
||||
POLYGON_MODE aFastMode );
|
||||
void InflateWithLinkedHoles( int aFactor, CORNER_STRATEGY aCornerStrategy, int aMaxError );
|
||||
|
||||
/// Convert a set of polygons with holes to a single outline with "slits"/"fractures"
|
||||
/// connecting the outer ring to the inner holes
|
||||
/// For \a aFastMode meaning, see function booleanOp
|
||||
void Fracture( POLYGON_MODE aFastMode );
|
||||
void Fracture();
|
||||
|
||||
/// Convert a single outline slitted ("fractured") polygon into a set ouf outlines
|
||||
/// with holes.
|
||||
void Unfracture( POLYGON_MODE aFastMode );
|
||||
void Unfracture();
|
||||
|
||||
/// Return true if the polygon set has any holes.
|
||||
bool HasHoles() const;
|
||||
@ -1108,8 +1079,7 @@ public:
|
||||
|
||||
|
||||
/// Simplify the polyset (merges overlapping polys, eliminates degeneracy/self-intersections)
|
||||
/// For \a aFastMode meaning, see function booleanOp
|
||||
void Simplify( POLYGON_MODE aFastMode );
|
||||
void Simplify();
|
||||
|
||||
/**
|
||||
* Simplifies the lines in the polyset. This checks intermediate points to see if they are
|
||||
@ -1464,11 +1434,9 @@ public:
|
||||
* Build a SHAPE_POLY_SET from a bunch of outlines in provided in random order.
|
||||
*
|
||||
* @param aPath set of closed outlines forming the polygon. Positive orientation = outline, negative = hole
|
||||
* @param aReverseOrientation inverts the sign of the orientation of aPaths (so negative = outline)
|
||||
* @param aEvenOdd forces the even-off fill rule (default is non zero)
|
||||
* @return the constructed poly set
|
||||
*/
|
||||
static const SHAPE_POLY_SET BuildPolysetFromOrientedPaths( const std::vector<SHAPE_LINE_CHAIN>& aPaths, bool aReverseOrientation = false, bool aEvenOdd = false );
|
||||
void BuildPolysetFromOrientedPaths( const std::vector<SHAPE_LINE_CHAIN>& aPaths, bool aEvenOdd = false );
|
||||
|
||||
void TransformToPolygon( SHAPE_POLY_SET& aBuffer, int aError,
|
||||
ERROR_LOC aErrorLoc ) const override
|
||||
@ -1487,9 +1455,6 @@ private:
|
||||
|
||||
void fractureSingle( POLYGON& paths );
|
||||
void unfractureSingle ( POLYGON& path );
|
||||
void importTree( ClipperLib::PolyTree* tree,
|
||||
const std::vector<CLIPPER_Z_VALUE>& aZValueBuffer,
|
||||
const std::vector<SHAPE_ARC>& aArcBuffe );
|
||||
void importTree( Clipper2Lib::PolyTree64& tree,
|
||||
const std::vector<CLIPPER_Z_VALUE>& aZValueBuffer,
|
||||
const std::vector<SHAPE_ARC>& aArcBuffe );
|
||||
@ -1500,7 +1465,6 @@ private:
|
||||
const std::vector<CLIPPER_Z_VALUE>& aZValueBuffer,
|
||||
const std::vector<SHAPE_ARC>& aArcBuffer );
|
||||
|
||||
void inflate1( int aAmount, int aCircleSegCount, CORNER_STRATEGY aCornerStrategy );
|
||||
void inflate2( int aAmount, int aCircleSegCount, CORNER_STRATEGY aCornerStrategy, bool aSimplify = false );
|
||||
|
||||
void inflateLine2( const SHAPE_LINE_CHAIN& aLine, int aAmount, int aCircleSegCount,
|
||||
@ -1510,20 +1474,9 @@ private:
|
||||
* This is the engine to execute all polygon boolean transforms (AND, OR, ... and polygon
|
||||
* simplification (merging overlapping polygons).
|
||||
*
|
||||
* @param aType is the transform type ( see ClipperLib::ClipType )
|
||||
* @param aType is the transform type ( see Clipper2Lib::ClipType )
|
||||
* @param aOtherShape is the SHAPE_LINE_CHAIN to combine with me.
|
||||
* @param aFastMode is an option to choose if the result can be a weak polygon
|
||||
* or a strictly simple polygon.
|
||||
* if aFastMode is PM_FAST the result can be a weak polygon
|
||||
* if aFastMode is PM_STRICTLY_SIMPLE (default) the result is (theoretically) a strictly
|
||||
* simple polygon, but calculations can be really significantly time consuming
|
||||
*/
|
||||
void booleanOp( ClipperLib::ClipType aType, const SHAPE_POLY_SET& aOtherShape,
|
||||
POLYGON_MODE aFastMode );
|
||||
|
||||
void booleanOp( ClipperLib::ClipType aType, const SHAPE_POLY_SET& aShape,
|
||||
const SHAPE_POLY_SET& aOtherShape, POLYGON_MODE aFastMode );
|
||||
|
||||
void booleanOp( Clipper2Lib::ClipType aType, const SHAPE_POLY_SET& aOtherShape );
|
||||
|
||||
void booleanOp( Clipper2Lib::ClipType aType, const SHAPE_POLY_SET& aShape,
|
||||
|
@ -214,7 +214,7 @@ void TransformOvalToPolygon( SHAPE_POLY_SET& aBuffer, const VECTOR2I& aStart, co
|
||||
bbox.Append( corner.x, corner.y );
|
||||
|
||||
// Now, clamp the shape
|
||||
polyshape.BooleanIntersection( bbox, SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
||||
polyshape.BooleanIntersection( bbox );
|
||||
// Note the final polygon is a simple, convex polygon with no hole
|
||||
// due to the shape of initial polygons
|
||||
|
||||
@ -663,6 +663,6 @@ void TransformRingToPolygon( SHAPE_POLY_SET& aBuffer, const VECTOR2I& aCentre, i
|
||||
TransformCircleToPolygon( buffer.Hole( 0, 0 ), aCentre, inner_radius,
|
||||
aError, inner_err_loc );
|
||||
|
||||
buffer.Fracture( SHAPE_POLY_SET::PM_FAST );
|
||||
buffer.Fracture();
|
||||
aBuffer.Append( buffer );
|
||||
}
|
||||
|
@ -29,7 +29,6 @@
|
||||
#include <map>
|
||||
#include <string> // for basic_string
|
||||
|
||||
#include <clipper.hpp>
|
||||
#include <clipper2/clipper.h>
|
||||
#include <core/kicad_algo.h> // for alg::run_on_pair
|
||||
#include <geometry/circle.h>
|
||||
@ -79,50 +78,6 @@ SHAPE_LINE_CHAIN::SHAPE_LINE_CHAIN( const SHAPE_ARC& aArc, bool aClosed ) :
|
||||
}
|
||||
|
||||
|
||||
SHAPE_LINE_CHAIN::SHAPE_LINE_CHAIN( const ClipperLib::Path& aPath,
|
||||
const std::vector<CLIPPER_Z_VALUE>& aZValueBuffer,
|
||||
const std::vector<SHAPE_ARC>& aArcBuffer ) :
|
||||
SHAPE_LINE_CHAIN_BASE( SH_LINE_CHAIN ),
|
||||
m_closed( true ), m_width( 0 )
|
||||
{
|
||||
std::map<ssize_t, ssize_t> loadedArcs;
|
||||
m_points.reserve( aPath.size() );
|
||||
m_shapes.reserve( aPath.size() );
|
||||
|
||||
auto loadArc =
|
||||
[&]( ssize_t aArcIndex ) -> ssize_t
|
||||
{
|
||||
if( aArcIndex == SHAPE_IS_PT )
|
||||
{
|
||||
return SHAPE_IS_PT;
|
||||
}
|
||||
else if( loadedArcs.count( aArcIndex ) == 0 )
|
||||
{
|
||||
loadedArcs.insert( { aArcIndex, m_arcs.size() } );
|
||||
m_arcs.push_back( aArcBuffer.at( aArcIndex ) );
|
||||
}
|
||||
|
||||
return loadedArcs.at( aArcIndex );
|
||||
};
|
||||
|
||||
for( size_t ii = 0; ii < aPath.size(); ++ii )
|
||||
{
|
||||
Append( aPath[ii].X, aPath[ii].Y );
|
||||
|
||||
m_shapes[ii].first = loadArc( aZValueBuffer[aPath[ii].Z].m_FirstArcIdx );
|
||||
m_shapes[ii].second = loadArc( aZValueBuffer[aPath[ii].Z].m_SecondArcIdx );
|
||||
}
|
||||
|
||||
// Clipper shouldn't return duplicate contiguous points. if it did, these would be
|
||||
// removed during Append() and we would have different number of shapes to points
|
||||
wxASSERT( m_shapes.size() == m_points.size() );
|
||||
|
||||
// Clipper might mess up the rotation of the indices such that an arc can be split between
|
||||
// the end point and wrap around to the start point. Lets fix the indices up now
|
||||
fixIndicesRotation();
|
||||
}
|
||||
|
||||
|
||||
SHAPE_LINE_CHAIN::SHAPE_LINE_CHAIN( const Clipper2Lib::Path64& aPath,
|
||||
const std::vector<CLIPPER_Z_VALUE>& aZValueBuffer,
|
||||
const std::vector<SHAPE_ARC>& aArcBuffer ) :
|
||||
@ -167,40 +122,6 @@ SHAPE_LINE_CHAIN::SHAPE_LINE_CHAIN( const Clipper2Lib::Path64& aPath,
|
||||
}
|
||||
|
||||
|
||||
ClipperLib::Path SHAPE_LINE_CHAIN::convertToClipper( bool aRequiredOrientation,
|
||||
std::vector<CLIPPER_Z_VALUE>& aZValueBuffer,
|
||||
std::vector<SHAPE_ARC>& aArcBuffer ) const
|
||||
{
|
||||
ClipperLib::Path c_path;
|
||||
SHAPE_LINE_CHAIN input;
|
||||
bool orientation = Area( false ) >= 0;
|
||||
ssize_t shape_offset = aArcBuffer.size();
|
||||
|
||||
if( orientation != aRequiredOrientation )
|
||||
input = Reverse();
|
||||
else
|
||||
input = *this;
|
||||
|
||||
int pointCount = input.PointCount();
|
||||
c_path.reserve( pointCount );
|
||||
|
||||
for( int i = 0; i < pointCount; i++ )
|
||||
{
|
||||
const VECTOR2I& vertex = input.CPoint( i );
|
||||
|
||||
CLIPPER_Z_VALUE z_value( input.m_shapes[i], shape_offset );
|
||||
size_t z_value_ptr = aZValueBuffer.size();
|
||||
aZValueBuffer.push_back( z_value );
|
||||
|
||||
c_path.emplace_back( vertex.x, vertex.y, z_value_ptr );
|
||||
}
|
||||
|
||||
aArcBuffer.insert( aArcBuffer.end(), input.m_arcs.begin(), input.m_arcs.end() );
|
||||
|
||||
return c_path;
|
||||
}
|
||||
|
||||
|
||||
Clipper2Lib::Path64 SHAPE_LINE_CHAIN::convertToClipper2( bool aRequiredOrientation,
|
||||
std::vector<CLIPPER_Z_VALUE>& aZValueBuffer,
|
||||
std::vector<SHAPE_ARC>& aArcBuffer ) const
|
||||
|
@ -744,118 +744,6 @@ void SHAPE_POLY_SET::RebuildHolesFromContours()
|
||||
}
|
||||
|
||||
|
||||
void SHAPE_POLY_SET::booleanOp( ClipperLib::ClipType aType, const SHAPE_POLY_SET& aOtherShape,
|
||||
POLYGON_MODE aFastMode )
|
||||
{
|
||||
booleanOp( aType, *this, aOtherShape, aFastMode );
|
||||
}
|
||||
|
||||
|
||||
void SHAPE_POLY_SET::booleanOp( ClipperLib::ClipType aType, const SHAPE_POLY_SET& aShape,
|
||||
const SHAPE_POLY_SET& aOtherShape, POLYGON_MODE aFastMode )
|
||||
{
|
||||
if( ( aShape.OutlineCount() > 1 || aOtherShape.OutlineCount() > 0 )
|
||||
&& ( aShape.ArcCount() > 0 || aOtherShape.ArcCount() > 0 ) )
|
||||
{
|
||||
wxFAIL_MSG( wxT( "Boolean ops on curved polygons are not supported. You should call "
|
||||
"ClearArcs() before carrying out the boolean operation." ) );
|
||||
}
|
||||
|
||||
ClipperLib::Clipper c;
|
||||
|
||||
c.StrictlySimple( aFastMode == PM_STRICTLY_SIMPLE );
|
||||
|
||||
std::vector<CLIPPER_Z_VALUE> zValues;
|
||||
std::vector<SHAPE_ARC> arcBuffer;
|
||||
std::map<VECTOR2I, CLIPPER_Z_VALUE> newIntersectPoints;
|
||||
|
||||
for( const POLYGON& poly : aShape.m_polys )
|
||||
{
|
||||
for( size_t i = 0; i < poly.size(); i++ )
|
||||
{
|
||||
c.AddPath( poly[i].convertToClipper( i == 0, zValues, arcBuffer ),
|
||||
ClipperLib::ptSubject, true );
|
||||
}
|
||||
}
|
||||
|
||||
for( const POLYGON& poly : aOtherShape.m_polys )
|
||||
{
|
||||
for( size_t i = 0; i < poly.size(); i++ )
|
||||
{
|
||||
c.AddPath( poly[i].convertToClipper( i == 0, zValues, arcBuffer ),
|
||||
ClipperLib::ptClip, true );
|
||||
}
|
||||
}
|
||||
|
||||
ClipperLib::PolyTree solution;
|
||||
|
||||
ClipperLib::ZFillCallback callback =
|
||||
[&]( ClipperLib::IntPoint & e1bot, ClipperLib::IntPoint & e1top,
|
||||
ClipperLib::IntPoint & e2bot, ClipperLib::IntPoint & e2top,
|
||||
ClipperLib::IntPoint & pt )
|
||||
{
|
||||
auto arcIndex =
|
||||
[&]( const ssize_t& aZvalue, const ssize_t& aCompareVal = -1 ) -> ssize_t
|
||||
{
|
||||
ssize_t retval;
|
||||
|
||||
retval = zValues.at( aZvalue ).m_SecondArcIdx;
|
||||
|
||||
if( retval == -1 || ( aCompareVal > 0 && retval != aCompareVal ) )
|
||||
retval = zValues.at( aZvalue ).m_FirstArcIdx;
|
||||
|
||||
return retval;
|
||||
};
|
||||
|
||||
auto arcSegment =
|
||||
[&]( const ssize_t& aBottomZ, const ssize_t aTopZ ) -> ssize_t
|
||||
{
|
||||
ssize_t retval = arcIndex( aBottomZ );
|
||||
|
||||
if( retval != -1 )
|
||||
{
|
||||
if( retval != arcIndex( aTopZ, retval ) )
|
||||
retval = -1; // Not an arc segment as the two indices do not match
|
||||
}
|
||||
|
||||
return retval;
|
||||
};
|
||||
|
||||
ssize_t e1ArcSegmentIndex = arcSegment( e1bot.Z, e1top.Z );
|
||||
ssize_t e2ArcSegmentIndex = arcSegment( e2bot.Z, e2top.Z );
|
||||
|
||||
CLIPPER_Z_VALUE newZval;
|
||||
|
||||
if( e1ArcSegmentIndex != -1 )
|
||||
{
|
||||
newZval.m_FirstArcIdx = e1ArcSegmentIndex;
|
||||
newZval.m_SecondArcIdx = e2ArcSegmentIndex;
|
||||
}
|
||||
else
|
||||
{
|
||||
newZval.m_FirstArcIdx = e2ArcSegmentIndex;
|
||||
newZval.m_SecondArcIdx = -1;
|
||||
}
|
||||
|
||||
size_t z_value_ptr = zValues.size();
|
||||
zValues.push_back( newZval );
|
||||
|
||||
// Only worry about arc segments for later processing
|
||||
if( newZval.m_FirstArcIdx != -1 )
|
||||
newIntersectPoints.insert( { VECTOR2I( pt.X, pt.Y ), newZval } );
|
||||
|
||||
pt.Z = z_value_ptr;
|
||||
//@todo amend X,Y values to true intersection between arcs or arc and segment
|
||||
};
|
||||
|
||||
c.ZFillFunction( std::move( callback ) ); // register callback
|
||||
|
||||
c.Execute( aType, solution, ClipperLib::pftNonZero, ClipperLib::pftNonZero );
|
||||
|
||||
importTree( &solution, zValues, arcBuffer );
|
||||
}
|
||||
|
||||
|
||||
void SHAPE_POLY_SET::booleanOp( Clipper2Lib::ClipType aType, const SHAPE_POLY_SET& aOtherShape )
|
||||
{
|
||||
booleanOp( aType, *this, aOtherShape );
|
||||
@ -970,155 +858,60 @@ void SHAPE_POLY_SET::booleanOp( Clipper2Lib::ClipType aType, const SHAPE_POLY_SE
|
||||
}
|
||||
|
||||
|
||||
void SHAPE_POLY_SET::BooleanAdd( const SHAPE_POLY_SET& b, POLYGON_MODE aFastMode )
|
||||
void SHAPE_POLY_SET::BooleanAdd( const SHAPE_POLY_SET& b )
|
||||
{
|
||||
booleanOp( Clipper2Lib::ClipType::Union, b );
|
||||
}
|
||||
|
||||
|
||||
void SHAPE_POLY_SET::BooleanSubtract( const SHAPE_POLY_SET& b, POLYGON_MODE aFastMode )
|
||||
void SHAPE_POLY_SET::BooleanSubtract( const SHAPE_POLY_SET& b )
|
||||
{
|
||||
booleanOp( Clipper2Lib::ClipType::Difference, b );
|
||||
}
|
||||
|
||||
|
||||
void SHAPE_POLY_SET::BooleanIntersection( const SHAPE_POLY_SET& b, POLYGON_MODE aFastMode )
|
||||
void SHAPE_POLY_SET::BooleanIntersection( const SHAPE_POLY_SET& b )
|
||||
{
|
||||
booleanOp( Clipper2Lib::ClipType::Intersection, b );
|
||||
}
|
||||
|
||||
|
||||
void SHAPE_POLY_SET::BooleanXor( const SHAPE_POLY_SET& b, POLYGON_MODE aFastMode )
|
||||
void SHAPE_POLY_SET::BooleanXor( const SHAPE_POLY_SET& b )
|
||||
{
|
||||
booleanOp( Clipper2Lib::ClipType::Xor, b );
|
||||
}
|
||||
|
||||
|
||||
void SHAPE_POLY_SET::BooleanAdd( const SHAPE_POLY_SET& a, const SHAPE_POLY_SET& b,
|
||||
POLYGON_MODE aFastMode )
|
||||
void SHAPE_POLY_SET::BooleanAdd( const SHAPE_POLY_SET& a, const SHAPE_POLY_SET& b )
|
||||
{
|
||||
booleanOp( Clipper2Lib::ClipType::Union, a, b );
|
||||
}
|
||||
|
||||
|
||||
void SHAPE_POLY_SET::BooleanSubtract( const SHAPE_POLY_SET& a, const SHAPE_POLY_SET& b,
|
||||
POLYGON_MODE aFastMode )
|
||||
void SHAPE_POLY_SET::BooleanSubtract( const SHAPE_POLY_SET& a, const SHAPE_POLY_SET& b )
|
||||
{
|
||||
booleanOp( Clipper2Lib::ClipType::Difference, a, b );
|
||||
}
|
||||
|
||||
|
||||
void SHAPE_POLY_SET::BooleanIntersection( const SHAPE_POLY_SET& a, const SHAPE_POLY_SET& b,
|
||||
POLYGON_MODE aFastMode )
|
||||
void SHAPE_POLY_SET::BooleanIntersection( const SHAPE_POLY_SET& a, const SHAPE_POLY_SET& b )
|
||||
{
|
||||
booleanOp( Clipper2Lib::ClipType::Intersection, a, b );
|
||||
}
|
||||
|
||||
|
||||
void SHAPE_POLY_SET::BooleanXor( const SHAPE_POLY_SET& a, const SHAPE_POLY_SET& b,
|
||||
POLYGON_MODE aFastMode )
|
||||
void SHAPE_POLY_SET::BooleanXor( const SHAPE_POLY_SET& a, const SHAPE_POLY_SET& b )
|
||||
{
|
||||
booleanOp( Clipper2Lib::ClipType::Xor, a, b );
|
||||
}
|
||||
|
||||
|
||||
void SHAPE_POLY_SET::InflateWithLinkedHoles( int aFactor, CORNER_STRATEGY aCornerStrategy,
|
||||
int aMaxError, POLYGON_MODE aFastMode )
|
||||
int aMaxError )
|
||||
{
|
||||
Unfracture( aFastMode );
|
||||
Unfracture();
|
||||
Inflate( aFactor, aCornerStrategy, aMaxError );
|
||||
Fracture( aFastMode );
|
||||
}
|
||||
|
||||
|
||||
void SHAPE_POLY_SET::inflate1( int aAmount, int aCircleSegCount, CORNER_STRATEGY aCornerStrategy )
|
||||
{
|
||||
using namespace ClipperLib;
|
||||
// A static table to avoid repetitive calculations of the coefficient
|
||||
// 1.0 - cos( M_PI / aCircleSegCount )
|
||||
// aCircleSegCount is most of time <= 64 and usually 8, 12, 16, 32
|
||||
#define SEG_CNT_MAX 64
|
||||
static double arc_tolerance_factor[SEG_CNT_MAX + 1];
|
||||
|
||||
ClipperOffset c;
|
||||
|
||||
// N.B. see the Clipper documentation for jtSquare/jtMiter/jtRound. They are poorly named
|
||||
// and are not what you'd think they are.
|
||||
// http://www.angusj.com/delphi/clipper/documentation/Docs/Units/ClipperLib/Types/JoinType.htm
|
||||
JoinType joinType = jtRound; // The way corners are offsetted
|
||||
double miterLimit = 2.0; // Smaller value when using jtMiter for joinType
|
||||
JoinType miterFallback = jtSquare;
|
||||
|
||||
switch( aCornerStrategy )
|
||||
{
|
||||
case CORNER_STRATEGY::ALLOW_ACUTE_CORNERS:
|
||||
joinType = jtMiter;
|
||||
miterLimit = 10; // Allows large spikes
|
||||
miterFallback = jtSquare;
|
||||
break;
|
||||
|
||||
case CORNER_STRATEGY::CHAMFER_ACUTE_CORNERS: // Acute angles are chamfered
|
||||
joinType = jtMiter;
|
||||
miterFallback = jtRound;
|
||||
break;
|
||||
|
||||
case CORNER_STRATEGY::ROUND_ACUTE_CORNERS: // Acute angles are rounded
|
||||
joinType = jtMiter;
|
||||
miterFallback = jtSquare;
|
||||
break;
|
||||
|
||||
case CORNER_STRATEGY::CHAMFER_ALL_CORNERS: // All angles are chamfered.
|
||||
joinType = jtSquare;
|
||||
miterFallback = jtSquare;
|
||||
break;
|
||||
|
||||
case CORNER_STRATEGY::ROUND_ALL_CORNERS: // All angles are rounded.
|
||||
joinType = jtRound;
|
||||
miterFallback = jtSquare;
|
||||
break;
|
||||
}
|
||||
|
||||
std::vector<CLIPPER_Z_VALUE> zValues;
|
||||
std::vector<SHAPE_ARC> arcBuffer;
|
||||
|
||||
for( const POLYGON& poly : m_polys )
|
||||
{
|
||||
for( size_t i = 0; i < poly.size(); i++ )
|
||||
{
|
||||
c.AddPath( poly[i].convertToClipper( i == 0, zValues, arcBuffer ),
|
||||
joinType, etClosedPolygon );
|
||||
}
|
||||
}
|
||||
|
||||
PolyTree solution;
|
||||
|
||||
// Calculate the arc tolerance (arc error) from the seg count by circle. The seg count is
|
||||
// nn = M_PI / acos(1.0 - c.ArcTolerance / abs(aAmount))
|
||||
// http://www.angusj.com/delphi/clipper/documentation/Docs/Units/ClipperLib/Classes/ClipperOffset/Properties/ArcTolerance.htm
|
||||
|
||||
if( aCircleSegCount < 6 ) // avoid incorrect aCircleSegCount values
|
||||
aCircleSegCount = 6;
|
||||
|
||||
double coeff;
|
||||
|
||||
if( aCircleSegCount > SEG_CNT_MAX || arc_tolerance_factor[aCircleSegCount] == 0 )
|
||||
{
|
||||
coeff = 1.0 - cos( M_PI / aCircleSegCount );
|
||||
|
||||
if( aCircleSegCount <= SEG_CNT_MAX )
|
||||
arc_tolerance_factor[aCircleSegCount] = coeff;
|
||||
}
|
||||
else
|
||||
{
|
||||
coeff = arc_tolerance_factor[aCircleSegCount];
|
||||
}
|
||||
|
||||
c.ArcTolerance = std::abs( aAmount ) * coeff;
|
||||
c.MiterLimit = miterLimit;
|
||||
c.MiterFallback = miterFallback;
|
||||
c.Execute( solution, aAmount );
|
||||
|
||||
importTree( &solution, zValues, arcBuffer );
|
||||
Fracture();
|
||||
}
|
||||
|
||||
|
||||
@ -1341,30 +1134,6 @@ void SHAPE_POLY_SET::OffsetLineChain( const SHAPE_LINE_CHAIN& aLine, int aAmount
|
||||
}
|
||||
|
||||
|
||||
void SHAPE_POLY_SET::importTree( ClipperLib::PolyTree* tree,
|
||||
const std::vector<CLIPPER_Z_VALUE>& aZValueBuffer,
|
||||
const std::vector<SHAPE_ARC>& aArcBuffer )
|
||||
{
|
||||
m_polys.clear();
|
||||
|
||||
for( ClipperLib::PolyNode* n = tree->GetFirst(); n; n = n->GetNext() )
|
||||
{
|
||||
if( !n->IsHole() )
|
||||
{
|
||||
POLYGON paths;
|
||||
paths.reserve( n->Childs.size() + 1 );
|
||||
|
||||
paths.emplace_back( n->Contour, aZValueBuffer, aArcBuffer );
|
||||
|
||||
for( unsigned int i = 0; i < n->Childs.size(); i++ )
|
||||
paths.emplace_back( n->Childs[i]->Contour, aZValueBuffer, aArcBuffer );
|
||||
|
||||
m_polys.push_back( paths );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SHAPE_POLY_SET::importPolyPath( const std::unique_ptr<Clipper2Lib::PolyPath64>& aPolyPath,
|
||||
const std::vector<CLIPPER_Z_VALUE>& aZValueBuffer,
|
||||
const std::vector<SHAPE_ARC>& aArcBuffer )
|
||||
@ -1886,9 +1655,9 @@ void SHAPE_POLY_SET::fractureSingle( POLYGON& paths )
|
||||
}
|
||||
|
||||
|
||||
void SHAPE_POLY_SET::Fracture( POLYGON_MODE aFastMode )
|
||||
void SHAPE_POLY_SET::Fracture()
|
||||
{
|
||||
Simplify( aFastMode ); // remove overlapping holes/degeneracy
|
||||
Simplify(); // remove overlapping holes/degeneracy
|
||||
|
||||
for( POLYGON& paths : m_polys )
|
||||
fractureSingle( paths );
|
||||
@ -2077,16 +1846,16 @@ bool SHAPE_POLY_SET::HasHoles() const
|
||||
}
|
||||
|
||||
|
||||
void SHAPE_POLY_SET::Unfracture( POLYGON_MODE aFastMode )
|
||||
void SHAPE_POLY_SET::Unfracture()
|
||||
{
|
||||
for( POLYGON& path : m_polys )
|
||||
unfractureSingle( path );
|
||||
|
||||
Simplify( aFastMode ); // remove overlapping holes/degeneracy
|
||||
Simplify(); // remove overlapping holes/degeneracy
|
||||
}
|
||||
|
||||
|
||||
void SHAPE_POLY_SET::Simplify( POLYGON_MODE aFastMode )
|
||||
void SHAPE_POLY_SET::Simplify()
|
||||
{
|
||||
SHAPE_POLY_SET empty;
|
||||
|
||||
@ -2110,7 +1879,7 @@ int SHAPE_POLY_SET::NormalizeAreaOutlines()
|
||||
{
|
||||
// We are expecting only one main outline, but this main outline can have holes
|
||||
// if holes: combine holes and remove them from the main outline.
|
||||
// Note also we are using SHAPE_POLY_SET::PM_STRICTLY_SIMPLE in polygon
|
||||
// Note also we are usingin polygon
|
||||
// calculations, but it is not mandatory. It is used mainly
|
||||
// because there is usually only very few vertices in area outlines
|
||||
SHAPE_POLY_SET::POLYGON& outline = Polygon( 0 );
|
||||
@ -2124,13 +1893,13 @@ int SHAPE_POLY_SET::NormalizeAreaOutlines()
|
||||
outline.pop_back();
|
||||
}
|
||||
|
||||
Simplify( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
||||
Simplify();
|
||||
|
||||
// If any hole, subtract it to main outline
|
||||
if( holesBuffer.OutlineCount() )
|
||||
{
|
||||
holesBuffer.Simplify( SHAPE_POLY_SET::PM_FAST );
|
||||
BooleanSubtract( holesBuffer, SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
||||
holesBuffer.Simplify();
|
||||
BooleanSubtract( holesBuffer );
|
||||
}
|
||||
|
||||
// In degenerate cases, simplify might return no outlines
|
||||
@ -3210,10 +2979,10 @@ static SHAPE_POLY_SET partitionPolyIntoRegularCellGrid( const SHAPE_POLY_SET& aP
|
||||
}
|
||||
}
|
||||
|
||||
ps1.BooleanIntersection( maskSetOdd, SHAPE_POLY_SET::PM_FAST );
|
||||
ps2.BooleanIntersection( maskSetEven, SHAPE_POLY_SET::PM_FAST );
|
||||
ps1.Fracture( SHAPE_POLY_SET::PM_FAST );
|
||||
ps2.Fracture( SHAPE_POLY_SET::PM_FAST );
|
||||
ps1.BooleanIntersection( maskSetOdd );
|
||||
ps2.BooleanIntersection( maskSetEven );
|
||||
ps1.Fracture();
|
||||
ps2.Fracture();
|
||||
|
||||
for( int i = 0; i < ps2.OutlineCount(); i++ )
|
||||
ps1.AddOutline( ps2.COutline( i ) );
|
||||
@ -3269,10 +3038,6 @@ void SHAPE_POLY_SET::cacheTriangulation( bool aPartition, bool aSimplify,
|
||||
++pass;
|
||||
|
||||
if( pass == 1 )
|
||||
{
|
||||
polySet.Fracture( PM_FAST );
|
||||
}
|
||||
else if( pass == 2 )
|
||||
{
|
||||
polySet.SimplifyOutlines( TRIANGULATESIMPLIFICATIONLEVEL );
|
||||
}
|
||||
@ -3310,9 +3075,9 @@ void SHAPE_POLY_SET::cacheTriangulation( bool aPartition, bool aSimplify,
|
||||
flattened.ClearArcs();
|
||||
|
||||
if( flattened.HasHoles() || flattened.IsSelfIntersecting() )
|
||||
flattened.Fracture( PM_FAST );
|
||||
flattened.Fracture();
|
||||
else if( aSimplify )
|
||||
flattened.Simplify( PM_FAST );
|
||||
flattened.Simplify();
|
||||
|
||||
SHAPE_POLY_SET partitions = partitionPolyIntoRegularCellGrid( flattened, 1e7 );
|
||||
|
||||
@ -3336,8 +3101,7 @@ void SHAPE_POLY_SET::cacheTriangulation( bool aPartition, bool aSimplify,
|
||||
SHAPE_POLY_SET tmpSet( *this );
|
||||
|
||||
tmpSet.ClearArcs();
|
||||
|
||||
tmpSet.Fracture( PM_FAST );
|
||||
tmpSet.Fracture();
|
||||
|
||||
if( !triangulate( tmpSet, -1, m_triangulatedPolys, aHintData ) )
|
||||
{
|
||||
@ -3498,55 +3262,35 @@ SHAPE_POLY_SET::TRIANGULATED_POLYGON::~TRIANGULATED_POLYGON()
|
||||
}
|
||||
|
||||
|
||||
const SHAPE_POLY_SET
|
||||
void
|
||||
SHAPE_POLY_SET::BuildPolysetFromOrientedPaths( const std::vector<SHAPE_LINE_CHAIN>& aPaths,
|
||||
bool aReverseOrientation, bool aEvenOdd )
|
||||
bool aEvenOdd )
|
||||
{
|
||||
ClipperLib::Clipper clipper;
|
||||
ClipperLib::PolyTree tree;
|
||||
|
||||
// fixme: do we need aReverseOrientation?
|
||||
Clipper2Lib::Clipper64 clipper;
|
||||
Clipper2Lib::PolyTree64 tree;
|
||||
Clipper2Lib::Paths64 paths;
|
||||
|
||||
for( const SHAPE_LINE_CHAIN& path : aPaths )
|
||||
{
|
||||
ClipperLib::Path lc;
|
||||
Clipper2Lib::Path64 lc;
|
||||
lc.reserve( path.PointCount() );
|
||||
|
||||
for( int i = 0; i < path.PointCount(); i++ )
|
||||
{
|
||||
lc.emplace_back( path.CPoint( i ).x, path.CPoint( i ).y );
|
||||
|
||||
paths.push_back( lc );
|
||||
}
|
||||
|
||||
clipper.AddPath( lc, ClipperLib::ptSubject, true );
|
||||
}
|
||||
clipper.AddSubject( paths );
|
||||
clipper.Execute( Clipper2Lib::ClipType::Union, aEvenOdd ? Clipper2Lib::FillRule::EvenOdd
|
||||
: Clipper2Lib::FillRule::NonZero, tree );
|
||||
|
||||
clipper.StrictlySimple( true );
|
||||
clipper.Execute( ClipperLib::ctUnion, tree,
|
||||
aEvenOdd ? ClipperLib::pftEvenOdd : ClipperLib::pftNonZero,
|
||||
ClipperLib::pftNonZero );
|
||||
SHAPE_POLY_SET result;
|
||||
|
||||
for( ClipperLib::PolyNode* n = tree.GetFirst(); n; n = n->GetNext() )
|
||||
{
|
||||
if( !n->IsHole() )
|
||||
{
|
||||
int outl = result.NewOutline();
|
||||
std::vector<CLIPPER_Z_VALUE> zValues;
|
||||
std::vector<SHAPE_ARC> arcBuffer;
|
||||
|
||||
for( unsigned int i = 0; i < n->Contour.size(); i++ )
|
||||
result.Outline( outl ).Append( n->Contour[i].X, n->Contour[i].Y );
|
||||
|
||||
for( unsigned int i = 0; i < n->Childs.size(); i++ )
|
||||
{
|
||||
int outh = result.NewHole( outl );
|
||||
for( unsigned int j = 0; j < n->Childs[i]->Contour.size(); j++ )
|
||||
{
|
||||
result.Hole( outl, outh )
|
||||
.Append( n->Childs[i]->Contour[j].X, n->Childs[i]->Contour[j].Y );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
importTree( tree, zValues, arcBuffer );
|
||||
tree.Clear(); // Free used memory (not done in dtor)
|
||||
}
|
||||
|
||||
|
||||
|
@ -146,7 +146,7 @@ bool AR_AUTOPLACER::fillMatrix()
|
||||
|
||||
// Create a single board outline:
|
||||
SHAPE_POLY_SET brd_shape = m_boardShape.CloneDropTriangulation();
|
||||
brd_shape.Fracture( SHAPE_POLY_SET::PM_FAST );
|
||||
brd_shape.Fracture();
|
||||
const SHAPE_LINE_CHAIN& outline = brd_shape.Outline(0);
|
||||
const BOX2I& rect = outline.BBox();
|
||||
|
||||
@ -393,8 +393,8 @@ void AR_AUTOPLACER::genModuleOnRoutingMatrix( FOOTPRINT* Module )
|
||||
buildFpAreas( Module, margin );
|
||||
|
||||
// Substract the shape to free areas
|
||||
m_topFreeArea.BooleanSubtract( m_fpAreaTop, SHAPE_POLY_SET::PM_FAST );
|
||||
m_bottomFreeArea.BooleanSubtract( m_fpAreaBottom, SHAPE_POLY_SET::PM_FAST );
|
||||
m_topFreeArea.BooleanSubtract( m_fpAreaTop );
|
||||
m_bottomFreeArea.BooleanSubtract( m_fpAreaBottom );
|
||||
}
|
||||
|
||||
|
||||
@ -802,7 +802,7 @@ void AR_AUTOPLACER::drawPlacementRoutingMatrix( )
|
||||
m_overlay->SetIsStroke( false );
|
||||
|
||||
SHAPE_POLY_SET freeArea = m_topFreeArea.CloneDropTriangulation();
|
||||
freeArea.Fracture( SHAPE_POLY_SET::PM_FAST );
|
||||
freeArea.Fracture();
|
||||
|
||||
// Draw the free polygon areas, top side:
|
||||
if( freeArea.OutlineCount() > 0 )
|
||||
@ -814,7 +814,7 @@ void AR_AUTOPLACER::drawPlacementRoutingMatrix( )
|
||||
}
|
||||
|
||||
freeArea = m_bottomFreeArea;
|
||||
freeArea.Fracture( SHAPE_POLY_SET::PM_FAST );
|
||||
freeArea.Fracture();
|
||||
|
||||
// Draw the free polygon areas, bottom side:
|
||||
if( freeArea.OutlineCount() > 0 )
|
||||
|
@ -2541,7 +2541,7 @@ bool BOARD::GetBoardPolygonOutlines( SHAPE_POLY_SET& aOutlines,
|
||||
}
|
||||
|
||||
// Make polygon strictly simple to avoid issues (especially in 3D viewer)
|
||||
aOutlines.Simplify( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
||||
aOutlines.Simplify();
|
||||
|
||||
return success;
|
||||
}
|
||||
|
@ -164,8 +164,7 @@ static bool isCopperOutside( const FOOTPRINT* aFootprint, SHAPE_POLY_SET& aShape
|
||||
|
||||
poly.ClearArcs();
|
||||
|
||||
poly.BooleanIntersection( *pad->GetEffectivePolygon( aLayer, ERROR_INSIDE ),
|
||||
SHAPE_POLY_SET::PM_FAST );
|
||||
poly.BooleanIntersection( *pad->GetEffectivePolygon( aLayer, ERROR_INSIDE ) );
|
||||
|
||||
if( poly.OutlineCount() == 0 )
|
||||
{
|
||||
|
@ -283,7 +283,7 @@ bool DRC_TEST_PROVIDER_ANNULAR_WIDTH::Run()
|
||||
otherPadHoles, 0, maxError, ERROR_INSIDE );
|
||||
}
|
||||
|
||||
otherPadOutline.BooleanSubtract( otherPadHoles, SHAPE_POLY_SET::POLYGON_MODE::PM_FAST );
|
||||
otherPadOutline.BooleanSubtract( otherPadHoles );
|
||||
|
||||
// If the pad hole under test intersects with another pad outline,
|
||||
// the annular width calculated above is used.
|
||||
|
@ -384,7 +384,7 @@ bool DRC_TEST_PROVIDER_CONNECTION_WIDTH::Run()
|
||||
ERROR_OUTSIDE );
|
||||
}
|
||||
|
||||
itemsPoly.Poly.Fracture( SHAPE_POLY_SET::PM_FAST );
|
||||
itemsPoly.Poly.Fracture();
|
||||
|
||||
done.fetch_add( calc_effort( itemsPoly.Items, aLayer ) );
|
||||
|
||||
|
@ -132,7 +132,7 @@ bool DRC_TEST_PROVIDER_DISALLOW::Run()
|
||||
// exclude it. This is particularly important for detecting copper fills as
|
||||
// they will be exactly touching along the entire exclusion border.
|
||||
SHAPE_POLY_SET areaPoly = ruleArea->Outline()->CloneDropTriangulation();
|
||||
areaPoly.Fracture( SHAPE_POLY_SET::PM_FAST );
|
||||
areaPoly.Fracture();
|
||||
areaPoly.Deflate( epsilon, CORNER_STRATEGY::ALLOW_ACUTE_CORNERS, ARC_LOW_DEF );
|
||||
|
||||
DRC_RTREE* zoneRTree = board->m_CopperZoneRTreeCache[ copperZone ].get();
|
||||
|
@ -555,7 +555,7 @@ void DRC_TEST_PROVIDER_PHYSICAL_CLEARANCE::testZoneLayer( ZONE* aZone, PCB_LAYER
|
||||
SHAPE_POLY_SET fill = aZone->GetFilledPolysList( aLayer )->CloneDropTriangulation();
|
||||
|
||||
// Turn fractured fill into outlines and holes
|
||||
fill.Simplify( SHAPE_POLY_SET::PM_FAST );
|
||||
fill.Simplify();
|
||||
|
||||
for( int outlineIdx = 0; outlineIdx < fill.OutlineCount(); ++outlineIdx )
|
||||
{
|
||||
|
@ -155,7 +155,7 @@ bool DRC_TEST_PROVIDER_SLIVER_CHECKER::Run()
|
||||
if( m_drcEngine->IsCancelled() )
|
||||
return 0;
|
||||
|
||||
poly.Simplify( SHAPE_POLY_SET::POLYGON_MODE::PM_FAST );
|
||||
poly.Simplify();
|
||||
|
||||
return 1;
|
||||
};
|
||||
|
@ -122,8 +122,7 @@ void DRC_TEST_PROVIDER_SOLDER_MASK::addItemToRTrees( BOARD_ITEM* aItem )
|
||||
{
|
||||
if( zone->IsOnLayer( layer ) )
|
||||
{
|
||||
solderMask->GetFill( layer )->BooleanAdd( *zone->GetFilledPolysList( layer ),
|
||||
SHAPE_POLY_SET::PM_FAST );
|
||||
solderMask->GetFill( layer )->BooleanAdd( *zone->GetFilledPolysList( layer ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -222,8 +221,8 @@ void DRC_TEST_PROVIDER_SOLDER_MASK::buildRTrees()
|
||||
return true;
|
||||
} );
|
||||
|
||||
solderMask->GetFill( F_Mask )->Simplify( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
||||
solderMask->GetFill( B_Mask )->Simplify( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
||||
solderMask->GetFill( F_Mask )->Simplify();
|
||||
solderMask->GetFill( B_Mask )->Simplify();
|
||||
|
||||
solderMask->GetFill( F_Mask )->Deflate( m_webWidth / 2, CORNER_STRATEGY::CHAMFER_ALL_CORNERS,
|
||||
m_maxError );
|
||||
|
@ -177,7 +177,7 @@ bool DRC_TEST_PROVIDER_TEXT_DIMS::Run()
|
||||
SHAPE_POLY_SET poly = outlineGlyph->CloneDropTriangulation();
|
||||
poly.Deflate( constraint.Value().Min() / 2,
|
||||
CORNER_STRATEGY::CHAMFER_ALL_CORNERS, ARC_LOW_DEF );
|
||||
poly.Simplify( SHAPE_POLY_SET::PM_FAST );
|
||||
poly.Simplify();
|
||||
|
||||
int resultingOutlineCount = poly.OutlineCount();
|
||||
int resultingHoleCount = 0;
|
||||
|
@ -502,7 +502,7 @@ bool HYPERLYNX_EXPORTER::writeNetObjects( const std::vector<BOARD_ITEM*>& aObjec
|
||||
const wxString layerName = m_board->GetLayerName( layer );
|
||||
SHAPE_POLY_SET fill = zone->GetFilledPolysList( layer )->CloneDropTriangulation();
|
||||
|
||||
fill.Simplify( SHAPE_POLY_SET::PM_FAST );
|
||||
fill.Simplify();
|
||||
|
||||
for( int i = 0; i < fill.OutlineCount(); i++ )
|
||||
{
|
||||
|
@ -394,8 +394,8 @@ void EXPORTER_PCB_VRML::ExportVrmlSolderMask()
|
||||
outlines = m_pcbOutlines;
|
||||
m_board->ConvertBrdLayerToPolygonalContours( pcb_layer, holes );
|
||||
|
||||
outlines.BooleanSubtract( holes, SHAPE_POLY_SET::PM_FAST );
|
||||
outlines.Fracture( SHAPE_POLY_SET::PM_FAST );
|
||||
outlines.BooleanSubtract( holes );
|
||||
outlines.Fracture();
|
||||
ExportVrmlPolygonSet( vrmllayer, outlines );
|
||||
|
||||
pcb_layer = B_Mask;
|
||||
@ -426,8 +426,8 @@ void EXPORTER_PCB_VRML::ExportStandardLayers()
|
||||
|
||||
outlines.RemoveAllContours();
|
||||
m_board->ConvertBrdLayerToPolygonalContours( pcb_layer[lcnt], outlines );
|
||||
outlines.BooleanIntersection( m_pcbOutlines, SHAPE_POLY_SET::PM_FAST );
|
||||
outlines.Fracture( SHAPE_POLY_SET::PM_FAST );
|
||||
outlines.BooleanIntersection( m_pcbOutlines );
|
||||
outlines.Fracture();
|
||||
|
||||
ExportVrmlPolygonSet( vrmllayer[lcnt], outlines );
|
||||
}
|
||||
|
@ -463,7 +463,7 @@ void EXPORTER_STEP::buildZones3DShape( VECTOR2D aOrigin )
|
||||
{
|
||||
SHAPE_POLY_SET fill_shape;
|
||||
zone->TransformSolidAreasShapesToPolygon( layer, fill_shape );
|
||||
fill_shape.Unfracture( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
||||
fill_shape.Unfracture();
|
||||
|
||||
fill_shape.SimplifyOutlines( ADVANCED_CFG::GetCfg().m_TriangulateSimplificationLevel );
|
||||
|
||||
@ -640,31 +640,31 @@ bool EXPORTER_STEP::buildBoard3DShapes()
|
||||
for( PCB_LAYER_ID pcblayer : m_layersToExport.Seq() )
|
||||
{
|
||||
SHAPE_POLY_SET poly = m_poly_shapes[pcblayer];
|
||||
poly.Simplify( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
||||
poly.Simplify();
|
||||
|
||||
poly.SimplifyOutlines( pcbIUScale.mmToIU( 0.003 ) );
|
||||
poly.Simplify( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
||||
poly.Simplify();
|
||||
|
||||
SHAPE_POLY_SET holes = m_poly_holes[pcblayer];
|
||||
holes.Simplify( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
||||
holes.Simplify();
|
||||
|
||||
// Mask layer is negative
|
||||
if( pcblayer == F_Mask || pcblayer == B_Mask )
|
||||
{
|
||||
SHAPE_POLY_SET mask = pcbOutlinesNoArcs;
|
||||
|
||||
mask.BooleanSubtract( poly, SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
||||
mask.BooleanSubtract( holes, SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
||||
mask.BooleanSubtract( poly );
|
||||
mask.BooleanSubtract( holes );
|
||||
|
||||
poly = mask;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Subtract holes
|
||||
poly.BooleanSubtract( holes, SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
||||
poly.BooleanSubtract( holes );
|
||||
|
||||
// Clip to board outline
|
||||
poly.BooleanIntersection( pcbOutlinesNoArcs, SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
||||
poly.BooleanIntersection( pcbOutlinesNoArcs );
|
||||
}
|
||||
|
||||
m_pcbModel->AddPolygonShapes( &poly, pcblayer, origin );
|
||||
|
@ -1561,7 +1561,7 @@ bool STEP_PCB_MODEL::MakeShapes( std::vector<TopoDS_Shape>& aShapes, const SHAPE
|
||||
double aThickness, double aZposition, const VECTOR2D& aOrigin )
|
||||
{
|
||||
SHAPE_POLY_SET workingPoly = aPolySet;
|
||||
workingPoly.Simplify( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
||||
workingPoly.Simplify();
|
||||
|
||||
SHAPE_POLY_SET fallbackPoly = workingPoly;
|
||||
|
||||
|
@ -2777,7 +2777,7 @@ double FOOTPRINT::GetCoverageArea( const BOARD_ITEM* aItem, const GENERAL_COLLEC
|
||||
{
|
||||
SHAPE_POLY_SET padPoly;
|
||||
aItem->TransformShapeToPolygon( padPoly, aLayer, 0, ARC_LOW_DEF, ERROR_OUTSIDE );
|
||||
poly.BooleanAdd( padPoly, SHAPE_POLY_SET::PM_FAST );
|
||||
poly.BooleanAdd( padPoly );
|
||||
} );
|
||||
}
|
||||
else
|
||||
@ -2837,7 +2837,7 @@ double FOOTPRINT::CoverageRatio( const GENERAL_COLLECTOR& aCollector ) const
|
||||
}
|
||||
}
|
||||
|
||||
coveredRegion.BooleanIntersection( footprintRegion, SHAPE_POLY_SET::PM_FAST );
|
||||
coveredRegion.BooleanIntersection( footprintRegion );
|
||||
|
||||
double footprintRegionArea = polygonArea( footprintRegion );
|
||||
double uncoveredRegionArea = footprintRegionArea - polygonArea( coveredRegion );
|
||||
@ -3327,7 +3327,7 @@ void FOOTPRINT::CheckNetTies( const std::function<void( const BOARD_ITEM* aItem,
|
||||
}
|
||||
}
|
||||
|
||||
copperOutlines.Simplify( SHAPE_POLY_SET::PM_FAST );
|
||||
copperOutlines.Simplify();
|
||||
|
||||
// Index each pad to the outline in the set that it is part of.
|
||||
|
||||
|
@ -1804,7 +1804,7 @@ SHAPE_LINE_CHAIN PCB_TUNING_PATTERN::getOutline() const
|
||||
}
|
||||
|
||||
SHAPE_POLY_SET merged;
|
||||
merged.BooleanAdd( chain1, chain2, SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
||||
merged.BooleanAdd( chain1, chain2 );
|
||||
|
||||
if( merged.OutlineCount() > 0 )
|
||||
return merged.Outline( 0 );
|
||||
@ -1832,7 +1832,7 @@ SHAPE_LINE_CHAIN PCB_TUNING_PATTERN::getOutline() const
|
||||
CORNER_STRATEGY::ROUND_ALL_CORNERS, ARC_LOW_DEF, false );
|
||||
|
||||
SHAPE_POLY_SET merged;
|
||||
merged.BooleanAdd( poly, polyCoupled, SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
||||
merged.BooleanAdd( poly, polyCoupled );
|
||||
|
||||
if( merged.OutlineCount() > 0 )
|
||||
return merged.Outline( 0 );
|
||||
|
@ -1956,7 +1956,7 @@ void PAD::TransformShapeToPolygon( SHAPE_POLY_SET& aBuffer, PCB_LAYER_ID aLayer,
|
||||
aClearance += aMaxError;
|
||||
|
||||
outline.Inflate( aClearance, CORNER_STRATEGY::ROUND_ALL_CORNERS, aMaxError );
|
||||
outline.Fracture( SHAPE_POLY_SET::PM_FAST );
|
||||
outline.Fracture();
|
||||
}
|
||||
else if( aClearance < 0 )
|
||||
{
|
||||
@ -1965,7 +1965,7 @@ void PAD::TransformShapeToPolygon( SHAPE_POLY_SET& aBuffer, PCB_LAYER_ID aLayer,
|
||||
|
||||
// aClearance is negative so this is actually a deflate
|
||||
outline.Inflate( aClearance, CORNER_STRATEGY::ALLOW_ACUTE_CORNERS, aMaxError );
|
||||
outline.Fracture( SHAPE_POLY_SET::PM_FAST );
|
||||
outline.Fracture();
|
||||
}
|
||||
|
||||
aBuffer.Append( outline );
|
||||
@ -2008,7 +2008,7 @@ std::vector<PCB_SHAPE*> PAD::Recombine( bool aIsDryRun, int maxError )
|
||||
|
||||
SHAPE_POLY_SET drawPoly;
|
||||
shape->TransformShapeToPolygon( drawPoly, aLayer, 0, maxError, ERROR_INSIDE );
|
||||
drawPoly.BooleanIntersection( padPoly, SHAPE_POLY_SET::PM_FAST );
|
||||
drawPoly.BooleanIntersection( padPoly );
|
||||
|
||||
if( !drawPoly.IsEmpty() )
|
||||
return shape;
|
||||
@ -2275,7 +2275,7 @@ void PAD::doCheckPad( PCB_LAYER_ID aLayer, UNITS_PROVIDER* aUnitsProvider,
|
||||
hole->GetWidth(), ARC_HIGH_DEF, ERROR_OUTSIDE );
|
||||
|
||||
SHAPE_POLY_SET copper = padOutline;
|
||||
copper.BooleanSubtract( holeOutline, SHAPE_POLY_SET::POLYGON_MODE::PM_FAST );
|
||||
copper.BooleanSubtract( holeOutline );
|
||||
|
||||
if( copper.IsEmpty() )
|
||||
{
|
||||
@ -2284,7 +2284,7 @@ void PAD::doCheckPad( PCB_LAYER_ID aLayer, UNITS_PROVIDER* aUnitsProvider,
|
||||
else
|
||||
{
|
||||
// Test if the pad hole is fully inside the copper area
|
||||
holeOutline.BooleanSubtract( padOutline, SHAPE_POLY_SET::POLYGON_MODE::PM_FAST );
|
||||
holeOutline.BooleanSubtract( padOutline );
|
||||
|
||||
if( !holeOutline.IsEmpty() )
|
||||
aErrorHandler( DRCE_PADSTACK, _( "(PTH pad hole non fully inside copper)" ) );
|
||||
|
@ -45,7 +45,7 @@ void PAD::AddPrimitivePoly( PCB_LAYER_ID aLayer, const SHAPE_POLY_SET& aPoly, in
|
||||
poly_no_hole.Append( aPoly );
|
||||
|
||||
if( poly_no_hole.HasHoles() )
|
||||
poly_no_hole.Fracture( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
||||
poly_no_hole.Fracture();
|
||||
|
||||
// There should never be multiple shapes, but if there are, we split them into
|
||||
// primitives so that we can edit them both.
|
||||
@ -142,13 +142,13 @@ void PAD::addPadPrimitivesToPolygon( PCB_LAYER_ID aLayer, SHAPE_POLY_SET* aMerge
|
||||
primitive->TransformShapeToPolygon( polyset, UNDEFINED_LAYER, 0, aError, aErrorLoc );
|
||||
}
|
||||
|
||||
polyset.Simplify( SHAPE_POLY_SET::PM_FAST );
|
||||
polyset.Simplify();
|
||||
|
||||
// Merge all polygons with the initial pad anchor shape
|
||||
if( polyset.OutlineCount() )
|
||||
{
|
||||
aMergedPolygon->BooleanAdd( polyset, SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
||||
aMergedPolygon->Fracture( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
||||
aMergedPolygon->BooleanAdd( polyset );
|
||||
aMergedPolygon->Fracture();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -320,7 +320,7 @@ void PCB_BASE_FRAME::FocusOnItems( std::vector<BOARD_ITEM*> aItems, PCB_LAYER_ID
|
||||
|
||||
try
|
||||
{
|
||||
viewportPoly.BooleanSubtract( dialogPoly, SHAPE_POLY_SET::PM_FAST );
|
||||
viewportPoly.BooleanSubtract( dialogPoly );
|
||||
}
|
||||
catch( const std::exception& e )
|
||||
{
|
||||
@ -426,7 +426,7 @@ void PCB_BASE_FRAME::FocusOnItems( std::vector<BOARD_ITEM*> aItems, PCB_LAYER_ID
|
||||
|
||||
try
|
||||
{
|
||||
clippedPoly.BooleanIntersection( itemPoly, viewportPoly, SHAPE_POLY_SET::PM_FAST );
|
||||
clippedPoly.BooleanIntersection( itemPoly, viewportPoly );
|
||||
}
|
||||
catch( const std::exception& e )
|
||||
{
|
||||
|
@ -598,7 +598,7 @@ void ALTIUM_PCB::Parse( const ALTIUM_PCB_COMPOUND_FILE& altiumP
|
||||
if( !zone->HasFilledPolysForLayer( layer ) )
|
||||
continue;
|
||||
|
||||
zone->GetFilledPolysList( layer )->Fracture( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
||||
zone->GetFilledPolysList( layer )->Fracture();
|
||||
}
|
||||
}
|
||||
|
||||
@ -2824,9 +2824,9 @@ void ALTIUM_PCB::ParseRegions6Data( const ALTIUM_PCB_COMPOUND_FILE& aAltiumP
|
||||
}
|
||||
|
||||
if( zone->HasFilledPolysForLayer( klayer ) )
|
||||
fill.BooleanAdd( *zone->GetFill( klayer ), SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
||||
fill.BooleanAdd( *zone->GetFill( klayer ) );
|
||||
|
||||
fill.Fracture( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
||||
fill.Fracture();
|
||||
|
||||
zone->SetFilledPolysList( klayer, fill );
|
||||
zone->SetIsFilled( true );
|
||||
|
@ -2173,7 +2173,7 @@ void CADSTAR_PCB_ARCHIVE_LOADER::loadCoppers()
|
||||
}
|
||||
|
||||
poly.ClearArcs();
|
||||
fill.BooleanAdd( poly, SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
||||
fill.BooleanAdd( poly );
|
||||
}
|
||||
|
||||
}
|
||||
@ -2186,11 +2186,10 @@ void CADSTAR_PCB_ARCHIVE_LOADER::loadCoppers()
|
||||
|
||||
if( pouredZone->HasFilledPolysForLayer( getKiCadLayer( csCopper.LayerID ) ) )
|
||||
{
|
||||
fill.BooleanAdd( *pouredZone->GetFill( getKiCadLayer( csCopper.LayerID ) ),
|
||||
SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
||||
fill.BooleanAdd( *pouredZone->GetFill( getKiCadLayer( csCopper.LayerID ) ) );
|
||||
}
|
||||
|
||||
fill.Fracture( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
||||
fill.Fracture();
|
||||
|
||||
pouredZone->SetFilledPolysList( getKiCadLayer( csCopper.LayerID ), fill );
|
||||
pouredZone->SetIsFilled( true );
|
||||
@ -2270,7 +2269,7 @@ void CADSTAR_PCB_ARCHIVE_LOADER::loadCoppers()
|
||||
zone->SetAssignedPriority( m_zonesMap.size() + 1 ); // Highest priority (always fill first)
|
||||
|
||||
SHAPE_POLY_SET fill( *zone->Outline() );
|
||||
fill.Fracture( SHAPE_POLY_SET::POLYGON_MODE::PM_STRICTLY_SIMPLE );
|
||||
fill.Fracture();
|
||||
|
||||
zone->SetFilledPolysList( getKiCadLayer( csCopper.LayerID ), fill );
|
||||
}
|
||||
@ -2822,7 +2821,7 @@ void CADSTAR_PCB_ARCHIVE_LOADER::drawCadstarShape( const SHAPE& aCadstarShape,
|
||||
aScalingFactor, aTransformCentre,
|
||||
aMirrorInvert );
|
||||
|
||||
shapePolys.Fracture( SHAPE_POLY_SET::POLYGON_MODE::PM_STRICTLY_SIMPLE );
|
||||
shapePolys.Fracture();
|
||||
|
||||
shape->SetPolyShape( shapePolys );
|
||||
shape->SetStroke( STROKE_PARAMS( aLineThickness, LINE_STYLE::SOLID ) );
|
||||
@ -3770,9 +3769,9 @@ bool CADSTAR_PCB_ARCHIVE_LOADER::calculateZonePriorities( PCB_LAYER_ID& aLayer )
|
||||
SHAPE_POLY_SET lowerZoneFill( *aLowerZone->GetFilledPolysList( aLayer ) );
|
||||
SHAPE_POLY_SET lowerZoneOutline( *aLowerZone->Outline() );
|
||||
|
||||
lowerZoneOutline.BooleanSubtract( intersectShape, SHAPE_POLY_SET::PM_FAST );
|
||||
lowerZoneOutline.BooleanSubtract( intersectShape );
|
||||
|
||||
lowerZoneFill.BooleanSubtract( lowerZoneOutline, SHAPE_POLY_SET::PM_FAST );
|
||||
lowerZoneFill.BooleanSubtract( lowerZoneOutline );
|
||||
|
||||
double leftOverArea = lowerZoneFill.Area();
|
||||
|
||||
@ -3790,7 +3789,7 @@ bool CADSTAR_PCB_ARCHIVE_LOADER::calculateZonePriorities( PCB_LAYER_ID& aLayer )
|
||||
outLineB.Inflate( inflateValue( aZoneA, aZoneB ), CORNER_STRATEGY::ROUND_ALL_CORNERS,
|
||||
ARC_HIGH_DEF );
|
||||
|
||||
outLineA.BooleanIntersection( outLineB, SHAPE_POLY_SET::PM_FAST );
|
||||
outLineA.BooleanIntersection( outLineB );
|
||||
|
||||
return outLineA.Area();
|
||||
};
|
||||
|
@ -572,7 +572,7 @@ void PCB_IO_EASYEDA_PARSER::ParseToBoardItemContainer(
|
||||
}
|
||||
}
|
||||
|
||||
fillPolySet.Fracture( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
||||
fillPolySet.Fracture();
|
||||
|
||||
zone->SetFilledPolysList( layer, fillPolySet );
|
||||
zone->SetIsFilled( true );
|
||||
|
@ -880,7 +880,7 @@ FOOTPRINT* PCB_IO_EASYEDAPRO_PARSER::ParseFootprint( const nlohmann::json&
|
||||
true );
|
||||
}
|
||||
|
||||
polySet.Simplify( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
||||
polySet.Simplify();
|
||||
|
||||
std::unique_ptr<ZONE> zone = std::make_unique<ZONE>( footprint );
|
||||
|
||||
@ -1158,7 +1158,7 @@ void PCB_IO_EASYEDAPRO_PARSER::ParseBoard(
|
||||
zoneFillPoly.AddOutline( contour );
|
||||
|
||||
zoneFillPoly.RebuildHolesFromContours();
|
||||
zoneFillPoly.Fracture( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
||||
zoneFillPoly.Fracture();
|
||||
|
||||
std::unique_ptr<ZONE> zone = std::make_unique<ZONE>( aBoard );
|
||||
|
||||
@ -1771,7 +1771,7 @@ void PCB_IO_EASYEDAPRO_PARSER::ParseBoard(
|
||||
|
||||
// The contour can be self-intersecting
|
||||
SHAPE_POLY_SET simple( contour );
|
||||
simple.Simplify( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
||||
simple.Simplify();
|
||||
|
||||
if( dataId == 0 )
|
||||
{
|
||||
@ -1779,7 +1779,7 @@ void PCB_IO_EASYEDAPRO_PARSER::ParseBoard(
|
||||
}
|
||||
else
|
||||
{
|
||||
thisPoly.BooleanSubtract( simple, SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
||||
thisPoly.BooleanSubtract( simple );
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -1801,16 +1801,16 @@ void PCB_IO_EASYEDAPRO_PARSER::ParseBoard(
|
||||
|
||||
if( !fillPolySet.IsEmpty() )
|
||||
{
|
||||
fillPolySet.Simplify( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
||||
fillPolySet.Simplify();
|
||||
|
||||
const int strokeWidth = pcbIUScale.MilsToIU( 8 ); // Seems to be 8 mils
|
||||
|
||||
fillPolySet.Inflate( strokeWidth / 2, CORNER_STRATEGY::ROUND_ALL_CORNERS,
|
||||
ARC_HIGH_DEF, false );
|
||||
|
||||
fillPolySet.BooleanAdd( thermalSpokes, SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
||||
fillPolySet.BooleanAdd( thermalSpokes );
|
||||
|
||||
fillPolySet.Fracture( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
||||
fillPolySet.Fracture();
|
||||
|
||||
zone->SetFilledPolysList( zone->GetFirstLayer(), fillPolySet );
|
||||
zone->SetNeedRefill( false );
|
||||
|
@ -2724,7 +2724,7 @@ bool FABMASTER::loadFootprints( BOARD* aBoard )
|
||||
}
|
||||
else
|
||||
{
|
||||
poly_outline.Fracture( SHAPE_POLY_SET::POLYGON_MODE::PM_FAST );
|
||||
poly_outline.Fracture();
|
||||
|
||||
poly_outline.Move( -newpad->GetPosition() );
|
||||
|
||||
@ -3324,7 +3324,7 @@ bool FABMASTER::loadPolygon( BOARD* aBoard, const std::unique_ptr<FABMASTER::TRA
|
||||
|
||||
SHAPE_POLY_SET poly_outline = loadShapePolySet( aLine->segment );
|
||||
|
||||
poly_outline.Fracture( SHAPE_POLY_SET::POLYGON_MODE::PM_FAST );
|
||||
poly_outline.Fracture();
|
||||
|
||||
if( poly_outline.OutlineCount() < 1 || poly_outline.COutline( 0 ).PointCount() < 3 )
|
||||
return false;
|
||||
@ -3552,7 +3552,7 @@ bool FABMASTER::loadGraphics( BOARD* aBoard )
|
||||
{
|
||||
SHAPE_POLY_SET poly_outline = loadShapePolySet( *( geom.elements ) );
|
||||
|
||||
poly_outline.Fracture( SHAPE_POLY_SET::POLYGON_MODE::PM_FAST );
|
||||
poly_outline.Fracture();
|
||||
|
||||
if( poly_outline.OutlineCount() < 1 || poly_outline.COutline( 0 ).PointCount() < 3 )
|
||||
continue;
|
||||
|
@ -606,7 +606,7 @@ void PCB_IO_IPC2581::addKnockoutText( wxXmlNode* aContentNode, PCB_TEXT* aText )
|
||||
SHAPE_POLY_SET finalPoly;
|
||||
|
||||
aText->TransformTextToPolySet( finalPoly, 0, ARC_HIGH_DEF, ERROR_INSIDE );
|
||||
finalPoly.Fracture( SHAPE_POLY_SET::PM_FAST );
|
||||
finalPoly.Fracture();
|
||||
|
||||
for( int ii = 0; ii < finalPoly.OutlineCount(); ++ii )
|
||||
addContourNode( aContentNode, finalPoly, ii );
|
||||
@ -889,7 +889,7 @@ void PCB_IO_IPC2581::addShape( wxXmlNode* aContentNode, const PAD& aPad, PCB_LAY
|
||||
if( expansion.x )
|
||||
{
|
||||
outline.InflateWithLinkedHoles( expansion.x, CORNER_STRATEGY::ROUND_ALL_CORNERS,
|
||||
maxError, SHAPE_POLY_SET::PM_FAST );
|
||||
maxError );
|
||||
}
|
||||
|
||||
addContourNode( entry_node, outline );
|
||||
@ -910,8 +910,7 @@ void PCB_IO_IPC2581::addShape( wxXmlNode* aContentNode, const PAD& aPad, PCB_LAY
|
||||
if( expansion != VECTOR2I( 0, 0 ) )
|
||||
{
|
||||
shape.InflateWithLinkedHoles( std::max( expansion.x, expansion.y ),
|
||||
CORNER_STRATEGY::ROUND_ALL_CORNERS, maxError,
|
||||
SHAPE_POLY_SET::PM_FAST );
|
||||
CORNER_STRATEGY::ROUND_ALL_CORNERS, maxError );
|
||||
}
|
||||
|
||||
addContourNode( entry_node, shape );
|
||||
|
@ -2627,8 +2627,7 @@ void PCB_IO_KICAD_LEGACY::loadZONE_CONTAINER()
|
||||
|
||||
inflatedFill.InflateWithLinkedHoles( zc->GetMinThickness() / 2,
|
||||
CORNER_STRATEGY::ROUND_ALL_CORNERS,
|
||||
ARC_HIGH_DEF / 2,
|
||||
SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
||||
ARC_HIGH_DEF / 2 );
|
||||
|
||||
zc->SetFilledPolysList( layer, inflatedFill );
|
||||
}
|
||||
|
@ -7231,8 +7231,7 @@ ZONE* PCB_IO_KICAD_SEXPR_PARSER::parseZONE( BOARD_ITEM_CONTAINER* aParent )
|
||||
{
|
||||
polyset.InflateWithLinkedHoles( zone->GetMinThickness() / 2,
|
||||
CORNER_STRATEGY::ROUND_ALL_CORNERS,
|
||||
ARC_HIGH_DEF / 2,
|
||||
SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
||||
ARC_HIGH_DEF / 2 );
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -7271,7 +7270,7 @@ ZONE* PCB_IO_KICAD_SEXPR_PARSER::parseZONE( BOARD_ITEM_CONTAINER* aParent )
|
||||
TransformOvalToPolygon( segPolygon, seg.A, seg.B, zone->GetMinThickness(),
|
||||
ARC_HIGH_DEF, ERROR_OUTSIDE );
|
||||
|
||||
layerFill.BooleanAdd( segPolygon, SHAPE_POLY_SET::PM_FAST );
|
||||
layerFill.BooleanAdd( segPolygon );
|
||||
}
|
||||
|
||||
|
||||
|
@ -141,7 +141,7 @@ void FEATURES_MANAGER::AddShape( const PCB_SHAPE& aShape, PCB_LAYER_ID aLayer )
|
||||
if( soldermask_min_thickness == 0 )
|
||||
{
|
||||
poly_set = aShape.GetPolyShape().CloneDropTriangulation();
|
||||
poly_set.Fracture( SHAPE_POLY_SET::PM_FAST );
|
||||
poly_set.Fracture();
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -152,11 +152,11 @@ void FEATURES_MANAGER::AddShape( const PCB_SHAPE& aShape, PCB_LAYER_ID aLayer )
|
||||
aShape.TransformShapeToPolygon( poly_set, aLayer, soldermask_min_thickness / 2 - 1,
|
||||
maxError, ERROR_OUTSIDE );
|
||||
|
||||
poly_set.Simplify( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
||||
poly_set.Simplify();
|
||||
poly_set.Deflate( soldermask_min_thickness / 2 - 1,
|
||||
CORNER_STRATEGY::CHAMFER_ALL_CORNERS, maxError );
|
||||
poly_set.BooleanAdd( initialPolys, SHAPE_POLY_SET::PM_FAST );
|
||||
poly_set.Fracture( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
||||
poly_set.BooleanAdd( initialPolys );
|
||||
poly_set.Fracture();
|
||||
}
|
||||
|
||||
int strokeWidth = aShape.GetStroke().GetWidth();
|
||||
@ -338,7 +338,7 @@ void FEATURES_MANAGER::AddPadShape( const PAD& aPad, PCB_LAYER_ID aLayer )
|
||||
if( mask_clearance )
|
||||
{
|
||||
outline.InflateWithLinkedHoles( expansion.x, CORNER_STRATEGY::ROUND_ALL_CORNERS,
|
||||
maxError, SHAPE_POLY_SET::PM_FAST );
|
||||
maxError );
|
||||
}
|
||||
|
||||
for( int ii = 0; ii < outline.OutlineCount(); ++ii )
|
||||
@ -360,8 +360,7 @@ void FEATURES_MANAGER::AddPadShape( const PAD& aPad, PCB_LAYER_ID aLayer )
|
||||
if( expansion != VECTOR2I( 0, 0 ) )
|
||||
{
|
||||
shape.InflateWithLinkedHoles( std::max( expansion.x, expansion.y ),
|
||||
CORNER_STRATEGY::ROUND_ALL_CORNERS, maxError,
|
||||
SHAPE_POLY_SET::PM_FAST );
|
||||
CORNER_STRATEGY::ROUND_ALL_CORNERS, maxError );
|
||||
}
|
||||
|
||||
for( int ii = 0; ii < shape.OutlineCount(); ++ii )
|
||||
@ -644,7 +643,7 @@ void FEATURES_MANAGER::InitFeatureList( PCB_LAYER_ID aLayer, std::vector<BOARD_I
|
||||
|
||||
text->TransformTextToPolySet( finalpolyset, 0, m_board->GetDesignSettings().m_MaxError,
|
||||
ERROR_INSIDE );
|
||||
finalpolyset.Fracture( SHAPE_POLY_SET::PM_FAST );
|
||||
finalpolyset.Fracture();
|
||||
|
||||
for( int ii = 0; ii < finalpolyset.OutlineCount(); ++ii )
|
||||
{
|
||||
|
@ -2238,7 +2238,7 @@ void PCB_PAINTER::draw( const PCB_TEXT* aText, int aLayer )
|
||||
{
|
||||
SHAPE_POLY_SET finalPoly;
|
||||
aText->TransformTextToPolySet( finalPoly, 0, m_maxError, ERROR_INSIDE );
|
||||
finalPoly.Fracture( SHAPE_POLY_SET::PM_FAST );
|
||||
finalPoly.Fracture();
|
||||
|
||||
m_gal->SetIsStroke( false );
|
||||
m_gal->SetIsFill( true );
|
||||
|
@ -538,7 +538,7 @@ void PCB_TEXT::TransformTextToPolySet( SHAPE_POLY_SET& aBuffer, int aClearance,
|
||||
} );
|
||||
|
||||
font->Draw( &callback_gal, GetShownText( true ), GetTextPos(), attrs, GetFontMetrics() );
|
||||
textShape.Simplify( SHAPE_POLY_SET::PM_FAST );
|
||||
textShape.Simplify();
|
||||
|
||||
if( IsKnockout() )
|
||||
{
|
||||
@ -546,7 +546,7 @@ void PCB_TEXT::TransformTextToPolySet( SHAPE_POLY_SET& aBuffer, int aClearance,
|
||||
int margin = GetKnockoutTextMargin( attrs.m_Size, penWidth );
|
||||
|
||||
buildBoundingHull( &finalPoly, textShape, margin + aClearance );
|
||||
finalPoly.BooleanSubtract( textShape, SHAPE_POLY_SET::PM_FAST );
|
||||
finalPoly.BooleanSubtract( textShape );
|
||||
|
||||
aBuffer.Append( finalPoly );
|
||||
}
|
||||
|
@ -665,7 +665,7 @@ void PCB_TEXTBOX::TransformTextToPolySet( SHAPE_POLY_SET& aBuffer, int aClearanc
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer.Simplify( SHAPE_POLY_SET::PM_FAST );
|
||||
buffer.Simplify();
|
||||
}
|
||||
|
||||
aBuffer.Append( buffer );
|
||||
|
@ -860,8 +860,7 @@ static void enclosedByAreaFunc( LIBEVAL::CONTEXT* aCtx, void* self )
|
||||
}
|
||||
else
|
||||
{
|
||||
itemShape.BooleanSubtract( *aArea->Outline(),
|
||||
SHAPE_POLY_SET::PM_FAST );
|
||||
itemShape.BooleanSubtract( *aArea->Outline() );
|
||||
|
||||
enclosedByArea = itemShape.IsEmpty();
|
||||
}
|
||||
|
@ -467,8 +467,7 @@ void PlotStandardLayer( BOARD* aBoard, PLOTTER* aPlotter, LSET aLayerMask,
|
||||
// Shape polygon can have holes so use InflateWithLinkedHoles(), not Inflate()
|
||||
// which can create bad shapes if margin.x is < 0
|
||||
outline.InflateWithLinkedHoles( mask_clearance,
|
||||
CORNER_STRATEGY::ROUND_ALL_CORNERS, maxError,
|
||||
SHAPE_POLY_SET::PM_FAST );
|
||||
CORNER_STRATEGY::ROUND_ALL_CORNERS, maxError );
|
||||
dummy.DeletePrimitivesList();
|
||||
dummy.AddPrimitivePoly( aLayer, outline, 0, true );
|
||||
|
||||
@ -518,8 +517,7 @@ void PlotStandardLayer( BOARD* aBoard, PLOTTER* aPlotter, LSET aLayerMask,
|
||||
dummy.TransformShapeToPolygon( outline, UNDEFINED_LAYER, 0, maxError,
|
||||
ERROR_INSIDE );
|
||||
outline.InflateWithLinkedHoles( mask_clearance,
|
||||
CORNER_STRATEGY::ROUND_ALL_CORNERS, maxError,
|
||||
SHAPE_POLY_SET::PM_FAST );
|
||||
CORNER_STRATEGY::ROUND_ALL_CORNERS, maxError );
|
||||
|
||||
// Initialize the dummy pad shape:
|
||||
dummy.SetAnchorPadShape( aLayer, PAD_SHAPE::CIRCLE );
|
||||
@ -554,8 +552,7 @@ void PlotStandardLayer( BOARD* aBoard, PLOTTER* aPlotter, LSET aLayerMask,
|
||||
// Shape polygon can have holes so use InflateWithLinkedHoles(), not Inflate()
|
||||
// which can create bad shapes if margin.x is < 0
|
||||
shape.InflateWithLinkedHoles( mask_clearance,
|
||||
CORNER_STRATEGY::ROUND_ALL_CORNERS, maxError,
|
||||
SHAPE_POLY_SET::PM_FAST );
|
||||
CORNER_STRATEGY::ROUND_ALL_CORNERS, maxError );
|
||||
dummy.DeletePrimitivesList();
|
||||
dummy.AddPrimitivePoly( aLayer, shape, 0, true );
|
||||
|
||||
@ -792,7 +789,7 @@ void PlotLayerOutlines( BOARD* aBoard, PLOTTER* aPlotter, LSET aLayerMask,
|
||||
outlines.RemoveAllContours();
|
||||
aBoard->ConvertBrdLayerToPolygonalContours( layer, outlines );
|
||||
|
||||
outlines.Simplify( SHAPE_POLY_SET::PM_FAST );
|
||||
outlines.Simplify();
|
||||
|
||||
// Plot outlines
|
||||
std::vector<VECTOR2I> cornerList;
|
||||
@ -1046,7 +1043,7 @@ void PlotSolderMaskLayer( BOARD *aBoard, PLOTTER* aPlotter, LSET aLayerMask,
|
||||
|
||||
// Merge all polygons: After deflating, not merged (not overlapping) polygons will have the
|
||||
// initial shape (with perhaps small changes due to deflating transform)
|
||||
areas.Simplify( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
||||
areas.Simplify();
|
||||
areas.Deflate( inflate, CORNER_STRATEGY::CHAMFER_ALL_CORNERS, maxError );
|
||||
|
||||
// To avoid a lot of code, use a ZONE to handle and plot polygons, because our polygons look
|
||||
@ -1060,8 +1057,8 @@ void PlotSolderMaskLayer( BOARD *aBoard, PLOTTER* aPlotter, LSET aLayerMask,
|
||||
|
||||
// Combine the current areas to initial areas. This is mandatory because inflate/deflate
|
||||
// transform is not perfect, and we want the initial areas perfectly kept
|
||||
areas.BooleanAdd( initialPolys, SHAPE_POLY_SET::PM_FAST );
|
||||
areas.Fracture( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
||||
areas.BooleanAdd( initialPolys );
|
||||
areas.Fracture();
|
||||
|
||||
itemplotter.PlotZone( &zone, layer, areas );
|
||||
}
|
||||
|
@ -733,7 +733,7 @@ void BRDITEMS_PLOTTER::PlotText( const EDA_TEXT* aText, PCB_LAYER_ID aLayer, boo
|
||||
|
||||
text->TransformTextToPolySet( finalPoly, 0, m_board->GetDesignSettings().m_MaxError,
|
||||
ERROR_INSIDE );
|
||||
finalPoly.Fracture( SHAPE_POLY_SET::PM_FAST );
|
||||
finalPoly.Fracture();
|
||||
|
||||
for( int ii = 0; ii < finalPoly.OutlineCount(); ++ii )
|
||||
m_plotter->PlotPoly( finalPoly.Outline( ii ), FILL_T::FILLED_SHAPE, 0, &gbr_metadata );
|
||||
@ -966,7 +966,7 @@ void BRDITEMS_PLOTTER::PlotShape( const PCB_SHAPE* aShape )
|
||||
// This must be simplified and fractured to prevent overlapping polygons
|
||||
// from generating invalid Gerber files
|
||||
SHAPE_POLY_SET tmpPoly = aShape->GetPolyShape().CloneDropTriangulation();
|
||||
tmpPoly.Fracture( SHAPE_POLY_SET::PM_FAST );
|
||||
tmpPoly.Fracture();
|
||||
|
||||
if( margin < 0 )
|
||||
{
|
||||
|
@ -89,7 +89,7 @@ const SHAPE_LINE_CHAIN HOLE::Hull( int aClearance, int aWalkaroundThickness, int
|
||||
BuildHullForPrimitiveShape( shape, aClearance, aWalkaroundThickness ) );
|
||||
}
|
||||
|
||||
hullSet.Simplify( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
||||
hullSet.Simplify();
|
||||
return hullSet.Outline( 0 );
|
||||
}
|
||||
}
|
||||
|
@ -24,6 +24,7 @@
|
||||
#define __PNS_ITEM_H
|
||||
|
||||
#include <memory>
|
||||
#include <set>
|
||||
#include <unordered_set>
|
||||
#include <math/vector2d.h>
|
||||
|
||||
|
@ -60,7 +60,7 @@ const SHAPE_LINE_CHAIN SOLID::Hull( int aClearance, int aWalkaroundThickness, in
|
||||
aWalkaroundThickness ) );
|
||||
}
|
||||
|
||||
hullSet.Simplify( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
||||
hullSet.Simplify();
|
||||
return hullSet.Outline( 0 );
|
||||
}
|
||||
}
|
||||
|
@ -843,7 +843,7 @@ IMAGE* SPECCTRA_DB::makeIMAGE( BOARD* aBoard, FOOTPRINT* aFootprint )
|
||||
TransformCircleToPolygon( polyBuffer, graphic->GetEnd() - move,
|
||||
graphic->GetWidth() / 2, ARC_HIGH_DEF, ERROR_INSIDE );
|
||||
|
||||
polyBuffer.Simplify( SHAPE_POLY_SET::PM_FAST );
|
||||
polyBuffer.Simplify();
|
||||
SHAPE_LINE_CHAIN& poly = polyBuffer.Outline( 0 );
|
||||
|
||||
for( int ii = 0; ii < poly.PointCount(); ++ii )
|
||||
|
@ -388,7 +388,7 @@ bool TEARDROP_MANAGER::computeAnchorPoints( const TEARDROP_PARAMETERS& aParams,
|
||||
clipping_rect.Move( ref_on_track );
|
||||
|
||||
// Clip the shape to the max allowed teadrop area
|
||||
c_buffer.BooleanIntersection( clipping_rect, SHAPE_POLY_SET::PM_FAST );
|
||||
c_buffer.BooleanIntersection( clipping_rect );
|
||||
}
|
||||
|
||||
/* in aPts:
|
||||
|
@ -1320,11 +1320,10 @@ static bool mergeZones( EDA_DRAW_FRAME* aFrame, BOARD_COMMIT& aCommit,
|
||||
|
||||
for( unsigned int i = 1; i < aOriginZones.size(); i++ )
|
||||
{
|
||||
aOriginZones[0]->Outline()->BooleanAdd( *aOriginZones[i]->Outline(),
|
||||
SHAPE_POLY_SET::PM_FAST );
|
||||
aOriginZones[0]->Outline()->BooleanAdd( *aOriginZones[i]->Outline() );
|
||||
}
|
||||
|
||||
aOriginZones[0]->Outline()->Simplify( SHAPE_POLY_SET::PM_FAST );
|
||||
aOriginZones[0]->Outline()->Simplify();
|
||||
|
||||
// We should have one polygon, possibly with holes. If we end up with two polygons (either
|
||||
// because the intersection was a single point or because the intersection was within one of
|
||||
|
@ -373,7 +373,7 @@ int CONVERT_TOOL::CreatePolys( const TOOL_EVENT& aEvent )
|
||||
polySet.Append( makePolysFromOpenGraphics( selection.GetItems(), 0 ) );
|
||||
|
||||
polySet.ClearArcs();
|
||||
polySet.Simplify( SHAPE_POLY_SET::PM_FAST );
|
||||
polySet.Simplify();
|
||||
|
||||
// Now inflate the bounding hull by cfg.m_Gap
|
||||
polySet.Inflate( cfg.m_Gap, CORNER_STRATEGY::ROUND_ALL_CORNERS, bds.m_MaxError,
|
||||
|
@ -571,8 +571,7 @@ std::optional<wxString> POLYGON_MERGE_ROUTINE::GetStatusMessage() const
|
||||
|
||||
bool POLYGON_MERGE_ROUTINE::ProcessSubsequentPolygon( const SHAPE_POLY_SET& aPolygon )
|
||||
{
|
||||
const SHAPE_POLY_SET::POLYGON_MODE poly_mode = SHAPE_POLY_SET::POLYGON_MODE::PM_FAST;
|
||||
GetWorkingPolygons().BooleanAdd( aPolygon, poly_mode );
|
||||
GetWorkingPolygons().BooleanAdd( aPolygon );
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -599,11 +598,9 @@ std::optional<wxString> POLYGON_SUBTRACT_ROUTINE::GetStatusMessage() const
|
||||
|
||||
bool POLYGON_SUBTRACT_ROUTINE::ProcessSubsequentPolygon( const SHAPE_POLY_SET& aPolygon )
|
||||
{
|
||||
const SHAPE_POLY_SET::POLYGON_MODE poly_mode = SHAPE_POLY_SET::POLYGON_MODE::PM_FAST;
|
||||
|
||||
SHAPE_POLY_SET& working_polygons = GetWorkingPolygons();
|
||||
SHAPE_POLY_SET working_copy = working_polygons;
|
||||
working_copy.BooleanSubtract( aPolygon, poly_mode );
|
||||
working_copy.BooleanSubtract( aPolygon );
|
||||
|
||||
// Subtraction can create holes or delete the polygon
|
||||
// In theory we can allow holes as the EDA_SHAPE will fracture for us, but that's
|
||||
@ -642,11 +639,9 @@ std::optional<wxString> POLYGON_INTERSECT_ROUTINE::GetStatusMessage() const
|
||||
|
||||
bool POLYGON_INTERSECT_ROUTINE::ProcessSubsequentPolygon( const SHAPE_POLY_SET& aPolygon )
|
||||
{
|
||||
const SHAPE_POLY_SET::POLYGON_MODE poly_mode = SHAPE_POLY_SET::POLYGON_MODE::PM_FAST;
|
||||
|
||||
SHAPE_POLY_SET& working_polygons = GetWorkingPolygons();
|
||||
SHAPE_POLY_SET working_copy = working_polygons;
|
||||
working_copy.BooleanIntersection( aPolygon, poly_mode );
|
||||
working_copy.BooleanIntersection( aPolygon );
|
||||
|
||||
// Is there anything left?
|
||||
if( working_copy.OutlineCount() == 0 )
|
||||
|
@ -36,7 +36,6 @@ using namespace std::placeholders;
|
||||
#include <board.h>
|
||||
#include <board_design_settings.h>
|
||||
#include <board_item.h>
|
||||
#include <clipper.hpp>
|
||||
#include <pcb_reference_image.h>
|
||||
#include <pcb_track.h>
|
||||
#include <footprint.h>
|
||||
|
@ -171,7 +171,7 @@ void ZONE_CREATE_HELPER::performZoneCutout( ZONE& aZone, const ZONE& aCutout )
|
||||
toolMgr->RunAction( PCB_ACTIONS::selectionClear );
|
||||
|
||||
SHAPE_POLY_SET originalOutline( *aZone.Outline() );
|
||||
originalOutline.BooleanSubtract( *aCutout.Outline(), SHAPE_POLY_SET::PM_FAST );
|
||||
originalOutline.BooleanSubtract( *aCutout.Outline() );
|
||||
|
||||
// After substracting the hole, originalOutline can have more than one main outline.
|
||||
// But a zone can have only one main outline, so create as many zones as originalOutline
|
||||
|
@ -344,8 +344,7 @@ void TRACKS_CLEANER::deleteTracksInPads()
|
||||
track->TransformShapeToPolygon( poly, track->GetLayer(), 0, ARC_HIGH_DEF,
|
||||
ERROR_INSIDE );
|
||||
|
||||
poly.BooleanSubtract( *pad->GetEffectivePolygon( track->GetLayer(), ERROR_INSIDE ),
|
||||
SHAPE_POLY_SET::PM_FAST );
|
||||
poly.BooleanSubtract( *pad->GetEffectivePolygon( track->GetLayer(), ERROR_INSIDE ) );
|
||||
|
||||
if( poly.IsEmpty() )
|
||||
{
|
||||
|
@ -991,7 +991,7 @@ void ZONE::RemoveCutout( int aOutlineIdx, int aHoleIdx )
|
||||
SHAPE_POLY_SET cutPoly( m_Poly->Hole( aOutlineIdx, aHoleIdx ) );
|
||||
|
||||
// Add the cutout back to the zone
|
||||
m_Poly->BooleanAdd( cutPoly, SHAPE_POLY_SET::PM_FAST );
|
||||
m_Poly->BooleanAdd( cutPoly );
|
||||
|
||||
SetNeedRefill( true );
|
||||
}
|
||||
@ -1434,7 +1434,7 @@ bool ZONE::BuildSmoothedPoly( SHAPE_POLY_SET& aSmoothedPoly, PCB_LAYER_ID aLayer
|
||||
{
|
||||
withFillets = flattened;
|
||||
smooth( withFillets );
|
||||
withFillets.BooleanAdd( flattened, SHAPE_POLY_SET::PM_FAST );
|
||||
withFillets.BooleanAdd( flattened );
|
||||
maxExtents = &withFillets;
|
||||
}
|
||||
|
||||
@ -1466,7 +1466,7 @@ bool ZONE::BuildSmoothedPoly( SHAPE_POLY_SET& aSmoothedPoly, PCB_LAYER_ID aLayer
|
||||
if( diffNetZone->HigherPriority( sameNetZone )
|
||||
&& diffNetZone->GetBoundingBox().Intersects( sameNetBoundingBox ) )
|
||||
{
|
||||
diffNetPoly.BooleanAdd( *diffNetZone->Outline(), SHAPE_POLY_SET::PM_FAST );
|
||||
diffNetPoly.BooleanAdd( *diffNetZone->Outline() );
|
||||
}
|
||||
}
|
||||
|
||||
@ -1479,19 +1479,19 @@ bool ZONE::BuildSmoothedPoly( SHAPE_POLY_SET& aSmoothedPoly, PCB_LAYER_ID aLayer
|
||||
{
|
||||
SHAPE_POLY_SET thisPoly = Outline()->CloneDropTriangulation();
|
||||
|
||||
thisPoly.BooleanSubtract( diffNetPoly, SHAPE_POLY_SET::PM_FAST );
|
||||
thisPoly.BooleanSubtract( diffNetPoly );
|
||||
isolated = thisPoly.OutlineCount() == 0;
|
||||
}
|
||||
|
||||
if( !isolated )
|
||||
{
|
||||
sameNetPoly.ClearArcs();
|
||||
aSmoothedPoly.BooleanAdd( sameNetPoly, SHAPE_POLY_SET::PM_FAST );
|
||||
aSmoothedPoly.BooleanAdd( sameNetPoly );
|
||||
}
|
||||
}
|
||||
|
||||
if( aBoardOutline )
|
||||
aSmoothedPoly.BooleanIntersection( *aBoardOutline, SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
||||
aSmoothedPoly.BooleanIntersection( *aBoardOutline );
|
||||
|
||||
SHAPE_POLY_SET withSameNetIntersectingZones = aSmoothedPoly.CloneDropTriangulation();
|
||||
|
||||
@ -1508,13 +1508,13 @@ bool ZONE::BuildSmoothedPoly( SHAPE_POLY_SET& aSmoothedPoly, PCB_LAYER_ID aLayer
|
||||
poly.Inflate( m_ZoneMinThickness, CORNER_STRATEGY::ROUND_ALL_CORNERS, maxError );
|
||||
|
||||
if( !keepExternalFillets )
|
||||
poly.BooleanIntersection( withSameNetIntersectingZones, SHAPE_POLY_SET::PM_FAST );
|
||||
poly.BooleanIntersection( withSameNetIntersectingZones );
|
||||
|
||||
*aSmoothedPolyWithApron = aSmoothedPoly;
|
||||
aSmoothedPolyWithApron->BooleanIntersection( poly, SHAPE_POLY_SET::PM_FAST );
|
||||
aSmoothedPolyWithApron->BooleanIntersection( poly );
|
||||
}
|
||||
|
||||
aSmoothedPoly.BooleanIntersection( *maxExtents, SHAPE_POLY_SET::PM_FAST );
|
||||
aSmoothedPoly.BooleanIntersection( *maxExtents );
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -1576,7 +1576,7 @@ void ZONE::TransformSmoothedOutlineToPolygon( SHAPE_POLY_SET& aBuffer, int aClea
|
||||
polybuffer.Inflate( aClearance, CORNER_STRATEGY::ROUND_ALL_CORNERS, maxError );
|
||||
}
|
||||
|
||||
polybuffer.Fracture( SHAPE_POLY_SET::PM_FAST );
|
||||
polybuffer.Fracture();
|
||||
aBuffer.Append( polybuffer );
|
||||
}
|
||||
|
||||
@ -1612,8 +1612,7 @@ void ZONE::TransformShapeToPolygon( SHAPE_POLY_SET& aBuffer, PCB_LAYER_ID aLayer
|
||||
if( aErrorLoc == ERROR_OUTSIDE )
|
||||
aClearance += aError;
|
||||
|
||||
temp_buf.InflateWithLinkedHoles( aClearance, CORNER_STRATEGY::ROUND_ALL_CORNERS, aError,
|
||||
SHAPE_POLY_SET::PM_FAST );
|
||||
temp_buf.InflateWithLinkedHoles( aClearance, CORNER_STRATEGY::ROUND_ALL_CORNERS, aError );
|
||||
}
|
||||
|
||||
aBuffer.Append( temp_buf );
|
||||
|
@ -796,8 +796,7 @@ bool ZONE_FILLER::Fill( const std::vector<ZONE*>& aZones, bool aCheck, wxWindow*
|
||||
|
||||
|
||||
island.AddOutline( test_poly );
|
||||
intersection.BooleanIntersection( m_boardOutline, island,
|
||||
SHAPE_POLY_SET::POLYGON_MODE::PM_FAST );
|
||||
intersection.BooleanIntersection( m_boardOutline, island );
|
||||
|
||||
// Nominally, all of these areas should be either inside or outside the
|
||||
// board outline. So this test should be able to just compare areas (if
|
||||
@ -1118,7 +1117,7 @@ void ZONE_FILLER::knockoutThermalReliefs( const ZONE* aZone, PCB_LAYER_ID aLayer
|
||||
}
|
||||
}
|
||||
|
||||
aFill.BooleanSubtract( holes, SHAPE_POLY_SET::PM_FAST );
|
||||
aFill.BooleanSubtract( holes );
|
||||
}
|
||||
|
||||
|
||||
@ -1505,7 +1504,7 @@ void ZONE_FILLER::buildCopperItemClearances( const ZONE* aZone, PCB_LAYER_ID aLa
|
||||
}
|
||||
}
|
||||
|
||||
aHoles.Simplify( SHAPE_POLY_SET::PM_FAST );
|
||||
aHoles.Simplify();
|
||||
}
|
||||
|
||||
|
||||
@ -1533,7 +1532,7 @@ void ZONE_FILLER::subtractHigherPriorityZones( const ZONE* aZone, PCB_LAYER_ID a
|
||||
SHAPE_POLY_SET outline = aKnockout->Outline()->CloneDropTriangulation();
|
||||
outline.ClearArcs();
|
||||
|
||||
aRawFill.BooleanSubtract( outline, SHAPE_POLY_SET::PM_FAST );
|
||||
aRawFill.BooleanSubtract( outline );
|
||||
}
|
||||
};
|
||||
|
||||
@ -1617,7 +1616,7 @@ void ZONE_FILLER::connect_nearby_polys( SHAPE_POLY_SET& aPolys, double aDistance
|
||||
{ \
|
||||
m_board->SetLayerName( b, c ); \
|
||||
SHAPE_POLY_SET d = a; \
|
||||
d.Fracture( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE ); \
|
||||
d.Fracture(); \
|
||||
aFillPolys = d; \
|
||||
return false; \
|
||||
} \
|
||||
@ -1699,7 +1698,7 @@ bool ZONE_FILLER::fillCopperZone( const ZONE* aZone, PCB_LAYER_ID aLayer, PCB_LA
|
||||
// because the "real" subtract-clearance-holes has to be done after the spokes are added.
|
||||
static const bool USE_BBOX_CACHES = true;
|
||||
SHAPE_POLY_SET testAreas = aFillPolys.CloneDropTriangulation();
|
||||
testAreas.BooleanSubtract( clearanceHoles, SHAPE_POLY_SET::PM_FAST );
|
||||
testAreas.BooleanSubtract( clearanceHoles );
|
||||
DUMP_POLYS_TO_COPPER_LAYER( testAreas, In4_Cu, wxT( "minus-clearance-holes" ) );
|
||||
|
||||
// Prune features that don't meet minimum-width criteria
|
||||
@ -1767,7 +1766,7 @@ bool ZONE_FILLER::fillCopperZone( const ZONE* aZone, PCB_LAYER_ID aLayer, PCB_LA
|
||||
if( m_progressReporter && m_progressReporter->IsCancelled() )
|
||||
return false;
|
||||
|
||||
aFillPolys.BooleanSubtract( clearanceHoles, SHAPE_POLY_SET::PM_FAST );
|
||||
aFillPolys.BooleanSubtract( clearanceHoles );
|
||||
DUMP_POLYS_TO_COPPER_LAYER( aFillPolys, In8_Cu, wxT( "after-spoke-trimming" ) );
|
||||
|
||||
/* -------------------------------------------------------------------------------------
|
||||
@ -1818,7 +1817,7 @@ bool ZONE_FILLER::fillCopperZone( const ZONE* aZone, PCB_LAYER_ID aLayer, PCB_LA
|
||||
* Connect nearby polygons with zero-width lines in order to ensure correct
|
||||
* re-inflation.
|
||||
*/
|
||||
aFillPolys.Fracture( SHAPE_POLY_SET::PM_FAST );
|
||||
aFillPolys.Fracture();
|
||||
connect_nearby_polys( aFillPolys, aZone->GetMinThickness() );
|
||||
|
||||
DUMP_POLYS_TO_COPPER_LAYER( aFillPolys, In10_Cu, wxT( "connected-nearby-polys" ) );
|
||||
@ -1845,9 +1844,9 @@ bool ZONE_FILLER::fillCopperZone( const ZONE* aZone, PCB_LAYER_ID aLayer, PCB_LA
|
||||
for( PAD* pad : thermalConnectionPads )
|
||||
addHoleKnockout( pad, 0, clearanceHoles );
|
||||
|
||||
aFillPolys.BooleanIntersection( aMaxExtents, SHAPE_POLY_SET::PM_FAST );
|
||||
aFillPolys.BooleanIntersection( aMaxExtents );
|
||||
DUMP_POLYS_TO_COPPER_LAYER( aFillPolys, In16_Cu, wxT( "after-trim-to-outline" ) );
|
||||
aFillPolys.BooleanSubtract( clearanceHoles, SHAPE_POLY_SET::PM_FAST );
|
||||
aFillPolys.BooleanSubtract( clearanceHoles );
|
||||
DUMP_POLYS_TO_COPPER_LAYER( aFillPolys, In17_Cu, wxT( "after-trim-to-clearance-holes" ) );
|
||||
|
||||
/* -------------------------------------------------------------------------------------
|
||||
@ -1857,7 +1856,7 @@ bool ZONE_FILLER::fillCopperZone( const ZONE* aZone, PCB_LAYER_ID aLayer, PCB_LA
|
||||
subtractHigherPriorityZones( aZone, aLayer, aFillPolys );
|
||||
DUMP_POLYS_TO_COPPER_LAYER( aFillPolys, In18_Cu, wxT( "minus-higher-priority-zones" ) );
|
||||
|
||||
aFillPolys.Fracture( SHAPE_POLY_SET::PM_FAST );
|
||||
aFillPolys.Fracture();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1911,7 +1910,7 @@ bool ZONE_FILLER::fillNonCopperZone( const ZONE* aZone, PCB_LAYER_ID aLayer,
|
||||
}
|
||||
|
||||
aFillPolys = aSmoothedOutline;
|
||||
aFillPolys.BooleanSubtract( clearanceHoles, SHAPE_POLY_SET::PM_FAST );
|
||||
aFillPolys.BooleanSubtract( clearanceHoles );
|
||||
|
||||
for( ZONE* keepout : m_board->Zones() )
|
||||
{
|
||||
@ -1927,13 +1926,13 @@ bool ZONE_FILLER::fillNonCopperZone( const ZONE* aZone, PCB_LAYER_ID aLayer,
|
||||
{
|
||||
if( keepout->Outline()->ArcCount() == 0 )
|
||||
{
|
||||
aFillPolys.BooleanSubtract( *keepout->Outline(), SHAPE_POLY_SET::PM_FAST );
|
||||
aFillPolys.BooleanSubtract( *keepout->Outline() );
|
||||
}
|
||||
else
|
||||
{
|
||||
SHAPE_POLY_SET keepoutOutline( *keepout->Outline() );
|
||||
keepoutOutline.ClearArcs();
|
||||
aFillPolys.BooleanSubtract( keepoutOutline, SHAPE_POLY_SET::PM_FAST );
|
||||
aFillPolys.BooleanSubtract( keepoutOutline );
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1958,7 +1957,7 @@ bool ZONE_FILLER::fillNonCopperZone( const ZONE* aZone, PCB_LAYER_ID aLayer,
|
||||
if( half_min_width - epsilon > epsilon )
|
||||
aFillPolys.Inflate( half_min_width - epsilon, CORNER_STRATEGY::ROUND_ALL_CORNERS, m_maxError );
|
||||
|
||||
aFillPolys.Fracture( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
||||
aFillPolys.Fracture();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -2375,12 +2374,12 @@ bool ZONE_FILLER::addHatchFillTypeOnZone( const ZONE* aZone, PCB_LAYER_ID aLayer
|
||||
SHAPE_POLY_SET deflatedFilledPolys = aFillPolys.CloneDropTriangulation();
|
||||
deflatedFilledPolys.Deflate( outline_margin - aZone->GetMinThickness(),
|
||||
CORNER_STRATEGY::CHAMFER_ALL_CORNERS, maxError );
|
||||
holes.BooleanIntersection( deflatedFilledPolys, SHAPE_POLY_SET::PM_FAST );
|
||||
holes.BooleanIntersection( deflatedFilledPolys );
|
||||
DUMP_POLYS_TO_COPPER_LAYER( holes, In11_Cu, wxT( "fill-clipped-hatch-holes" ) );
|
||||
|
||||
SHAPE_POLY_SET deflatedOutline = aZone->Outline()->CloneDropTriangulation();
|
||||
deflatedOutline.Deflate( outline_margin, CORNER_STRATEGY::CHAMFER_ALL_CORNERS, maxError );
|
||||
holes.BooleanIntersection( deflatedOutline, SHAPE_POLY_SET::PM_FAST );
|
||||
holes.BooleanIntersection( deflatedOutline );
|
||||
DUMP_POLYS_TO_COPPER_LAYER( holes, In12_Cu, wxT( "outline-clipped-hatch-holes" ) );
|
||||
|
||||
if( aZone->GetNetCode() != 0 )
|
||||
@ -2438,7 +2437,7 @@ bool ZONE_FILLER::addHatchFillTypeOnZone( const ZONE* aZone, PCB_LAYER_ID aLayer
|
||||
}
|
||||
}
|
||||
|
||||
holes.BooleanSubtract( aprons, SHAPE_POLY_SET::PM_FAST );
|
||||
holes.BooleanSubtract( aprons );
|
||||
}
|
||||
DUMP_POLYS_TO_COPPER_LAYER( holes, In13_Cu, wxT( "pad-via-clipped-hatch-holes" ) );
|
||||
|
||||
@ -2454,9 +2453,9 @@ bool ZONE_FILLER::addHatchFillTypeOnZone( const ZONE* aZone, PCB_LAYER_ID aLayer
|
||||
++ii;
|
||||
}
|
||||
|
||||
// create grid. Use SHAPE_POLY_SET::PM_STRICTLY_SIMPLE to
|
||||
// create grid. Useto
|
||||
// generate strictly simple polygons needed by Gerber files and Fracture()
|
||||
aFillPolys.BooleanSubtract( aFillPolys, holes, SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
||||
aFillPolys.BooleanSubtract( aFillPolys, holes );
|
||||
DUMP_POLYS_TO_COPPER_LAYER( aFillPolys, In14_Cu, wxT( "after-hatching" ) );
|
||||
|
||||
return true;
|
||||
|
@ -131,21 +131,6 @@ BOOST_AUTO_TEST_CASE( ClipperConstructorCase1 )
|
||||
// Case of an arc followed by a segment
|
||||
// The clipper path is not in order (on purpose), to simulate the typical return from clipper
|
||||
|
||||
ClipperLib::Path pathClipper1 = {
|
||||
{ { 125663951, 120099260, 24 }, { 125388111, 120170850, 25 }, { 125124975, 120280270, 26 },
|
||||
{ 124879705, 120425376, 27 }, { 124657110, 120603322, 28 }, { 124461556, 120810617, 29 },
|
||||
{ 124296876, 121043198, 30 }, { 124166301, 121296503, 31 }, { 124072391, 121565564, 32 },
|
||||
{ 124016988, 121845106, 33 }, { 124001177, 122129646, 34 }, { 124025270, 122413605, 35 },
|
||||
{ 124088794, 122691414, 36 }, { 124190502, 122957625, 37 }, { 124328401, 123207018, 38 },
|
||||
{ 124499787, 123434703, 39 }, { 124598846, 123537154, 40 }, { 127171000, 123786000, 4 },
|
||||
{ 127287862, 123704439, 5 }, { 127499716, 123513831, 6 }, { 127682866, 123295498, 7 },
|
||||
{ 127833720, 123053722, 8 }, { 127949321, 122793242, 9 }, { 128027402, 122519168, 10 },
|
||||
{ 128066430, 122236874, 11 }, { 128065642, 121951896, 12 }, { 128025053, 121669823, 13 },
|
||||
{ 127945457, 121396185, 14 }, { 127828417, 121136349, 15 }, { 127676227, 120895410, 16 },
|
||||
{ 127491873, 120678094, 17 }, { 127278968, 120488661, 18 }, { 127041689, 120330827, 19 },
|
||||
{ 126784688, 120207687, 20 }, { 126513005, 120121655, 21 }, { 126231968, 120074419, 22 },
|
||||
{ 125947087, 120066905, 23 } }
|
||||
};
|
||||
Clipper2Lib::Path64 pathClipper2 = {
|
||||
{ { 125663951, 120099260, 24 }, { 125388111, 120170850, 25 }, { 125124975, 120280270, 26 },
|
||||
{ 124879705, 120425376, 27 }, { 124657110, 120603322, 28 }, { 124461556, 120810617, 29 },
|
||||
@ -180,22 +165,16 @@ BOOST_AUTO_TEST_CASE( ClipperConstructorCase1 )
|
||||
SHAPE_ARC( { 127171000, 123786000 }, { 126231718, 120077003 }, { 124598846, 123537154 }, 0 )
|
||||
};
|
||||
|
||||
SHAPE_LINE_CHAIN clipper1chain( pathClipper1, z_values, arcs );
|
||||
SHAPE_LINE_CHAIN clipper2chain( pathClipper2, z_values, arcs );
|
||||
|
||||
BOOST_CHECK( GEOM_TEST::IsOutlineValid( clipper1chain ) );
|
||||
BOOST_CHECK( GEOM_TEST::IsOutlineValid( clipper2chain ) );
|
||||
|
||||
BOOST_CHECK_EQUAL( clipper1chain.PointCount(), 37 );
|
||||
BOOST_CHECK_EQUAL( clipper2chain.PointCount(), 37 );
|
||||
|
||||
BOOST_CHECK_EQUAL( clipper1chain.ArcCount(), 1 );
|
||||
BOOST_CHECK_EQUAL( clipper2chain.ArcCount(), 1 );
|
||||
|
||||
BOOST_CHECK_EQUAL( clipper1chain.ShapeCount(), 2 );
|
||||
BOOST_CHECK_EQUAL( clipper2chain.ShapeCount(), 2 );
|
||||
|
||||
BOOST_CHECK_EQUAL( clipper1chain.IsClosed(), true );
|
||||
BOOST_CHECK_EQUAL( clipper2chain.IsClosed(), true );
|
||||
}
|
||||
|
||||
|
@ -64,7 +64,7 @@ BOOST_AUTO_TEST_CASE( TestSimplify )
|
||||
{
|
||||
BOOST_TEST_CONTEXT( "Simplify Iteration " << i )
|
||||
{
|
||||
testPoly.Simplify( SHAPE_POLY_SET::POLYGON_MODE::PM_FAST );
|
||||
testPoly.Simplify();
|
||||
|
||||
std::vector<SHAPE_ARC> foundArcs;
|
||||
testPoly.GetArcs( foundArcs );
|
||||
@ -119,14 +119,14 @@ BOOST_AUTO_TEST_CASE( TestIntersectUnion )
|
||||
double opPolyArea = opPoly.Area();
|
||||
|
||||
SHAPE_POLY_SET intersectionPoly = testPoly;
|
||||
intersectionPoly.BooleanIntersection( opPoly, SHAPE_POLY_SET::POLYGON_MODE::PM_STRICTLY_SIMPLE );
|
||||
intersectionPoly.BooleanIntersection( opPoly );
|
||||
double intersectArea = intersectionPoly.Area();
|
||||
|
||||
BOOST_CHECK( GEOM_TEST::IsPolySetValid( intersectionPoly ) );
|
||||
|
||||
|
||||
SHAPE_POLY_SET unionPoly = testPoly;
|
||||
unionPoly.BooleanAdd( opPoly, SHAPE_POLY_SET::POLYGON_MODE::PM_STRICTLY_SIMPLE );
|
||||
unionPoly.BooleanAdd( opPoly );
|
||||
double unionArea = unionPoly.Area();
|
||||
|
||||
BOOST_CHECK( GEOM_TEST::IsPolySetValid( unionPoly ) );
|
||||
|
@ -158,8 +158,7 @@ BOOST_FIXTURE_TEST_CASE( NotchedZones, ZONE_FILL_TEST_FIXTURE )
|
||||
{
|
||||
if( zone->GetLayerSet().Contains( F_Cu ) )
|
||||
{
|
||||
frontCopper.BooleanAdd( *zone->GetFilledPolysList( F_Cu ),
|
||||
SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
||||
frontCopper.BooleanAdd( *zone->GetFilledPolysList( F_Cu ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -135,7 +135,7 @@ int runDRCProto( PROJECT_CONTEXT project, std::shared_ptr<KIGFX::VIEW_OVERLAY> a
|
||||
{
|
||||
drcEngine->RunTests( EDA_UNITS::MILLIMETRES, true, false );
|
||||
}
|
||||
catch( const ClipperLib::clipperException& e )
|
||||
catch( const Clipper2Lib::Clipper2Exception& e )
|
||||
{
|
||||
consoleLog.Print( wxString::Format( "Clipper exception %s occurred.", e.what() ) );
|
||||
}
|
||||
|
@ -246,7 +246,7 @@ int polygon_triangulation_main( int argc, char *argv[] )
|
||||
ignore_unused( poly );
|
||||
#if 0
|
||||
PROF_TIMER unfrac("unfrac");
|
||||
poly.Unfracture( SHAPE_POLY_SET::PM_FAST );
|
||||
poly.Unfracture();
|
||||
unfrac.Show();
|
||||
|
||||
PROF_TIMER triangulate("triangulate");
|
||||
|
@ -307,12 +307,12 @@ int playground_main_func( int argc, char* argv[] )
|
||||
|
||||
SHAPE_POLY_SET xorPad1ToPad2 = pad1Outline;
|
||||
|
||||
xorPad1ToPad2.BooleanXor( pad2Outline, SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
||||
xorPad1ToPad2.BooleanXor( pad2Outline );
|
||||
xorPad1ToPad2.Move( VECTOR2I( pcbIUScale.mmToIU( 10 ), 0 ) );
|
||||
|
||||
SHAPE_POLY_SET andPad1ToPad2 = pad2Outline;
|
||||
|
||||
andPad1ToPad2.BooleanIntersection( pad1Outline, SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
||||
andPad1ToPad2.BooleanIntersection( pad1Outline );
|
||||
andPad1ToPad2.Move( VECTOR2I( pcbIUScale.mmToIU( 20 ), 0 ) );
|
||||
|
||||
std::shared_ptr<SHAPE_SEGMENT> slot = pad2.GetEffectiveHoleShape();
|
||||
|
1
thirdparty/CMakeLists.txt
vendored
1
thirdparty/CMakeLists.txt
vendored
@ -34,7 +34,6 @@ set( CMAKE_POLICY_DEFAULT_CMP0077 NEW )
|
||||
|
||||
set( ARGPARSE_INSTALL OFF )
|
||||
add_subdirectory( argparse )
|
||||
add_subdirectory( clipper )
|
||||
add_subdirectory( clipper2 )
|
||||
add_subdirectory( compoundfilereader )
|
||||
add_subdirectory( delaunator )
|
||||
|
9
thirdparty/clipper/CMakeLists.txt
vendored
9
thirdparty/clipper/CMakeLists.txt
vendored
@ -1,9 +0,0 @@
|
||||
|
||||
add_library( clipper OBJECT
|
||||
clipper.cpp
|
||||
)
|
||||
|
||||
target_include_directories( clipper
|
||||
PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
)
|
23
thirdparty/clipper/LICENSE.BOOSTv1_0
vendored
23
thirdparty/clipper/LICENSE.BOOSTv1_0
vendored
@ -1,23 +0,0 @@
|
||||
Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
Permission is hereby granted, free of charge, to any person or organization
|
||||
obtaining a copy of the software and accompanying documentation covered by
|
||||
this license (the "Software") to use, reproduce, display, distribute,
|
||||
execute, and transmit the Software, and to prepare derivative works of the
|
||||
Software, and to permit third-parties to whom the Software is furnished to
|
||||
do so, all subject to the following:
|
||||
|
||||
The copyright notices in the Software and this entire statement, including
|
||||
the above license grant, this restriction and the following disclaimer,
|
||||
must be included in all copies of the Software, in whole or in part, and
|
||||
all derivative works of the Software, unless such copies or derivative
|
||||
works are solely in the form of machine-executable object code generated by
|
||||
a source language processor.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
4
thirdparty/clipper/README.txt
vendored
4
thirdparty/clipper/README.txt
vendored
@ -1,4 +0,0 @@
|
||||
This directory contains the Clipper library for interacting with polygons.
|
||||
https://sourceforge.net/projects/polyclipping/
|
||||
|
||||
It is licensed under the Boost Software License, with the license text in this directory.
|
5999
thirdparty/clipper/clipper.cpp
vendored
5999
thirdparty/clipper/clipper.cpp
vendored
File diff suppressed because it is too large
Load Diff
457
thirdparty/clipper/clipper.hpp
vendored
457
thirdparty/clipper/clipper.hpp
vendored
@ -1,457 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* *
|
||||
* Author : Angus Johnson *
|
||||
* Version : 6.4.2 *
|
||||
* Date : 27 February 2017 *
|
||||
* Website : http://www.angusj.com *
|
||||
* Copyright : Angus Johnson 2010-2017 *
|
||||
* *
|
||||
* License: *
|
||||
* Use, modification & distribution is subject to Boost Software License Ver 1. *
|
||||
* http://www.boost.org/LICENSE_1_0.txt *
|
||||
* *
|
||||
* Attributions: *
|
||||
* The code in this library is an extension of Bala Vatti's clipping algorithm: *
|
||||
* "A generic solution to polygon clipping" *
|
||||
* Communications of the ACM, Vol 35, Issue 7 (July 1992) pp 56-63. *
|
||||
* http://portal.acm.org/citation.cfm?id=129906 *
|
||||
* *
|
||||
* Computer graphics and geometric modeling: implementation and algorithms *
|
||||
* By Max K. Agoston *
|
||||
* Springer; 1 edition (January 4, 2005) *
|
||||
* http://books.google.com/books?q=vatti+clipping+agoston *
|
||||
* *
|
||||
* See also: *
|
||||
* "Polygon Offsetting by Computing Winding Numbers" *
|
||||
* Paper no. DETC2005-85513 pp. 565-575 *
|
||||
* ASME 2005 International Design Engineering Technical Conferences *
|
||||
* and Computers and Information in Engineering Conference (IDETC/CIE2005) *
|
||||
* September 24-28, 2005 , Long Beach, California, USA *
|
||||
* http://www.me.berkeley.edu/~mcmains/pubs/DAC05OffsetPolygon.pdf *
|
||||
* *
|
||||
*******************************************************************************/
|
||||
|
||||
#ifndef clipper_hpp
|
||||
#define clipper_hpp
|
||||
|
||||
#define CLIPPER_VERSION "6.4.2"
|
||||
|
||||
// use_int32: When enabled 32bit ints are used instead of 64bit ints. This
|
||||
// improve performance but coordinate values are limited to the range +/- 46340
|
||||
// #define use_int32
|
||||
|
||||
// use_xyz: adds a Z member to IntPoint. Adds a minor cost to perfomance.
|
||||
#define use_xyz
|
||||
|
||||
// use_lines: Enables line clipping. Adds a very minor cost to performance.
|
||||
#define use_lines
|
||||
|
||||
// use_deprecated: Enables temporary support for the obsolete functions
|
||||
// #define use_deprecated
|
||||
|
||||
#include <functional>
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include <set>
|
||||
#include <stdexcept>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
#include <ostream>
|
||||
#include <functional>
|
||||
#include <queue>
|
||||
|
||||
namespace ClipperLib {
|
||||
enum ClipType
|
||||
{
|
||||
ctIntersection, ctUnion, ctDifference, ctXor
|
||||
};
|
||||
enum PolyType
|
||||
{
|
||||
ptSubject, ptClip
|
||||
};
|
||||
// By far the most widely used winding rules for polygon filling are
|
||||
// EvenOdd & NonZero (GDI, GDI+, XLib, OpenGL, Cairo, AGG, Quartz, SVG, Gr32)
|
||||
// Others rules include Positive, Negative and ABS_GTR_EQ_TWO (only in OpenGL)
|
||||
// see http://glprogramming.com/red/chapter11.html
|
||||
enum PolyFillType
|
||||
{
|
||||
pftEvenOdd, pftNonZero, pftPositive, pftNegative
|
||||
};
|
||||
|
||||
#ifdef use_int32
|
||||
typedef int cInt;
|
||||
static cInt const loRange = 0x7FFF;
|
||||
static cInt const hiRange = 0x7FFF;
|
||||
#else
|
||||
typedef signed long long cInt;
|
||||
static cInt const loRange = 0x3FFFFFFF;
|
||||
static cInt const hiRange = 0x3FFFFFFFFFFFFFFFLL;
|
||||
typedef signed long long long64; // used by Int128 class
|
||||
typedef unsigned long long ulong64;
|
||||
|
||||
#endif
|
||||
|
||||
struct IntPoint
|
||||
{
|
||||
cInt X;
|
||||
cInt Y;
|
||||
#ifdef use_xyz
|
||||
cInt Z;
|
||||
IntPoint( cInt x = 0, cInt y = 0, cInt z = 0 ) : X( x ), Y( y ), Z( z ) {};
|
||||
#else
|
||||
IntPoint( cInt x = 0, cInt y = 0 ) : X( x ), Y( y ) {};
|
||||
#endif
|
||||
|
||||
friend inline bool operator==( const IntPoint& a, const IntPoint& b )
|
||||
{
|
||||
return a.X == b.X && a.Y == b.Y;
|
||||
}
|
||||
|
||||
friend inline bool operator!=( const IntPoint& a, const IntPoint& b )
|
||||
{
|
||||
return a.X != b.X || a.Y != b.Y;
|
||||
}
|
||||
};
|
||||
// ------------------------------------------------------------------------------
|
||||
|
||||
typedef std::vector<IntPoint> Path;
|
||||
typedef std::vector<Path> Paths;
|
||||
|
||||
inline Path& operator <<( Path& poly, const IntPoint& p )
|
||||
{
|
||||
poly.push_back( p ); return poly;
|
||||
}
|
||||
|
||||
|
||||
inline Paths& operator <<( Paths& polys, const Path& p )
|
||||
{
|
||||
polys.push_back( p ); return polys;
|
||||
}
|
||||
|
||||
|
||||
std::ostream& operator <<( std::ostream& s, const IntPoint& p );
|
||||
std::ostream& operator <<( std::ostream& s, const Path& p );
|
||||
std::ostream& operator <<( std::ostream& s, const Paths& p );
|
||||
|
||||
struct DoublePoint
|
||||
{
|
||||
double X;
|
||||
double Y;
|
||||
DoublePoint( double x = 0, double y = 0 ) : X( x ), Y( y ) {}
|
||||
DoublePoint( IntPoint ip ) : X( (double) ip.X ), Y( (double) ip.Y ) {}
|
||||
};
|
||||
// ------------------------------------------------------------------------------
|
||||
|
||||
#ifdef use_xyz
|
||||
typedef std::function<void( IntPoint& e1bot, IntPoint& e1top, IntPoint& e2bot, IntPoint& e2top,
|
||||
IntPoint& pt )> ZFillCallback;
|
||||
#endif
|
||||
|
||||
enum InitOptions
|
||||
{
|
||||
ioReverseSolution = 1, ioStrictlySimple = 2, ioPreserveCollinear = 4
|
||||
};
|
||||
enum JoinType
|
||||
{
|
||||
jtSquare, jtRound, jtMiter
|
||||
};
|
||||
enum EndType
|
||||
{
|
||||
etClosedPolygon, etClosedLine, etOpenButt, etOpenSquare, etOpenRound
|
||||
};
|
||||
|
||||
class PolyNode;
|
||||
typedef std::vector<PolyNode*> PolyNodes;
|
||||
|
||||
class PolyNode
|
||||
{
|
||||
public:
|
||||
PolyNode();
|
||||
virtual ~PolyNode() {};
|
||||
Path Contour;
|
||||
PolyNodes Childs;
|
||||
PolyNode* Parent;
|
||||
PolyNode* GetNext() const;
|
||||
bool IsHole() const;
|
||||
bool IsOpen() const;
|
||||
int ChildCount() const;
|
||||
|
||||
private:
|
||||
// PolyNode& operator =(PolyNode& other);
|
||||
unsigned Index; // node index in Parent.Childs
|
||||
bool m_IsOpen;
|
||||
JoinType m_jointype;
|
||||
EndType m_endtype;
|
||||
PolyNode* GetNextSiblingUp() const;
|
||||
void AddChild( PolyNode& child );
|
||||
|
||||
friend class Clipper; // to access Index
|
||||
friend class ClipperOffset;
|
||||
};
|
||||
|
||||
class PolyTree : public PolyNode
|
||||
{
|
||||
public:
|
||||
~PolyTree() { Clear(); };
|
||||
PolyNode* GetFirst() const;
|
||||
void Clear();
|
||||
int Total() const;
|
||||
|
||||
private:
|
||||
// PolyTree& operator =(PolyTree& other);
|
||||
PolyNodes AllNodes;
|
||||
friend class Clipper; // to access AllNodes
|
||||
};
|
||||
|
||||
bool Orientation( const Path& poly );
|
||||
double Area( const Path& poly );
|
||||
int PointInPolygon( const IntPoint& pt, const Path& path );
|
||||
|
||||
void SimplifyPolygon( const Path& in_poly, Paths& out_polys,
|
||||
PolyFillType fillType = pftEvenOdd );
|
||||
void SimplifyPolygons( const Paths& in_polys,
|
||||
Paths& out_polys,
|
||||
PolyFillType fillType = pftEvenOdd );
|
||||
void SimplifyPolygons( Paths& polys, PolyFillType fillType = pftEvenOdd );
|
||||
|
||||
void CleanPolygon( const Path& in_poly, Path& out_poly, double distance = 1.415 );
|
||||
void CleanPolygon( Path& poly, double distance = 1.415 );
|
||||
void CleanPolygons( const Paths& in_polys, Paths& out_polys, double distance = 1.415 );
|
||||
void CleanPolygons( Paths& polys, double distance = 1.415 );
|
||||
|
||||
void MinkowskiSum( const Path& pattern, const Path& path, Paths& solution, bool pathIsClosed );
|
||||
void MinkowskiSum( const Path& pattern, const Paths& paths, Paths& solution, bool pathIsClosed );
|
||||
void MinkowskiDiff( const Path& poly1, const Path& poly2, Paths& solution );
|
||||
|
||||
void PolyTreeToPaths( const PolyTree& polytree, Paths& paths );
|
||||
void ClosedPathsFromPolyTree( const PolyTree& polytree, Paths& paths );
|
||||
void OpenPathsFromPolyTree( PolyTree& polytree, Paths& paths );
|
||||
|
||||
void ReversePath( Path& p );
|
||||
void ReversePaths( Paths& p );
|
||||
|
||||
struct IntRect
|
||||
{
|
||||
cInt left; cInt top; cInt right; cInt bottom;
|
||||
};
|
||||
|
||||
// enums that are used internally ...
|
||||
enum EdgeSide
|
||||
{
|
||||
esLeft = 1, esRight = 2
|
||||
};
|
||||
|
||||
// forward declarations (for stuff used internally) ...
|
||||
struct TEdge;
|
||||
struct IntersectNode;
|
||||
struct LocalMinimum;
|
||||
struct OutPt;
|
||||
struct OutRec;
|
||||
struct Join;
|
||||
|
||||
typedef std::vector <OutRec*> PolyOutList;
|
||||
typedef std::vector <TEdge*> EdgeList;
|
||||
typedef std::vector <Join*> JoinList;
|
||||
typedef std::vector <IntersectNode*> IntersectList;
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
|
||||
// ClipperBase is the ancestor to the Clipper class. It should not be
|
||||
// instantiated directly. This class simply abstracts the conversion of sets of
|
||||
// polygon coordinates into edge objects that are stored in a LocalMinima list.
|
||||
class ClipperBase
|
||||
{
|
||||
public:
|
||||
ClipperBase();
|
||||
virtual ~ClipperBase();
|
||||
virtual bool AddPath( const Path& pg, PolyType PolyTyp, bool Closed );
|
||||
bool AddPaths( const Paths& ppg, PolyType PolyTyp, bool Closed );
|
||||
virtual void Clear();
|
||||
IntRect GetBounds();
|
||||
|
||||
bool PreserveCollinear() { return m_PreserveCollinear; };
|
||||
void PreserveCollinear( bool value ) { m_PreserveCollinear = value; };
|
||||
|
||||
protected:
|
||||
void DisposeLocalMinimaList();
|
||||
TEdge* AddBoundsToLML( TEdge* e, bool IsClosed );
|
||||
virtual void Reset();
|
||||
TEdge* ProcessBound( TEdge* E, bool IsClockwise );
|
||||
void InsertScanbeam( const cInt Y );
|
||||
bool PopScanbeam( cInt& Y );
|
||||
bool LocalMinimaPending();
|
||||
bool PopLocalMinima( cInt Y, const LocalMinimum*& locMin );
|
||||
OutRec* CreateOutRec();
|
||||
void DisposeAllOutRecs();
|
||||
void DisposeOutRec( PolyOutList::size_type index );
|
||||
void SwapPositionsInAEL( TEdge* edge1, TEdge* edge2 );
|
||||
void DeleteFromAEL( TEdge* e );
|
||||
void UpdateEdgeIntoAEL( TEdge*& e );
|
||||
|
||||
typedef std::vector<LocalMinimum> MinimaList;
|
||||
MinimaList::iterator m_CurrentLM;
|
||||
MinimaList m_MinimaList;
|
||||
|
||||
bool m_UseFullRange;
|
||||
EdgeList m_edges;
|
||||
bool m_PreserveCollinear;
|
||||
bool m_HasOpenPaths;
|
||||
PolyOutList m_PolyOuts;
|
||||
TEdge* m_ActiveEdges;
|
||||
|
||||
typedef std::priority_queue<cInt> ScanbeamList;
|
||||
ScanbeamList m_Scanbeam;
|
||||
};
|
||||
// ------------------------------------------------------------------------------
|
||||
|
||||
class Clipper : public virtual ClipperBase
|
||||
{
|
||||
public:
|
||||
Clipper( int initOptions = 0 );
|
||||
bool Execute( ClipType clipType,
|
||||
Paths& solution,
|
||||
PolyFillType fillType = pftEvenOdd );
|
||||
bool Execute( ClipType clipType,
|
||||
Paths& solution,
|
||||
PolyFillType subjFillType,
|
||||
PolyFillType clipFillType );
|
||||
bool Execute( ClipType clipType,
|
||||
PolyTree& polytree,
|
||||
PolyFillType fillType = pftEvenOdd );
|
||||
bool Execute( ClipType clipType,
|
||||
PolyTree& polytree,
|
||||
PolyFillType subjFillType,
|
||||
PolyFillType clipFillType );
|
||||
|
||||
bool ReverseSolution() { return m_ReverseOutput; };
|
||||
void ReverseSolution( bool value ) { m_ReverseOutput = value; };
|
||||
bool StrictlySimple() { return m_StrictSimple; };
|
||||
void StrictlySimple( bool value ) { m_StrictSimple = value; };
|
||||
// set the callback function for z value filling on intersections (otherwise Z is 0)
|
||||
#ifdef use_xyz
|
||||
void ZFillFunction( ZFillCallback zFillFunc );
|
||||
|
||||
#endif
|
||||
|
||||
protected:
|
||||
virtual bool ExecuteInternal();
|
||||
|
||||
private:
|
||||
JoinList m_Joins;
|
||||
JoinList m_GhostJoins;
|
||||
IntersectList m_IntersectList;
|
||||
ClipType m_ClipType;
|
||||
typedef std::list<cInt> MaximaList;
|
||||
MaximaList m_Maxima;
|
||||
TEdge* m_SortedEdges;
|
||||
bool m_ExecuteLocked;
|
||||
PolyFillType m_ClipFillType;
|
||||
PolyFillType m_SubjFillType;
|
||||
bool m_ReverseOutput;
|
||||
bool m_UsingPolyTree;
|
||||
bool m_StrictSimple;
|
||||
#ifdef use_xyz
|
||||
ZFillCallback m_ZFill; // custom callback
|
||||
#endif
|
||||
void SetWindingCount( TEdge& edge );
|
||||
bool IsEvenOddFillType( const TEdge& edge ) const;
|
||||
bool IsEvenOddAltFillType( const TEdge& edge ) const;
|
||||
void InsertLocalMinimaIntoAEL( const cInt botY );
|
||||
void InsertEdgeIntoAEL( TEdge* edge, TEdge* startEdge );
|
||||
void AddEdgeToSEL( TEdge* edge );
|
||||
bool PopEdgeFromSEL( TEdge*& edge );
|
||||
void CopyAELToSEL();
|
||||
void DeleteFromSEL( TEdge* e );
|
||||
void SwapPositionsInSEL( TEdge* edge1, TEdge* edge2 );
|
||||
bool IsContributing( const TEdge& edge ) const;
|
||||
bool IsTopHorz( const cInt XPos );
|
||||
void DoMaxima( TEdge* e );
|
||||
void ProcessHorizontals();
|
||||
void ProcessHorizontal( TEdge* horzEdge );
|
||||
void AddLocalMaxPoly( TEdge* e1, TEdge* e2, const IntPoint& pt );
|
||||
OutPt* AddLocalMinPoly( TEdge* e1, TEdge* e2, const IntPoint& pt );
|
||||
OutRec* GetOutRec( int idx );
|
||||
void AppendPolygon( TEdge* e1, TEdge* e2 );
|
||||
void IntersectEdges( TEdge* e1, TEdge* e2, IntPoint& pt );
|
||||
OutPt* AddOutPt( TEdge* e, const IntPoint& pt );
|
||||
OutPt* GetLastOutPt( TEdge* e );
|
||||
bool ProcessIntersections( const cInt topY );
|
||||
void BuildIntersectList( const cInt topY );
|
||||
void ProcessIntersectList();
|
||||
void ProcessEdgesAtTopOfScanbeam( const cInt topY );
|
||||
void BuildResult( Paths& polys );
|
||||
void BuildResult2( PolyTree& polytree );
|
||||
void SetHoleState( TEdge* e, OutRec* outrec );
|
||||
void DisposeIntersectNodes();
|
||||
bool FixupIntersectionOrder();
|
||||
void FixupOutPolygon( OutRec& outrec );
|
||||
void FixupOutPolyline( OutRec& outrec );
|
||||
bool IsHole( TEdge* e );
|
||||
bool FindOwnerFromSplitRecs( OutRec& outRec, OutRec*& currOrfl );
|
||||
void FixHoleLinkage( OutRec& outrec );
|
||||
void AddJoin( OutPt* op1, OutPt* op2, const IntPoint offPt );
|
||||
void ClearJoins();
|
||||
void ClearGhostJoins();
|
||||
void AddGhostJoin( OutPt* op, const IntPoint offPt );
|
||||
bool JoinPoints( Join* j, OutRec* outRec1, OutRec* outRec2 );
|
||||
void JoinCommonEdges();
|
||||
void DoSimplePolygons();
|
||||
void FixupFirstLefts1( OutRec* OldOutRec, OutRec* NewOutRec );
|
||||
void FixupFirstLefts2( OutRec* InnerOutRec, OutRec* OuterOutRec );
|
||||
void FixupFirstLefts3( OutRec* OldOutRec, OutRec* NewOutRec );
|
||||
|
||||
#ifdef use_xyz
|
||||
void SetZ( IntPoint& pt, TEdge& e1, TEdge& e2 );
|
||||
|
||||
#endif
|
||||
};
|
||||
// ------------------------------------------------------------------------------
|
||||
|
||||
class ClipperOffset
|
||||
{
|
||||
public:
|
||||
ClipperOffset( double miterLimit = 2.0, double roundPrecision = 0.25 );
|
||||
~ClipperOffset();
|
||||
void AddPath( const Path& path, JoinType joinType, EndType endType );
|
||||
void AddPaths( const Paths& paths, JoinType joinType, EndType endType );
|
||||
void Execute( Paths& solution, double delta );
|
||||
void Execute( PolyTree& solution, double delta );
|
||||
void Clear();
|
||||
|
||||
double MiterLimit;
|
||||
JoinType MiterFallback;
|
||||
double ArcTolerance;
|
||||
|
||||
private:
|
||||
Paths m_destPolys;
|
||||
Path m_srcPoly;
|
||||
Path m_destPoly;
|
||||
std::vector<DoublePoint> m_normals;
|
||||
double m_delta, m_sinA, m_sin, m_cos;
|
||||
double m_miterLim, m_StepsPerRad;
|
||||
IntPoint m_lowest;
|
||||
PolyNode m_polyNodes;
|
||||
|
||||
void FixOrientations();
|
||||
void DoOffset( double delta );
|
||||
void OffsetPoint( int j, int& k, JoinType jointype );
|
||||
void DoSquare( int j, int k );
|
||||
void DoMiter( int j, int k, double r );
|
||||
void DoRound( int j, int k );
|
||||
};
|
||||
// ------------------------------------------------------------------------------
|
||||
|
||||
class clipperException : public std::exception
|
||||
{
|
||||
public:
|
||||
clipperException( const char* description ) : m_descr( description ) {}
|
||||
virtual ~clipperException() throw() {}
|
||||
virtual const char* what() const throw()override { return m_descr.c_str(); }
|
||||
|
||||
private:
|
||||
std::string m_descr;
|
||||
};
|
||||
// ------------------------------------------------------------------------------
|
||||
} // ClipperLib namespace
|
||||
|
||||
#endif // clipper_hpp
|
Loading…
x
Reference in New Issue
Block a user