Ejemplo n.º 1
0
		public static List<Mesh> SplitVolumesIntoMeshes(Mesh meshToSplit, ReportProgressRatio reportProgress)
		{
			List<Mesh> discreetVolumes = new List<Mesh>();
			HashSet<Face> facesThatHaveBeenAdded = new HashSet<Face>();
			Mesh meshFromCurrentVolume = null;
			Stack<Face> attachedFaces = new Stack<Face>();
			for (int faceIndex = 0; faceIndex < meshToSplit.Faces.Count; faceIndex++)
			{
				Face currentFace = meshToSplit.Faces[faceIndex];
				// If this face as not been added to any volume, create a new volume and add all of the attached faces.
				if (!facesThatHaveBeenAdded.Contains(currentFace))
				{
					attachedFaces.Push(currentFace);
					meshFromCurrentVolume = new Mesh();

					MeshMaterialData materialDataToCopy = MeshMaterialData.Get(meshToSplit);
					MeshMaterialData newMaterialData = MeshMaterialData.Get(meshFromCurrentVolume);
					newMaterialData.MaterialIndex = materialDataToCopy.MaterialIndex;

					while (attachedFaces.Count > 0)
					{
						Face faceToAdd = attachedFaces.Pop();
						foreach (Vertex attachedVertex in faceToAdd.Vertices())
						{
							foreach (Face faceAttachedToVertex in attachedVertex.ConnectedFaces())
							{
								if (!facesThatHaveBeenAdded.Contains(faceAttachedToVertex))
								{
									// marke that this face has been taken care of
									facesThatHaveBeenAdded.Add(faceAttachedToVertex);
									// add it to the list of faces we need to walk
									attachedFaces.Push(faceAttachedToVertex);

									// Add a new face to the new mesh we are creating.
									List<Vertex> faceVertices = new List<Vertex>();
									foreach (FaceEdge faceEdgeToAdd in faceAttachedToVertex.FaceEdges())
									{
										Vertex newVertex = meshFromCurrentVolume.CreateVertex(faceEdgeToAdd.firstVertex.Position, CreateOption.CreateNew, SortOption.WillSortLater);
										faceVertices.Add(newVertex);
									}

									meshFromCurrentVolume.CreateFace(faceVertices.ToArray(), CreateOption.CreateNew);
								}
							}
						}
					}

					meshFromCurrentVolume.CleanAndMergMesh();
					discreetVolumes.Add(meshFromCurrentVolume);
					meshFromCurrentVolume = null;
				}
				if (reportProgress != null)
				{
					double progress = faceIndex / (double)meshToSplit.Faces.Count;
					bool continueProcessing;
					reportProgress(progress, "Split Into Meshes", out continueProcessing);
				}
			}

			return discreetVolumes;
		}
