static public GLMeshTrianglePlugin Get(Mesh meshToGetDisplayListFor) { GLMeshTrianglePlugin plugin; meshesWithCacheData.TryGetValue(meshToGetDisplayListFor, out plugin); if (plugin != null && meshToGetDisplayListFor.ChangedCount != plugin.meshUpdateCount) { plugin.meshUpdateCount = meshToGetDisplayListFor.ChangedCount; plugin.AddRemoveData(); plugin.CreateRenderData(meshToGetDisplayListFor); plugin.meshUpdateCount = meshToGetDisplayListFor.ChangedCount; } if (plugin == null) { GLMeshTrianglePlugin newPlugin = new GLMeshTrianglePlugin(); meshesWithCacheData.Add(meshToGetDisplayListFor, newPlugin); newPlugin.CreateRenderData(meshToGetDisplayListFor); newPlugin.meshUpdateCount = meshToGetDisplayListFor.ChangedCount; return newPlugin; } return plugin; }
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 UpArrow3D(View3DWidget view3DWidget) : base(null, view3DWidget.meshViewerWidget) { heightDisplay = new HeightValueDisplay(view3DWidget); heightDisplay.Visible = false; DrawOnTop = true; this.view3DWidget = view3DWidget; string arrowFile = Path.Combine("Icons", "3D Icons", "up_pointer.stl"); if (StaticData.Instance.FileExists(arrowFile)) { using (Stream staticDataStream = StaticData.Instance.OpenSteam(arrowFile)) { using (MemoryStream arrowStream = new MemoryStream()) { staticDataStream.CopyTo(arrowStream, 1 << 16); List<MeshGroup> loadedMeshGroups = MeshFileIo.Load(arrowStream, Path.GetExtension(arrowFile)); upArrow = loadedMeshGroups[0].Meshes[0]; CollisionVolume = PlatingHelper.CreateTraceDataForMesh(upArrow); //CollisionVolume = new CylinderShape(arrowBounds.XSize / 2, arrowBounds.ZSize, new SolidMaterial(RGBA_Floats.Red, .5, 0, .4)); //CollisionVolume = new CylinderShape(arrowBounds.XSize / 2 * 4, arrowBounds.ZSize * 4, new SolidMaterial(RGBA_Floats.Red, .5, 0, .4)); } } } }
static public GLMeshWirePlugin Get(Mesh meshToGetDisplayListFor, double nonPlanarAngleRequired = 0) { GLMeshWirePlugin plugin; meshesWithCacheData.TryGetValue(meshToGetDisplayListFor, out plugin); if (plugin != null && (meshToGetDisplayListFor.ChangedCount != plugin.meshUpdateCount || nonPlanarAngleRequired != plugin.nonPlanarAngleRequired)) { plugin.meshUpdateCount = meshToGetDisplayListFor.ChangedCount; plugin.AddRemoveData(); plugin.CreateRenderData(meshToGetDisplayListFor, nonPlanarAngleRequired); plugin.meshUpdateCount = meshToGetDisplayListFor.ChangedCount; plugin.nonPlanarAngleRequired = nonPlanarAngleRequired; } if (plugin == null) { GLMeshWirePlugin newPlugin = new GLMeshWirePlugin(); meshesWithCacheData.Add(meshToGetDisplayListFor, newPlugin); newPlugin.CreateRenderData(meshToGetDisplayListFor, nonPlanarAngleRequired); newPlugin.meshUpdateCount = meshToGetDisplayListFor.ChangedCount; newPlugin.nonPlanarAngleRequired = nonPlanarAngleRequired; return newPlugin; } return plugin; }
public void GetPerimetersForAllLayers(Mesh meshToSlice, double firstLayerHeight, double otherLayerHeights) { AllLayers.Clear(); AxisAlignedBoundingBox meshBounds = meshToSlice.GetAxisAlignedBoundingBox(); double heightWithoutFirstLayer = meshBounds.ZSize - firstLayerHeight; int layerCount = (int)((heightWithoutFirstLayer / otherLayerHeights) + .5); double currentZ = otherLayerHeights; if (firstLayerHeight > 0) { layerCount++; currentZ = firstLayerHeight; } for (int i = 0; i < layerCount; i++) { allLayers.Add(new SliceLayer(currentZ)); currentZ += otherLayerHeights; } foreach (Face face in meshToSlice.Faces) { double minZ = double.MaxValue; double maxZ = double.MinValue; foreach (FaceEdge faceEdge in face.FaceEdges()) { minZ = Math.Min(minZ, faceEdge.firstVertex.Position.z); maxZ = Math.Max(maxZ, faceEdge.firstVertex.Position.z); } for (int layerIndex = 0; layerIndex < layerCount; layerIndex++) { SliceLayer layer = allLayers[layerIndex]; double zHeight = layer.ZHeight; if (zHeight < minZ) { // not up to the start of the face yet continue; } if (zHeight > maxZ) { // done with this face break; } Plane cutPlane = new Plane(Vector3.UnitZ, zHeight); Vector3 start; Vector3 end; if (face.GetCutLine(cutPlane, out start, out end)) { layer.UnorderedSegments.Add(new SliceLayer.Segment(new Vector2(start.x, start.y), new Vector2(end.x, end.y))); } } } }
static public MeshMaterialData Get(Mesh meshToGetMaterialDataFor) { MeshMaterialData plugin; meshsWithMaterialData.TryGetValue(meshToGetMaterialDataFor, out plugin); if (plugin == null) { MeshMaterialData newPlugin = new MeshMaterialData(); meshsWithMaterialData.Add(meshToGetMaterialDataFor, newPlugin); return newPlugin; } return plugin; }
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 DebugRenderToImage(Mesh meshToRender) { this.meshToRender = meshToRender; image = new ImageBuffer(xResolution, yResolution, 32, new BlenderBGRA()); graphics = image.NewGraphics2D(); // assume project on y for now foreach (Vertex vertex in meshToRender.Vertices) { min.x = Math.Min(min.x, vertex.Position[xAxis]); min.y = Math.Min(min.y, vertex.Position[yAxis]); max.x = Math.Max(max.x, vertex.Position[xAxis]); max.y = Math.Max(max.y, vertex.Position[yAxis]); } scale = Math.Min((image.Width - padding * 2) / (max.x - min.x), (image.Height - padding * 2) / (max.y - min.y)); origin = new Vector2(min.x * scale, min.y * scale) - new Vector2(padding, padding); }
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 MeshViewerWidget(double bedXSize, double bedYSize, double scale) { ShowWireFrame = false; RenderBed = true; PartColor = RGBA_Bytes.White; this.partScale = scale; trackballTumbleWidget = new TrackballTumbleWidget(); trackballTumbleWidget.DrawRotationHelperCircle = false; trackballTumbleWidget.DrawGlContent += trackballTumbleWidget_DrawGlContent; AddChild(trackballTumbleWidget); CreateBedGridImage((int)(bedXSize / 10), (int)(bedYSize / 10)); printerBed = PlatonicSolids.CreateCube(bedXSize, bedYSize, 2); Face face = printerBed.Faces[0]; { FaceData faceData = new FaceData(); faceData.Textures.Add(bedCentimeterGridImage); face.Data = faceData; foreach (FaceEdge faceEdge in face.FaceEdgeIterator()) { FaceEdgeData edgeUV = new FaceEdgeData(); edgeUV.TextureUV.Add(new Vector2((bedXSize / 2 + faceEdge.vertex.Position.x) / bedXSize, (bedYSize / 2 + faceEdge.vertex.Position.y) / bedYSize)); faceEdge.Data = edgeUV; } } foreach (Vertex vertex in printerBed.Vertices) { vertex.Position = vertex.Position - new Vector3(0, 0, 1); } trackballTumbleWidget.AnchorAll(); }
public static void DrawTo(Graphics2D graphics2D, MatterHackers.PolygonMesh.Mesh meshToDraw, Vector2 offset, double scale) { foreach (MatterHackers.PolygonMesh.Face face in meshToDraw.Faces) { PathStorage polygonProjected = new PathStorage(); bool first = true; foreach (FaceEdge faceEdge in face.FaceEdges()) { Vector2 position = new Vector2(faceEdge.firstVertex.Position.x, faceEdge.firstVertex.Position.y); position += offset; position *= scale; if (first) { polygonProjected.MoveTo(position.x, position.y); first = false; } else { polygonProjected.LineTo(position.x, position.y); } } graphics2D.Render(polygonProjected, RGBA_Bytes.Blue); } }
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; }
private static void DrawToGL(Mesh meshToRender) { GLMeshTrianglePlugin glMeshPlugin = GLMeshTrianglePlugin.Get(meshToRender); for (int i = 0; i < glMeshPlugin.subMeshs.Count; i++) { SubTriangleMesh subMesh = glMeshPlugin.subMeshs[i]; // Make sure the GLMeshPlugin has a reference to hold onto the image so it does not go away before this. if (subMesh.texture != null) { ImageGlPlugin glPlugin = ImageGlPlugin.GetImageGlPlugin(subMesh.texture, true); GL.Enable(EnableCap.Texture2D); GL.BindTexture(TextureTarget.Texture2D, glPlugin.GLTextureHandle); GL.EnableClientState(ArrayCap.TextureCoordArray); } else { GL.Disable(EnableCap.Texture2D); GL.DisableClientState(ArrayCap.TextureCoordArray); } #if true GL.EnableClientState(ArrayCap.NormalArray); GL.EnableClientState(ArrayCap.VertexArray); unsafe { fixed (VertexTextureData* pTextureData = subMesh.textrueData.Array) { fixed (VertexNormalData* pNormalData = subMesh.normalData.Array) { fixed (VertexPositionData* pPosition = subMesh.positionData.Array) { GL.TexCoordPointer(2, TexCordPointerType.Float, 0, new IntPtr(pTextureData)); GL.NormalPointer(NormalPointerType.Float, 0, new IntPtr(pNormalData)); GL.VertexPointer(3, VertexPointerType.Float, 0, new IntPtr(pPosition)); GL.DrawArrays(BeginMode.Triangles, 0, subMesh.positionData.Count); } } } } #else GL.InterleavedArrays(InterleavedArrayFormat.T2fN3fV3f, 0, subMesh.vertexDatas.Array); if (subMesh.texture != null) { //GL.TexCoordPointer(2, TexCoordPointerType.Float, VertexData.Stride, subMesh.vertexDatas.Array); //GL.EnableClientState(ArrayCap.TextureCoordArray); } else { GL.DisableClientState(ArrayCap.TextureCoordArray); } #endif GL.DisableClientState(ArrayCap.NormalArray); GL.DisableClientState(ArrayCap.VertexArray); GL.DisableClientState(ArrayCap.TextureCoordArray); GL.TexCoordPointer(2, TexCordPointerType.Float, 0, new IntPtr(0)); GL.NormalPointer(NormalPointerType.Float, 0, new IntPtr(0)); GL.VertexPointer(3, VertexPointerType.Float, 0, new IntPtr(0)); if (subMesh.texture != null) { GL.DisableClientState(ArrayCap.TextureCoordArray); } } }
public static void Render(Mesh meshToRender, IColorType partColor, Matrix4X4 transform, RenderTypes renderType) { if (meshToRender != null) { GL.Color4(partColor.Red0To255, partColor.Green0To255, partColor.Blue0To255, partColor.Alpha0To255); if (partColor.Alpha0To1 < 1) { GL.Enable(EnableCap.Blend); } else { GL.Disable(EnableCap.Blend); } GL.MatrixMode(MatrixMode.Modelview); GL.PushMatrix(); GL.MultMatrix(transform.GetAsFloatArray()); switch (renderType) { case RenderTypes.Hidden: break; case RenderTypes.Shaded: DrawToGL(meshToRender); break; case RenderTypes.Polygons: case RenderTypes.Outlines: DrawWithWireOverlay(meshToRender, renderType); break; } GL.PopMatrix(); } }
public static void Render(Mesh meshToRender, IColorType partColor, RenderTypes renderType = RenderTypes.Shaded) { Render(meshToRender, partColor, Matrix4X4.Identity, renderType); }
private static void DrawWithWireOverlay(Mesh meshToRender, RenderTypes renderType) { GLMeshTrianglePlugin glMeshPlugin = GLMeshTrianglePlugin.Get(meshToRender); GL.Enable(EnableCap.PolygonOffsetFill); GL.PolygonOffset(1, 1); DrawToGL(meshToRender); GL.Color4(0, 0, 0, 255); GL.PolygonOffset(0, 0); GL.Disable(EnableCap.PolygonOffsetFill); GL.Disable(EnableCap.Lighting); GL.DisableClientState(ArrayCap.TextureCoordArray); GLMeshWirePlugin glWireMeshPlugin = null; if (renderType == RenderTypes.Outlines) { glWireMeshPlugin = GLMeshWirePlugin.Get(meshToRender, MathHelper.Tau / 8); } else { glWireMeshPlugin = GLMeshWirePlugin.Get(meshToRender); } VectorPOD<WireVertexData> edegLines = glWireMeshPlugin.edgeLinesData; GL.EnableClientState(ArrayCap.VertexArray); #if true unsafe { fixed (WireVertexData* pv = edegLines.Array) { GL.VertexPointer(3, VertexPointerType.Float, 0, new IntPtr(pv)); GL.DrawArrays(BeginMode.Lines, 0, edegLines.Count); } } #else GL.InterleavedArrays(InterleavedArrayFormat.V3f, 0, edegLines.Array); GL.DrawArrays(BeginMode.Lines, 0, edegLines.Count); #endif GL.DisableClientState(ArrayCap.VertexArray); GL.Enable(EnableCap.Lighting); }
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 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[] SplitIntoMeshesOnOrthographicZ(Mesh meshToSplit, Vector3 buildVolume, ReportProgressRatio reportProgress) { // check if the part is bigger than the build plate (if it is we need to use that as our size) AxisAlignedBoundingBox partBounds = meshToSplit.GetAxisAlignedBoundingBox(); buildVolume.x = Math.Max(buildVolume.x, partBounds.XSize + 2); buildVolume.y = Math.Max(buildVolume.y, partBounds.YSize + 2); buildVolume.z = Math.Max(buildVolume.z, partBounds.ZSize + 2); // Find all the separate objects that are on the plate // Create a 2D image the size of the printer bed at some scale with the parts draw on it top down double scaleFactor = 5; ImageBuffer partPlate = new ImageBuffer((int)(buildVolume.x * scaleFactor), (int)(buildVolume.y * scaleFactor), 32, new BlenderBGRA()); Vector2 renderOffset = new Vector2(buildVolume.x / 2, buildVolume.y / 2) - new Vector2(partBounds.Center.x, partBounds.Center.y); PolygonMesh.Rendering.OrthographicZProjection.DrawTo(partPlate.NewGraphics2D(), meshToSplit, renderOffset, scaleFactor, RGBA_Bytes.White); bool continueProcessin = true; if (reportProgress != null) { reportProgress(.2, "", out continueProcessin); } //ImageIO.SaveImageData("test part plate 0.png", partPlate); // expand the bounds a bit so that we can collect all the vertices and polygons within each bound Dilate.DoDilate3x3Binary(partPlate, 1); //ImageIO.SaveImageData("test part plate 1.png", partPlate); // trace all the bounds of the objects on the plate PolyTree polyTreeForPlate = FindDistictObjectBounds(partPlate); if (polyTreeForPlate == null) { Mesh[] singleMesh = new Mesh[1]; singleMesh[0] = meshToSplit; return singleMesh; } // get all the discrete areas that are polygons so we can search them Polygons discreteAreas = new Polygons(); GetAreasRecursive(polyTreeForPlate, discreteAreas); if (discreteAreas.Count == 0) { return null; } else if (discreteAreas.Count == 1) { Mesh[] singleMesh = new Mesh[1]; singleMesh[0] = meshToSplit; return singleMesh; } Graphics2D graphics2D = partPlate.NewGraphics2D(); graphics2D.Clear(RGBA_Bytes.Black); Random rand = new Random(); foreach (Polygon polygon in discreteAreas) { graphics2D.Render(PlatingHelper.PolygonToPathStorage(polygon), new RGBA_Bytes(rand.Next(128, 255), rand.Next(128, 255), rand.Next(128, 255))); } if (reportProgress != null) { reportProgress(.5, "", out continueProcessin); } //ImageIO.SaveImageData("test part plate 2.png", partPlate); // add each of the separate bounds polygons to new meshes Mesh[] discreteMeshes = new Mesh[discreteAreas.Count]; for (int i = 0; i < discreteAreas.Count; i++) { discreteMeshes[i] = new Mesh(); } foreach (Face face in meshToSplit.Faces) { bool faceDone = false; // figure out which area one or more of the vertices are in add the face to the right new mesh foreach (FaceEdge faceEdge in face.FaceEdges()) { Vector2 position = new Vector2(faceEdge.firstVertex.Position.x, faceEdge.firstVertex.Position.y); position += renderOffset; position *= scaleFactor; for (int areaIndex = discreteAreas.Count - 1; areaIndex >= 0; areaIndex--) { if (PointInPolygon(discreteAreas[areaIndex], new IntPoint((int)position.x, (int)position.y))) { List<Vertex> faceVertices = new List<Vertex>(); foreach (FaceEdge faceEdgeToAdd in face.FaceEdges()) { Vertex newVertex = discreteMeshes[areaIndex].CreateVertex(faceEdgeToAdd.firstVertex.Position); faceVertices.Add(newVertex); } discreteMeshes[areaIndex].CreateFace(faceVertices.ToArray()); faceDone = true; break; } } if (faceDone) { break; } } } if (reportProgress != null) { reportProgress(.8, "", out continueProcessin); } for (int i = 0; i < discreteMeshes.Count(); i++) { Mesh mesh = discreteMeshes[i]; } return discreteMeshes; }
public static void FindPositionForPartAndAddToPlate(Mesh meshToAdd, ScaleRotateTranslate meshTransform, List<PlatingMeshData> perMeshInfo, List<Mesh> meshesToAvoid, List<ScaleRotateTranslate> meshTransforms) { if (meshToAdd == null || meshToAdd.Vertices.Count < 3) { return; } meshesToAvoid.Add(meshToAdd); PlatingMeshData newMeshInfo = new PlatingMeshData(); perMeshInfo.Add(newMeshInfo); meshTransforms.Add(meshTransform); int index = meshesToAvoid.Count-1; MoveMeshToOpenPosition(index, perMeshInfo, meshesToAvoid, meshTransforms); PlaceMeshOnBed(meshesToAvoid, meshTransforms, index, false); }
public SliceLayer GetPerimetersAtHeight(Mesh meshToSlice, double zHeight) { throw new NotImplementedException(); }
public void CreatePrintBed(Vector3 displayVolume, Vector2 bedCenter, BedShape bedShape) { if (MeshViewerWidget.BedCenter == bedCenter && MeshViewerWidget.bedShape == bedShape && MeshViewerWidget.displayVolume == displayVolume) { return; } MeshViewerWidget.BedCenter = bedCenter; MeshViewerWidget.bedShape = bedShape; MeshViewerWidget.displayVolume = displayVolume; Vector3 displayVolumeToBuild = Vector3.ComponentMax(displayVolume, new Vector3(1, 1, 1)); switch (bedShape) { case BedShape.Rectangular: if (displayVolumeToBuild.z > 0) { buildVolume = PlatonicSolids.CreateCube(displayVolumeToBuild); foreach (Vertex vertex in buildVolume.Vertices) { vertex.Position = vertex.Position + new Vector3(0, 0, displayVolumeToBuild.z / 2); } } CreateRectangularBedGridImage(displayVolumeToBuild, bedCenter); printerBed = PlatonicSolids.CreateCube(displayVolumeToBuild.x, displayVolumeToBuild.y, 4); { Face face = printerBed.Faces[0]; { FaceTextureData faceData = FaceTextureData.Get(face); faceData.Textures.Add(BedImage); foreach (FaceEdge faceEdge in face.FaceEdges()) { FaceEdgeTextureUvData edgeUV = FaceEdgeTextureUvData.Get(faceEdge); edgeUV.TextureUV.Add(new Vector2((displayVolumeToBuild.x / 2 + faceEdge.firstVertex.Position.x) / displayVolumeToBuild.x, (displayVolumeToBuild.y / 2 + faceEdge.firstVertex.Position.y) / displayVolumeToBuild.y)); } } } break; case BedShape.Circular: { if (displayVolumeToBuild.z > 0) { buildVolume = VertexSourceToMesh.Extrude(new Ellipse(new Vector2(), displayVolumeToBuild.x / 2, displayVolumeToBuild.y / 2), displayVolumeToBuild.z); foreach (Vertex vertex in buildVolume.Vertices) { vertex.Position = vertex.Position + new Vector3(0, 0, .2); } } CreateCircularBedGridImage((int)(displayVolumeToBuild.x / 10), (int)(displayVolumeToBuild.y / 10)); printerBed = VertexSourceToMesh.Extrude(new Ellipse(new Vector2(), displayVolumeToBuild.x / 2, displayVolumeToBuild.y / 2), 2); { foreach (Face face in printerBed.Faces) { if (face.normal.z > 0) { FaceTextureData faceData = FaceTextureData.Get(face); faceData.Textures.Add(BedImage); foreach (FaceEdge faceEdge in face.FaceEdges()) { FaceEdgeTextureUvData edgeUV = FaceEdgeTextureUvData.Get(faceEdge); edgeUV.TextureUV.Add(new Vector2((displayVolumeToBuild.x / 2 + faceEdge.firstVertex.Position.x) / displayVolumeToBuild.x, (displayVolumeToBuild.y / 2 + faceEdge.firstVertex.Position.y) / displayVolumeToBuild.y)); } } } } } break; default: throw new NotImplementedException(); } foreach (Vertex vertex in printerBed.Vertices) { vertex.Position = vertex.Position - new Vector3(-bedCenter, 2.2); } if (buildVolume != null) { foreach (Vertex vertex in buildVolume.Vertices) { vertex.Position = vertex.Position - new Vector3(-bedCenter, 2.2); } } Invalidate(); }
private static Dictionary<Vertex, int> GetVertexToIndexDictionary(Mesh meshToCopy, Mesh newMesh) { Dictionary<Vertex, int> vertexIndexMapping = new Dictionary<Vertex, int>(meshToCopy.Vertices.Count); for (int vertexIndex = 0; vertexIndex < meshToCopy.Vertices.Count; vertexIndex++) { Vertex vertexToCopy = meshToCopy.Vertices[vertexIndex]; vertexIndexMapping.Add(vertexToCopy, vertexIndex); newMesh.Vertices.Add(new Vertex(vertexToCopy.Position)); } return vertexIndexMapping; }
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); }
private static Dictionary<MeshEdge, int> GetMeshEdgeToIndexDictionary(Mesh meshToCopy, Mesh newMesh) { Dictionary<MeshEdge, int> meshEdgeIndexDictionary = new Dictionary<MeshEdge, int>(meshToCopy.MeshEdges.Count); for (int edgeIndex = 0; edgeIndex < meshToCopy.MeshEdges.Count; edgeIndex++) { MeshEdge edgeToCopy = meshToCopy.MeshEdges[edgeIndex]; meshEdgeIndexDictionary.Add(edgeToCopy, edgeIndex); newMesh.MeshEdges.Add(new MeshEdge()); } return meshEdgeIndexDictionary; }
public void GetMinMaxZ(Mesh mesh, ref double minZ, ref double maxZ) { AxisAlignedBoundingBox meshBounds = mesh.GetAxisAlignedBoundingBox(trackballTumbleWidget.ModelviewMatrix); minZ = Math.Min(meshBounds.minXYZ.z, minZ); maxZ = Math.Max(meshBounds.maxXYZ.z, maxZ); }
public void DrawTo(Graphics2D graphics2D, Mesh meshToDraw, RGBA_Bytes partColorIn, double minZ, double maxZ) { RGBA_Floats partColor = partColorIn.GetAsRGBA_Floats(); graphics2D.Rasterizer.gamma(new gamma_power(.3)); RenderPoint[] points = new RenderPoint[3] { new RenderPoint(), new RenderPoint(), new RenderPoint() }; foreach (Face face in meshToDraw.Faces) { int i = 0; Vector3 normal = Vector3.TransformVector(face.normal, trackballTumbleWidget.ModelviewMatrix).GetNormal(); if (normal.z > 0) { foreach (FaceEdge faceEdge in face.FaceEdges()) { points[i].position = trackballTumbleWidget.GetScreenPosition(faceEdge.firstVertex.Position); Vector3 transformedPosition = Vector3.TransformPosition(faceEdge.firstVertex.Position, trackballTumbleWidget.ModelviewMatrix); points[i].z = transformedPosition.z; i++; } RGBA_Floats polyDrawColor = new RGBA_Floats(); double L = Vector3.Dot(lightNormal, normal); if (L > 0.0f) { polyDrawColor = partColor * lightIllumination * L; } polyDrawColor = RGBA_Floats.ComponentMax(polyDrawColor, partColor * ambiantIllumination); for (i = 0; i < 3; i++) { double ratio = (points[i].z - minZ) / (maxZ - minZ); int ratioInt16 = (int)(ratio * 65536); points[i].color = new RGBA_Bytes(polyDrawColor.Red0To255, ratioInt16 >> 8, ratioInt16 & 0xFF); } #if true scanline_unpacked_8 sl = new scanline_unpacked_8(); ScanlineRasterizer ras = new ScanlineRasterizer(); render_gouraud(graphics2D.DestImage, sl, ras, points); #else IRecieveBlenderByte oldBlender = graphics2D.DestImage.GetRecieveBlender(); graphics2D.DestImage.SetRecieveBlender(new BlenderZBuffer()); graphics2D.Render(polygonProjected, renderColor); graphics2D.DestImage.SetRecieveBlender(oldBlender); #endif byte[] buffer = graphics2D.DestImage.GetBuffer(); int pixels = graphics2D.DestImage.Width * graphics2D.DestImage.Height; for (int pixelIndex = 0; pixelIndex < pixels; pixelIndex++) { buffer[pixelIndex * 4 + ImageBuffer.OrderR] = buffer[pixelIndex * 4 + ImageBuffer.OrderR]; buffer[pixelIndex * 4 + ImageBuffer.OrderG] = buffer[pixelIndex * 4 + ImageBuffer.OrderR]; buffer[pixelIndex * 4 + ImageBuffer.OrderB] = buffer[pixelIndex * 4 + ImageBuffer.OrderR]; } } } }
public override void OnParentChanged(EventArgs e) { #region Abort on platforms which will not be able to execute the ops properly /* if (!GL.SupportsExtension("VERSION_1_2")) { Trace.WriteLine("Aborting. OpenGL 1.2 or later required."); this.Exit(); } int[] t = new int[2]; GL.GetInteger(GetPName.MajorVersion, out t[0]); GL.GetInteger(GetPName.MinorVersion, out t[1]); Trace.WriteLine("OpenGL Context Version: " + t[0] + "." + t[1]); GL.GetInteger(GetPName.DepthBits, out t[0]); Trace.WriteLine("Depth Bits: " + t[0]); GL.GetInteger(GetPName.StencilBits, out t[1]); Trace.WriteLine("Stencil Bits: " + t[1]); if (t[0] < 16) { Trace.WriteLine("Aborting. Need at least 16 depth bits, only " + t[0] + " available."); this.Exit(); } if (t[1] < 1) { Trace.WriteLine("Aborting. Need at least 1 stencil bit, only " + t[1] + " available."); this.Exit(); } */ #endregion Abort on platforms which will not be able to execute the ops properly WindowTitle = "Cube-Sphere Stencil CSG " + GL.GetString(StringName.Renderer) + " (GL " + GL.GetString(StringName.Version) + ")"; SetGLState(); #region Load Texture //Bitmap bitmap = new Bitmap("Data/Textures/logo-dark.jpg"); //bitmap.RotateFlip(RotateFlipType.RotateNoneFlipY); GL.GenTextures(1, out Texture); GL.BindTexture(TextureTarget.Texture2D, Texture); //BitmapData data = bitmap.LockBits(new System.Drawing.Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); //GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, data.Width, data.Height, 0, OpenTK.Graphics.OpenGL.PixelFormat.Bgra, PixelType.UnsignedByte, data.Scan0); //GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear); //GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear); //GL.Finish(); //bitmap.UnlockBits(data); #endregion Load Texture OperandA = PlatonicSolids.CreateCube(1.5, 2.0, 2.5); OperandB = PlatonicSolids.CreateCube(1, 1, 1); #region Invert Operand B's Normals // only the inside of the operand is ever drawn to color buffers and lighting requires this. foreach (Face face in OperandB.Faces) { face.normal = (face.normal * -1).GetNormal(); } #endregion Invert Operand B's Normals base.OnParentChanged(e); }
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; }
private static List<IPrimitive> AddTraceDataForMesh(Mesh mesh, int totalActionCount, ref int currentAction, ref bool needToUpdateProgressReport, ReportProgressRatio reportProgress) { bool continueProcessing; List<IPrimitive> allPolys = new List<IPrimitive>(); List<Vector3> positions = new List<Vector3>(); foreach (Face face in mesh.Faces) { positions.Clear(); foreach (Vertex vertex in face.Vertices()) { positions.Add(vertex.Position); } // We should use the teselator for this if it is greater than 3. Vector3 next = positions[1]; for (int positionIndex = 2; positionIndex < positions.Count; positionIndex++) { TriangleShape triangel = new TriangleShape(positions[0], next, positions[positionIndex], null); allPolys.Add(triangel); next = positions[positionIndex]; } if (reportProgress != null) { if ((currentAction % 256) == 0 || needToUpdateProgressReport) { reportProgress(currentAction / (double)totalActionCount, "Creating Trace Polygons", out continueProcessing); needToUpdateProgressReport = false; } currentAction++; } } return allPolys; }