public static Mesh TriangulateFaces(IVertexSource vertexSource)
		{
			vertexSource.rewind();
			CachedTesselator teselatedSource = new CachedTesselator();
            VertexSourceToTesselator.SendShapeToTesselator(teselatedSource, vertexSource);

			Mesh extrudedVertexSource = new Mesh();

			int numIndicies = teselatedSource.IndicesCache.Count;

			// build the top first so it will render first when we are translucent
			for (int i = 0; i < numIndicies; i += 3)
			{
				Vector2 v0 = teselatedSource.VerticesCache[teselatedSource.IndicesCache[i + 0].Index].Position;
				Vector2 v1 = teselatedSource.VerticesCache[teselatedSource.IndicesCache[i + 1].Index].Position;
				Vector2 v2 = teselatedSource.VerticesCache[teselatedSource.IndicesCache[i + 2].Index].Position;
				if (v0 == v1 || v1 == v2 || v2 == v0)
				{
					continue;
				}

				Vertex topVertex0 = extrudedVertexSource.CreateVertex(new Vector3(v0, 0));
				Vertex topVertex1 = extrudedVertexSource.CreateVertex(new Vector3(v1, 0));
				Vertex topVertex2 = extrudedVertexSource.CreateVertex(new Vector3(v2, 0));

				extrudedVertexSource.CreateFace(new Vertex[] { topVertex0, topVertex1, topVertex2 });
			}

			return extrudedVertexSource;
		}
Beispiel #2
0
        public static Mesh CreateCube(Vector3 scale)
        {
            scale *= .5;             // the cube is -1 to 1 and we want it to be -.5 to .5 so it is a unit cube.
            Mesh cube = new Mesh();

            Vertex[] verts = new Vertex[8];
            verts[0] = cube.CreateVertex(new Vector3(-1, -1, 1) * scale);
            verts[1] = cube.CreateVertex(new Vector3(1, -1, 1) * scale);
            verts[2] = cube.CreateVertex(new Vector3(1, 1, 1) * scale);
            verts[3] = cube.CreateVertex(new Vector3(-1, 1, 1) * scale);
            verts[4] = cube.CreateVertex(new Vector3(-1, -1, -1) * scale);
            verts[5] = cube.CreateVertex(new Vector3(1, -1, -1) * scale);
            verts[6] = cube.CreateVertex(new Vector3(1, 1, -1) * scale);
            verts[7] = cube.CreateVertex(new Vector3(-1, 1, -1) * scale);

            // front
            cube.CreateFace(new Vertex[] { verts[0], verts[1], verts[2], verts[3] });
            // left
            cube.CreateFace(new Vertex[] { verts[4], verts[0], verts[3], verts[7] });
            // right
            cube.CreateFace(new Vertex[] { verts[1], verts[5], verts[6], verts[2] });
            // back
            cube.CreateFace(new Vertex[] { verts[4], verts[7], verts[6], verts[5] });
            // top
            cube.CreateFace(new Vertex[] { verts[3], verts[2], verts[6], verts[7] });
            // bottom
            cube.CreateFace(new Vertex[] { verts[4], verts[5], verts[1], verts[0] });

            return(cube);
        }
Beispiel #3
0
		public static Mesh CreateCube(Vector3 scale)
		{
			scale *= .5; // the cube is -1 to 1 and I want it to be -.5 to .5 so it is a unit cube.
			Mesh cube = new Mesh();
			Vertex[] verts = new Vertex[8];
			verts[0] = cube.CreateVertex(new Vector3(-1, -1, 1) * scale);
			verts[1] = cube.CreateVertex(new Vector3(1, -1, 1) * scale);
			verts[2] = cube.CreateVertex(new Vector3(1, 1, 1) * scale);
			verts[3] = cube.CreateVertex(new Vector3(-1, 1, 1) * scale);
			verts[4] = cube.CreateVertex(new Vector3(-1, -1, -1) * scale);
			verts[5] = cube.CreateVertex(new Vector3(1, -1, -1) * scale);
			verts[6] = cube.CreateVertex(new Vector3(1, 1, -1) * scale);
			verts[7] = cube.CreateVertex(new Vector3(-1, 1, -1) * scale);

			// front
			cube.CreateFace(new Vertex[] { verts[0], verts[1], verts[2], verts[3] });
			// left
			cube.CreateFace(new Vertex[] { verts[4], verts[0], verts[3], verts[7] });
			// right
			cube.CreateFace(new Vertex[] { verts[1], verts[5], verts[6], verts[2] });
			// back
			cube.CreateFace(new Vertex[] { verts[4], verts[7], verts[6], verts[5] });
			// top
			cube.CreateFace(new Vertex[] { verts[3], verts[2], verts[6], verts[7] });
			// bottom
			cube.CreateFace(new Vertex[] { verts[4], verts[5], verts[1], verts[0] });

			return cube;
		}
        public static Mesh CreatePlane(Vector2 scaleIn)
        {
            Vector3 scale = new Vector3(scaleIn * .5);             // the plane is -1 to 1 and we want it to be -.5 to .5 so it is a unit cube.
            Mesh    plane = new Mesh();

            Vertex[] verts = new Vertex[8];
            verts[0] = plane.CreateVertex(new Vector3(-1, -1, 0) * scale);
            verts[1] = plane.CreateVertex(new Vector3(1, -1, 0) * scale);
            verts[2] = plane.CreateVertex(new Vector3(1, 1, 0) * scale);
            verts[3] = plane.CreateVertex(new Vector3(-1, 1, 0) * scale);

            // front
            plane.CreateFace(new Vertex[] { verts[0], verts[1], verts[2], verts[3] });

            return(plane);
        }
