IsValid() public method

public IsValid ( ) : bool
return bool
Exemplo n.º 1
0
    public void Flip()
    {
                #if UNITY_EDITOR
        if (IsBoundary())
        {
            Debug.LogError("Cannot flip boundary edge");
            return;
        }
        if (face.NoEdges() != 3 || opp.face.NoEdges() != 3)
        {
            Debug.LogError("Can only flip edge between two triangles");
        }
        Debug.Assert(hmesh.IsValid());
                #endif

        Halfedge oldNext    = next;
        Halfedge oldPrev    = prev;
        Halfedge oldOppNext = opp.next;
        Halfedge oldOppPrev = opp.prev;

        Vertex thisVert         = vert;
        Vertex oppVert          = opp.vert;
        Vertex thisOppositeVert = next.vert;
        Vertex oppOppositeVert  = opp.next.vert;

        // flip halfedges
        oldOppNext.Link(this);
        this.Link(oldPrev);

        oldNext.Link(opp);
        opp.Link(oldOppPrev);

        oldOppPrev.Link(oldNext);
        oldPrev.Link(oldOppNext);

        // reassign vertices
        this.vert = thisOppositeVert;
        thisOppositeVert.halfedge = oldPrev;
        opp.vert = oppOppositeVert;
        oppOppositeVert.halfedge  = oldOppPrev;
        thisOppositeVert.halfedge = oldPrev;
        thisVert.halfedge         = oldNext;
        oppVert.halfedge          = oldOppNext;

        face.halfedge = this;
        face.ReassignFaceToEdgeLoop();
        opp.face.halfedge = opp;
        opp.face.ReassignFaceToEdgeLoop();
                #if UNITY_EDITOR
        Debug.Assert(hmesh.IsValid());
                #endif
    }
Exemplo n.º 2
0
    public HMesh Triangulate(bool step = false)
    {
        if (step)
        {
            var faces = new List <Face>(hmesh.GetFacesRaw());
            faces.Sort((face, face1) =>
            {
                return(-face.Circulate().Count + face1.Circulate().Count);
            });
            Debug.Log("Triangulate " + faces[0]);
            faces[0].Triangulate(true);
        }
        else
        {
            hmesh.Triangulate(step);
        }
        Debug.Log("Valid hmesh " + hmesh.IsValid());

        return(hmesh);
    }
Exemplo n.º 3
0
    // return the number of collapsed faces
    public static int SimplifyByCollapse(HMesh hmesh, int maxIter = int.MaxValue)
    {
        List <Halfedge> faceLabelBoundary = new List <Halfedge>();
        int             collapsed         = 0;

        bool changed;
        int  iter          = 0;
        int  collapsedEven = 0;

        do
        {
            iter++;
            changed = false;
            // collapse he if vertex contains two parallel halfedges, which separates labels or is boundary)
            foreach (var vert in hmesh.GetVertices())
            {
                if (vert.IsDestroyed())
                {
                    continue;
                }
                if (vert.IsBoundary())
                {
                    // boundary collapses should be handled by DissolveUnneededBoundaryVertices
                    continue;
                }
                faceLabelBoundary.Clear();
                var vertCirculate = vert.Circulate();
                foreach (var he in vertCirculate)
                {
                    if (he.face.label != he.opp.face.label)
                    {
                        faceLabelBoundary.Add(he);
                    }
                }
                if (faceLabelBoundary.Count == 1)
                {
                    Debug.Assert(false, "Cannot have a single face label boundary (without the vertex is a boundary");
                }
                else if (faceLabelBoundary.Count == 2)
                {
                    var    dirs          = new[] { faceLabelBoundary[0].GetDirection(), faceLabelBoundary[1].GetDirection() };
                    var    line          = new LineSegment(faceLabelBoundary[0].vert.positionD, faceLabelBoundary[1].vert.positionD);
                    double distance      = line.DistancePoint(faceLabelBoundary[0].prev.vert.positionD);
                    double distThreshold = hmesh.zeroMagnitudeTreshold;
                    var    dot           = Vector3D.Dot(dirs[0], dirs[1]);
                    bool   sameDir       = dot < 0.0;
                    if (distance < distThreshold && sameDir)
                    {
                        var position = faceLabelBoundary[0].vert.positionD;

                        if (IsFacesOnSamePlane(hmesh, vertCirculate, faceLabelBoundary[0].face.label) && IsFacesOnSamePlane(hmesh, vertCirculate, faceLabelBoundary[1].face.label))
                        {
                            if (PreconditionLegalCollapse(faceLabelBoundary[0], position))
                            {
                                //if (PreconditionLegalCollapse(faceLabelBoundary[0])){
                                var newVertex = faceLabelBoundary[0].Collapse(faceLabelBoundary[0].vert.positionD);
                                if (newVertex != null)
                                {
                                    newVertex.positionD = position;
                                }
                                collapsed++;
                                changed = true;
#if HMDebug
                                if (!hmesh.IsValid())
                                {
                                    Debug.Log("Invalid");
                                }
#endif
                                if (debugOneStep)
                                {
                                    return(-1);
                                }
                            }
                            else if (PreconditionLegalCollapse(faceLabelBoundary[1], position))
                            {
                                var newVertex = faceLabelBoundary[1].Collapse(faceLabelBoundary[1].vert.positionD);
                                if (newVertex != null)
                                {
                                    newVertex.positionD = position;
                                }
                                collapsed++;
                                changed = true;
#if HMDebug
                                if (!hmesh.IsValid())
                                {
                                    Debug.Log("Invalid");
                                }
#endif
                                if (debugOneStep)
                                {
                                    return(-1);
                                }
                            }
                        }
                    }
                }
                else if (faceLabelBoundary.Count == 0)
                {
                    if (IsFacesOnSamePlane(hmesh, vertCirculate))
                    {
                        // search for which to collapse (should not result in flipped vectors)

                        for (int i = 0; i < vertCirculate.Count; i++)
                        {
#if HMDebug
                            if (!hmesh.IsValid())
                            {
                                Debug.LogError("PreInvalid");
                            }
#endif
                            if (PreconditionLegalCollapse(vertCirculate[i], vertCirculate[i].vert.positionD))
                            {
                                var collapseStr = vertCirculate[i].ToString();
                                var position    = vertCirculate[i].vert.positionD;
                                var newVertex   = vertCirculate[i].Collapse();
                                collapsed++;
                                newVertex.positionD = position;
#if HMDebug
                                if (!hmesh.IsValid())
                                {
                                    Debug.Log("Invalid");
                                    Debug.LogError(collapseStr);
                                }
#endif
                                i = int.MaxValue - 1;
                                if (debugOneStep)
                                {
                                    return(-1);
                                }
                                break;
                            }
                        }
                    }
                }
            }
        } while (changed && iter < maxIter);

        return(collapsed);
    }
