public FaceList(FaceList f) { for (int i = 0; i < f.Count; i++) { Add(new Face(f[i].v0, f[i].v1, f[i].v2, f[i].normal)); } }
public void CleanAndMerge() { var newVertices = new List <Vector3Float>(); var newFaces = new FaceList(); var positionToIndex = new Dictionary <(float, float, float), int>(); int GetIndex(Vector3Float position) { int index; if (positionToIndex.TryGetValue((position.X, position.Y, position.Z), out index)) { return(index); } var count = newVertices.Count; positionToIndex.Add((position.X, position.Y, position.Z), count); newVertices.Add(position); return(count); } foreach (var face in Faces) { int iv0 = GetIndex(Vertices[face.v0]); int iv1 = GetIndex(Vertices[face.v1]); int iv2 = GetIndex(Vertices[face.v2]); newFaces.Add(iv0, iv1, iv2, newVertices); } this.Faces = newFaces; this.Vertices = newVertices; }
public Mesh(List <Vector3Float> v, FaceList f) { Vertices.Clear(); Vertices.AddRange(v); Faces.Clear(); Faces.AddRange(f); }
public bool Split(Plane plane, double onPlaneDistance = .001, Func <SplitData, bool> clipFace = null, bool cleanAndMerge = true) { var newVertices = new List <Vector3Float>(); var newFaces = new List <Face>(); var facesToRemove = new HashSet <int>(); for (int i = 0; i < Faces.Count; i++) { var face = Faces[i]; if (face.Split(this.Vertices, plane, newFaces, newVertices, onPlaneDistance, clipFace)) { // record the face for removal facesToRemove.Add(i); } } // make a new list of all the faces we are keeping var keptFaces = new FaceList(); for (int i = 0; i < Faces.Count; i++) { if (!facesToRemove.Contains(i)) { keptFaces.Add(Faces[i]); } } var vertexCount = Vertices.Count; // add the new vertices Vertices.AddRange(newVertices); // add the new faces (have to make the vertex indices to the new vertices foreach (var newFace in newFaces) { Face faceNewIndices = newFace; faceNewIndices.v0 += vertexCount; faceNewIndices.v1 += vertexCount; faceNewIndices.v2 += vertexCount; keptFaces.Add(faceNewIndices); } Faces = keptFaces; if (cleanAndMerge) { CleanAndMerge(); } return(true); }
public void MergeVertices(double treatAsSameDistance) { if (Vertices.Count < 2) { return; } var sameDistance = new Vector3Float(treatAsSameDistance, treatAsSameDistance, treatAsSameDistance); var tinyDistance = new Vector3Float(.001, .001, .001); // build a bvh tree of all the vertices var bvhBuilder = new TradeOffBvhConstructor <int>(); var bvhTree = bvhBuilder.CreateNewHierachy(this.Vertices .Select((v, i) => new BvhTreeItemData <int>(i, new AxisAlignedBoundingBox(v - tinyDistance, v + tinyDistance))).ToList()); var newVertices = new List <Vector3Float>(Vertices.Count); var vertexIndexRemaping = Enumerable.Range(0, Vertices.Count).Select(i => - 1).ToList(); var searchResults = new List <int>(); // build up the list of index mapping for (int i = 0; i < Vertices.Count; i++) { // first check if we have already found this vertex if (vertexIndexRemaping[i] == -1) { var vertex = Vertices[i]; // remember the new index var newIndex = newVertices.Count; // add it to the vertices we will end up with newVertices.Add(vertex); // clear for new search searchResults.Clear(); // find everything close bvhTree.SearchBounds(new AxisAlignedBoundingBox(vertex - sameDistance, vertex + sameDistance), searchResults); // map them to this new vertex foreach (var result in searchResults) { // this vertex has not been mapped if (vertexIndexRemaping[result] == -1) { vertexIndexRemaping[result] = newIndex; } } } } // now make a new face list with the merge vertices int GetIndex(int originalIndex) { return(vertexIndexRemaping[originalIndex]); } var newFaces = new FaceList(); foreach (var face in Faces) { int iv0 = GetIndex(face.v0); int iv1 = GetIndex(face.v1); int iv2 = GetIndex(face.v2); if (iv0 != iv1 && iv1 != iv2 && iv2 != iv0) { newFaces.Add(iv0, iv1, iv2, newVertices); } } this.Faces = newFaces; this.Vertices = newVertices; }