Exemple #1
0
    public static HMesh CreateTestMeshQuad()
    {
        HMesh mesh = new HMesh();
        var face = mesh.CreateFace();
        var edges = new Halfedge[]{
            mesh.CreateHalfedge(),
            mesh.CreateHalfedge(),
            mesh.CreateHalfedge(),
            mesh.CreateHalfedge(),
        };
        var verts = new Vertex[]{
            mesh.CreateVertex(new Vector3(0,0,0)),
            mesh.CreateVertex(new Vector3(1,0,0)),
            mesh.CreateVertex(new Vector3(1,0,1)),
            mesh.CreateVertex(new Vector3(0,0,1)),
        };
        for (int i=0;i<4;i++){
            edges[i].Link(face);
            edges[i].next = edges[(i+1)%4];
            edges[(i+1)%4].prev = edges[i];

            edges[i].vert = verts[i];
            verts[i].halfedge = edges[i].next;
        }
        return mesh;
    }
 public EdgeList(float xmin,float deltax,int sqrt_nsites)
 {
     _xmin=xmin;
     _deltax=deltax;
     _hashsize=2*sqrt_nsites;
     int i;
     _hash=new List<Halfedge>();
     _leftEnd = Halfedge.createDummy();
     _rightEnd = Halfedge.createDummy();
     _leftEnd.edgeListLeftNeighbor = null;
     _leftEnd.edgeListRightNeighbor = _rightEnd;
     _rightEnd.edgeListLeftNeighbor = _leftEnd;
     _rightEnd.edgeListRightNeighbor = null;
     _hash[0] = _leftEnd;
     _hash[_hashsize - 1] = _rightEnd;
 }
 public void remove(Halfedge halfEdge)
 {
     Halfedge previous;
     int removalBucket=bucket(halfEdge);
     if(halfEdge.vertex!=null){
         previous = _hash[removalBucket];
         while (previous.nextInPriorityQueue != halfEdge)
         {
             previous = previous.nextInPriorityQueue;
         }
         previous.nextInPriorityQueue = halfEdge.nextInPriorityQueue;
         _count--;
         halfEdge.vertex = null;
         halfEdge.nextInPriorityQueue = null;
         halfEdge.dispose();
     }
 }
 public void insert(Halfedge halfEdge)
 {
     Halfedge previous,next;
     int insertionBucket=bucket(halfEdge);
     if (insertionBucket < _minBucket)
     {
         _minBucket = insertionBucket;
     }
     previous = _hash[insertionBucket];
     while ((next = previous.nextInPriorityQueue) != null
            &&     (halfEdge.ystar  > next.ystar || (halfEdge.ystar == next.ystar && halfEdge.vertex.x > next.vertex.x)))
     {
         previous = next;
     }
     halfEdge.nextInPriorityQueue = previous.nextInPriorityQueue;
     previous.nextInPriorityQueue = halfEdge;
     ++_count;
 }
    public void dispose()
    {
        Halfedge halfEdge=_leftEnd;
        Halfedge prevHe;
        while (halfEdge != _rightEnd)
        {
            prevHe = halfEdge;
            halfEdge = halfEdge.edgeListRightNeighbor;
            prevHe.dispose();
        }
        _leftEnd = null;
        _rightEnd.dispose();
        _rightEnd = null;

        int i;
        for (i = 0; i < _hashsize; ++i)
        {
            _hash[i] = null;
        }
        _hash = null;
    }
    public static Vertex intersect( Halfedge halfedge0,Halfedge halfedge1)
    {
        Edge edge0,edge1,edge;
        Halfedge helfedge;
        float determinant,intersectionX,intersectionY;
        bool rightOfSite;
        edge0=halfedge0.edge;
        edge1=halfedge1.edge;
        if(edge0==null || edge1==null){
            return null;
        }
        if(edge0.rightSite==edge1.rightSite){
            return null;
        }
        determinant=edge0.a*dege1.b-dege0.b*edge1.a;
        if(-1.0e-10 <determinant && determinant<1.0e-10){
            return null;
        }
        intersectionX = (edge0.c * edge1.b - edge1.c * edge0.b)/determinant;
        intersectionY = (edge1.c * edge0.a - edge0.c * edge1.a)/determinant;

        if (Voronoi.compareByYThenX(edge0.rightSite, edge1.rightSite) < 0)
        {
            halfedge = halfedge0; edge = edge0;
        }
        else
        {
            halfedge = halfedge1; edge = edge1;
        }
        rightOfSite = intersectionX >= edge.rightSite.x;
        if ((rightOfSite && halfedge.leftRight == LR.LEFT)
            ||  (!rightOfSite && halfedge.leftRight == LR.RIGHT))
        {
            return null;
        }

        return Vertex.create(intersectionX, intersectionY);
    }
