Polygon boolean operations on SHAPE_POLY_SET: Add a parameter (aFastMode) to speed up calculations. By default, the transforms use an option to create stricly simple polygons.
In 3D viewer, this option can take a *very long* calculation time (minutes instead of seconds, or hangs) and they are now using aFastMode = true to do polygon calculations, especially for zones inside zones belong to the same net but having different priority (which creates weak polygons). aFastMode = false is the default for other calculations (zone filling) as before.
This commit is contained in:
parent
cc2fe47c95
commit
c63f6aa3c5
|
@ -61,6 +61,7 @@
|
||||||
#include <reporter.h>
|
#include <reporter.h>
|
||||||
|
|
||||||
|
|
||||||
|
extern bool useFastModeForPolygons;
|
||||||
|
|
||||||
/* returns the Z orientation parameter 1.0 or -1.0 for aLayer
|
/* returns the Z orientation parameter 1.0 or -1.0 for aLayer
|
||||||
* Z orientation is 1.0 for all layers but "back" layers:
|
* Z orientation is 1.0 for all layers but "back" layers:
|
||||||
|
@ -702,7 +703,7 @@ void EDA_3D_CANVAS::buildBoard3DAuxLayers( REPORTER* aErrorMessages, REPORTER* a
|
||||||
if( bufferPolys.IsEmpty() )
|
if( bufferPolys.IsEmpty() )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
bufferPolys.Fracture();
|
bufferPolys.Simplify( useFastModeForPolygons );
|
||||||
|
|
||||||
int thickness = GetPrm3DVisu().GetLayerObjectThicknessBIU( layer );
|
int thickness = GetPrm3DVisu().GetLayerObjectThicknessBIU( layer );
|
||||||
int zpos = GetPrm3DVisu().GetLayerZcoordBIU( layer );
|
int zpos = GetPrm3DVisu().GetLayerZcoordBIU( layer );
|
||||||
|
|
|
@ -63,6 +63,15 @@
|
||||||
#include <CImage.h>
|
#include <CImage.h>
|
||||||
#include <reporter.h>
|
#include <reporter.h>
|
||||||
|
|
||||||
|
// An option for all operations on polygons:
|
||||||
|
// when useFastModeForPolygons = true, calculations can be *a lot* faster.
|
||||||
|
// but created polygons can be not stricty simple (can share edges)
|
||||||
|
// Although stricty simple are better for glu tesselation functions, I do not see
|
||||||
|
// any issue when allowing not stricty simple polygons.
|
||||||
|
// But I see *very* long calculations when setting useFastMode to false.
|
||||||
|
// So, be careful if changing thie option
|
||||||
|
bool useFastModeForPolygons = true;
|
||||||
|
|
||||||
/* returns the Z orientation parameter 1.0 or -1.0 for aLayer
|
/* returns the Z orientation parameter 1.0 or -1.0 for aLayer
|
||||||
* Z orientation is 1.0 for all layers but "back" layers:
|
* Z orientation is 1.0 for all layers but "back" layers:
|
||||||
* B_Cu , B_Adhes, B_Paste ), B_SilkS
|
* B_Cu , B_Adhes, B_Paste ), B_SilkS
|
||||||
|
@ -139,7 +148,7 @@ void EDA_3D_CANVAS::buildBoardThroughHolesPolygonList( SHAPE_POLY_SET& allBoardH
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
allBoardHoles.Simplify();
|
allBoardHoles.Simplify( useFastModeForPolygons );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -314,11 +323,11 @@ void EDA_3D_CANVAS::buildBoard3DView( GLuint aBoardList, GLuint aBodyOnlyList,
|
||||||
if( currLayerHoles.OutlineCount() )
|
if( currLayerHoles.OutlineCount() )
|
||||||
{
|
{
|
||||||
currLayerHoles.Append(allLayerHoles);
|
currLayerHoles.Append(allLayerHoles);
|
||||||
currLayerHoles.Simplify();
|
currLayerHoles.Simplify( useFastModeForPolygons );
|
||||||
bufferPolys.BooleanSubtract( currLayerHoles );
|
bufferPolys.BooleanSubtract( currLayerHoles, useFastModeForPolygons );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
bufferPolys.BooleanSubtract( allLayerHoles );
|
bufferPolys.BooleanSubtract( allLayerHoles, useFastModeForPolygons );
|
||||||
|
|
||||||
int thickness = GetPrm3DVisu().GetLayerObjectThicknessBIU( layer );
|
int thickness = GetPrm3DVisu().GetLayerObjectThicknessBIU( layer );
|
||||||
int zpos = GetPrm3DVisu().GetLayerZcoordBIU( layer );
|
int zpos = GetPrm3DVisu().GetLayerZcoordBIU( layer );
|
||||||
|
@ -414,7 +423,7 @@ void EDA_3D_CANVAS::buildBoard3DView( GLuint aBoardList, GLuint aBodyOnlyList,
|
||||||
zpos += (copper_thickness + epsilon) / 2.0f;
|
zpos += (copper_thickness + epsilon) / 2.0f;
|
||||||
board_thickness -= copper_thickness + epsilon;
|
board_thickness -= copper_thickness + epsilon;
|
||||||
|
|
||||||
bufferPcbOutlines.BooleanSubtract( allLayerHoles );
|
bufferPcbOutlines.BooleanSubtract( allLayerHoles, useFastModeForPolygons );
|
||||||
|
|
||||||
if( !bufferPcbOutlines.IsEmpty() )
|
if( !bufferPcbOutlines.IsEmpty() )
|
||||||
{
|
{
|
||||||
|
@ -574,15 +583,15 @@ void EDA_3D_CANVAS::buildTechLayers3DView( REPORTER* aErrorMessages, REPORTER* a
|
||||||
bufferPolys = bufferPcbOutlines;
|
bufferPolys = bufferPcbOutlines;
|
||||||
|
|
||||||
cuts.Append(allLayerHoles);
|
cuts.Append(allLayerHoles);
|
||||||
cuts.Simplify();
|
cuts.Simplify( useFastModeForPolygons );
|
||||||
|
|
||||||
bufferPolys.BooleanSubtract( cuts );
|
bufferPolys.BooleanSubtract( cuts, useFastModeForPolygons );
|
||||||
}
|
}
|
||||||
// Remove holes from Solder paste layers and silkscreen
|
// Remove holes from Solder paste layers and silkscreen
|
||||||
else if( layer == B_Paste || layer == F_Paste
|
else if( layer == B_Paste || layer == F_Paste
|
||||||
|| layer == B_SilkS || layer == F_SilkS )
|
|| layer == B_SilkS || layer == F_SilkS )
|
||||||
{
|
{
|
||||||
bufferPolys.BooleanSubtract( allLayerHoles );
|
bufferPolys.BooleanSubtract( allLayerHoles, useFastModeForPolygons );
|
||||||
}
|
}
|
||||||
|
|
||||||
int thickness = 0;
|
int thickness = 0;
|
||||||
|
|
|
@ -208,10 +208,12 @@ const SHAPE_LINE_CHAIN SHAPE_POLY_SET::convertFromClipper( const Path& aPath )
|
||||||
|
|
||||||
#include <common.h>
|
#include <common.h>
|
||||||
#include <wx/wx.h>
|
#include <wx/wx.h>
|
||||||
void SHAPE_POLY_SET::booleanOp( ClipType type, const SHAPE_POLY_SET& b )
|
void SHAPE_POLY_SET::booleanOp( ClipType aType, const SHAPE_POLY_SET& aOtherShape,
|
||||||
|
bool aFastMode )
|
||||||
{
|
{
|
||||||
Clipper c;
|
Clipper c;
|
||||||
|
|
||||||
|
if( !aFastMode )
|
||||||
c.StrictlySimple( true );
|
c.StrictlySimple( true );
|
||||||
|
|
||||||
BOOST_FOREACH( const POLYGON& poly, m_polys )
|
BOOST_FOREACH( const POLYGON& poly, m_polys )
|
||||||
|
@ -220,7 +222,7 @@ void SHAPE_POLY_SET::booleanOp( ClipType type, const SHAPE_POLY_SET& b )
|
||||||
c.AddPath( convertToClipper( poly[i], i > 0 ? false : true ), ptSubject, true );
|
c.AddPath( convertToClipper( poly[i], i > 0 ? false : true ), ptSubject, true );
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_FOREACH( const POLYGON& poly, b.m_polys )
|
BOOST_FOREACH( const POLYGON& poly, aOtherShape.m_polys )
|
||||||
{
|
{
|
||||||
for( unsigned int i = 0; i < poly.size(); i++ )
|
for( unsigned int i = 0; i < poly.size(); i++ )
|
||||||
c.AddPath( convertToClipper( poly[i], i > 0 ? false : true ), ptClip, true );
|
c.AddPath( convertToClipper( poly[i], i > 0 ? false : true ), ptClip, true );
|
||||||
|
@ -228,21 +230,21 @@ void SHAPE_POLY_SET::booleanOp( ClipType type, const SHAPE_POLY_SET& b )
|
||||||
|
|
||||||
PolyTree solution;
|
PolyTree solution;
|
||||||
|
|
||||||
c.Execute( type, solution, pftNonZero, pftNonZero );
|
c.Execute( aType, solution, pftNonZero, pftNonZero );
|
||||||
|
|
||||||
importTree( &solution );
|
importTree( &solution );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SHAPE_POLY_SET::BooleanAdd( const SHAPE_POLY_SET& b )
|
void SHAPE_POLY_SET::BooleanAdd( const SHAPE_POLY_SET& b, bool aFastMode )
|
||||||
{
|
{
|
||||||
booleanOp( ctUnion, b );
|
booleanOp( ctUnion, b, aFastMode );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SHAPE_POLY_SET::BooleanSubtract( const SHAPE_POLY_SET& b )
|
void SHAPE_POLY_SET::BooleanSubtract( const SHAPE_POLY_SET& b, bool aFastMode )
|
||||||
{
|
{
|
||||||
booleanOp( ctDifference, b );
|
booleanOp( ctDifference, b, aFastMode );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -496,9 +498,9 @@ void SHAPE_POLY_SET::fractureSingle( POLYGON& paths )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SHAPE_POLY_SET::Fracture()
|
void SHAPE_POLY_SET::Fracture( bool aFastMode )
|
||||||
{
|
{
|
||||||
Simplify(); // remove overlapping holes/degeneracy
|
Simplify( aFastMode ); // remove overlapping holes/degeneracy
|
||||||
|
|
||||||
BOOST_FOREACH( POLYGON& paths, m_polys )
|
BOOST_FOREACH( POLYGON& paths, m_polys )
|
||||||
{
|
{
|
||||||
|
@ -507,11 +509,11 @@ void SHAPE_POLY_SET::Fracture()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SHAPE_POLY_SET::Simplify()
|
void SHAPE_POLY_SET::Simplify( bool aFastMode )
|
||||||
{
|
{
|
||||||
SHAPE_POLY_SET empty;
|
SHAPE_POLY_SET empty;
|
||||||
|
|
||||||
booleanOp( ctUnion, empty );
|
booleanOp( ctUnion, empty, aFastMode );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -54,7 +54,8 @@ class SHAPE_POLY_SET : public SHAPE
|
||||||
* Base class for iterating over all vertices in a given SHAPE_POLY_SET
|
* Base class for iterating over all vertices in a given SHAPE_POLY_SET
|
||||||
*/
|
*/
|
||||||
template <class T>
|
template <class T>
|
||||||
class ITERATOR_TEMPLATE {
|
class ITERATOR_TEMPLATE
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
bool IsEndContour() const
|
bool IsEndContour() const
|
||||||
|
@ -245,17 +246,21 @@ class SHAPE_POLY_SET : public SHAPE
|
||||||
|
|
||||||
|
|
||||||
///> Performs boolean polyset union
|
///> Performs boolean polyset union
|
||||||
void BooleanAdd( const SHAPE_POLY_SET& b );
|
///> For aFastMode meaning, see function booleanOp
|
||||||
|
|
||||||
|
void BooleanAdd( const SHAPE_POLY_SET& b, bool aFastMode = false );
|
||||||
|
|
||||||
///> Performs boolean polyset difference
|
///> Performs boolean polyset difference
|
||||||
void BooleanSubtract( const SHAPE_POLY_SET& b );
|
///> For aFastMode meaning, see function booleanOp
|
||||||
|
void BooleanSubtract( const SHAPE_POLY_SET& b, bool aFastMode = false );
|
||||||
|
|
||||||
///> Performs outline inflation/deflation, using round corners.
|
///> Performs outline inflation/deflation, using round corners.
|
||||||
void Inflate( int aFactor, int aCircleSegmentsCount );
|
void Inflate( int aFactor, int aCircleSegmentsCount );
|
||||||
|
|
||||||
///> Converts a set of polygons with holes to a singe outline with "slits"/"fractures" connecting the outer ring
|
///> Converts a set of polygons with holes to a singe outline with "slits"/"fractures" connecting the outer ring
|
||||||
///> to the inner holes
|
///> to the inner holes
|
||||||
void Fracture();
|
///> For aFastMode meaning, see function booleanOp
|
||||||
|
void Fracture( bool aFastMode = false);
|
||||||
|
|
||||||
///> Converts a set of slitted polygons to a set of polygons with holes
|
///> Converts a set of slitted polygons to a set of polygons with holes
|
||||||
void Unfracture();
|
void Unfracture();
|
||||||
|
@ -264,7 +269,8 @@ class SHAPE_POLY_SET : public SHAPE
|
||||||
bool HasHoles() const;
|
bool HasHoles() const;
|
||||||
|
|
||||||
///> Simplifies the polyset (merges overlapping polys, eliminates degeneracy/self-intersections)
|
///> Simplifies the polyset (merges overlapping polys, eliminates degeneracy/self-intersections)
|
||||||
void Simplify();
|
///> For aFastMode meaning, see function booleanOp
|
||||||
|
void Simplify( bool aFastMode = false);
|
||||||
|
|
||||||
/// @copydoc SHAPE::Format()
|
/// @copydoc SHAPE::Format()
|
||||||
const std::string Format() const;
|
const std::string Format() const;
|
||||||
|
@ -316,7 +322,20 @@ class SHAPE_POLY_SET : public SHAPE
|
||||||
|
|
||||||
void fractureSingle( POLYGON& paths );
|
void fractureSingle( POLYGON& paths );
|
||||||
void importTree( ClipperLib::PolyTree* tree );
|
void importTree( ClipperLib::PolyTree* tree );
|
||||||
void booleanOp( ClipperLib::ClipType type, const SHAPE_POLY_SET& b );
|
|
||||||
|
/** Function booleanOp
|
||||||
|
* this is the engine to execute all polygon boolean transforms
|
||||||
|
* (AND, OR, ... and polygon simplification (merging overlaping polygons)
|
||||||
|
* @param aType is the transform type ( see ClipperLib::ClipType )
|
||||||
|
* @param aOtherShape is the SHAPE_LINE_CHAIN to combine with me.
|
||||||
|
* @param aFastMode is an option to choos if the result is a weak polygon
|
||||||
|
* or a stricty simple polygon.
|
||||||
|
* if aFastMode is true (default) the result can be a weak polygon
|
||||||
|
* if aFastMode is true (default) the result is (theorically) a strictly
|
||||||
|
* simple polygon, but calculations can be really significantly time consuming
|
||||||
|
*/
|
||||||
|
void booleanOp( ClipperLib::ClipType aType,
|
||||||
|
const SHAPE_POLY_SET& aOtherShape, bool aFastMode = false );
|
||||||
|
|
||||||
bool pointInPolygon( const VECTOR2I& aP, const SHAPE_LINE_CHAIN& aPath ) const;
|
bool pointInPolygon( const VECTOR2I& aP, const SHAPE_LINE_CHAIN& aPath ) const;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue