Пример #1
0
        // for all vertices in loopV, constrain to target
        // for all edges in loopV, disable flips and constrain to target
        public static void ConstrainVtxLoopTo(MeshConstraints cons, NGonsCore.geometry3Sharp.mesh.DMesh3 mesh, int[] loopV, IProjectionTarget target, int setID = -1)
        {
            VertexConstraint vc = new VertexConstraint(target);

            for (int i = 0; i < loopV.Length; ++i)
            {
                cons.SetOrUpdateVertexConstraint(loopV[i], vc);
            }

            EdgeConstraint ec = new EdgeConstraint(EdgeRefineFlags.NoFlip, target);

            ec.TrackingSetID = setID;
            for (int i = 0; i < loopV.Length; ++i)
            {
                int v0 = loopV[i];
                int v1 = loopV[(i + 1) % loopV.Length];

                int eid = mesh.FindEdge(v0, v1);
                Debug.Assert(eid != NGonsCore.geometry3Sharp.mesh.DMesh3.InvalidID);
                if (eid != NGonsCore.geometry3Sharp.mesh.DMesh3.InvalidID)
                {
                    cons.SetOrUpdateEdgeConstraint(eid, ec);
                }
            }
        }
Пример #2
0
 bool vertex_is_constrained(int vid)
 {
     if (constraints != null)
     {
         VertexConstraint vc = constraints.GetVertexConstraint(vid);
         if (vc.Fixed || vc.Target != null)
         {
             return(true);
         }
     }
     return(false);
 }
Пример #3
0
        // 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, NGonsCore.geometry3Sharp.mesh.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);
            }
        }
Пример #4
0
        // for all mesh boundary vertices, pin in current position, but allow collapses
        public static void FixAllBoundaryEdges_AllowCollapse(MeshConstraints cons, NGonsCore.geometry3Sharp.mesh.DMesh3 mesh, int setID)
        {
            EdgeConstraint   edgeCons = new EdgeConstraint(EdgeRefineFlags.NoFlip | EdgeRefineFlags.NoSplit);
            VertexConstraint vertCons = new VertexConstraint(true, setID);

            int NE = mesh.MaxEdgeID;

            for (int ei = 0; ei < NE; ++ei)
            {
                if (mesh.IsEdge(ei) && mesh.IsBoundaryEdge(ei))
                {
                    cons.SetOrUpdateEdgeConstraint(ei, edgeCons);

                    Index2i ev = mesh.GetEdgeV(ei);
                    cons.SetOrUpdateVertexConstraint(ev.a, vertCons);
                    cons.SetOrUpdateVertexConstraint(ev.b, vertCons);
                }
            }
        }
Пример #5
0
        /// <summary>
        /// This computes smoothed positions w/ proper constraints/etc.
        /// Does not modify mesh.
        /// </summary>
        protected virtual Vector3D ComputeSmoothedVertexPos(int vID, Func <NGonsCore.geometry3Sharp.mesh.DMesh3, int, double, Vector3D> smoothFunc, out bool bModified)
        {
            bModified = false;
            VertexConstraint vConstraint = get_vertex_constraint(vID);

            if (vConstraint.Fixed)
            {
                return(Mesh.GetVertex(vID));
            }
            VertexControl vControl = (VertexControlF == null) ? VertexControl.AllowAll : VertexControlF(vID);

            if ((vControl & VertexControl.NoSmooth) != 0)
            {
                return(Mesh.GetVertex(vID));
            }

            Vector3D vSmoothed = smoothFunc(mesh, vID, SmoothSpeedT);

            Debug.Assert(vSmoothed.IsFinite);     // this will really catch a lot of bugs...

            // project onto either vtx constraint target, or surface target
            if (vConstraint.Target != null)
            {
                vSmoothed = vConstraint.Target.Project(vSmoothed, vID);
            }
            else if (EnableInlineProjection && target != null)
            {
                if ((vControl & VertexControl.NoProject) == 0)
                {
                    vSmoothed = target.Project(vSmoothed, vID);
                }
            }

            bModified = true;
            return(vSmoothed);
        }
Пример #6
0
 // used by collapse-edge to get projected position for new vertex
 Vector3D get_projected_collapse_position(int vid, Vector3D vNewPos)
 {
     if (constraints != null)
     {
         VertexConstraint vc = constraints.GetVertexConstraint(vid);
         if (vc.Target != null)
         {
             return(vc.Target.Project(vNewPos, vid));
         }
         if (vc.Fixed)
         {
             return(vNewPos);
         }
     }
     // no constraint applied, so if we have a target surface, project to that
     if (EnableInlineProjection && target != null)
     {
         if (VertexControlF == null || (VertexControlF(vid) & VertexControl.NoProject) == 0)
         {
             return(target.Project(vNewPos, vid));
         }
     }
     return(vNewPos);
 }
Пример #7
0
        // resolve vertex constraints for collapsing edge eid=[a,b]. Generally we would
        // collapse a to b, and set the new position as 0.5*(v_a+v_b). However if a *or* b
        // are constrained, then we want to keep that vertex and collapse to its position.
        // This vertex (a or b) will be returned in collapse_to, which is -1 otherwise.
        // If a *and* b are constrained, then things are complicated (and documented below).
        bool can_collapse_vtx(int eid, int a, int b, out int collapse_to)
        {
            collapse_to = -1;
            if (constraints == null)
            {
                return(true);
            }
            VertexConstraint ca = constraints.GetVertexConstraint(a);
            VertexConstraint cb = constraints.GetVertexConstraint(b);

            // no constraint at all
            if (ca.Fixed == false && cb.Fixed == false && ca.Target == null && cb.Target == null)
            {
                return(true);
            }

            // handle a or b fixed
            if (ca.Fixed == true && cb.Fixed == false)
            {
                collapse_to = a;
                return(true);
            }
            if (cb.Fixed == true && ca.Fixed == false)
            {
                collapse_to = b;
                return(true);
            }
            // if both fixed, and options allow, treat this edge as unconstrained (eg collapse to midpoint)
            // [RMS] tried picking a or b here, but something weird happens, where
            //   eg cylinder cap will entirely erode away. Somehow edge lengths stay below threshold??
            if (AllowCollapseFixedVertsWithSameSetID &&
                ca.FixedSetID >= 0 &&
                ca.FixedSetID == cb.FixedSetID)
            {
                return(true);
            }

            // handle a or b w/ target
            if (ca.Target != null && cb.Target == null)
            {
                collapse_to = a;
                return(true);
            }
            if (cb.Target != null && ca.Target == null)
            {
                collapse_to = b;
                return(true);
            }
            // if both vertices are on the same target, and the edge is on that target,
            // then we can collapse to either and use the midpoint (which will be projected
            // to the target). *However*, if the edge is not on the same target, then we
            // cannot collapse because we would be changing the constraint topology!
            if (cb.Target != null && ca.Target != null && ca.Target == cb.Target)
            {
                if (constraints.GetEdgeConstraint(eid).Target == ca.Target)
                {
                    return(true);
                }
            }

            return(false);
        }
Пример #8
0
 public void SetOrUpdateVertexConstraint(int vid, VertexConstraint vc)
 {
     Vertices[vid] = vc;
 }