示例#1
0
        /// <summary>
        /// Inserts the specified number of vertices along the given edge.
        /// </summary>
        /// <param name="hedge"></param>
        /// <param name="count"></param>
        /// <returns></returns>
        public TE DivideEdge(TE hedge, int count)
        {
            hedge.UnusedCheck();
            Halfedges.OwnsCheck(hedge);

            return(DivideEdgeImpl(hedge, count));
        }
示例#2
0
        /// <summary>
        /// Splits the given edge creating a new vertex and halfedge pair.
        /// Returns the new halfedge which starts from the new vertex.
        /// </summary>
        /// <param name="hedge"></param>
        public TE SplitEdge(TE hedge)
        {
            Halfedges.ContainsCheck(hedge);
            hedge.UnusedCheck();

            return(SplitEdgeImpl(hedge));
        }
示例#3
0
        /// <summary>
        /// Splits the given edge creating a new vertex and halfedge pair.
        /// Returns the new halfedge which starts from the new vertex.
        /// </summary>
        /// <param name="hedge"></param>
        public TE SplitEdge(TE hedge)
        {
            hedge.UnusedCheck();
            Halfedges.OwnsCheck(hedge);

            return(SplitEdgeImpl(hedge));
        }
示例#4
0
        /// <summary>
        /// Removes the given edge from the mesh.
        /// </summary>
        /// <param name="hedge"></param>
        public void RemoveEdge(TE hedge)
        {
            hedge.UnusedCheck();
            Halfedges.OwnsCheck(hedge);

            RemoveEdgeImpl(hedge);
        }
示例#5
0
        /// <summary>
        /// Constructor to build a custom mesh from Rhino's mesh type
        /// </summary>
        /// <param name="source">the Rhino mesh</param>
        public Mesh(Rhino.Geometry.Mesh source)
            : this()
        {
            // Check that the mesh is oriented and manifold
            bool isOriented, hasBoundary;
            var  isManifold = source.IsManifold(true, out isOriented, out hasBoundary);

            if (!isManifold || !isOriented)
            {
                return;
            }

            // Remove unused vertices
            source.Vertices.CullUnused();

            //var faces = Enumerable.Range(0, source.Faces.Count).Select(i => source.TopologyVertices.IndicesFromFace(i));
            //InitIndexed(source.TopologyVertices, faces);

            // Add vertices
            Vertices.Capacity = source.TopologyVertices.Count;
            foreach (Point3f p in source.TopologyVertices)
            {
                Vertices.Add(new Vertex(p));
            }

            // Add faces (and construct halfedges and store in hash table)
            for (int i = 0; i < source.Faces.Count; i++)
            {
                var vertices = source.TopologyVertices.IndicesFromFace(i).Select(v => Vertices[v]);
                Faces.Add(vertices);
            }

            // Find and link halfedge pairs
            Halfedges.MatchPairs();
        }
示例#6
0
        /// <summary>
        /// Removes the given edge from the mesh.
        /// </summary>
        /// <param name="hedge"></param>
        public void RemoveEdge(TE hedge)
        {
            Halfedges.ContainsCheck(hedge);
            hedge.UnusedCheck();

            RemoveEdgeImpl(hedge);
        }
示例#7
0
        /// <summary>
        /// Collapses the given halfedge by merging the vertices at either end.
        /// The start vertex of the given halfedge is removed.
        /// </summary>
        /// <param name="hedge"></param>
        public void CollapseEdge(TE hedge)
        {
            Halfedges.ContainsCheck(hedge);
            hedge.UnusedCheck();

            CollapseEdgeImpl(hedge);
        }
示例#8
0
        /// <summary>
        /// Collapses the given halfedge by merging the vertices at either end.
        /// The start vertex of the given halfedge is removed.
        /// </summary>
        /// <param name="hedge"></param>
        public void CollapseEdge(TE hedge)
        {
            hedge.UnusedCheck();
            Halfedges.OwnsCheck(hedge);

            CollapseEdgeImpl(hedge);
        }
示例#9
0
        public Mesh Extrude(List <double> distance, bool symmetric)
        {
            Mesh ext, top; // ext (base) == target

            if (symmetric)
            {
                ext = Offset(distance.Select(d => 0.5 * d).ToList());
                top = Offset(distance.Select(d => - 0.5 * d).ToList());
            }
            else
            {
                ext = Duplicate();
                top = Offset(distance);
            }

            top.Halfedges.Flip();

            // append top to ext (can't use Append() because copy would reverse face loops)
            foreach (var v in top.Vertices)
            {
                ext.Vertices.Add(v);
            }
            foreach (var h in top.Halfedges)
            {
                ext.Halfedges.Add(h);
            }
            foreach (var f in top.Faces)
            {
                ext.Faces.Add(f);
            }

            // get indices of naked halfedges in source mesh
            var naked = Halfedges.Select((item, index) => index)
                        .Where(i => Halfedges[i].Pair == null).ToList();

            if (naked.Count > 0)
            {
                int n      = Halfedges.Count;
                int failed = 0;
                foreach (var i in naked)
                {
                    Vertex[] vertices = new Vertex[] {
                        ext.Halfedges[i].Vertex,
                        ext.Halfedges[i].Prev.Vertex,
                        ext.Halfedges[i + n].Vertex,
                        ext.Halfedges[i + n].Prev.Vertex
                    };
                    if (ext.Faces.Add(vertices) == false)
                    {
                        failed++;
                    }
                }
            }

            ext.Halfedges.MatchPairs();

            return(ext);
        }