Exemple #7
0
        // push the HalfEdge into the ordered linked list of vertices
        private void PQinsert( Halfedge he, Site v, double offset )
        {
            Halfedge last, next;

            he.vertex = v;
            he.ystar = (double)(v.coord.y + offset);
            last = PQhash [ PQbucket (he) ];

            while
                (
                    (next = last.PQnext) != null
                    &&
                    (he.ystar > next.ystar || (he.ystar == next.ystar && v.coord.x > next.vertex.coord.x))
                )
            {
                last = next;
            }

            he.PQnext = last.PQnext;
            last.PQnext = he;
            PQcount++;
        }
Exemple #8
0
        /* returns true if p is to right of halfedge e */
        private bool right_of(Halfedge el, Point p)
        {
            Edge e;
            Site topsite;
            bool right_of_site;
            bool above, fast;
            double dxp, dyp, dxs, t1, t2, t3, yl;

            e = el.ELedge;
            topsite = e.reg[1];

            if ( p.x > topsite.coord.x )
                right_of_site = true;
            else
                right_of_site = false;

            if ( right_of_site && el.ELpm == LE )
                return true;
            if (!right_of_site && el.ELpm == RE )
                return false;

            if ( e.a == 1.0 )
            {
                dxp = p.x - topsite.coord.x;
                dyp = p.y - topsite.coord.y;
                fast = false;

                if ( (!right_of_site & (e.b < 0.0)) | (right_of_site & (e.b >= 0.0)) )
                {
                    above = dyp >= e.b * dxp;
                    fast = above;
                }
                else
                {
                    above = p.x + p.y * e.b > e.c;
                    if ( e.b < 0.0 )
                        above = !above;
                    if ( !above )
                        fast = true;
                }
                if ( !fast )
                {
                    dxs = topsite.coord.x - ( e.reg[0] ).coord.x;
                    above = e.b * (dxp * dxp - dyp * dyp)
                    < dxs * dyp * (1.0 + 2.0 * dxp / dxs + e.b * e.b);

                    if ( e.b < 0 )
                        above = !above;
                }
            }
            else // e.b == 1.0
            {
                yl = e.c - e.a * p.x;
                t1 = p.y - yl;
                t2 = p.x - topsite.coord.x;
                t3 = yl - topsite.coord.y;
                above = t1 * t1 > t2 * t2 + t3 * t3;
            }
            return ( el.ELpm == LE ? above : !above );
        }
Exemple #9
0
 private Site leftreg( Halfedge he )
 {
     if (he.ELedge == null)
     {
         return bottomsite;
     }
     return (he.ELpm == LE ? he.ELedge.reg[LE] : he.ELedge.reg[RE]);
 }
Exemple #10
0
        // remove the HalfEdge from the list of vertices
        private void PQdelete( Halfedge he )
        {
            Halfedge last;

            if (he.vertex != null)
            {
                last = PQhash [ PQbucket (he) ];
                while ( last.PQnext != he )
                {
                    last = last.PQnext;
                }

                last.PQnext = he.PQnext;
                PQcount--;
                he.vertex = null;
            }
        }
Exemple #11
0
        private bool ELinitialize()
        {
            ELhashsize = 2 * sqrt_nsites;
            ELhash = new Halfedge[ELhashsize];

            for (int i = 0; i < ELhashsize; i++)
            {
                ELhash[i] = null;
            }

            ELleftend = HEcreate ( null, 0 );
            ELrightend = HEcreate ( null, 0 );
            ELleftend.ELleft = null;
            ELleftend.ELright = ELrightend;
            ELrightend.ELleft = ELleftend;
            ELrightend.ELright = null;
            ELhash[0] = ELleftend;
            ELhash[ELhashsize - 1] = ELrightend;

            return true;
        }