Beispiel #5
0
        public static void Render()
        {
            MatterHackers.PolygonMesh.Mesh mesh = new MatterHackers.PolygonMesh.Mesh();
            var v0 = mesh.CreateVertex(new Vector3(1, 0, 1));   // V0
            var v1 = mesh.CreateVertex(new Vector3(1, 0, -1));  // V1
            var v2 = mesh.CreateVertex(new Vector3(-1, 0, -1)); // V2
            var v3 = mesh.CreateVertex(new Vector3(-1, 0, 1));  // V3
            var v4 = mesh.CreateVertex(new Vector3(0, 1, 0));   // V4

            mesh.CreateFace(new Vertex[] { v0, v1, v2, v3 });
            mesh.CreateFace(new Vertex[] { v3, v0, v4 });
            mesh.CreateFace(new Vertex[] { v0, v1, v4 });
            mesh.CreateFace(new Vertex[] { v1, v2, v4 });
            mesh.CreateFace(new Vertex[] { v2, v3, v4 });

            RenderMeshToGl.Render(mesh, new RGBA_Floats(.3, .8, 7));
        }
Beispiel #6
0
		public static Mesh CreateTetrahedron()
		{
			Mesh tetrahedron = new Mesh();
			Vector2 basePoint = new Vector2(1, 0);
			double baseOffsetZ = -Math.Sin(MathHelper.DegreesToRadians(30));
			Vertex[] verts = new Vertex[4];
			verts[0] = tetrahedron.CreateVertex(new Vector3(basePoint, baseOffsetZ));
			verts[1] = tetrahedron.CreateVertex(new Vector3(Vector2.Rotate(basePoint, MathHelper.Tau / 3), baseOffsetZ));
			verts[2] = tetrahedron.CreateVertex(new Vector3(Vector2.Rotate(basePoint, 2 * MathHelper.Tau / 3), baseOffsetZ));
			verts[3] = tetrahedron.CreateVertex(new Vector3(0, 0, 1));

			tetrahedron.CreateFace(new Vertex[] { verts[0], verts[2], verts[1] }); // add reversed because we want to see the bottom.
			tetrahedron.CreateFace(new Vertex[] { verts[0], verts[1], verts[3] });
			tetrahedron.CreateFace(new Vertex[] { verts[1], verts[2], verts[3] });
			tetrahedron.CreateFace(new Vertex[] { verts[2], verts[0], verts[3] });

			return tetrahedron;
		}