示例#10
0
        /// <summary>
        /// Detaches the given halfedge from its start vertex.
        /// </summary>
        /// <param name="hedge"></param>
        public void DetachHalfedge(TE hedge)
        {
            hedge.UnusedCheck();
            Halfedges.OwnsCheck(hedge);

            if (hedge.IsAtDegree1)
            {
                return;
            }

            DetachHalfedgeImpl(hedge);
        }
示例#11
0
        /// <summary>
        /// Appends a copy of another mesh to this one.
        /// </summary>
        /// <param name="other">Mesh to append to this one.</param>
        public void Append(Mesh other)
        {
            Mesh dup = other.Duplicate();

            Vertices.AddRange(dup.Vertices);
            foreach (Halfedge edge in dup.Halfedges)
            {
                Halfedges.Add(edge);
            }
            foreach (Face face in dup.Faces)
            {
                Faces.Add(face);
            }
        }
示例#12
0
        /// <summary>
        /// Splits a vertex in 2 connected by a new edge.
        /// Returns the new halfedge leaving the new vertex on success and null on failure.
        /// </summary>
        /// <param name="he0"></param>
        /// <param name="he1"></param>
        public TE SplitVertex(TE he0, TE he1)
        {
            he0.UnusedCheck();
            he1.UnusedCheck();

            Halfedges.OwnsCheck(he0);
            Halfedges.OwnsCheck(he1);

            if (he0.Start != he1.Start)
            {
                return(null);
            }

            return(SplitVertexImpl(he0, he1));
        }
            /// <summary>
            /// Searches for an indexed halfedge by iterating.
            /// </summary>
            /// <param name="index">The index of the halfedge to return.</param>
            /// <exception cref="ArgumentOutOfRangeException">Thrown when <paramref name="index"/> is negative or too large.</exception>
            /// <returns>The specified halfedge.</returns>
            public Halfedge GetHalfedge(Int32 index)
            {
                if (index < 0)
                {
                    throw new ArgumentOutOfRangeException("index", index, "The given index cannot be negative.");
                }

                try
                {
                    return(Halfedges.Skip(index).First());
                }
                catch (InvalidOperationException)
                {
                    throw new ArgumentOutOfRangeException("index", index, "The given index is too large.");
                }
            }
示例#14
0
        /// <summary>
        /// Returns the new halfedge starting at the new vertex.
        /// </summary>
        /// <param name="he0"></param>
        /// <param name="he1"></param>
        /// <returns></returns>
        public TE ZipEdges(TE he0, TE he1)
        {
            he0.UnusedCheck();
            he1.UnusedCheck();

            Halfedges.OwnsCheck(he0);
            Halfedges.OwnsCheck(he1);

            // halfedges must start at the same vertex
            if (he0.Start != he1.Start)
            {
                return(null);
            }

            return(ZipEdgesImpl(he0, he1));
        }
示例#15
0
        private void InitIndexed(IEnumerable <Point3f> verticesByPoints, IEnumerable <IEnumerable <int> > facesByVertexIndices)
        {
            // Add vertices
            foreach (Point3f p in verticesByPoints)
            {
                Vertices.Add(new Vertex(p));
            }

            // Add faces
            foreach (IEnumerable <int> indices in facesByVertexIndices)
            {
                Faces.Add(indices.Select(i => Vertices[i]));
            }

            // Find and link halfedge pairs
            Halfedges.MatchPairs();
        }
 /// <summary>
 /// Searches for the halfedge pointing to the specified face from this vertex.
 /// </summary>
 /// <param name="face">The face the halfedge to find points to.</param>
 /// <returns>The halfedge if it is found, otherwise null.</returns>
 public Halfedge FindHalfedgeTo(IFace face)
 {
     return(Halfedges.FirstOrDefault(h => h.Face == face));
 }
 /// <summary>
 /// Searches for the edge associated with the specified face.
 /// </summary>
 /// <param name="face">A face sharing an edge with this face.</param>
 /// <returns>The edge if it is found; otherwise <c>null</c>.</returns>
 public Edge FindEdgeTo(IFace face)
 {
     return(Halfedges.Where(h => h.Opposite.Face == face).Select(h => h.Edge).FirstOrDefault());
 }
示例#18
0
 public List <Line> ToLines()
 {
     return(Halfedges.GetUnique().Select(h => new Rhino.Geometry.Line(h.Prev.Vertex.Position, h.Vertex.Position)).ToList());
 }
 /// <summary>
 /// Searches for the edge associated with the specified vertex.
 /// </summary>
 /// <param name="vertex">A vertex sharing an edge with this vertex.</param>
 /// <returns>The edge if it is found, otherwise null.</returns>
 public Edge FindEdgeTo(IVertex vertex)
 {
     return(Halfedges.Where(h => h.ToVertex == vertex).Select(h => h.Edge).FirstOrDefault());
 }
示例#20
0
 /// <summary>
 /// Removes all unused elements from the graph.
 /// </summary>
 public void Compact()
 {
     Vertices.Compact();
     Halfedges.Compact();
 }
示例#21
0
 /// <summary>
 /// Shrinks the capacity of each element list to twice its count.
 /// </summary>
 public void TrimExcess()
 {
     Vertices.TrimExcess();
     Halfedges.TrimExcess();
 }
 /// <summary>
 /// Searches for a halfedge pointing to a vertex from this vertex.
 /// </summary>
 /// <param name="vertex">A vertex pointed to by the halfedge to search for.</param>
 /// <returns>The halfedge from this vertex to the specified vertex. If none exists, returns null.</returns>
 public Halfedge FindHalfedgeTo(IVertex vertex)
 {
     return(Halfedges.FirstOrDefault(h => h.ToVertex == vertex));
 }