36 wxASSERT( aSegments.size() >= 3 );
39 unsigned int j = aSegments.size() - 1;
40 bool oddNodes =
false;
42 for( i = 0; i < aSegments.size(); j = i++ )
44 const float polyJY = aSegments[j].m_Start.y;
45 const float polyIY = aSegments[i].m_Start.y;
47 if( ( ( polyIY <= aPoint.y ) && ( polyJY >= aPoint.y ) )
48 || ( ( polyJY <= aPoint.y ) && ( polyIY >= aPoint.y ) ) )
50 const float polyJX = aSegments[j].m_Start.x;
51 const float polyIX = aSegments[i].m_Start.x;
53 if( ( polyIX <= aPoint.x ) || ( polyJX <= aPoint.x ) )
54 oddNodes ^= ( ( polyIX + ( ( aPoint.y - polyIY ) * aSegments[i].m_inv_JY_minus_IY )
55 * aSegments[i].m_JX_minus_IX )
379 float aBiuTo3dUnitsScale,
float aDivFactor,
380 const BOARD_ITEM& aBoardItem,
int aPolyIndex )
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 ) );
569 if( extractedSegments.empty() )
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 ) } );
621 outersAndHoles.
m_Holes.clear();
624 for(
int idx = 0; idx < solution.
OutlineCount(); idx++ )
631 outersAndHoles.
m_Outers.push_back( solutionSegment );
633 stats_sum_size_of_polygons += solutionSegment.size();
635 for(
int holeIdx = 0; holeIdx < solution.
HoleCount( idx ); holeIdx++ )
640 outersAndHoles.
m_Holes.push_back( solutionSegment );
641 stats_sum_size_of_polygons += solutionSegment.size();
645 if( !outersAndHoles.
m_Outers.empty() )
647 aDstContainer.
Add(
new POLYGON_2D( extractedSegments, outersAndHoles,
649 stats_n_poly_blocks++;
653 blockX += blockAdvance.x;
654 leftToRight += leftToRight_inc;
657 blockY -= blockAdvance.y;
658 topToBottom += topToBottom_inc;