Exemple #12
0
 double min_angle(Halfedge h)
 {
     compute_angles(h);
     return(System.Math.Min(System.Math.Min(System.Math.Min(System.Math.Min(aa_12, aa_b1), aa_c1), aa_2a), aa_2d));
 }
 public void remove(Halfedge halfEdge)
 {
     halfEdge.edgeListLeftNeighbor.edgeListRightNeighbor = halfEdge.edgeListRightNeighbor;
     halfEdge.edgeListRightNeighbor.edgeListLeftNeighbor = halfEdge.edgeListLeftNeighbor;
     halfEdge.edge = Edge.DELETED;
     halfEdge.edgeListLeftNeighbor = halfEdge.edgeListRightNeighbor = null;
 }
 private Halfedge init(Edge edge,LR lr)
 {
     this.edge=edge;
     leftRight=lr;
     nextInPriorityQueue=null;
     vertex=null;
     return this;
 }
Exemple #15
0
    bool PrecondFlipEdge(Halfedge h)
    {
        Face hf = h.face;

        if (h.opp == null)
        {
            return(false);
        }
        Face hof = h.opp.face;

        if (FaceLabelContrain)
        {
            if (hf.label != hof.label)
            {
                return(false);
            }
        }
        if (FaceNormalContrain)
        {
            var fn  = hf.GetNormal();
            var fon = hof.GetNormal();

            if (Vector3D.Angle(fn, fon) > epsilonAngle)
            {
                return(false);
            }
        }

        // boundary case
        if (hf == null || hof == null)
        {
            return(false);
        }

        // We can only flip an edge if both incident polygons are triangles.
        if (hf.Circulate().Count != 3 || hof.Circulate().Count != 3)
        {
            return(false);
        }


        // non boundary vertices with a valency of less than 4(less than 3 after operation) degenerates mesh.
        Vertex hv  = h.vert;
        var    hov = h.opp.vert;

        if ((hv.Valency < 4 && !hv.IsBoundary()) || (hov.Valency < 4 && !hov.IsBoundary()))
        {
            return(false);
        }

        // Disallow flip if vertices being connected already are.
        Vertex hnv  = h.next.vert;
        Vertex honv = h.opp.next.vert;

        if (hnv.GetSharedEdge(honv) != null)
        {
            return(false);
        }

        return(true);
    }
 public void insert(Halfedge lb,Halfedge newHalfedge)
 {
     newHalfedge.edgeListLeftNeighbor=lb;
     newHalfedge.edgeListRightNeighbor=lb.edgeListRightNeighbor;
     lb.edgeListRightNeighbor.edgeListLeftNeighbor=newHalfedge;
     lb.edgeListRightNeighbor=newHalfedge;
 }
Exemple #17
0
    private void AddToQueue(Dictionary <int, HalfEdgeCounter> counter, SimplePriorityQueue <PQElement> Q, Halfedge h, EnergyFun efun, Dictionary <int, int> flipCounter, int time)
    {
        if (h.IsBoundary())
        {
            return;
        }
        // only consider one of the halfedges
        if (h.id < h.opp.id)
        {
            h = h.opp;
        }
        // if half edge already tested for queue in the current frame then skip
        HalfEdgeCounter c = null;

        if (!counter.TryGetValue(h.id, out c))
        {
            c             = new HalfEdgeCounter();
            counter[h.id] = c;
        }
        if (c.touched == time)
        {
            return;
        }
        c.isRemovedFromQueue = false;

        if (!PrecondFlipEdge(h))
        {
            return;
        }

        double energy = efun.DeltaEnergy(h);

        c.touched = time;

        const int avgValence = 6;
        int       count      = 0;

        if (!flipCounter.TryGetValue(h.vert.id, out count))
        {
            flipCounter[h.vert.id] = 0;
        }
        if ((energy < 0) && (count < avgValence))
        {
            Q.Enqueue(new PQElement(energy, h, time), (float)energy);
        }
    }
Exemple #18
0
 //PQElement() {}
 public PQElement(double _pri, Halfedge _h, int _time)
 {
     pri  = _pri;
     h    = _h;
     time = _time;
 }
Exemple #19
0
 public virtual double Energy(Halfedge h)
 {
     return(0);
 }
