List <ICuttableEdge> MakeLoop(TopologyIntersection start_from, BopMap map) { var res = new List <ICuttableEdge>(); TopologyIntersection last = start_from; int deadloop = 0; do { if (deadloop++ > DeadloopMaxIters) { Debug.LogError("deadloop"); throw new UnityException("deadloop"); } LoopSegment seg = MakeLoopSegment(last, map); last = seg.end; res.AddRange(seg.edges); } while (last != start_from); // TODO: filter degen loops float total_len = 0; foreach (var edge in res) { total_len += edge.GetLen(); } // strict filter. such loops are useless for camera return(res.Count == 0 || total_len < 1.0e-2 ? null : res); }
LoopSegment MakeLoopSegment(TopologyIntersection start_from, BopMap map) { if (start_from.ToolEdgeEnters) { return(MakeLoopSegment(start_from, map, true, new EdgeIter(map.tool_edges, start_from.ToolEdgeIdx))); } else { return(MakeLoopSegment(start_from, map, false, new EdgeIter(map.target[start_from.LoopIdx], start_from.TargetEdgeIdx))); } }
public Face2D Intersect(Face2D target, List <ICuttableEdge> tool) { // 1. for each edge determine if intersection number is even, then find these intersections. // Then make new loops. // TODO : loops without intersections IList <TopologyIntersection> intersections = /*FilterIntersections(*/ FindAllIntersections(target, tool) /*, target, tool )*/; List <bool> loop_has_intersections = new List <bool>(target.Loops.Count); for (int i = 0; i < target.Loops.Count; ++i) { loop_has_intersections.Add(false); } List <List <ICuttableEdge> > new_loops = new List <List <ICuttableEdge> >(); if (intersections.Count == 0) { // test point on tool loop, if in target, add it to the target if (target.IsPointInside(tool[0].Eval(0).pt)) { new_loops.Add(tool); foreach (var loop in target.Loops) { new_loops.Add(loop); } return(new Face2D(new_loops)); } else { return(target); } } BopMap bop_map = new BopMap(); { bop_map.edge2intersections = MakeIntersectionMap(intersections, target.Loops, tool); bop_map.target = target.Loops; bop_map.tool_edges = tool; }; // find valid intersection and start from it bool unprocessed_found = false; int deadloop = 0; do { unprocessed_found = false; foreach (var intersection in intersections) { loop_has_intersections[intersection.LoopIdx] = true; if (intersection.Valid) { unprocessed_found = true; var new_loop = MakeLoop(intersection, bop_map); if (new_loop != null) { if (new_loop.Count >= 2) { for (int i = 0; i < new_loop.Count; ++i) { new_loop[i].Connect(new_loop[(i + new_loop.Count - 1) % new_loop.Count], true); } new_loops.Add(new_loop); } } } if (deadloop++ > DeadloopMaxIters) { Debug.LogError("deadloop"); throw new UnityException("deadloop"); } } if (deadloop++ > DeadloopMaxIters) { Debug.LogError("deadloop"); throw new UnityException("deadloop"); } } while (unprocessed_found); for (int i = 0; i < loop_has_intersections.Count; ++i) { if (!loop_has_intersections[i]) { new_loops.Add(target.Loops[i]); // todo: test if inside } } return(new Face2D(new_loops)); }
LoopSegment MakeLoopSegment(TopologyIntersection start_from, BopMap map, bool tool_seg, IEnumerator <ICuttableEdge> edge_iterator) { LoopSegment seg; seg.start = null; var seg_edges = new List <ICuttableEdge>(); seg.end = null; edge_iterator.Reset(); int deadloop = 0; do { var cur_edge = edge_iterator.Current; var cur_edge_intersections = map.edge2intersections[cur_edge]; TopologyIntersection start = null; TopologyIntersection end = null; if (cur_edge_intersections != null && cur_edge_intersections.Count > 0) { if (cur_edge_intersections.Contains(start_from) && seg.start == null) { seg.start = start_from; start = start_from; } if (!(start != null && cur_edge_intersections.Count == 1)) { bool stop_at_next_is = start == null; foreach (var intersection in cur_edge_intersections) { if (stop_at_next_is) { end = intersection; break; } else { stop_at_next_is = start.Equals(intersection); } } } } if (start != null || end != null) { cur_edge = CutEdgeWithIntersections(cur_edge, tool_seg, start, end); } if (cur_edge.GetLen() > 1.0e-3) { seg_edges.Add(cur_edge); } if (end != null) { seg.end = end; break; } if (deadloop++ > DeadloopMaxIters) { Debug.Log("deadloop"); throw new UnityException("deadloop"); } } while (edge_iterator.MoveNext()); seg.edges = seg_edges; seg.start.Valid = false; seg.end.Valid = false; return(seg); }