// insert point at bary_coords inside tid. If point is at vtx, just use that vtx. // If it is on an edge, do an edge split. Otherwise poke face. int insert_corner_from_bary(int iCorner, int tid, Vector3d bary_coords, double tol = MathUtil.ZeroTolerance) { Vector2d vInsert = Curve[iCorner]; Index3i tv = Mesh.GetTriangle(tid); // handle cases where corner is on a vertex if (bary_coords.x > 1 - tol) { return(tv.a); } else if (bary_coords.y > 1 - tol) { return(tv.b); } else if (bary_coords.z > 1 - tol) { return(tv.c); } // handle cases where corner is on an edge int split_edge = -1; if (bary_coords.x < tol) { split_edge = 1; } else if (bary_coords.y < tol) { split_edge = 2; } else if (bary_coords.z < tol) { split_edge = 0; } if (split_edge >= 0) { int eid = Mesh.GetTriEdge(tid, split_edge); DMesh3.EdgeSplitInfo split_info; MeshResult splitResult = Mesh.SplitEdge(eid, out split_info); if (splitResult != MeshResult.Ok) { throw new Exception("MeshInsertUVPolyCurve.insert_corner_special: edge split failed in case sum==2"); } SetPointF(split_info.vNew, vInsert); return(split_info.vNew); } // otherwise corner is inside triangle DMesh3.PokeTriangleInfo pokeinfo; MeshResult result = Mesh.PokeTriangle(tid, bary_coords, out pokeinfo); if (result != MeshResult.Ok) { throw new Exception("MeshInsertUVPolyCurve.insert_corner_special: face poke failed!"); } SetPointF(pokeinfo.new_vid, vInsert); return(pokeinfo.new_vid); }
/// <summary> /// For each on-face vtx, we poke the face, and re-sort /// the remaining vertices on that face onto new faces/edges /// </summary> void insert_face_vertices() { while (FaceVertices.Count > 0) { var pair = FaceVertices.First(); int tid = pair.Key; List <SegmentVtx> triVerts = pair.Value; SegmentVtx v = triVerts[triVerts.Count - 1]; triVerts.RemoveAt(triVerts.Count - 1); DMesh3.PokeTriangleInfo pokeInfo; MeshResult result = Target.PokeTriangle(tid, out pokeInfo); if (result != MeshResult.Ok) { throw new Exception("shit"); } int new_v = pokeInfo.new_vid; Target.SetVertex(new_v, v.v); v.vtx_id = new_v; VIDToSegVtxMap[v.vtx_id] = v; PointHash.InsertPoint(v.vtx_id, v.v); // remove this triangles vtx list because it is no longer valid FaceVertices.Remove(tid); // update remaining verts Index3i pokeEdges = pokeInfo.new_edges; var pokeTris = new Index3i(tid, pokeInfo.new_t1, pokeInfo.new_t2); foreach (SegmentVtx sv in triVerts) { update_from_poke(sv, pokeEdges, pokeTris); if (sv.type == 1) { add_edge_vtx(sv.elem_id, sv); } else if (sv.type == 2) { add_face_vtx(sv.elem_id, sv); } } // track poke subfaces add_poke_subfaces(tid, ref pokeInfo); } }
// insert point at bary_coords inside tid. If point is at vtx, just use that vtx. // If it is on an edge, do an edge split. Otherwise poke face. int insert_corner_from_bary(int iCorner, int tid, Vector3d bary_coords, double bary_tol, double spatial_tol, out bool is_existing_v) { is_existing_v = false; Vector2d vInsert = Curve[iCorner]; Index3i tv = Mesh.GetTriangle(tid); // handle cases where corner is on a vertex int cornerv = -1; if (bary_coords.x > 1 - bary_tol) { cornerv = tv.a; } else if (bary_coords.y > 1 - bary_tol) { cornerv = tv.b; } else if (bary_coords.z > 1 - bary_tol) { cornerv = tv.c; } if (cornerv != -1 && PointF(cornerv).Distance(vInsert) < spatial_tol) { is_existing_v = true; return(cornerv); } // handle cases where corner is on an edge int split_edge = -1; if (bary_coords.x < bary_tol) { split_edge = 1; } else if (bary_coords.y < bary_tol) { split_edge = 2; } else if (bary_coords.z < bary_tol) { split_edge = 0; } if (split_edge >= 0) { int eid = Mesh.GetTriEdge(tid, split_edge); Index2i ev = Mesh.GetEdgeV(eid); Segment2d seg = new Segment2d(PointF(ev.a), PointF(ev.b)); if (seg.DistanceSquared(vInsert) < spatial_tol * spatial_tol) { Index2i et = Mesh.GetEdgeT(eid); spatial_remove_triangles(et.a, et.b); DMesh3.EdgeSplitInfo split_info; MeshResult splitResult = Mesh.SplitEdge(eid, out split_info); if (splitResult != MeshResult.Ok) { throw new Exception("MeshInsertUVPolyCurve.insert_corner_from_bary: edge split failed in case sum==2 - " + splitResult.ToString()); } SetPointF(split_info.vNew, vInsert); spatial_add_triangles(et.a, et.b); spatial_add_triangles(split_info.eNewT2, split_info.eNewT3); return(split_info.vNew); } } spatial_remove_triangle(tid); // otherwise corner is inside triangle DMesh3.PokeTriangleInfo pokeinfo; MeshResult result = Mesh.PokeTriangle(tid, bary_coords, out pokeinfo); if (result != MeshResult.Ok) { throw new Exception("MeshInsertUVPolyCurve.insert_corner_from_bary: face poke failed - " + result.ToString()); } SetPointF(pokeinfo.new_vid, vInsert); spatial_add_triangle(tid); spatial_add_triangle(pokeinfo.new_t1); spatial_add_triangle(pokeinfo.new_t2); return(pokeinfo.new_vid); }