Exemple #20
0
    /// <summary>
    /// Split edges (and vertices) if
    ///     angle between faces is less than sharpEdgeAngle
    ///     or if face ids are different (when splitByFaceId is true)
    /// Note that this will not preserve the edge labels nor face labels
    /// </summary>
    /// <param name="sharpEdgeAngle"></param>
    /// <param name="splitByFaceId"></param>

    // Creates a new HMesh where sharp edges and materials (defined by face labels) results in edge splits
    public HMesh Split(bool splitByFaceLabel = true, double sharpEdgeAngle = 360)
    {
        MarkSharpEdges(sharpEdgeAngle);
        if (splitByFaceLabel)
        {
            MarkSharpEdgesByLabel();
        }

        Halfedge[] oldIdToNewEdge = new Halfedge[halfedgeMaxId + 1];

        // main concept:
        // halfedges with label != 0 should not be glued together
        // A vertex should be split into multiple vertices and assigned to regions of halfedges.
        // a pair of the max outgoing he id for a single side and the vertex id
        Vertex[] splitVertex = new Vertex[halfedgeMaxId + 1];
        HMesh    newHMesh    = new HMesh();

        var findOrCreateVertex = new Func <Halfedge, Vertex>(delegate(Halfedge he){
            // find maximum ingoing he
            var h = he;
            // rewind
            while (h.opp != null && h.label == 0 && h.opp.prev != he)
            {
                h = h.opp.prev;
            }
            int maxId = h.id;
            var first = h;
            while (h.next.opp != null && h.next.label == 0 && h.next.opp != first)
            {
                h     = h.next.opp;
                maxId = Mathf.Max(h.id, maxId);
            }

            Vertex res = splitVertex[maxId];
            if (res == null)
            {
                res                = newHMesh.CreateVertex(he.vert.positionD);
                res.label          = he.vert.label;
                res.uv1            = he.vert.uv1;
                res.uv2            = he.vert.uv2;
                splitVertex[maxId] = res;
            }

            return(res);
        });

        foreach (var face in GetFacesRaw())
        {
            // copy the face and half edges
            Face newFace = newHMesh.CreateFace();
            newFace.label = face.label;
            var edges      = face.Circulate();
            var edgeList   = new Halfedge[edges.Count];
            var vertexList = new Vertex[edges.Count];
            for (int i = 0; i < edges.Count; i++)
            {
                var newEdge = newHMesh.CreateHalfedge();
                oldIdToNewEdge[edges[i].id] = newEdge;
                var newVertex = findOrCreateVertex(edges[i]);

                edgeList[i]   = newEdge;
                vertexList[i] = newVertex;

                if (i > 0)
                {
                    edgeList[i - 1].Link(edgeList[i]);
                }
                if (i == edges.Count - 1)
                {
                    edgeList[i].Link(edgeList[0]);
                }

                newEdge.Link(newFace);
            }

            for (int i = 0; i < edgeList.Length; i++)
            {
                edgeList[i].vert = vertexList[i];
            }
        }
        foreach (var oldHE in GetHalfedgesRaw())
        {
            if (oldHE.opp == null || oldHE.label != 0)
            {
                continue;
            }
            if (oldHE.opp.id < oldHE.id)
            {
                continue;                                     // only glue one way
            }
            var newHe    = oldIdToNewEdge[oldHE.id];
            var newHeOpp = oldIdToNewEdge[oldHE.opp.id];
            newHe.Glue(newHeOpp);
        }
        return(newHMesh);
    }
Exemple #21
0
    public HMesh Copy()
    {
        List <Vertex>   fromVert     = new List <Vertex>();
        List <Face>     fromFaces    = new List <Face>();
        List <Halfedge> fromHalfedge = new List <Halfedge>();

        List <Vertex>   toVert     = new List <Vertex>();
        List <Face>     toFace     = new List <Face>();
        List <Halfedge> toHalfedge = new List <Halfedge>();

        HMesh newMesh = new HMesh();

        int index = 0;

        foreach (var v in vertices)
        {
            v.label = index;
            fromVert.Add(v);
            var nv = newMesh.CreateVertex(v.positionD);
            nv.uv1 = v.uv1;
            nv.uv2 = v.uv2;
            toVert.Add(nv);
            index++;
        }
        index = 0;
        foreach (var f in faces)
        {
            f.label = index;
            fromFaces.Add(f);
            var nf = newMesh.CreateFace();
            nf.label = f.label;
            toFace.Add(nf);
            index++;
        }
        index = 0;
        foreach (var e in halfedges)
        {
            e.label = index;
            fromHalfedge.Add(e);
            toHalfedge.Add(newMesh.CreateHalfedge());
            index++;
        }

        foreach (var from in faces)
        {
            Face to = toFace[from.label];
            if (from.halfedge != null)
            {
                to.halfedge = toHalfedge[from.halfedge.label];
            }
        }

        foreach (var from in halfedges)
        {
            Halfedge to = toHalfedge[from.label];
            if (from.face != null)
            {
                to.face = toFace[from.face.label];
            }
            if (from.opp != null)
            {
                to.opp = toHalfedge[from.opp.label];
            }
            if (from.next != null)
            {
                to.next = toHalfedge[from.next.label];
            }
            if (from.prev != null)
            {
                to.prev = toHalfedge[from.prev.label];
            }
            if (from.vert != null)
            {
                to.vert = toVert[from.vert.label];
            }
        }
        return(newMesh);
    }
