Ejemplo n.º 1
0
            public Vector3 CalcMidpoint()
            {
                Vector3 accum = Vector3.zero;
                int     ct    = 0;

                if (edges.Count >= 3) // Sanity check
                {
                    WEdge eStart = this.edges[0];
                    accum += eStart.GetEdgeVert(this).position;
                    ++ct;

                    for (
                        WEdge eIt = eStart.GetConnectingEdge(this);
                        eIt != eStart;
                        eIt = eIt.GetConnectingEdge(this))
                    {
                        accum += eIt.GetEdgeVert(this).position;
                        ++ct;
                    }
                }

                if (ct == 0)
                {
                    return(Vector3.zero);
                }

                return(accum / (float)ct);
            }
Ejemplo n.º 2
0
        public WGraph <T, TOp, WGraphNode <T, WEdge <T> >, WEdge <T> > ToGraph()
        {
            var res         = new WGraphNode <T, WEdge <T> > [edgeContainer.Length];
            var csr         = edgeContainer.ToCSR();
            var counter     = new int[res.Length];
            var rootCounter = edgeContainer.IsDirected ? new int[res.Length] : counter;
            var children    = new WEdge <T> [res.Length][];
            var roots       = edgeContainer.IsDirected ? new WEdge <T> [res.Length][] : children;

            for (int i = 0; i < res.Length; i++)
            {
                if (children[i] == null)
                {
                    children[i] = new WEdge <T> [edgeContainer.sizes[i]];
                }
                if (roots[i] == null)
                {
                    roots[i] = new WEdge <T> [edgeContainer.rootSizes[i]];
                }
                res[i] = new WGraphNode <T, WEdge <T> >(i, roots[i], children[i]);
                foreach (ref var e in csr.EList.AsSpan(csr.Start[i], csr.Start[i + 1] - csr.Start[i]))
                {
                    var to = e.To;
                    if (roots[to] == null)
                    {
                        roots[to] = new WEdge <T> [edgeContainer.rootSizes[to]];
                    }
                    children[i][counter[i]++]    = e;
                    roots[to][rootCounter[to]++] = e.Reversed(i);
                }
            }
            return(new WGraph <T, TOp, WGraphNode <T, WEdge <T> >, WEdge <T> >(res, csr));
        }
Ejemplo n.º 3
0
            public WEdge AddBlankEdge()
            {
                WEdge e = new WEdge();

                e.selfNode = this.edges.AddLast(e);
                return(e);
            }
Ejemplo n.º 4
0
            public bool SetEdgeFromFace(WEdge e, Face f)
            {
                if (this.conA.face == f)
                {
                    this.conA.edge = e;
                    return(true);
                }

                if (this.conB.face == f)
                {
                    this.conB.edge = e;
                    return(true);
                }

                return(false);
            }
Ejemplo n.º 5
0
            void SimpleTriangulate()
            {
                List <Face> origFaces = new List <Face>(this.faces);

                foreach (Face f in origFaces)
                {
                    if (f.edges.Count <= 3)
                    {
                        break;
                    }

                    List <WEdge> origEdges = new List <WEdge>(f.edges);

                    // Created edges that will be used as part of the next triangle in the fan
                    WEdge sE = null;

                    // Processing the first triangle of the fan is a bit different
                    // than the rest.

                    // TODO:
                }
            }
Ejemplo n.º 6
0
            public void Clear()
            {
                while (this.edges.Count != 0)
                {
                    WEdge e = this.edges.First.Value;

                    e.conA.edge = null;
                    e.conA.face = null;
                    e.conA.vert = null;
                    e.conB.edge = null;
                    e.conB.face = null;
                    e.conB.vert = null;

                    e.selfNode = null;

                    this.edges.RemoveFirst();
                }

                while (this.vertices.Count != 0)
                {
                    Vert v = this.vertices.First.Value;

                    v.edges.Clear();
                    v.selfNode = null;

                    this.vertices.RemoveFirst();
                }

                while (this.faces.Count != 0)
                {
                    Face f = this.faces.First.Value;

                    f.edges.Clear();
                    f.selfNode = null;

                    f.edges.Clear();
                }
            }
