GetVertices() 공개 메소드

public GetVertices ( ) : HashSet
리턴 HashSet
예제 #1
0
    //
    //   -----o------
    //
    // Remove boundary vertices with two edge (one ingoing + one outgoing) where edges are parallel
    // Remove non-boundary vertices with only two adjacent faces where edges are parallel
    //
    // The method undo edge split by removing the extra vertex
    public static int DissolveUnneededVertices(HMesh hmesh)
    {
        int count = 0;

        foreach (var vert in hmesh.GetVertices())
        {
            var circ = vert.Circulate();

            double parallelEpsilon = 1E-15;

            if (vert.IsBoundary() && circ.Count == 1 && VertexDistOnDissolve(vert, circ[0].vert, circ[0].prev.prev.vert) < hmesh.zeroMagnitudeTreshold)
            {
                vert.Dissolve();
                count++;
            }
            else if (!vert.IsBoundary() && circ.Count == 2)
            {
                if (VertexDistOnDissolve(vert, circ[0].vert, circ[1].vert) < hmesh.zeroMagnitudeTreshold)
                {
                    vert.Dissolve();
                    count++;
                }
            }
        }
        return(count);
    }
예제 #2
0
    public void ApplyTransform()
    {
        var localToWorld = transform.localToWorldMatrix;

        foreach (var vert in hmesh.GetVertices())
        {
            vert.position = localToWorld.MultiplyPoint(vert.position);
        }
        transform.position   = Vector3.zero;
        transform.localScale = Vector3.one;
        transform.rotation   = Quaternion.identity;
    }
