/// <summary> /// Initializes a new instance of the <see cref="MeshPoint"/> class. /// </summary> /// <param name="point">3D Point.</param> /// <param name="face">Mesh face.</param> public MeshPoint(Point3d point, MeshFace face) { List <MeshVertex> adj = face.AdjacentVertices(); double[] bary = Convert.Point3dToBarycentric(point, adj[0], adj[1], adj[2]); U = bary[0]; V = bary[1]; W = bary[2]; }
// Takes a List containing another List per face with the vertex indexes belonging to that face private bool CreateFaces(List <List <int> > faceIndexes) { Dictionary <string, int> edgeCount = new Dictionary <string, int>(); Dictionary <string, MeshHalfEdge> existingHalfEdges = new Dictionary <string, MeshHalfEdge>(); Dictionary <MeshHalfEdge, bool> hasTwinHalfEdge = new Dictionary <MeshHalfEdge, bool>(); // Create the faces, edges and half-edges, non-boundary loops and link references when possible; foreach (List <int> indexes in faceIndexes) { MeshFace f = new MeshFace(); Faces.Add(f); List <MeshHalfEdge> tempHEdges = new List <MeshHalfEdge>(indexes.Count); // Create empty half-edges for (int i = 0; i < indexes.Count; i++) { MeshHalfEdge h = new MeshHalfEdge(); tempHEdges.Add(h); } // Fill out each half edge for (int i = 0; i < indexes.Count; i++) { // Edge goes from v0 to v1 int v0 = indexes[i]; int v1 = indexes[(i + 1) % indexes.Count]; MeshHalfEdge 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 = Vertices[v0]; 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) { int temp = v0; v0 = v1; v1 = temp; } string key = v0 + " " + v1; if (existingHalfEdges.ContainsKey(key)) { // If this half-edge key already exists, it is the twin of this current half-edge MeshHalfEdge 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 MeshEdge e = new MeshEdge(); Edges.Add(e); h.Edge = e; e.HalfEdge = h; // Record the newly created half-edge existingHalfEdges.Add(key, h); edgeCount.Add(key, 1); } } HalfEdges.AddRange(tempHEdges); } // Create boundary edges for (int i = 0; i < HalfEdges.Count; i++) { MeshHalfEdge h = HalfEdges[i]; if (!hasTwinHalfEdge[h]) { MeshFace f = new MeshFace(); Boundaries.Add(f); List <MeshHalfEdge> boundaryCycle = new List <MeshHalfEdge>(); MeshHalfEdge hE = h; do { MeshHalfEdge bH = new MeshHalfEdge(); HalfEdges.Add(bH); boundaryCycle.Add(bH); MeshHalfEdge nextHE = hE.Next; while (hasTwinHalfEdge[nextHE]) { nextHE = nextHE.Twin.Next; } bH.Vertex = nextHE.Vertex; bH.Edge = hE.Edge; bH.OnBoundary = true; bH.Face = f; f.HalfEdge = bH; bH.Twin = hE; hE.Twin = bH; hE = nextHE; }while (hE != h); int n = boundaryCycle.Count; for (int 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) { MeshCorner corner = new MeshCorner { HalfEdge = h, }; h.Corner = corner; Corners.Add(corner); } } // Check mesh for common errors if (HasIsolatedFaces() || HasIsolatedVertices() || HasNonManifoldEdges()) { return(false); } // Index elements IndexElements(); return(true); }