Ejemplo n.º 2
0
        public static Mesh Copy(Mesh meshToCopy, ReportProgressRatio progress = null)
        {
            Mesh newMesh = new Mesh();

            if (meshToCopy.Vertices.IsSorted)
            {
                Dictionary <Vertex, int>   vertexIndexDictionary   = GetVertexToIndexDictionary(meshToCopy, newMesh);
                Dictionary <MeshEdge, int> meshEdgeIndexDictionary = GetMeshEdgeToIndexDictionary(meshToCopy, newMesh);

                for (int faceIndex = 0; faceIndex < meshToCopy.Faces.Count; faceIndex++)
                {
                    Face faceToCopy = meshToCopy.Faces[faceIndex];
                    newMesh.Faces.Add(new Face());
                }

                // now set all the data for the new mesh
                newMesh.Vertices.Capacity = meshToCopy.Vertices.Capacity;
                for (int vertexIndex = 0; vertexIndex < meshToCopy.Vertices.Count; vertexIndex++)
                {
                    Vertex vertexToCopy = meshToCopy.Vertices[vertexIndex];
                    // !!!! ON ERROR !!!!! If this throws an error, you likely need to CleanAndMergMesh the mesh before copying
                    int    indexOfFirstMeshEdge = meshEdgeIndexDictionary[vertexToCopy.firstMeshEdge];
                    Vertex newVertex            = newMesh.Vertices[vertexIndex];
                    newVertex.firstMeshEdge = newMesh.MeshEdges[indexOfFirstMeshEdge];
                    newVertex.Normal        = vertexToCopy.Normal;
                }

                newMesh.MeshEdges.Capacity = meshToCopy.MeshEdges.Capacity;
                for (int meshEdgeIndex = 0; meshEdgeIndex < meshToCopy.MeshEdges.Count; meshEdgeIndex++)
                {
                    MeshEdge meshEdgeToCopy = meshToCopy.MeshEdges[meshEdgeIndex];
                    MeshEdge newMeshEdge    = newMesh.MeshEdges[meshEdgeIndex];

                    newMeshEdge.NextMeshEdgeFromEnd[0] = newMesh.MeshEdges[meshEdgeIndexDictionary[meshEdgeToCopy.NextMeshEdgeFromEnd[0]]];
                    newMeshEdge.NextMeshEdgeFromEnd[1] = newMesh.MeshEdges[meshEdgeIndexDictionary[meshEdgeToCopy.NextMeshEdgeFromEnd[1]]];

                    newMeshEdge.VertexOnEnd[0] = newMesh.Vertices[vertexIndexDictionary[meshEdgeToCopy.VertexOnEnd[0]]];
                    newMeshEdge.VertexOnEnd[1] = newMesh.Vertices[vertexIndexDictionary[meshEdgeToCopy.VertexOnEnd[1]]];

                    // This will get hooked up when we create radial loops with the face edges below
                    //newMeshEdge.firstFaceEdge;
                    //newMesh.MeshEdges.Add(newMeshEdge);
                }

                newMesh.Faces.Capacity = meshToCopy.Faces.Capacity;
                for (int faceIndex = 0; faceIndex < meshToCopy.faces.Count; faceIndex++)
                {
                    Face faceToCopy = meshToCopy.faces[faceIndex];
                    Face newface    = newMesh.faces[faceIndex];

                    newface.normal = faceToCopy.normal;

                    // hook up the face edges
                    //public FaceEdge firstFaceEdge;
                    List <Vertex> verticesFromCopy = new List <Vertex>();
                    List <Vertex> verticesForNew   = new List <Vertex>();
                    foreach (Vertex vertex in faceToCopy.Vertices())
                    {
                        verticesFromCopy.Add(vertex);
                        verticesForNew.Add(newMesh.Vertices[vertexIndexDictionary[vertex]]);
                    }

                    List <MeshEdge> edgesFromCopy = new List <MeshEdge>();
                    List <MeshEdge> edgesForNew   = new List <MeshEdge>();
                    for (int i = 0; i < verticesForNew.Count - 1; i++)
                    {
                        MeshEdge meshEdgeFromCopy = verticesFromCopy[i].GetMeshEdgeConnectedToVertex(verticesFromCopy[i + 1]);
                        edgesFromCopy.Add(meshEdgeFromCopy);
                        edgesForNew.Add(newMesh.MeshEdges[meshEdgeIndexDictionary[meshEdgeFromCopy]]);
                    }
                    MeshEdge lastMeshEdgeFromCopy = verticesFromCopy[verticesFromCopy.Count - 1].GetMeshEdgeConnectedToVertex(verticesFromCopy[0]);
                    edgesFromCopy.Add(lastMeshEdgeFromCopy);
                    edgesForNew.Add(newMesh.MeshEdges[meshEdgeIndexDictionary[lastMeshEdgeFromCopy]]);

                    CreateFaceEdges(verticesForNew.ToArray(), edgesForNew, newface);
                }
            }
            else
            {
                foreach (Face face in meshToCopy.Faces)
                {
                    List <Vertex> faceVertices = new List <Vertex>();
                    foreach (FaceEdge faceEdgeToAdd in face.FaceEdges())
                    {
                        Vertex newVertex = newMesh.CreateVertex(faceEdgeToAdd.firstVertex.Position, CreateOption.CreateNew, SortOption.WillSortLater);
                        faceVertices.Add(newVertex);
                    }

                    newMesh.CreateFace(faceVertices.ToArray(), CreateOption.CreateNew);
                }

                newMesh.CleanAndMergMesh();
            }

            MeshMaterialData materialDataToCopy = MeshMaterialData.Get(meshToCopy);
            MeshMaterialData newMaterialData    = MeshMaterialData.Get(newMesh);

            newMaterialData.MaterialIndex = materialDataToCopy.MaterialIndex;

            return(newMesh);
        }
