SHAPE_POLY_SET: split polygons into rectangular cell grids to obtain more regular triangulations
This commit is contained in:
parent
a31c9ae7af
commit
aee06e46b0
|
@ -1900,6 +1900,72 @@ bool SHAPE_POLY_SET::IsTriangulationUpToDate() const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void partitionPolyIntoRegularCellGrid(
|
||||||
|
const SHAPE_POLY_SET& aPoly, int aCells, SHAPE_POLY_SET& aOut )
|
||||||
|
{
|
||||||
|
BOX2I bb = aPoly.BBox();
|
||||||
|
|
||||||
|
double w = bb.GetWidth();
|
||||||
|
double h = bb.GetHeight();
|
||||||
|
|
||||||
|
if( w == 0.0 || h == 0.0 )
|
||||||
|
return;
|
||||||
|
|
||||||
|
int n_cells_x, n_cells_y;
|
||||||
|
|
||||||
|
if( w > h )
|
||||||
|
{
|
||||||
|
n_cells_x = aCells;
|
||||||
|
n_cells_y = (int) floor( h / w * (double) aCells ) + 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
n_cells_x = (int) floor( w / h * (double) aCells ) + 1;
|
||||||
|
n_cells_y = aCells;
|
||||||
|
}
|
||||||
|
|
||||||
|
SHAPE_POLY_SET ps1( aPoly ), ps2( aPoly ), maskSetOdd, maskSetEven;
|
||||||
|
|
||||||
|
for( int yy = 0; yy < n_cells_y; yy++ )
|
||||||
|
for( int xx = 0; xx < n_cells_x; xx++ )
|
||||||
|
{
|
||||||
|
VECTOR2I p;
|
||||||
|
|
||||||
|
p.x = bb.GetX() + w * xx / n_cells_x;
|
||||||
|
p.y = bb.GetY() + h * yy / n_cells_y;
|
||||||
|
|
||||||
|
VECTOR2I p2;
|
||||||
|
|
||||||
|
p2.x = bb.GetX() + w * ( xx + 1 ) / n_cells_x;
|
||||||
|
p2.y = bb.GetY() + h * ( yy + 1 ) / n_cells_y;
|
||||||
|
|
||||||
|
|
||||||
|
SHAPE_LINE_CHAIN mask;
|
||||||
|
mask.Append( VECTOR2I( p.x, p.y ) );
|
||||||
|
mask.Append( VECTOR2I( p2.x, p.y ) );
|
||||||
|
mask.Append( VECTOR2I( p2.x, p2.y ) );
|
||||||
|
mask.Append( VECTOR2I( p.x, p2.y ) );
|
||||||
|
mask.SetClosed( true );
|
||||||
|
|
||||||
|
if( ( xx ^ yy ) & 1 )
|
||||||
|
maskSetOdd.AddOutline( mask );
|
||||||
|
else
|
||||||
|
maskSetEven.AddOutline( mask );
|
||||||
|
}
|
||||||
|
|
||||||
|
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 );
|
||||||
|
|
||||||
|
aOut = ps1;
|
||||||
|
for( int i = 0; i < ps2.OutlineCount(); i++ )
|
||||||
|
{
|
||||||
|
aOut.AddOutline( ps2.COutline( i ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void SHAPE_POLY_SET::CacheTriangulation()
|
void SHAPE_POLY_SET::CacheTriangulation()
|
||||||
{
|
{
|
||||||
bool recalculate = !m_hash.IsValid();
|
bool recalculate = !m_hash.IsValid();
|
||||||
|
@ -1922,10 +1988,9 @@ void SHAPE_POLY_SET::CacheTriangulation()
|
||||||
if( !recalculate )
|
if( !recalculate )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
SHAPE_POLY_SET tmpSet = *this;
|
SHAPE_POLY_SET tmpSet;
|
||||||
|
|
||||||
if( tmpSet.HasHoles() )
|
partitionPolyIntoRegularCellGrid( *this, 20, tmpSet );
|
||||||
tmpSet.Fracture( PM_FAST );
|
|
||||||
|
|
||||||
m_triangulatedPolys.clear();
|
m_triangulatedPolys.clear();
|
||||||
m_triangulationValid = true;
|
m_triangulationValid = true;
|
||||||
|
|
Loading…
Reference in New Issue