Use a polygon in the format of the ClipperLib::Path and process it and create multiple 2d objects (POLYGON_2D and DUMMY_BLOCK_2D) that can be used to represent this polygon area.
399 segments_and_normals.reserve(
path.PointCount() );
400 segments.reserve(
path.PointCount() );
404 for(
int i = 0; i <
path.PointCount(); i++ )
408 const SFVEC2F point( (
float) ( a.
x ) * aBiuTo3dUnitsScale,
409 (
float) ( -a.
y ) * aBiuTo3dUnitsScale );
412 if( ( i == 0 ) || ( fabs( prevPoint.x - point.x ) > FLT_EPSILON )
413 || ( fabs( prevPoint.y - point.y ) > FLT_EPSILON ) )
421 segments_and_normals.push_back( sn );
425 segments.push_back( ps );
433 unsigned int j = segments_and_normals.size() - 1;
436 std::vector<SFVEC2F> tmpSegmentNormals;
437 tmpSegmentNormals.resize( segments_and_normals.size() );
439 float medOfTheSquaresSegmentLength = 0.0f;
441 #ifdef PRINT_STATISTICS_3D_VIEWER 442 float minLength = FLT_MAX;
445 for( i = 0; i < segments_and_normals.size(); j = i++ )
447 const SFVEC2F slope = segments_and_normals[j].m_Start - segments_and_normals[i].m_Start;
449 segments_and_normals[i].m_Precalc_slope = slope;
452 segments[i].m_inv_JY_minus_IY =
453 1.0f / ( segments_and_normals[j].m_Start.y - segments_and_normals[i].m_Start.y );
455 segments[i].m_JX_minus_IX =
456 ( segments_and_normals[j].m_Start.x - segments_and_normals[i].m_Start.x );
460 tmpSegmentNormals[i] = glm::normalize(
SFVEC2F( slope.y, -slope.x ) );
462 const float length = slope.x * slope.x + slope.y * slope.y;
464 #ifdef PRINT_STATISTICS_3D_VIEWER 465 if( length < minLength )
469 medOfTheSquaresSegmentLength += length;
472 #ifdef PRINT_STATISTICS_3D_VIEWER 473 float minSegmentLength = sqrt( minLength );
478 medOfTheSquaresSegmentLength /= segments_and_normals.size();
479 medOfTheSquaresSegmentLength = sqrt( medOfTheSquaresSegmentLength );
485 j = segments_and_normals.size() - 1;
487 for( i = 0; i < segments_and_normals.size(); j = i++ )
489 const SFVEC2F normalBeforeSeg = tmpSegmentNormals[j];
490 const SFVEC2F normalSeg = tmpSegmentNormals[i];
491 const SFVEC2F normalAfterSeg = tmpSegmentNormals[( i + 1 ) % segments_and_normals.size()];
493 const float dotBefore = glm::dot( normalBeforeSeg, normalSeg );
494 const float dotAfter = glm::dot( normalAfterSeg, normalSeg );
496 if( dotBefore < 0.7f )
497 segments_and_normals[i].m_Normals.m_Start = normalSeg;
499 segments_and_normals[i].m_Normals.m_Start =
500 glm::normalize( ( normalBeforeSeg * dotBefore ) + normalSeg );
502 if( dotAfter < 0.7f )
503 segments_and_normals[i].m_Normals.m_End = normalSeg;
505 segments_and_normals[i].m_Normals.m_End =
506 glm::normalize( ( normalAfterSeg * dotAfter ) + normalSeg );
511 if( aDivFactor < 0.0f )
517 if( aDivFactor <= FLT_EPSILON )
518 aDivFactor = medOfTheSquaresSegmentLength;
520 grid_divisions.x = (
unsigned int) ( ( bbox.
GetExtent().x / aDivFactor ) );
521 grid_divisions.y = (
unsigned int) ( ( bbox.
GetExtent().y / aDivFactor ) );
523 grid_divisions = glm::clamp(
530 blockAdvance.x = bbox.
GetExtent().x / (float) grid_divisions.x;
531 blockAdvance.y = bbox.
GetExtent().y / (float) grid_divisions.y;
533 wxASSERT( blockAdvance.x > 0.0f );
534 wxASSERT( blockAdvance.y > 0.0f );
536 const int leftToRight_inc = ( pathBounds.
GetRight() - pathBounds.
GetLeft() ) / grid_divisions.x;
538 const int topToBottom_inc = ( pathBounds.
GetBottom() - pathBounds.
GetTop() ) / grid_divisions.y;
541 unsigned int stats_n_empty_blocks = 0;
542 unsigned int stats_n_dummy_blocks = 0;
543 unsigned int stats_n_poly_blocks = 0;
544 unsigned int stats_sum_size_of_polygons = 0;
547 int topToBottom = pathBounds.
GetTop();
548 float blockY = bbox.
Max().y;
550 for(
unsigned int iy = 0; iy < grid_divisions.y; iy++ )
552 int leftToRight = pathBounds.
GetLeft();
553 float blockX = bbox.
Min().x;
555 for(
unsigned int ix = 0; ix < grid_divisions.x; ix++ )
558 SFVEC2F( blockX + blockAdvance.x, blockY ) );
561 blockBox.ScaleNextUp();
562 blockBox.ScaleNextUp();
563 blockBox.ScaleNextUp();
569 if( extractedSegments.empty() )
572 SFVEC2F p1( blockBox.Min().x, blockBox.Min().y );
573 SFVEC2F p2( blockBox.Max().x, blockBox.Min().y );
574 SFVEC2F p3( blockBox.Max().x, blockBox.Max().y );
575 SFVEC2F p4( blockBox.Min().x, blockBox.Max().y );
586 stats_n_dummy_blocks++;
592 stats_n_empty_blocks++;
606 VECTOR2I( leftToRight + leftToRight_inc, topToBottom ),
607 VECTOR2I( leftToRight + leftToRight_inc, topToBottom + topToBottom_inc ),
608 VECTOR2I( leftToRight, topToBottom + topToBottom_inc ) } );
622 outersAndHoles.
m_Holes.clear();
625 for(
int idx = 0; idx < solution.
OutlineCount(); idx++ )
632 outersAndHoles.
m_Outers.push_back( solutionSegment );
634 stats_sum_size_of_polygons += solutionSegment.size();
636 for(
int holeIdx = 0; holeIdx < solution.
HoleCount( idx ); holeIdx++ )
641 outersAndHoles.
m_Holes.push_back( solutionSegment );
642 stats_sum_size_of_polygons += solutionSegment.size();
646 if( !outersAndHoles.
m_Outers.empty() )
648 aDstContainer.
Add(
new POLYGON_2D( extractedSegments, outersAndHoles,
650 stats_n_poly_blocks++;
654 blockX += blockAdvance.x;
655 leftToRight += leftToRight_inc;
658 blockY -= blockAdvance.y;
659 topToBottom += topToBottom_inc;
int OutlineCount() const
Return the number of vertices in a given outline/hole.
SFVEC2F GetExtent() const
coord_type GetTop() const
Define a general 2D-vector/point.
std::vector< SEGMENT_WITH_NORMALS > SEGMENTS_WIDTH_NORMALS
List used to test ray2d intersections.
coord_type GetRight() const
SHAPE_LINE_CHAIN & Hole(int aOutline, int aHole)
Return the aIndex-th subpolygon in the set.
coord_type GetBottom() const
A 2D bounding box built on top of an origin point and size vector.
static void extractPathsFrom(const SEGMENTS_WIDTH_NORMALS &aSegList, const BBOX_2D &aBBox, SEGMENTS_WIDTH_NORMALS &aOutSegThatIntersect)
void Add(OBJECT_2D *aObject)
const SFVEC2F & Max() const
void SetClosed(bool aClosed)
Mark the line chain as closed (i.e.
void Reset()
Reset the bounding box to zero and uninitialize it.
Represent a set of closed polygons.
SHAPE_LINE_CHAIN & Outline(int aIndex)
static bool polygon_IsPointInside(const SEGMENTS &aSegments, const SFVEC2F &aPoint)
std::vector< SEGMENTS > m_Outers
Handle a subset of a polygon.
static void polygon_Convert(const SHAPE_LINE_CHAIN &aPath, SEGMENTS &aOutSegment, float aBiuTo3dUnitsScale)
Manage a bounding box defined by two SFVEC2F min max points.
void BooleanIntersection(const SHAPE_POLY_SET &b, POLYGON_MODE aFastMode)
Perform boolean polyset union between a and b, store the result in it self For aFastMode meaning,...
int HoleCount(int aOutline) const
Return the reference to aIndex-th outline in the set.
std::vector< SEGMENTS > m_Holes
void Union(const SFVEC2F &aPoint)
Recalculate the bounding box adding a point.
int AddOutline(const SHAPE_LINE_CHAIN &aOutline)
Adds a new hole to the given outline (default: last) and returns its index.
std::vector< POLYSEGMENT > SEGMENTS
const SFVEC2F & Min() const
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
const SHAPE_LINE_CHAIN & COutline(int aIndex) const
void ScaleNextUp()
Scale a bounding box to the next float representation making it larger.
coord_type GetLeft() const
Represent a sub polygon block.
A dummy block defined by a 2d box size.