Ejemplo n.º 3
0
        public static Mesh DoMerge(List<Mesh> meshesToMerge, BackgroundWorker backgroundWorker, int startPercent, int endPercent, bool doCSGMerge = false)
        {
            int lengthPercent = endPercent - startPercent;

            Mesh allPolygons = new Mesh();
            if (doCSGMerge)
            {
                for (int i = 0; i < meshesToMerge.Count; i++)
                {
                    Mesh mesh = meshesToMerge[i];
                    allPolygons = CsgOperations.PerformOperation(allPolygons, mesh, CsgNode.Union);
                }
            }
            else
            {
                for (int i = 0; i < meshesToMerge.Count; i++)
                {
                    Mesh mesh = meshesToMerge[i];
                    foreach (Face face in mesh.Faces)
                    {
                        List<Vertex> faceVertices = new List<Vertex>();
                        foreach (FaceEdge faceEdgeToAdd in face.FaceEdges())
                        {
                            // we allow duplicates (the true) to make sure we are not changing the loaded models acuracy.
                            Vertex newVertex = allPolygons.CreateVertex(faceEdgeToAdd.firstVertex.Position, true, true);
                            faceVertices.Add(newVertex);
                        }

                        // we allow duplicates (the true) to make sure we are not changing the loaded models acuracy.
                        allPolygons.CreateFace(faceVertices.ToArray(), true);
                    }

                    int nextPercent = startPercent + (i + 1) * lengthPercent / meshesToMerge.Count;
                    backgroundWorker.ReportProgress(nextPercent);
                }

                allPolygons.CleanAndMergMesh();
            }

            return allPolygons;
        }