Exemple #22
0
    public void Build(Mesh mesh, Matrix4x4 transform, int submesh = 0)
    {
        if (mesh.GetTopology(0) != MeshTopology.Triangles)
        {
            Debug.LogError("Only triangles supported.");
        }

        Dictionary <ulong, Halfedge> halfedgeByVertexID = new Dictionary <ulong, Halfedge>();

        // Create a list of (HMesh) Vertices
        var           meshVertices = mesh.vertices;
        var           meshUv       = mesh.uv;
        var           meshUv2      = mesh.uv2;
        List <Vertex> vertexList   = new List <Vertex>(meshVertices.Length);
        bool          hasUv1       = meshUv != null && meshUv.Length == meshVertices.Length;
        bool          hasUv2       = meshUv2 != null && meshUv2.Length == meshVertices.Length;

        for (int i = 0; i < meshVertices.Length; i++)
        {
            var newV = CreateVertex();
            newV.position = transform.MultiplyPoint(meshVertices[i]);
            if (hasUv1)
            {
                newV.uv1 = meshUv[i];
            }
            if (hasUv2)
            {
                newV.uv2 = meshUv2[i];
            }
            vertexList.Add(newV);
        }


        // create faces and half edges
        var meshTriangles = mesh.GetTriangles(submesh);

        for (int i = 0; i < meshTriangles.Length; i += 3)
        {
            int[] idx = new int[] {
                meshTriangles[i],
                meshTriangles[i + 1],
                meshTriangles[i + 2]
            };
            Halfedge[] edges = new Halfedge[3];
            Face       face  = CreateFace();
            for (int j = 0; j < 3; j++)
            {
                Halfedge edge = CreateHalfedge();
                edge.Link(face);
                edges[j] = edge;
            }
            for (int j = 0; j < 3; j++)
            {
                int from = idx[j];
                int to   = idx[(j + 1) % 3];
                edges[j].Link(edges[(j + 1) % 3]);
                edges[j].vert = vertexList[to];
                edges[j].vert.label++;
                ulong edgeId = EdgeKey(from, to);
                if (halfedgeByVertexID.ContainsKey(edgeId))
                {
                    var oldEdge = halfedgeByVertexID[edgeId];

                    Debug.LogError("Edge old edge from " + oldEdge.vert.position + " to " + oldEdge.prev.vert.position);
                    Debug.LogError("Edge already exists from " + vertexList[to].position + " to " + vertexList[from].position);
                }
                halfedgeByVertexID.Add(edgeId, edges[j]);
            }
        }
        for (int i = vertexList.Count - 1; i >= 0; i--)
        {
            if (vertexList[i].label == 0)
            {
                Destroy(vertexList[i]);
            }
        }
        int glued = 0;

        // glue all opposite half edges
        for (int i = 0; i < meshTriangles.Length; i += 3)
        {
            int[] idx =
            {
                meshTriangles[i],
                meshTriangles[i + 1],
                meshTriangles[i + 2]
            };
            for (int j = 0; j < 3; j++)
            {
                int      from            = idx[j];
                int      to              = idx[(j + 1) % 3];
                ulong    key             = EdgeKey(from, to);
                ulong    oppKey          = EdgeKey(to, from);
                Halfedge edge            = halfedgeByVertexID[key];
                bool     isOppUnassigned = edge.opp == null;
                if (isOppUnassigned && key < oppKey && halfedgeByVertexID.ContainsKey(oppKey))
                {
                    Halfedge oppEdge = halfedgeByVertexID[oppKey];
                    edge.Glue(oppEdge);
                    glued++;
                }
            }
        }

        SplitNonManifoldVertices();
    }