Beispiel #7
0
        public static Mesh CreateTetrahedron()
        {
            Mesh    tetrahedron = new Mesh();
            Vector2 basePoint   = new Vector2(1, 0);
            double  baseOffsetZ = -Math.Sin(MathHelper.DegreesToRadians(30));

            Vertex[] verts = new Vertex[4];
            verts[0] = tetrahedron.CreateVertex(new Vector3(basePoint, baseOffsetZ));
            verts[1] = tetrahedron.CreateVertex(new Vector3(Vector2.Rotate(basePoint, MathHelper.Tau / 3), baseOffsetZ));
            verts[2] = tetrahedron.CreateVertex(new Vector3(Vector2.Rotate(basePoint, 2 * MathHelper.Tau / 3), baseOffsetZ));
            verts[3] = tetrahedron.CreateVertex(new Vector3(0, 0, 1));

            tetrahedron.CreateFace(new Vertex[] { verts[0], verts[2], verts[1] }); // add reversed because we want to see the bottom.
            tetrahedron.CreateFace(new Vertex[] { verts[0], verts[1], verts[3] });
            tetrahedron.CreateFace(new Vertex[] { verts[1], verts[2], verts[3] });
            tetrahedron.CreateFace(new Vertex[] { verts[2], verts[0], verts[3] });

            return(tetrahedron);
        }
        private static Mesh CreateHullMesh(Mesh mesh, VertexCollecton sourceVertices)
        {
            // Get the convex hull for the mesh
            var cHVertexList = new List <CHVertex>();

            foreach (var vertex in sourceVertices)
            {
                cHVertexList.Add(new CHVertex(vertex.Position));
            }
            var convexHull = ConvexHull <CHVertex, CHFace> .Create(cHVertexList, .01);

            if (convexHull != null)
            {
                // create the mesh from the hull data
                Mesh hullMesh = new Mesh();
                foreach (var face in convexHull.Faces)
                {
                    List <IVertex> vertices = new List <IVertex>();
                    foreach (var vertex in face.Vertices)
                    {
                        var meshVertex = hullMesh.CreateVertex(new Vector3(vertex.Position[0], vertex.Position[1], vertex.Position[2]));
                        vertices.Add(meshVertex);
                    }
                    hullMesh.CreateFace(vertices.ToArray());
                }

                try
                {
                    // make sure there is not currently a convex hull on this object
                    if (mesh.PropertyBag.ContainsKey(ConvexHullMesh))
                    {
                        mesh.PropertyBag.Remove(ConvexHullMesh);
                    }

                    // add the new hull
                    mesh.PropertyBag.Add(ConvexHullMesh, hullMesh);
                    // make sure we remove this hull if the mesh changes
                    mesh.Changed += MeshChanged_RemoveConvexHull;

                    // remove the marker that says we are building the hull
                    if (mesh.PropertyBag.ContainsKey(CreatingConvexHullMesh))
                    {
                        mesh.PropertyBag.Remove(CreatingConvexHullMesh);
                    }
                    return(hullMesh);
                }
                catch
                {
                }
            }

            return(null);
        }
Beispiel #9
0
        public static Mesh CreateBox(AxisAlignedBoundingBox aabb)
        {
            Mesh cube = new Mesh();
            Vertex[] verts = new Vertex[8];
            //verts[0] = cube.CreateVertex(new Vector3(-1, -1, 1));
            //verts[1] = cube.CreateVertex(new Vector3(1, -1, 1));
            //verts[2] = cube.CreateVertex(new Vector3(1, 1, 1));
            //verts[3] = cube.CreateVertex(new Vector3(-1, 1, 1));
            //verts[4] = cube.CreateVertex(new Vector3(-1, -1, -1));
            //verts[5] = cube.CreateVertex(new Vector3(1, -1, -1));
            //verts[6] = cube.CreateVertex(new Vector3(1, 1, -1));
            //verts[7] = cube.CreateVertex(new Vector3(-1, 1, -1));

            verts[0] = cube.CreateVertex(new Vector3(aabb.minXYZ.x, aabb.minXYZ.y, aabb.maxXYZ.z));
            verts[1] = cube.CreateVertex(new Vector3(aabb.maxXYZ.x, aabb.minXYZ.y, aabb.maxXYZ.z));
            verts[2] = cube.CreateVertex(new Vector3(aabb.maxXYZ.x, aabb.maxXYZ.y, aabb.maxXYZ.z));
            verts[3] = cube.CreateVertex(new Vector3(aabb.minXYZ.x, aabb.maxXYZ.y, aabb.maxXYZ.z));
            verts[4] = cube.CreateVertex(new Vector3(aabb.minXYZ.x, aabb.minXYZ.y, aabb.minXYZ.z));
            verts[5] = cube.CreateVertex(new Vector3(aabb.maxXYZ.x, aabb.minXYZ.y, aabb.minXYZ.z));
            verts[6] = cube.CreateVertex(new Vector3(aabb.maxXYZ.x, aabb.maxXYZ.y, aabb.minXYZ.z));
            verts[7] = cube.CreateVertex(new Vector3(aabb.minXYZ.x, aabb.maxXYZ.y, aabb.minXYZ.z));

            // front
            cube.CreateFace(new Vertex[] { verts[0], verts[1], verts[2], verts[3] });
            // left
            cube.CreateFace(new Vertex[] { verts[4], verts[0], verts[3], verts[7] });
            // right
            cube.CreateFace(new Vertex[] { verts[1], verts[5], verts[6], verts[2] });
            // back
            cube.CreateFace(new Vertex[] { verts[4], verts[7], verts[6], verts[5] });
            // top
            cube.CreateFace(new Vertex[] { verts[3], verts[2], verts[6], verts[7] });
            // bottom
            cube.CreateFace(new Vertex[] { verts[4], verts[5], verts[1], verts[0] });

            return cube;
        }
