/// <summary> /// Disconnect the given triangles from their neighbours, by duplicating "boundary" vertices, ie /// vertices on edges for which one triangle is in-set and the other is not. /// If bComputeEdgePairs is true, we return list of old/new edge pairs (useful for stitching) /// [TODO] currently boundary-edge behaviour is to *not* duplicate boundary verts /// </summary> public bool SeparateTriangles(IEnumerable <int> triangles, bool bComputeEdgePairs, out List <Index2i> EdgePairs) { HashSet <int> in_set = new HashSet <int>(triangles); Dictionary <int, int> VertexMap = new Dictionary <int, int>(); EdgePairs = null; HashSet <int> edges = null; List <Index2i> OldEdgeVerts = null; if (bComputeEdgePairs) { EdgePairs = new List <Index2i>(); edges = new HashSet <int>(); OldEdgeVerts = new List <Index2i>(); } // duplicate vertices on edges that are on boundary of triangles roi foreach (int tid in triangles) { Index3i te = Mesh.GetTriEdges(tid); for (int j = 0; j < 3; ++j) { Index2i et = Mesh.GetEdgeT(te[j]); // [TODO] what about behavior where we want to also duplicate boundary verts?? if (et.b == DMesh3.InvalidID || (et.a == tid && in_set.Contains(et.b)) || (et.b == tid && in_set.Contains(et.a))) { te[j] = -1; } } for (int j = 0; j < 3; ++j) { if (te[j] == -1) { continue; } Index2i ev = Mesh.GetEdgeV(te[j]); if (VertexMap.ContainsKey(ev.a) == false) { VertexMap[ev.a] = Mesh.AppendVertex(Mesh, ev.a); } if (VertexMap.ContainsKey(ev.b) == false) { VertexMap[ev.b] = Mesh.AppendVertex(Mesh, ev.b); } if (bComputeEdgePairs && edges.Contains(te[j]) == false) { edges.Add(te[j]); OldEdgeVerts.Add(ev); EdgePairs.Add(new Index2i(te[j], -1)); } } } // update triangles foreach (int tid in triangles) { Index3i tv = Mesh.GetTriangle(tid); Index3i tv_new = tv; for (int j = 0; j < 3; ++j) { int newv; if (VertexMap.TryGetValue(tv[j], out newv)) { tv_new[j] = newv; } } if (tv_new != tv) { Mesh.SetTriangle(tid, tv_new); } } if (bComputeEdgePairs) { for (int k = 0; k < EdgePairs.Count; ++k) { Index2i old_ev = OldEdgeVerts[k]; int new_a = VertexMap[old_ev.a]; int new_b = VertexMap[old_ev.b]; int new_eid = Mesh.FindEdge(new_a, new_b); Util.gDevAssert(new_eid != DMesh3.InvalidID); EdgePairs[k] = new Index2i(EdgePairs[k].a, new_eid); } } return(true); }