Exemple #23
0
 private Halfedge ELleft( Halfedge he )
 {
     return he.ELleft;
 }
Exemple #24
0
 /*
  * This delete routine can't reclaim node, since pointers from hash table
  * may be present.
  */
 private void ELdelete( Halfedge he )
 {
     (he.ELleft).ELright = he.ELright;
     (he.ELright).ELleft = he.ELleft;
     he.deleted = true;
 }
Exemple #25
0
        private Halfedge HEcreate(Edge e, int pm)
        {
            Halfedge answer = new Halfedge();
            answer.ELedge = e;
            answer.ELpm = pm;
            answer.PQnext = null;
            answer.vertex = null;

            return answer;
        }
Exemple #26
0
 private void ELinsert( Halfedge lb, Halfedge newHe )
 {
     newHe.ELleft = lb;
     newHe.ELright = lb.ELright;
     (lb.ELright).ELleft = newHe;
     lb.ELright = newHe;
 }
Exemple #27
0
 public abstract double DeltaEnergy(Halfedge h);
Exemple #28
0
 private Halfedge ELright( Halfedge he )
 {
     return he.ELright;
 }
 static bool PrecondFlipEdge(HMesh mesh, Halfedge he)
 {
     return true;
 }
Exemple #30
0
        // create a new site where the HalfEdges el1 and el2 intersect - note that
        // the Point in the argument list is not used, don't know why it's there
        private Site intersect( Halfedge el1, Halfedge el2 )
        {
            Edge e1, e2, e;
            Halfedge el;
            double d, xint, yint;
            bool right_of_site;
            Site v; // vertex

            e1 = el1.ELedge;
            e2 = el2.ELedge;

            if ( e1 == null || e2 == null )
                return null;

            // if the two edges bisect the same parent, return null
            if ( e1.reg[1] == e2.reg[1] )
                return null;

            d = e1.a * e2.b - e1.b * e2.a;
            if ( -1.0e-10 < d && d < 1.0e-10 )
                return null;

            xint = ( e1.c * e2.b - e2.c * e1.b ) / d;
            yint = ( e2.c * e1.a - e1.c * e2.a ) / d;

            if ( (e1.reg[1].coord.y < e2.reg[1].coord.y)
                || (e1.reg[1].coord.y == e2.reg[1].coord.y && e1.reg[1].coord.x < e2.reg[1].coord.x) )
            {
                el = el1;
                e = e1;
            }
            else
            {
                el = el2;
                e = e2;
            }

            right_of_site = xint >= e.reg[1].coord.x;
            if ((right_of_site && el.ELpm == LE)
                || (!right_of_site && el.ELpm == RE))
                return null;

            // create a new site at the point of intersection - this is a new vector
            // event waiting to happen
            v = new Site();
            v.coord.x = xint;
            v.coord.y = yint;
            return v;
        }
 static void FlipEdge(Halfedge e, Stack<Halfedge> flipStack)
 {
     e.Flip();
 }
Exemple #32
0
        private int PQbucket( Halfedge he )
        {
            int bucket;

            bucket = (int) ((he.ystar - ymin) / deltay * PQhashsize);
            if ( bucket < 0 )
                bucket = 0;
            if ( bucket >= PQhashsize )
                bucket = PQhashsize - 1;
            if ( bucket < PQmin )
                PQmin = bucket;

            return bucket;
        }
    static bool IsLocalDelaunay(Halfedge e)
    {
        if (e.IsBoundary()){
            return true;
        }
        Vector3 p1 = e.vert.position;
        Vector3 p2 = e.next.vert.position;
        Vector3 p3 = e.next.next.vert.position;
        Vector3 p4 = e.opp.next.vert.position;

        return HMeshMath.InCircle(p1,p2,p3,p4) || HMeshMath.InCircle(p2,p1,p4,p2);
    }
