diff --git a/include/poly_ops/clip.hpp b/include/poly_ops/clip.hpp index ad95cdf..390c229 100644 --- a/include/poly_ops/clip.hpp +++ b/include/poly_ops/clip.hpp @@ -1820,6 +1820,7 @@ template class clipper { Index s2, i_point_tracker *pt); void add_fb_events(Index sa,Index sb); + Index insert_anchor_point(Index i); void do_op(bool_op op,i_point_tracker *pt,bool TreeOut); template R> void _add_loop(R &&loop,bool_set cat,i_point_tracker *pt) { @@ -2271,6 +2272,19 @@ void clipper::calc_line_bal(bool_op op) { } } +template +Index clipper::insert_anchor_point(Index i) { + if(!(lpoints[lpoints[i].next].state() & detail::line_state::anchor)) { + Index new_i = Index(lpoints.size()); + lpoints.push_back(lpoints[i]); + lpoints.back().state() = detail::line_state::anchor_undef; + lpoints[i].next = new_i; + + POLY_OPS_DEBUG_LOG("Adding anchor point {} after {}",new_i,i); + } + return lpoints[i].next; +} + template void clipper::do_op(bool_op op,i_point_tracker *pt,bool tree_out) { using namespace detail; @@ -2293,22 +2307,18 @@ void clipper::do_op(bool_op op,i_point_tracker *pt,bool tree overlapping line segments changing in the next few steps */ if(tree_out) { for(auto &intr : samples) { - for(Index &i : intr.hits) { - if(!(lpoints[lpoints[i].next].state() & line_state::anchor)) { - Index new_i = Index(lpoints.size()); - lpoints.push_back(lpoints[i]); - lpoints.back().state() = line_state::anchor_undef; - lpoints[i].next = new_i; - - POLY_OPS_DEBUG_LOG("Adding anchor point {} after {}",new_i,i); - } - i = lpoints[i].next; - } + for(Index &i : intr.hits) i = insert_anchor_point(i); + } + for(auto &intr : samples) { + follow_balance( + lpoints, + std::exchange(intr.p,insert_anchor_point(intr.p)), + breaks,pt); + } + } else { + for(auto &intr : samples) { + follow_balance(lpoints,intr.p,breaks,pt); } - } - - for(auto &intr : samples) { - follow_balance(lpoints,intr.p,breaks,pt); } /* match all the orphan points to virtual points to make the virtual into diff --git a/tests/misc_tests.cpp b/tests/misc_tests.cpp index ec631a8..28afd57 100644 --- a/tests/misc_tests.cpp +++ b/tests/misc_tests.cpp @@ -34,6 +34,32 @@ void sort_by_size(auto &x) { std::ranges::sort(x,{},[](auto &item) { return item.items.size(); }); } +void for_each_combination( + std::span>> input, + auto &&fun, + std::vector>> &buffer) +{ + if(input.empty()) fun(buffer); + else { + std::vector>> current; + current.reserve(input.size()-1); + for(std::size_t i=0; i>> input,auto &&fun) +{ + std::vector>> buffer; + buffer.reserve(input.size()); + for_each_combination(input,fun,buffer); +} + int main() { using namespace boost::ut; @@ -63,10 +89,13 @@ int main() { {230,255} }}; - /* This shape should decompose into exactly 10 shapes and 0 holes */ - auto out = poly_ops::normalize_op(loops); - expect(out.size() == 10_u); - expect(std::ranges::all_of(out,[](auto loop) { return loop.inner_loops().size() == 0; })); + std::vector>> current{loops.begin(),loops.end()}; + for_each_combination(current,[](auto &data) { + /* This shape should decompose into exactly 10 shapes and 0 holes */ + auto out = poly_ops::normalize_op(data); + expect(out.size() == 10_u); + expect(std::ranges::all_of(out,[](auto loop) { return loop.inner_loops().size() == 0; })); + }); }; "Test nesting"_test = [] {