// After we split an edge, we have created a new edge and a new vertex. // The edge needs to inherit the constraint on the other pre-existing edge that we kept. // In addition, if the edge vertices were both constrained, then we /might/ // want to also constrain this new vertex, possibly project to constraint target. void update_after_split(int edgeID, int va, int vb, DMesh3.EdgeSplitInfo splitInfo) { bool bPositionFixed = false; if (constraints != null && constraints.HasEdgeConstraint(edgeID)) { // inherit edge constraint constraints.SetOrUpdateEdgeConstraint(splitInfo.eNewBN, constraints.GetEdgeConstraint(edgeID)); // [RMS] update vertex constraints. Note that there is some ambiguity here. // Both verts being constrained doesn't inherently mean that the edge is on // a constraint, that's why these checks are only applied if edge is constrained. // But constrained edge doesn't necessarily mean we want to inherit vert constraints!! // // although, pretty safe to assume that we would at least disable flips // if both vertices are constrained to same line/curve. So, maybe this makes sense... // // (perhaps edge constraint should be explicitly tagged to resolve this ambiguity??) // vert inherits Fixed if both orig edge verts Fixed, and both tagged with same SetID VertexConstraint ca = constraints.GetVertexConstraint(va); VertexConstraint cb = constraints.GetVertexConstraint(vb); if (ca.Fixed && cb.Fixed) { int nSetID = (ca.FixedSetID > 0 && ca.FixedSetID == cb.FixedSetID) ? ca.FixedSetID : VertexConstraint.InvalidSetID; constraints.SetOrUpdateVertexConstraint(splitInfo.vNew, new VertexConstraint(true, nSetID)); bPositionFixed = true; } // vert inherits Target if both source verts and edge have same Target if (ca.Target != null && ca.Target == cb.Target && constraints.GetEdgeConstraint(edgeID).Target == ca.Target) { constraints.SetOrUpdateVertexConstraint(splitInfo.vNew, new VertexConstraint(ca.Target)); project_vertex(splitInfo.vNew, ca.Target); bPositionFixed = true; } } if (EnableInlineProjection && bPositionFixed == false && target != null) { project_vertex(splitInfo.vNew, target); } }
void add_split_subfaces(Index2i origTris, ref DMesh3.EdgeSplitInfo splitInfo) { int parent_1 = get_parent(origTris.a); HashSet <int> subfaces_1 = get_subfaces(parent_1); if (origTris.a != parent_1) { add_subface(subfaces_1, parent_1, origTris.a); } add_subface(subfaces_1, parent_1, splitInfo.eNewT2); if (origTris.b != DMesh3.InvalidID) { int parent_2 = get_parent(origTris.b); HashSet <int> subfaces_2 = get_subfaces(parent_2); if (origTris.b != parent_2) { add_subface(subfaces_2, parent_2, origTris.b); } add_subface(subfaces_2, parent_2, splitInfo.eNewT3); } }
protected override void OnEdgeSplit(int edgeID, int va, int vb, DMesh3.EdgeSplitInfo splitInfo) { int aidx = CurrentLoopV.FindIndex((i) => { return(i == va); }); int bidx = CurrentLoopV.FindIndex((i) => { return(i == vb); }); int eidx = CurrentLoopE.FindIndex((i) => { return(i == edgeID); }); if (eidx == CurrentLoopE.Count - 1) // list-wrap case { CurrentLoopV.Add(splitInfo.vNew); } else if (aidx < bidx) { CurrentLoopV.Insert(bidx, splitInfo.vNew); } else { CurrentLoopV.Insert(aidx, splitInfo.vNew); } // ugh! expensive! rebuild_edge_list(); Debug.Assert(check_loop()); }
// subclasses can override these to implement custom behavior... protected virtual void OnEdgeSplit(int edgeID, int va, int vb, DMesh3.EdgeSplitInfo splitInfo) { // this is for subclasses... }