Exemple #34
0
        private bool PQinitialize()
        {
            PQcount = 0;
            PQmin = 0;
            PQhashsize = 4 * sqrt_nsites;
            PQhash = new Halfedge[ PQhashsize ];

            for ( int i = 0; i < PQhashsize; i++ )
            {
                PQhash [i] = new Halfedge();
            }
            return true;
        }
 /// <summary>
 ///
 /// </summary>
 /// <typeparam name="V"></typeparam>
 /// <typeparam name="E"></typeparam>
 /// <param name="hedge"></param>
 /// <param name="getPosition"></param>
 /// <returns></returns>
 public static Line ToLine <V, E>(this Halfedge <V, E> hedge)
     where V : HeVertex <V, E>, IPosition3d
     where E : Halfedge <V, E>
 {
     return(ToLine(hedge, IPosition3d <V> .Get));
 }
Exemple #36
0
        private Site rightreg(Halfedge he)
        {
            if (he.ELedge == (Edge) null)
                // if this halfedge has no edge, return the bottom site (whatever
                // that is)
            {
                return (bottomsite);
            }

            // if the ELpm field is zero, return the site 0 that this edge bisects,
            // otherwise return site number 1
            return (he.ELpm == LE ? he.ELedge.reg[RE] : he.ELedge.reg[LE]);
        }
 Site rightRegion(Halfedge he,Site bottomMostSite)
 {
     Edge edge = he.edge;
     if (edge == null)
     {
         return bottomMostSite;
     }
     return edge.site(LR.other(he.leftRight));
 }
 private int bucket(Halfedge halfEdge)
 {
     int theBucket= (halfEdge.ystar - _ymin)/_deltay * _hashsize;
     if (theBucket < 0) theBucket = 0;
     if (theBucket >= _hashsize) theBucket = _hashsize - 1;
     return theBucket;
 }
 public void reallyDispose()
 {
     edgeListLeftNeighbor = null;
     edgeListRightNeighbor = null;
     nextInPriorityQueue = null;
     edge = null;
     leftRight = null;
     vertex = null;
     _pool.RemoveAt(_pool.Count-1);
 }
Exemple #40
0
    /// <summary>
    /// Construct the geometry from a mesh.
    /// </summary>
    public void FromMesh(Mesh mesh)
    {
        linkedMesh = mesh;
        Clear();

        // Build vertices
        Vector3[] meshVerts = mesh.vertices;
        for (int i = 0; i < meshVerts.Length; i++) {
            vertices.Add(new Vertex(meshVerts[i]));
            vertices[i].index = i;
            vertices[i].edges = new List<Halfedge>();
        }

        // Build faces and halfedges, linked to vertices
        int[] meshFaces = mesh.triangles;
        for (int i = 0; i < meshFaces.Length / 3; i++) {
            Face trig = new Face();
            Halfedge e1 = new Halfedge(), e2 = new Halfedge(), e3 = new Halfedge();
            e1.face = trig;
            e1.next = e2;
            e1.prev = e3;
            e1.vertex = vertices[meshFaces[3*i]];
            e2.face = trig;
            e2.next = e3;
            e2.prev = e1;
            e2.vertex = vertices[meshFaces[3*i+1]];
            e3.face = trig;
            e3.next = e1;
            e3.prev = e2;
            e3.vertex = vertices[meshFaces[3*i+2]];
            trig.edge = e1;
            trig.index = i;

            faces.Add(trig);
            halfedges.Add(e1);
            halfedges.Add(e2);
            halfedges.Add(e3);
            e1.vertex.edge = e1;
            e1.vertex.edges.Add(e1);
            e2.vertex.edge = e2;
            e2.vertex.edges.Add(e2);
            e3.vertex.edge = e3;
            e3.vertex.edges.Add(e3);
        }

        // Set the corresponding opposite to each halfedge
        for (int i = 0; i < vertices.Count; i++) {
            vertices[i].onBorder = false;
            for (int j = 0; j < vertices[i].edges.Count; j++) {
                Halfedge et = vertices[i].edges[j];
                if (et.opposite == null) {
                    Vertex vt = et.prev.vertex;
                    bool foundOpposite = false;
                    for (int k = 0; k < vt.edges.Count; k++) {
                        if (vt.edges[k].prev.vertex == vertices[i]) {
                            if (foundOpposite) {
                                //GameObject.Instantiate(GameObject.Find("Pin")).transform.position = vertices[i].p;
                                throw new Exception("Edge shared by 3 faces, not manifold!");
                            }
                            et.opposite = vt.edges[k];
                            //vt.edges[k].opposite = et;
                            //break;
                            foundOpposite = true;
                        }
                    }

                    // If no opposite, we are on a boundary
                    if (et.opposite == null) {
                        vertices[i].onBorder = true;
                        et.opposite = new Halfedge();
                        et.opposite.opposite = et;
                        et.opposite.vertex = et.prev.vertex;
                        halfedges.Add(et.opposite);
                    }
                }
            }
        }
        //throw new UnityException("WOW");

        // Reconnect all newly created halfedges on a boundary
        for (int i = 0; i < halfedges.Count; i++) {
            if (halfedges[i].next == null) {
                // This halfedge is on a boundary, adding a new boundary face.
                Face boundary = new Face();
                boundaries.Add(boundary);
                boundary.edge = halfedges[i];
                boundary.index = -1;

                // Connect all halfedges of this boundary
                Halfedge first = halfedges[i], temp = halfedges[i];
                do {
                    Halfedge next = temp.opposite;
                    while (next.prev != null) {
                        next = next.prev.opposite;
                    }
                    temp.next = next;
                    next.prev = temp;
                    temp.face = boundary;
                    temp.vertex.edges.Add(temp);
                    temp = next;
                } while (temp != first);
            }
        }
        //throw new UnityException("WOW");

        for (int i = 0; i < vertices.Count; i++) {
            vertices[i].ClearEdgeArray();
        }

        // Calculate the max edge length
        h = 0;
        foreach (Halfedge e in halfedges) {
            if (e.Length() > h) {
                h = e.Length();
            }
            //h += e.Length();
        }
        //h /= halfedges.Count;

        Debug.Log("Geometry created, Eular number = " + (vertices.Count - halfedges.Count / 2 + faces.Count));
    }
