/// <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)); }
/// <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)); }
/// <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)); }
/// <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); }
/// <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(); }
/// <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); }
/// <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); }
/// <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); }
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); }
/// <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); }
/// <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); } }
/// <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."); } }
/// <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)); }
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()); }
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()); }
/// <summary> /// Removes all unused elements from the graph. /// </summary> public void Compact() { Vertices.Compact(); Halfedges.Compact(); }
/// <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)); }