Ejemplo n.º 7
0
            public Face CreateFace(params Vector3 [] rv3s)
            {
                List <Vert> verts = new List <Vert>();

                foreach (Vector3 v in rv3s)
                {
                    verts.Add(this.GetVert(v));
                }

                Face f = this.shape.AddBlankFace();

                for (int i = 0; i < verts.Count; ++i)
                {
                    WEdge we;
                    Vert  vCur = verts[i];
                    Vert  vNxt = verts[(i + 1) % verts.Count];

                    if (this.knownEdgeFromVerts.TryGetValue(new TwoVert(vCur, vNxt), out we) == true)
                    {
                        if (we.conA.face == null || we.conB.face != null)
                        {
                        }   // Throw error

                        we.conB.face = f;
                    }
                    else
                    {
                        we = this.shape.AddBlankEdge();
                        this.knownEdgeFromVerts.Add(new TwoVert(vCur, vNxt), we);

                        vCur.edges.Add(we);
                        vNxt.edges.Add(we);

                        we.conA.vert = vCur;
                        we.conB.vert = vNxt;

                        we.conA.face = f;
                    }
                    f.edges.Add(we);
                }

                // Define the faceloop
                for (int i = 0; i < f.edges.Count; ++i)
                {
                    // At this point, the size of edges and verts should be the same size,
                    // with
                    WEdge we = f.edges[i];
                    Vert  v  = verts[i];

                    WEdge weNext = f.edges[(i + 1) % f.edges.Count];

                    if (we.conA.face == f)
                    {
                        we.conA.edge = weNext;
                    }
                    else if (we.conB.face == f)
                    {
                        we.conB.edge = weNext;
                    }
                    else
                    {
                        // Throw error
                    }
                }
                return(f);
            }
Ejemplo n.º 8
0
 public VertEdgeCon(Vert vert, WEdge edge, Face face)
 {
     this.vert = vert;
     this.edge = edge;
     this.face = face;
 }
Ejemplo n.º 9
0
            public Shape Clone()
            {
                Shape sret = new Shape();

                // Create a map, where we can reference an old element and know what the
                // equivalent is in the new clone.
                Dictionary <Vert, Vert>   oldToNewVert = new Dictionary <Vert, Vert>();
                Dictionary <WEdge, WEdge> oldToNewEdge = new Dictionary <WEdge, WEdge>();
                Dictionary <Face, Face>   oldToNewFace = new Dictionary <Face, Face>();

                // Start copying elements to fill the maps.
                foreach (Vert v in this.vertices)
                {
                    oldToNewVert.Add(v, sret.AddVertice(v.position));
                }

                foreach (WEdge e in this.edges)
                {
                    oldToNewEdge.Add(e, sret.AddBlankEdge());
                }

                foreach (Face f in this.faces)
                {
                    oldToNewFace.Add(f, sret.AddBlankFace());
                }

                // Now that we have everything that could be referenced when constructing
                // the clone, start making the equivalent cloned connections.

                foreach (KeyValuePair <Vert, Vert> kvpv in oldToNewVert)
                {
                    Vert oldV = kvpv.Key;
                    Vert newV = kvpv.Value;

                    foreach (WEdge e in oldV.edges)
                    {
                        newV.edges.Add(oldToNewEdge[e]);
                    }
                }

                foreach (KeyValuePair <WEdge, WEdge> kvpe in oldToNewEdge)
                {
                    WEdge oldE = kvpe.Key;
                    WEdge newE = kvpe.Value;

                    // Transfer mapped conA stuff
                    if (oldE.conA.edge != null)
                    {
                        newE.conA.edge = oldToNewEdge[oldE.conA.edge];
                    }

                    if (oldE.conA.face != null)
                    {
                        newE.conA.face = oldToNewFace[oldE.conA.face];
                    }

                    if (oldE.conA.vert != null)
                    {
                        newE.conA.vert = oldToNewVert[oldE.conA.vert];
                    }

                    // Transfer mapped conB stuff
                    if (oldE.conB.edge != null)
                    {
                        newE.conB.edge = oldToNewEdge[oldE.conB.edge];
                    }

                    if (oldE.conB.face != null)
                    {
                        newE.conB.face = oldToNewFace[oldE.conB.face];
                    }

                    if (oldE.conB.vert != null)
                    {
                        newE.conB.vert = oldToNewVert[oldE.conB.vert];
                    }
                }

                foreach (KeyValuePair <Face, Face> kvpf in oldToNewFace)
                {
                    Face oldF = kvpf.Key;
                    Face newF = kvpf.Value;

                    foreach (WEdge e in oldF.edges)
                    {
                        newF.edges.Add(oldToNewEdge[e]);
                    }
                }

                return(sret);
            }
