示例#1
0
        /// <summary>
        ///     Calculates the midpoint of the specified edge.
        /// </summary>
        /// <returns>The point.</returns>
        /// <param name="edge">Edge.</param>
        public static Point3d MidPoint(MeshEdge edge)
        {
            var     halfEdge = edge.HalfEdge;
            Point3d a        = halfEdge.Vertex;
            Point3d b        = halfEdge.Twin.Vertex;

            return((a + b) / 2);
        }
示例#2
0
 /// <summary>
 ///     Calculates the length of the specified edge.
 /// </summary>
 /// <returns>The length.</returns>
 /// <param name="edge">Edge.</param>
 public static double Length(MeshEdge edge) => Vector(edge.HalfEdge).Length;
示例#3
0
文件: Mesh.cs 项目: Paramdigma/Core
        // Takes a List containing another List per face with the vertex indexes belonging to that face
        private bool CreateFaces(IEnumerable <List <int> > faceIndexes)
        {
            var edgeCount         = new Dictionary <string, int>();
            var existingHalfEdges = new Dictionary <string, MeshHalfEdge>();
            var hasTwinHalfEdge   = new Dictionary <MeshHalfEdge, bool>();

            // Create the faces, edges and half-edges, non-boundary loops and link references when possible;
            foreach (var indexes in faceIndexes)
            {
                var f = new MeshFace();
                this.Faces.Add(f);

                var tempHEdges = new List <MeshHalfEdge>(indexes.Count);

                // Create empty half-edges
                for (var i = 0; i < indexes.Count; i++)
                {
                    var h = new MeshHalfEdge();
                    tempHEdges.Add(h);
                }

                // Fill out each half edge
                for (var i = 0; i < indexes.Count; i++)
                {
                    // Edge goes from v0 to v1
                    var v0 = indexes[i];
                    var v1 = indexes[(i + 1) % indexes.Count];

                    var h = tempHEdges[i];

                    // Set previous and next
                    h.Next = tempHEdges[(i + 1) % indexes.Count];
                    h.Prev = tempHEdges[(i + indexes.Count - 1) % indexes.Count];

                    h.OnBoundary = false;
                    hasTwinHalfEdge.Add(h, false);

                    // Set half-edge & vertex mutually
                    h.Vertex = this.Vertices[v0];
                    this.Vertices[v0].HalfEdge = h;

                    // Set half-edge face & vice versa
                    h.Face     = f;
                    f.HalfEdge = h;

                    // Reverse v0 and v1 if v0 > v1
                    if (v0 > v1)
                    {
                        var temp = v0;
                        v0 = v1;
                        v1 = temp;
                    }

                    var key = v0 + " " + v1;
                    if (existingHalfEdges.ContainsKey(key))
                    {
                        // If this half-edge key already exists, it is the twin of this current half-edge
                        var twin = existingHalfEdges[key];
                        h.Twin                = twin;
                        twin.Twin             = h;
                        h.Edge                = twin.Edge;
                        hasTwinHalfEdge[h]    = true;
                        hasTwinHalfEdge[twin] = true;
                        edgeCount[key]++;
                    }
                    else
                    {
                        // Create an edge and set its half-edge
                        var e = new MeshEdge();
                        this.Edges.Add(e);
                        h.Edge     = e;
                        e.HalfEdge = h;

                        // Record the newly created half-edge
                        existingHalfEdges.Add(key, h);
                        edgeCount.Add(key, 1);
                    }
                }

                this.HalfEdges.AddRange(tempHEdges);
            }

            // Create boundary edges
            for (var i = 0; i < this.HalfEdges.Count; i++)
            {
                var h = this.HalfEdges[i];
                if (!hasTwinHalfEdge[h])
                {
                    var f = new MeshFace();
                    this.Boundaries.Add(f);

                    var boundaryCycle = new List <MeshHalfEdge>();
                    var halfEdge      = h;
                    do
                    {
                        var boundaryHalfEdge = new MeshHalfEdge();
                        this.HalfEdges.Add(boundaryHalfEdge);
                        boundaryCycle.Add(boundaryHalfEdge);

                        var nextHalfEdge = halfEdge.Next;
                        while (hasTwinHalfEdge[nextHalfEdge])
                        {
                            nextHalfEdge = nextHalfEdge.Twin.Next;
                        }

                        boundaryHalfEdge.Vertex     = nextHalfEdge.Vertex;
                        boundaryHalfEdge.Edge       = halfEdge.Edge;
                        boundaryHalfEdge.OnBoundary = true;

                        boundaryHalfEdge.Face = f;
                        f.HalfEdge            = boundaryHalfEdge;

                        boundaryHalfEdge.Twin = halfEdge;
                        halfEdge.Twin         = boundaryHalfEdge;

                        halfEdge = nextHalfEdge;
                    } while (halfEdge != h);

                    var n = boundaryCycle.Count;
                    for (var j = 0; j < n; j++)
                    {
                        boundaryCycle[j].Next                  = boundaryCycle[(j + n - 1) % n];
                        boundaryCycle[j].Prev                  = boundaryCycle[(j + 1) % n];
                        hasTwinHalfEdge[boundaryCycle[j]]      = true;
                        hasTwinHalfEdge[boundaryCycle[j].Twin] = true;
                    }
                }

                if (h.OnBoundary)
                {
                    continue;
                }

                var corner = new MeshCorner {
                    HalfEdge = h
                };
                h.Corner = corner;
                this.Corners.Add(corner);
            }

            // Check mesh for common errors
            if (this.HasIsolatedFaces() || this.HasIsolatedVertices() || this.HasNonManifoldEdges())
            {
                return(false);
            }

            // Index elements
            this.IndexElements();

            return(true);
        }