Beispiel #10
0
        public static void CopyFaces(this Mesh copyTo, Mesh copyFrom)
        {
            foreach (Face face in copyFrom.Faces)
            {
                List <IVertex> faceVertices = new List <IVertex>();
                foreach (FaceEdge faceEdgeToAdd in face.FaceEdges())
                {
                    // we allow duplicates (the true) to make sure we are not changing the loaded models accuracy.
                    IVertex newVertex = copyTo.CreateVertex(faceEdgeToAdd.FirstVertex.Position, CreateOption.CreateNew, SortOption.WillSortLater);
                    faceVertices.Add(newVertex);
                }

                // we allow duplicates (the true) to make sure we are not changing the loaded models accuracy.
                copyTo.CreateFace(faceVertices.ToArray(), CreateOption.CreateNew);
            }
        }
        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;
        }
Beispiel #12
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;
		}
Beispiel #13
0
        public static Mesh CreateCylinder(Cylinder.CylinderPrimitive cylinderToMeasure)
        {
            Mesh cylinder = new Mesh();
            List<Vertex> bottomVerts = new List<Vertex>();
            List<Vertex> topVerts = new List<Vertex>();

            int count = 20;
            for (int i = 0; i < count; i++)
            {
                Vector2 bottomRadialPos = Vector2.Rotate(new Vector2(cylinderToMeasure.Radius1, 0), MathHelper.Tau*i/20);
                Vertex bottomVertex = cylinder.CreateVertex(new Vector3(bottomRadialPos.x, bottomRadialPos.y, - cylinderToMeasure.Height / 2));
                bottomVerts.Add(bottomVertex);
                Vector2 topRadialPos = Vector2.Rotate(new Vector2(cylinderToMeasure.Radius1, 0), MathHelper.Tau * i / 20);
                Vertex topVertex = cylinder.CreateVertex(new Vector3(topRadialPos.x, topRadialPos.y, cylinderToMeasure.Height / 2));
                topVerts.Add(topVertex);
            }

            cylinder.ReverseFaceEdges(cylinder.CreateFace(bottomVerts.ToArray()));
            cylinder.CreateFace(topVerts.ToArray());

            for (int i = 0; i < count - 1; i++)
            {
                cylinder.CreateFace(new Vertex[] { topVerts[i], bottomVerts[i], bottomVerts[i + 1], topVerts[i + 1] });
            }
            cylinder.CreateFace(new Vertex[] { topVerts[count - 1], bottomVerts[count - 1], bottomVerts[0], topVerts[0] });

            return cylinder;
        }
Beispiel #14
0
        public static Mesh CreateIcosahedron(double scale = 1)
        {
            Mesh icosahedron = new Mesh();

            double[] icosahedronVertices =
            {
                0,         -0.525731,  0.850651,
                0.850651,          0,  0.525731,
                0.850651,          0, -0.525731,
                -0.850651,         0, -0.525731,
                -0.850651,         0,  0.525731,
                -0.525731,  0.850651,         0,
                0.525731,   0.850651,         0,
                0.525731,  -0.850651,         0,
                -0.525731, -0.850651,         0,
                0,         -0.525731, -0.850651,
                0,          0.525731, -0.850651,
                0,          0.525731, 0.850651
            };

            int[] icosahedronIndicies =
            {
                1,   2,  6,
                1,   7,  2,
                3,   4,  5,
                4,   3,  8,
                6,   5, 11,
                5,   6, 10,
                9,  10,  2,
                10,  9,  3,
                7,   8,  9,
                8,   7,  0,
                11,  0,  1,
                0,  11,  4,
                6,   2, 10,
                1,   6, 11,
                3,   5, 10,
                5,   4, 11,
                2,   7,  9,
                7,   1,  0,
                3,   9,  8,
                4,   8,  0,
            };

            Vertex[] verts = new Vertex[icosahedronVertices.Length / 3];
            for (int i = 0; i < icosahedronVertices.Length / 3; i++)
            {
                verts[i] = icosahedron.CreateVertex(new Vector3(icosahedronVertices[i * 3 + 0], icosahedronVertices[i * 3 + 1], icosahedronVertices[i * 3 + 2]));
            }

            for (int i = 0; i < icosahedronIndicies.Length / 3; i++)
            {
                Vertex[] triangleVertices = new Vertex[]
                {
                    verts[icosahedronIndicies[i * 3 + 0]],
                    verts[icosahedronIndicies[i * 3 + 1]],
                    verts[icosahedronIndicies[i * 3 + 2]],
                };
                icosahedron.CreateFace(triangleVertices);
            }

            icosahedron.Transform(Matrix4X4.CreateScale(scale));

            return(icosahedron);
        }