Ejemplo n.º 10
0
            public Mesh GenerateMesh()
            {
                // Convert unique verts to an array of Vector3 that can be
                // int indexable.
                List <Vector3>         mverts  = new List <Vector3>();
                Dictionary <Vert, int> vlookup = new Dictionary <Vert, int>();

                foreach (Vert v in this.vertices)
                {
                    vlookup.Add(v, mverts.Count);
                    mverts.Add(v.position);
                }

                // Convert the polygons into faces
                List <int> tris = new List <int>();

                foreach (Face f in this.faces)
                {
                    List <int> facevertidxs = new List <int>();

                    // An edge can have two faces comming off if it, so an edge
                    // has two faces assigned to it. Which edge and edge loop do we
                    // trace to create the face?
                    WEdge startingEdge = null;
                    for (WEdge wit = f.edges[0]; wit != startingEdge; /*adv done in loop*/)
                    {
                        WEdge next = null;
                        if (wit.conA.face == f)
                        {
                            facevertidxs.Add(vlookup[wit.conA.vert]);
                            next = wit.conA.edge;
                        }
                        else if (wit.conB.face == f)
                        {
                            facevertidxs.Add(vlookup[wit.conB.vert]);
                            next = wit.conB.edge;
                        }
                        else
                        {
                        }   // TODO: Throw error

                        if (startingEdge == null)
                        {
                            startingEdge = wit;
                        }

                        wit = next;
                    }

                    // This shouldn't happen unless we're in a degenerate state
                    if (facevertidxs.Count < 3)
                    {
                        continue;
                    }
                    else if (facevertidxs.Count == 3)
                    {
                        // Just append them in directly - no need for extra complicated code.
                        tris.AddRange(facevertidxs);
                    }
                    else
                    {
                        // For else we need to tesselate the polygon into triangles. For now we're just going
                        // to be simple and direct, do a triangle fan tesselation, using the first point as a pivot.
                        int pivot = facevertidxs[0];
                        for (
                            int i = 1;                  // The first point is already accounted for in pivot
                            i < facevertidxs.Count - 1; // We can only process points that aren't the last one.
                            ++i)
                        {
                            tris.Add(pivot);
                            tris.Add(facevertidxs[i + 0]);
                            tris.Add(facevertidxs[i + 1]);
                        }
                    }
                }


                Mesh m = new Mesh();

                if (mverts.Count != 0 && tris.Count != 0)
                {
                    m.subMeshCount = 1;
                    m.vertices     = mverts.ToArray();
                    m.SetIndices(tris.ToArray(), MeshTopology.Triangles, 0);
                    //m.RecalculateNormals();
                    m.RecalculateBounds();
                }

                return(m);
            }
Ejemplo n.º 11
0
 public bool CollapseSingleEdge(WEdge e)
 {
     return(false); // !TODO
 }