Ejemplo n.º 4
0
		public static Mesh Copy(Mesh meshToCopy, ReportProgressRatio progress = null)
		{
			Mesh newMesh = new Mesh();

			if (meshToCopy.Vertices.IsSorted)
			{
				Dictionary<Vertex, int> vertexIndexDictionary = GetVertexToIndexDictionary(meshToCopy, newMesh);
				Dictionary<MeshEdge, int> meshEdgeIndexDictionary = GetMeshEdgeToIndexDictionary(meshToCopy, newMesh);

				for (int faceIndex = 0; faceIndex < meshToCopy.Faces.Count; faceIndex++)
				{
					Face faceToCopy = meshToCopy.Faces[faceIndex];
					newMesh.Faces.Add(new Face());
				}

				// now set all the data for the new mesh
				newMesh.Vertices.Capacity = meshToCopy.Vertices.Capacity;
				for (int vertexIndex = 0; vertexIndex < meshToCopy.Vertices.Count; vertexIndex++)
				{
					Vertex vertexToCopy = meshToCopy.Vertices[vertexIndex];
					// !!!! ON ERROR !!!!! If this throws an error, you likely need to CleanAndMergMesh the mesh before copying
					int indexOfFirstMeshEdge = meshEdgeIndexDictionary[vertexToCopy.firstMeshEdge];
					Vertex newVertex = newMesh.Vertices[vertexIndex];
					newVertex.firstMeshEdge = newMesh.MeshEdges[indexOfFirstMeshEdge];
					newVertex.Normal = vertexToCopy.Normal;
				}

				newMesh.MeshEdges.Capacity = meshToCopy.MeshEdges.Capacity;
				for (int meshEdgeIndex = 0; meshEdgeIndex < meshToCopy.MeshEdges.Count; meshEdgeIndex++)
				{
					MeshEdge meshEdgeToCopy = meshToCopy.MeshEdges[meshEdgeIndex];
					MeshEdge newMeshEdge = newMesh.MeshEdges[meshEdgeIndex];

					newMeshEdge.NextMeshEdgeFromEnd[0] = newMesh.MeshEdges[meshEdgeIndexDictionary[meshEdgeToCopy.NextMeshEdgeFromEnd[0]]];
					newMeshEdge.NextMeshEdgeFromEnd[1] = newMesh.MeshEdges[meshEdgeIndexDictionary[meshEdgeToCopy.NextMeshEdgeFromEnd[1]]];

					newMeshEdge.VertexOnEnd[0] = newMesh.Vertices[vertexIndexDictionary[meshEdgeToCopy.VertexOnEnd[0]]];
					newMeshEdge.VertexOnEnd[1] = newMesh.Vertices[vertexIndexDictionary[meshEdgeToCopy.VertexOnEnd[1]]];

					// This will get hooked up when we create radial loops with the face edges below
					//newMeshEdge.firstFaceEdge;
					//newMesh.MeshEdges.Add(newMeshEdge);
				}

				newMesh.Faces.Capacity = meshToCopy.Faces.Capacity;
				for (int faceIndex = 0; faceIndex < meshToCopy.faces.Count; faceIndex++)
				{
					Face faceToCopy = meshToCopy.faces[faceIndex];
					Face newface = newMesh.faces[faceIndex];

					newface.normal = faceToCopy.normal;

					// hook up the face edges
					//public FaceEdge firstFaceEdge;
					List<Vertex> verticesFromCopy = new List<Vertex>();
					List<Vertex> verticesForNew = new List<Vertex>();
					foreach (Vertex vertex in faceToCopy.Vertices())
					{
						verticesFromCopy.Add(vertex);
						verticesForNew.Add(newMesh.Vertices[vertexIndexDictionary[vertex]]);
					}

					List<MeshEdge> edgesFromCopy = new List<MeshEdge>();
					List<MeshEdge> edgesForNew = new List<MeshEdge>();
					for (int i = 0; i < verticesForNew.Count - 1; i++)
					{
						MeshEdge meshEdgeFromCopy = verticesFromCopy[i].GetMeshEdgeConnectedToVertex(verticesFromCopy[i + 1]);
						edgesFromCopy.Add(meshEdgeFromCopy);
						edgesForNew.Add(newMesh.MeshEdges[meshEdgeIndexDictionary[meshEdgeFromCopy]]);
					}
					MeshEdge lastMeshEdgeFromCopy = verticesFromCopy[verticesFromCopy.Count - 1].GetMeshEdgeConnectedToVertex(verticesFromCopy[0]);
					edgesFromCopy.Add(lastMeshEdgeFromCopy);
					edgesForNew.Add(newMesh.MeshEdges[meshEdgeIndexDictionary[lastMeshEdgeFromCopy]]);

					CreateFaceEdges(verticesForNew.ToArray(), edgesForNew, newface);
				}
			}
			else
			{
				foreach (Face face in meshToCopy.Faces)
				{
					List<Vertex> faceVertices = new List<Vertex>();
					foreach (FaceEdge faceEdgeToAdd in face.FaceEdges())
					{
						Vertex newVertex = newMesh.CreateVertex(faceEdgeToAdd.firstVertex.Position, CreateOption.CreateNew, SortOption.WillSortLater);
						faceVertices.Add(newVertex);
					}

					newMesh.CreateFace(faceVertices.ToArray(), CreateOption.CreateNew);
				}

				newMesh.CleanAndMergMesh();
			}

			MeshMaterialData materialDataToCopy = MeshMaterialData.Get(meshToCopy);
			MeshMaterialData newMaterialData = MeshMaterialData.Get(newMesh);
			newMaterialData.MaterialIndex = materialDataToCopy.MaterialIndex;

			return newMesh;
		}