Beispiel #15
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);
        }
        void copyPartBackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
            BackgroundWorker backgroundWorker = (BackgroundWorker)sender;

            PushMeshDataToAsynchLists(true);

            Mesh copyMesh = new Mesh();

            int faceCount = asynchMeshesList[SelectedMeshIndex].Faces.Count;
            for (int i = 0; i < faceCount; i++)
            {
                Face face = asynchMeshesList[SelectedMeshIndex].Faces[i];
                List<Vertex> faceVertices = new List<Vertex>();
                foreach (FaceEdge faceEdgeToAdd in face.FaceEdgeIterator())
                {
                    Vertex newVertex = copyMesh.CreateVertex(faceEdgeToAdd.vertex.Position, true);
                    faceVertices.Add(newVertex);
                }

                int nextPercent = (i + 1) * 80 / faceCount;
                backgroundWorker.ReportProgress(nextPercent);

                copyMesh.CreateFace(faceVertices.ToArray(), true);
            }

            PlatingHelper.FindPositionForPartAndAddToPlate(copyMesh, SelectedMeshTransform, asynchPlatingDataList, asynchMeshesList, asynchMeshTransforms);
            PlatingHelper.CreateITraceableForMesh(asynchPlatingDataList, asynchMeshesList, asynchMeshesList.Count-1);

            backgroundWorker.ReportProgress(95);
        }
Beispiel #17
0
		public static Mesh CreateIcosahedron(double scale = 1)
		{
			Mesh icosahedron = new Mesh();
			double[] icosahedronVertices =
            {
                0, -0.525731, 0.850651,
                0.850651, 0, 0.525731,
                0.850651, 0, -0.525731,
                -0.850651, 0, -0.525731,
                -0.850651, 0, 0.525731,
                -0.525731, 0.850651, 0,
                0.525731, 0.850651, 0,
                0.525731, -0.850651, 0,
                -0.525731, -0.850651, 0,
                0, -0.525731, -0.850651,
                0, 0.525731, -0.850651,
                0, 0.525731, 0.850651
            };

			int[] icosahedronIndicies =
            {
                1, 2, 6,
                1, 7, 2,
                3, 4, 5,
                4, 3, 8,
                6, 5, 11,
                5, 6, 10,
                9, 10, 2,
                10, 9, 3,
                7, 8, 9,
                8, 7, 0,
                11, 0, 1,
                0, 11, 4,
                6, 2, 10,
                1, 6, 11,
                3, 5, 10,
                5, 4, 11,
                2, 7, 9,
                7, 1, 0,
                3, 9, 8,
                4, 8, 0,
            };

			Vertex[] verts = new Vertex[icosahedronVertices.Length / 3];
			for (int i = 0; i < icosahedronVertices.Length / 3; i++)
			{
				verts[i] = icosahedron.CreateVertex(new Vector3(icosahedronVertices[i * 3 + 0], icosahedronVertices[i * 3 + 1], icosahedronVertices[i * 3 + 2]));
			}

			for (int i = 0; i < icosahedronIndicies.Length / 3; i++)
			{
				Vertex[] triangleVertices = new Vertex[]
                {
                    verts[icosahedronIndicies[i * 3 + 0]],
                    verts[icosahedronIndicies[i * 3 + 1]],
                    verts[icosahedronIndicies[i * 3 + 2]],
                };
				icosahedron.CreateFace(triangleVertices);
			}

			icosahedron.Transform(Matrix4X4.CreateScale(scale));

			return icosahedron;
		}
		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;
		}