예제 #3
0
    void OnGUI()
    {
        if (GUI.Button(new Rect(0,0,200,50), "FaceSplit")){
            HMesh hMesh = new HMesh();
            var mf = GetComponent<MeshFilter>();
            hMesh.Build(mf.mesh);

            foreach (var f in hMesh.GetFaces()){
                f.Split();
            }

            var mesh = hMesh.Export();
            mesh.RecalculateNormals();
            mf.mesh = mesh;
        }
        if (GUI.Button(new Rect(200,0,200,50), "EdgeFlip")){
            HMesh hMesh = new HMesh();
            var mf = GetComponent<MeshFilter>();
            hMesh.Build(mf.mesh);
            HashSet<Halfedge> isFlipped = new HashSet<Halfedge>();
            foreach (var h in hMesh.GetHalfedges()){
                if (!h.IsBoundary() && !isFlipped.Contains(h)){
                    Debug.DrawLine(h.vert.position, h.prev.vert.position,Color.cyan,5);
                    h.Flip();
                    isFlipped.Add(h.opp);
                }
            }
            var mesh = hMesh.Export();
            mesh.RecalculateNormals();
            mf.mesh = mesh;
        }
        if (GUI.Button(new Rect(400,0,200,50), "EdgeSplit")){
            HMesh hMesh = new HMesh();
            var mf = GetComponent<MeshFilter>();
            hMesh.Build(mf.mesh);
            HashSet<Halfedge> isSplit = new HashSet<Halfedge>();
            foreach (var h in hMesh.GetHalfedges()){
                if (!h.IsBoundary() && !isSplit.Contains(h)){
                    Debug.DrawLine(h.vert.position, h.prev.vert.position,Color.cyan,5);
                    isSplit.Add(h.opp);
                    h.Split();
                }
            }
            var mesh = hMesh.Export();
            mesh.RecalculateNormals();
            mf.mesh = mesh;
        }
        if (GUI.Button(new Rect(600,0,200,50), "CollapseEdge")){
            HMesh hMesh = new HMesh();
            var mf = GetComponent<MeshFilter>();
            hMesh.Build(mf.mesh);
            HashSet<Halfedge> isCollapsed = new HashSet<Halfedge>();
            foreach (var h in hMesh.GetHalfedges()){
                if (!h.IsBoundary()){
                    if (!h.vert.IsBoundary() && !h.prev.vert.IsBoundary() && !isCollapsed.Contains(h)){
                        Debug.DrawLine(h.vert.position, h.prev.vert.position,Color.cyan,5);
                        isCollapsed.Add(h.opp);
                        h.Collapse();
                        break;
                    }
                }
            }
            var mesh = hMesh.Export();
            mesh.RecalculateNormals();
            mf.mesh = mesh;
        }

        if (GUI.Button(new Rect(0,50,200,50), "CirculateRndVertex")){
            HMesh hMesh = new HMesh();
            var mf = GetComponent<MeshFilter>();
            hMesh.Build(mf.mesh);
            HashSet<Halfedge> isCollapsed = new HashSet<Halfedge>();

            var vertices = new List<Vertex>(hMesh.GetVertices());
            var vertex = vertices[1];//Random.Range(0,vertices.Count-1)];
            foreach (var h in vertex.Circulate()){
                Debug.DrawLine(h.vert.position, h.prev.vert.position,Color.cyan,5);
            }
            Debug.Log("Circulate vertex: "+vertex.Circulate().Count);
        }
        if (GUI.Button(new Rect(200,50,200,50), "CirculateOppRndVertex")){
            HMesh hMesh = new HMesh();
            var mf = GetComponent<MeshFilter>();
            hMesh.Build(mf.mesh);
            //HashSet<Halfedge> isCollapsed = new HashSet<Halfedge>();

            var vertices = new List<Vertex>(hMesh.GetVertices());
            var vertex = vertices[1];//Random.Range(0,vertices.Count-1)];
            foreach (var h in vertex.CirculateOpp()){
                Debug.DrawLine(h.vert.position, h.prev.vert.position,Color.cyan,5);
            }
            Debug.Log("Circulate vertex: "+vertex.Circulate().Count);
        }
        if (GUI.Button(new Rect(400,50,200,50), "Circulate1RingRndVertex")){
            HMesh hMesh = new HMesh();
            var mf = GetComponent<MeshFilter>();
            hMesh.Build(mf.mesh);
            // HashSet<Halfedge> isCollapsed = new HashSet<Halfedge>();

            var vertices = new List<Vertex>(hMesh.GetVertices());
            var vertex = vertices[Random.Range(0,vertices.Count-1)];
            foreach (var h in vertex.CirculateOneRing()){
                Debug.DrawLine(h.vert.position, h.prev.vert.position,Color.cyan,5);
            }
            Debug.Log("Circulate 1-ring: "+vertex.CirculateOneRing().Count);
        }
        if (GUI.Button(new Rect(600,50,200,50), "CirculateRndFace")){
            HMesh hMesh = new HMesh();
            var mf = GetComponent<MeshFilter>();
            hMesh.Build(mf.mesh);
            HashSet<Halfedge> isCollapsed = new HashSet<Halfedge>();

            var faces = new List<Face>(hMesh.GetFaces());
            var face = faces[Random.Range(0,faces.Count-1)];
            foreach (var h in face.Circulate()){
                Debug.DrawLine(h.vert.position, h.prev.vert.position, Color.cyan, 5);
            }
            Debug.Log("Circulate face: "+face.Circulate().Count);
        }
    }