Exemplo n.º 4
0
    // <summary>
    // Collapses boundary edges, such any point of the shape does not move more than (approx) hmesh.zeroMagnitudeTreshold.
    // </summary>
    public static int DissolveUnneededBoundaryVertices(HMesh hmesh, bool keepFaceLabels = true)
    {
        Debug.Assert(hmesh.IsValid(HMeshValidationRules.All), "Precondition failed: Mesh should be valid");

        List <Halfedge> boundaryHalfedges = new List <Halfedge>();
        var             count             = 0;
        var             verts             = new List <Vertex>(hmesh.GetVerticesRaw());

        foreach (var v in verts)
        {
            if (v.IsDestroyed())
            {
                continue;
            }
            if (v.IsBoundary())
            {
                var hes    = v.Circulate();
                var heOpps = v.CirculateOpp();

                boundaryHalfedges.Clear();

                bool isSameLabel = true;

                foreach (var he in hes)
                {
                    if (keepFaceLabels && he.face.label != hes[0].face.label)
                    {
                        isSameLabel = false;
                        break;
                    }
                    if (he.IsBoundary())
                    {
                        boundaryHalfedges.Add(he);
                    }
                }

                foreach (var he in heOpps)
                {
                    if (keepFaceLabels && he.face.label != hes[0].face.label)
                    {
                        isSameLabel = false;
                        break;
                    }
                    if (he.IsBoundary())
                    {
                        boundaryHalfedges.Add(he);
                    }
                }
                if (!isSameLabel)
                {
                    continue;
                }
                double largeThreshold = hmesh.zeroMagnitudeTresholdSqr;
                if (!Vector3D.IsParallelDist(boundaryHalfedges[0].GetDirection(), boundaryHalfedges[1].GetDirection(),
                                             largeThreshold))
                {
                    continue;
                }

                // find face plane that are not degenerate
                bool facesAreOnSamePlane = IsFacesOnSamePlane(hmesh, hes);
                if (!facesAreOnSamePlane)
                {
                    continue;
                }

                LineSegment virtuelEdge = new LineSegment(
                    boundaryHalfedges[0].vert.positionD,
                    boundaryHalfedges[1].prev.vert.positionD
                    );
                if (virtuelEdge.DistancePoint(v.positionD) < hmesh.zeroMagnitudeTreshold)
                {
                    boundaryHalfedges[0].Collapse(boundaryHalfedges[0].vert.positionD);
                    count++;
                }
            }
        }
        return(count);
    }