Ejemplo n.º 12
0
            public void SimpleSubdivide()
            {
                Dictionary <WEdge, Vert> midEdge = new Dictionary <WEdge, Vert>();
                Dictionary <Face, Vert>  midFace = new Dictionary <Face, Vert>();

                // We need to record what we're starting out with, because as we subdivide,
                // it's going to change those containers
                List <WEdge> startingEdges = new List <WEdge>(this.edges);
                List <Face>  startingFaces = new List <Face>(this.faces);

                // Edge centroids
                foreach (WEdge e in startingEdges)

                {
                    this.edges.Remove(e.selfNode);
                    if (e.conA.vert != null)
                    {
                        e.conA.vert.edges.Remove(e);
                    }

                    if (e.conB.vert != null)
                    {
                        e.conB.vert.edges.Remove(e);
                    }

                    // Centroid
                    Vert v = this.AddVertice(e.CalcMidpoint());
                    midEdge[e] = v;

                    WEdge e1 = this.AddBlankEdge();
                    WEdge e2 = this.AddBlankEdge();

                    // Subdivision
                    v.edges.Add(e1);
                    v.edges.Add(e2);

                    // Set them to the old faces (new faces don't exist yet)
                    // we do this, so later on we can identify them.
                    e1.conA.face = e.conA.face;
                    e2.conA.face = e.conA.face;
                    e1.conB.face = e.conB.face;
                    e2.conB.face = e.conB.face;

                    // Define the verts for the edges
                    e1.conA.vert = e.conA.vert;
                    e1.conB.vert = v;
                    // Define the verts for the edges
                    e2.conA.vert = v;
                    e2.conB.vert = e.conB.vert;
                }

                // Face centroids
                foreach (Face f in startingFaces)
                {
                    this.faces.Remove(f.selfNode);

                    // Create subdivided centroid vert.
                    Vert v = this.AddVertice(f.CalcMidpoint());
                    midFace[f] = v;

                    foreach (WEdge e in f.edges)
                    {
                        WEdge enew = this.AddBlankEdge();

                        enew.conA.vert = v;
                        enew.conB.vert = midEdge[e];

                        v.edges.Add(enew);
                        midEdge[e].edges.Add(enew);
                    }
                }

                foreach (Face f in startingFaces)
                {
                    // The edges in a vertice aren't in a certain order, but
                    // there's a property we can leverage
                    Vert v = midFace[f];
                    for (int i = 0; i < v.edges.Count; ++i)
                    {
                        int   nextIdx     = (i + 1) % v.edges.Count;
                        WEdge oldEdge     = f.edges[i];
                        WEdge oldEdgeNext = f.edges[nextIdx];

                        // the subdividing vert for oldEdge
                        Vert subdivVert     = midEdge[oldEdge];
                        Vert subdivVertNext = midEdge[oldEdgeNext];

                        // New edge from centroid vert to subdivVert
                        WEdge e0 = v.edges[i];
                        WEdge e1 = subdivVert.EdgeWithFaceAndNotVert(f, oldEdge.GetEdgeVert(f));
                        WEdge e2 = subdivVertNext.EdgeWithFaceAndVert(f, oldEdgeNext.GetEdgeVert(f));
                        WEdge e3 = v.edges[nextIdx];

                        Face fnew = this.AddBlankFace();

                        // Add edges
                        fnew.edges.Add(e0);
                        fnew.edges.Add(e1);
                        fnew.edges.Add(e2);
                        fnew.edges.Add(e3);
                        // Assemble the edge loop
                        e0.conA.edge = e1;
                        e0.conA.face = fnew;
                        //
                        e1.ReplaceFace(f, fnew);
                        e1.SetEdgeFromFace(e2, fnew);
                        //
                        e2.ReplaceFace(f, fnew);
                        e2.SetEdgeFromFace(e3, fnew);
                        //
                        e3.conB.edge = e0;
                        e3.conB.face = fnew;
                    }
                }
            }