예제 #4
0
    void OnGUI()
    {
        if (GUI.Button(new Rect(0, 0, 200, 50), "FaceSplit"))
        {
            HMesh hMesh = new HMesh();
            var   mf    = GetComponent <MeshFilter>();
            hMesh.Build(mf.mesh);

            foreach (var f in hMesh.GetFaces())
            {
                f.Split();
            }

            var mesh = hMesh.Export();
            mesh.RecalculateNormals();
            mf.mesh = mesh;
        }
        if (GUI.Button(new Rect(200, 0, 200, 50), "EdgeFlip"))
        {
            HMesh hMesh = new HMesh();
            var   mf    = GetComponent <MeshFilter>();
            hMesh.Build(mf.mesh);
            HashSet <Halfedge> isFlipped = new HashSet <Halfedge>();
            foreach (var h in hMesh.GetHalfedges())
            {
                if (!h.IsBoundary() && !isFlipped.Contains(h))
                {
                    Debug.DrawLine(h.vert.position, h.prev.vert.position, Color.cyan, 5);
                    h.Flip();
                    isFlipped.Add(h.opp);
                }
            }
            var mesh = hMesh.Export();
            mesh.RecalculateNormals();
            mf.mesh = mesh;
        }
        if (GUI.Button(new Rect(400, 0, 200, 50), "EdgeSplit"))
        {
            HMesh hMesh = new HMesh();
            var   mf    = GetComponent <MeshFilter>();
            hMesh.Build(mf.mesh);
            HashSet <Halfedge> isSplit = new HashSet <Halfedge>();
            foreach (var h in hMesh.GetHalfedges())
            {
                if (!h.IsBoundary() && !isSplit.Contains(h))
                {
                    Debug.DrawLine(h.vert.position, h.prev.vert.position, Color.cyan, 5);
                    isSplit.Add(h.opp);
                    h.Split();
                }
            }
            var mesh = hMesh.Export();
            mesh.RecalculateNormals();
            mf.mesh = mesh;
        }
        if (GUI.Button(new Rect(600, 0, 200, 50), "CollapseEdge"))
        {
            HMesh hMesh = new HMesh();
            var   mf    = GetComponent <MeshFilter>();
            hMesh.Build(mf.mesh);
            HashSet <Halfedge> isCollapsed = new HashSet <Halfedge>();
            foreach (var h in hMesh.GetHalfedges())
            {
                if (!h.IsBoundary())
                {
                    if (!h.vert.IsBoundary() && !h.prev.vert.IsBoundary() && !isCollapsed.Contains(h))
                    {
                        Debug.DrawLine(h.vert.position, h.prev.vert.position, Color.cyan, 5);
                        isCollapsed.Add(h.opp);
                        h.Collapse();
                        break;
                    }
                }
            }
            var mesh = hMesh.Export();
            mesh.RecalculateNormals();
            mf.mesh = mesh;
        }

        if (GUI.Button(new Rect(0, 50, 200, 50), "CirculateRndVertex"))
        {
            HMesh hMesh = new HMesh();
            var   mf    = GetComponent <MeshFilter>();
            hMesh.Build(mf.mesh);
            HashSet <Halfedge> isCollapsed = new HashSet <Halfedge>();

            var vertices = new List <Vertex>(hMesh.GetVertices());
            var vertex   = vertices[1];          //Random.Range(0,vertices.Count-1)];
            foreach (var h in vertex.Circulate())
            {
                Debug.DrawLine(h.vert.position, h.prev.vert.position, Color.cyan, 5);
            }
            Debug.Log("Circulate vertex: " + vertex.Circulate().Count);
        }
        if (GUI.Button(new Rect(200, 50, 200, 50), "CirculateOppRndVertex"))
        {
            HMesh hMesh = new HMesh();
            var   mf    = GetComponent <MeshFilter>();
            hMesh.Build(mf.mesh);
            //HashSet<Halfedge> isCollapsed = new HashSet<Halfedge>();

            var vertices = new List <Vertex>(hMesh.GetVertices());
            var vertex   = vertices[1];          //Random.Range(0,vertices.Count-1)];
            foreach (var h in vertex.CirculateOpp())
            {
                Debug.DrawLine(h.vert.position, h.prev.vert.position, Color.cyan, 5);
            }
            Debug.Log("Circulate vertex: " + vertex.Circulate().Count);
        }
        if (GUI.Button(new Rect(400, 50, 200, 50), "Circulate1RingRndVertex"))
        {
            HMesh hMesh = new HMesh();
            var   mf    = GetComponent <MeshFilter>();
            hMesh.Build(mf.mesh);
            // HashSet<Halfedge> isCollapsed = new HashSet<Halfedge>();

            var vertices = new List <Vertex>(hMesh.GetVertices());
            var vertex   = vertices[Random.Range(0, vertices.Count - 1)];
            foreach (var h in vertex.CirculateOneRing())
            {
                Debug.DrawLine(h.vert.position, h.prev.vert.position, Color.cyan, 5);
            }
            Debug.Log("Circulate 1-ring: " + vertex.CirculateOneRing().Count);
        }
        if (GUI.Button(new Rect(600, 50, 200, 50), "CirculateRndFace"))
        {
            HMesh hMesh = new HMesh();
            var   mf    = GetComponent <MeshFilter>();
            hMesh.Build(mf.mesh);
            HashSet <Halfedge> isCollapsed = new HashSet <Halfedge>();

            var faces = new List <Face>(hMesh.GetFaces());
            var face  = faces[Random.Range(0, faces.Count - 1)];
            foreach (var h in face.Circulate())
            {
                Debug.DrawLine(h.vert.position, h.prev.vert.position, Color.cyan, 5);
            }
            Debug.Log("Circulate face: " + face.Circulate().Count);
        }
    }
예제 #5
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);
    }