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 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; }
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)); }
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; }
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); }
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); }
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); }
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); } }
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); }
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; }
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; }
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); }
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; }
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; }
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 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; }
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; }