22
33#include " shape/offset.hpp"
44#include " shape/extract_borders.hpp"
5+ #include " shape/self_intersections_removal.hpp"
56
67#include < sstream>
78
@@ -432,6 +433,49 @@ void InstanceBuilder::read(
432433// ////////////////////////////////// Build /////////////////////////////////////
433434// //////////////////////////////////////////////////////////////////////////////
434435
436+ namespace
437+ {
438+
439+ std::pair<Shape, std::vector<Shape>> process_shape_outer (
440+ const Shape& shape)
441+ {
442+ bool outer = true ;
443+ Shape shape_tmp = shape::approximate_by_line_segments (shape, 1 , outer);
444+ for (int i;; ++i) {
445+ if (i == 100 ) {
446+ throw std::runtime_error (
447+ " packingsolver::irregular::process_shape_outer: "
448+ " too many iterations." );
449+ }
450+ auto res = shape::clean_extreme_slopes (shape_tmp, outer);
451+ if (!res.first )
452+ break ;
453+ shape_tmp = res.second ;
454+ }
455+ return shape::remove_self_intersections (shape_tmp);
456+ }
457+
458+ std::vector<Shape> process_shape_inner (
459+ const Shape& shape)
460+ {
461+ bool outer = false ;
462+ Shape shape_tmp = shape::approximate_by_line_segments (shape, 1 , outer);
463+ for (int i = 0 ;; ++i) {
464+ if (i == 100 ) {
465+ throw std::runtime_error (
466+ " packingsolver::irregular::process_shape_inner: "
467+ " too many iterations." );
468+ }
469+ auto res = shape::clean_extreme_slopes (shape_tmp, outer);
470+ if (!res.first )
471+ break ;
472+ shape_tmp = res.second ;
473+ }
474+ return shape::extract_all_holes_from_self_intersecting_hole (shape_tmp);
475+ }
476+
477+ }
478+
435479Instance InstanceBuilder::build ()
436480{
437481 // Compute scale value.
@@ -466,9 +510,17 @@ Instance InstanceBuilder::build()
466510 ItemShape& item_shape = item_type.shapes [shape_pos];
467511 if (!item_shape.shape_scaled .elements .empty ())
468512 continue ;
469- item_shape.shape_scaled = instance_.parameters ().scale_value * item_shape.shape_orig ;
470- for (const Shape& hole: item_shape.holes_orig )
471- item_shape.holes_scaled .push_back (instance_.parameters ().scale_value * hole);
513+
514+ auto res = process_shape_outer (instance_.parameters ().scale_value * item_shape.shape_orig );
515+ item_shape.shape_scaled = res.first ;
516+ for (const Shape& hole: res.second )
517+ item_shape.holes_scaled .push_back (hole);
518+
519+ for (const Shape& hole: item_shape.holes_orig ) {
520+ auto res = process_shape_inner (instance_.parameters ().scale_value * hole);
521+ for (const Shape& hole: res)
522+ item_shape.holes_scaled .push_back (hole);
523+ }
472524 }
473525
474526 // Compute inflated shapes.
@@ -478,18 +530,22 @@ Instance InstanceBuilder::build()
478530 ItemShape& item_shape = item_type.shapes [shape_pos];
479531 if (!item_shape.shape_inflated .elements .empty ())
480532 continue ;
481- auto inflated_item_shape = inflate (
533+ auto shape_tmp_0 = inflate (
482534 item_shape.shape_scaled ,
483- instance_.parameters ().scale_value * instance_.parameters ().item_item_minimum_spacing );
484- item_shape.shape_inflated = inflated_item_shape.first ;
485- for (const Shape& hole: inflated_item_shape.second )
535+ instance_.parameters ().scale_value * instance_.parameters ().item_item_minimum_spacing ,
536+ false );
537+ auto res = process_shape_outer (shape_tmp_0.first );
538+ item_shape.shape_inflated = res.first ;
539+ for (const Shape& hole: res.second )
486540 item_shape.holes_deflated .push_back (hole);
487541
488542 for (const Shape& hole: item_shape.holes_scaled ) {
489- auto deflated_hole = deflate (
543+ auto shape_tmp_0 = deflate (
490544 hole,
491- instance_.parameters ().scale_value * instance_.parameters ().item_item_minimum_spacing );
492- for (const Shape& hole: deflated_hole)
545+ instance_.parameters ().scale_value * instance_.parameters ().item_item_minimum_spacing ,
546+ false );
547+ auto res = process_shape_inner (shape_tmp_0.front ());
548+ for (const Shape& hole: res)
493549 item_shape.holes_deflated .push_back (hole);
494550 }
495551 }
@@ -545,9 +601,16 @@ Instance InstanceBuilder::build()
545601 if (bin_type.shape_scaled .elements .empty ()) {
546602 bin_type.shape_scaled = instance_.parameters ().scale_value * bin_type.shape_orig ;
547603 for (Defect& defect: bin_type.defects ) {
548- defect.shape_scaled = instance_.parameters ().scale_value * defect.shape_orig ;
549- for (const Shape& hole: defect.holes_orig )
550- defect.holes_scaled .push_back (instance_.parameters ().scale_value * hole);
604+ auto res = process_shape_outer (instance_.parameters ().scale_value * defect.shape_orig );
605+ defect.shape_scaled = res.first ;
606+ for (const Shape& hole: res.second )
607+ defect.holes_scaled .push_back (hole);
608+
609+ for (const Shape& hole: defect.holes_orig ) {
610+ auto res = process_shape_inner (instance_.parameters ().scale_value * hole);
611+ for (const Shape& hole: res)
612+ defect.holes_scaled .push_back (hole);
613+ }
551614 }
552615 }
553616
@@ -556,34 +619,42 @@ Instance InstanceBuilder::build()
556619 if (!defect.shape_inflated .elements .empty ())
557620 continue ;
558621
559- auto inflated_defect_shape = inflate (
622+ auto shape_tmp_0 = inflate (
560623 defect.shape_scaled ,
561- instance_.parameters ().scale_value * instance_.parameters ().item_bin_minimum_spacing );
562- defect.shape_inflated = inflated_defect_shape.first ;
563- for (const Shape& hole: inflated_defect_shape.second )
624+ instance_.parameters ().scale_value * instance_.parameters ().item_bin_minimum_spacing ,
625+ false );
626+ auto res = process_shape_outer (shape_tmp_0.first );
627+ defect.shape_inflated = res.first ;
628+ for (const Shape& hole: res.second )
564629 defect.holes_deflated .push_back (hole);
565630
566631 for (const Shape& hole: defect.holes_scaled ) {
567- auto deflated_hole = deflate (
632+ auto shape_tmp_0 = deflate (
568633 hole,
569- instance_.parameters ().scale_value * instance_.parameters ().item_bin_minimum_spacing );
570- for (const Shape& hole: deflated_hole)
634+ instance_.parameters ().scale_value * instance_.parameters ().item_bin_minimum_spacing ,
635+ false );
636+ auto res = process_shape_inner (shape_tmp_0.front ());
637+ for (const Shape& hole: res)
571638 defect.holes_deflated .push_back (hole);
572639 }
573640 }
574641
575642 // Compute inflated borders.
576643 if (bin_type.borders .empty ()) {
577644 for (const Shape& shape_border: extract_borders (bin_type.shape_scaled )) {
578- auto inflated_shape_border = inflate (
579- shape_border,
580- instance_.parameters ().scale_value * instance_.parameters ().item_bin_minimum_spacing );
581645 Defect border;
582646 border.type = -2 ;
583647 border.shape_scaled = shape_border;
584- border.shape_inflated = inflated_shape_border.first ;
585- for (const Shape& hole: inflated_shape_border.second )
648+
649+ auto shape_tmp_0 = inflate (
650+ shape_border,
651+ instance_.parameters ().scale_value * instance_.parameters ().item_bin_minimum_spacing ,
652+ false );
653+ auto res = process_shape_outer (shape_tmp_0.first );
654+ border.shape_inflated = res.first ;
655+ for (const Shape& hole: res.second )
586656 border.holes_deflated .push_back (hole);
657+
587658 bin_type.borders .push_back (border);
588659 }
589660 }
0 commit comments