Exemple #41
0
    public void BuildFromObj(string objFileContent, bool splitNonManifoldVertices = true)
    {
        StringReader  stringReader = new StringReader(objFileContent);
        string        line;
        List <Vertex> vertices = new List <Vertex>();
        Dictionary <IntPair, Halfedge> heLookup = new Dictionary <IntPair, Halfedge> ();
        int label = -1;

        while ((line = stringReader.ReadLine()) != null)
        {
            var tokens = line.Trim().Split(' ');
            if (tokens.Length == 0)
            {
                continue;
            }
            if (tokens[0] == "o")
            {
                label++;
            }
            if (tokens[0] == "v")
            {
                var v = CreateVertex(new Vector3D(double.Parse(tokens[1]), double.Parse(tokens[2]),
                                                  double.Parse(tokens[3])));
                vertices.Add(v);
            }
            if (tokens[0] == "f")
            {
                List <int> vertexIndices = new List <int>();
                for (var i = 1; i < tokens.Length; i++)
                {
                    var vertexIdx = int.Parse(tokens[i].Split('/')[0]) - 1;
                    vertexIndices.Add(vertexIdx);
                }
                var face = CreateFace();
                face.label = Mathf.Max(0, label);
                for (var i = 0; i < vertexIndices.Count; i++)
                {
                    var halfEdge = CreateHalfedge();
                    halfEdge.Link(face);
                    heLookup[new IntPair(vertexIndices[i], vertexIndices[(i + 1) % vertexIndices.Count])] = halfEdge;
                    Halfedge opp = null;
                    if (heLookup.TryGetValue(
                            new IntPair(vertexIndices[(i + 1) % vertexIndices.Count], vertexIndices[i]), out opp))
                    {
                        // if (invalid) 2-gon face, then don't glue
                        // this would connect opp to itself
                        if (vertexIndices.Count > 2)
                        {
                            halfEdge.Glue(opp);
                        }
                    }
                    halfEdge.vert = vertices[vertexIndices[(i + 1) % vertexIndices.Count]];
                }
                for (var i = 0; i < vertexIndices.Count; i++)
                {
                    var thisHe = heLookup[new IntPair(vertexIndices[i], vertexIndices[(i + 1) % vertexIndices.Count])];
                    var nextHe = heLookup[
                        new IntPair(vertexIndices[(i + 1) % vertexIndices.Count],
                                    vertexIndices[(i + 2) % vertexIndices.Count])];
                    thisHe.Link(nextHe);
                }
            }
        }
        if (splitNonManifoldVertices)
        {
            SplitNonManifoldVertices();
        }
    }