Beispiel #19
0
        public static Mesh Extrude(IVertexSource vertexSource, double zHeight)
        {
            vertexSource.rewind();
            CachedTesselator teselatedSource = new CachedTesselator();
            Graphics2DOpenGL.SendShapeToTesselator(teselatedSource, vertexSource);

            Mesh extrudedVertexSource = new Mesh();

            int numIndicies = teselatedSource.IndicesCache.Count;

            // build the top first so it will render first when we are translucent
            for (int i = 0; i < numIndicies; i += 3)
            {
                Vector2 v0 = teselatedSource.VerticesCache[teselatedSource.IndicesCache[i + 0].Index].Position;
                Vector2 v1 = teselatedSource.VerticesCache[teselatedSource.IndicesCache[i + 1].Index].Position;
                Vector2 v2 = teselatedSource.VerticesCache[teselatedSource.IndicesCache[i + 2].Index].Position;
                if (v0 == v1 || v1 == v2 || v2 == v0)
                {
                    continue;
                }

                Vertex topVertex0 = extrudedVertexSource.CreateVertex(new Vector3(v0, zHeight));
                Vertex topVertex1 = extrudedVertexSource.CreateVertex(new Vector3(v1, zHeight));
                Vertex topVertex2 = extrudedVertexSource.CreateVertex(new Vector3(v2, zHeight));

                extrudedVertexSource.CreateFace(new Vertex[] { topVertex0, topVertex1, topVertex2 });
            }

            // then the outside edge
            for (int i = 0; i < numIndicies; i += 3)
            {
                Vector2 v0 = teselatedSource.VerticesCache[teselatedSource.IndicesCache[i + 0].Index].Position;
                Vector2 v1 = teselatedSource.VerticesCache[teselatedSource.IndicesCache[i + 1].Index].Position;
                Vector2 v2 = teselatedSource.VerticesCache[teselatedSource.IndicesCache[i + 2].Index].Position;
                if (v0 == v1 || v1 == v2 || v2 == v0)
                {
                    continue;
                }

                Vertex bottomVertex0 = extrudedVertexSource.CreateVertex(new Vector3(v0, 0));
                Vertex bottomVertex1 = extrudedVertexSource.CreateVertex(new Vector3(v1, 0));
                Vertex bottomVertex2 = extrudedVertexSource.CreateVertex(new Vector3(v2, 0));

                Vertex topVertex0 = extrudedVertexSource.CreateVertex(new Vector3(v0, zHeight));
                Vertex topVertex1 = extrudedVertexSource.CreateVertex(new Vector3(v1, zHeight));
                Vertex topVertex2 = extrudedVertexSource.CreateVertex(new Vector3(v2, zHeight));

                if (teselatedSource.IndicesCache[i + 0].IsEdge)
                {
                    extrudedVertexSource.CreateFace(new Vertex[] { bottomVertex0, bottomVertex1, topVertex1, topVertex0 });
                }

                if (teselatedSource.IndicesCache[i + 1].IsEdge)
                {
                    extrudedVertexSource.CreateFace(new Vertex[] { bottomVertex1, bottomVertex2, topVertex2, topVertex1 });
                }

                if (teselatedSource.IndicesCache[i + 2].IsEdge)
                {
                    extrudedVertexSource.CreateFace(new Vertex[] { bottomVertex2, bottomVertex0, topVertex0, topVertex2 });
                }
            }

            // then the bottom
            for (int i = 0; i < numIndicies; i += 3)
            {
                Vector2 v0 = teselatedSource.VerticesCache[teselatedSource.IndicesCache[i + 0].Index].Position;
                Vector2 v1 = teselatedSource.VerticesCache[teselatedSource.IndicesCache[i + 1].Index].Position;
                Vector2 v2 = teselatedSource.VerticesCache[teselatedSource.IndicesCache[i + 2].Index].Position;
                if (v0 == v1 || v1 == v2 || v2 == v0)
                {
                    continue;
                }

                Vertex bottomVertex0 = extrudedVertexSource.CreateVertex(new Vector3(v0, 0));
                Vertex bottomVertex1 = extrudedVertexSource.CreateVertex(new Vector3(v1, 0));
                Vertex bottomVertex2 = extrudedVertexSource.CreateVertex(new Vector3(v2, 0));

                extrudedVertexSource.CreateFace(new Vertex[] { bottomVertex2, bottomVertex1, bottomVertex0 });
            }

            return extrudedVertexSource;
        }