public void Normal(Submesh mesh, out float nx, out float ny, out float nz) { Vector3 v0 = mesh.vertices[vertex1]; Vector3 v1 = mesh.vertices[vertex2]; Vector3 v2 = mesh.vertices[vertex3]; float a1 = v1.X - v0.X; float a2 = v1.Y - v0.Y; float a3 = v1.Z - v0.Z; float b1 = v2.X - v1.X; float b2 = v2.Y - v1.Y; float b3 = v2.Z - v1.Z; nx = a2 * b3 - a3 * b2; ny = a3 * b1 - a1 * b3; nz = a1 * b2 - a2 * b1; float length = (float)Math.Sqrt(nx * nx + ny * ny + nz * nz); if (length == 0) { nx = ny = 0; nz = 1; } else { nx /= length; ny /= length; nz /= length; } }
//QFont font; //float arrow_length; internal Coordinate() { submesh = new Submesh[3]; model = new TopoModel[3]; //arrow_length = Convert.ToSingle(Math.Abs(model.boundingBox.zMax - model.boundingBox.zMin)); // override mesh color for (int i = 0; i < 3; i++) { // import mesh from STL. model[i] = new TopoModel(); model[i].importSTL(Application.StartupPath + Path.DirectorySeparatorChar + names[i],1); submesh[i] = new Submesh(); model[i].FillMeshTrianglesOnly(submesh[i], 0); submesh[i].Compress(true, coordinate_colors[i]); submesh[i].vertices.Clear(); } model = null; // release memory // config font /*font = new QFont("data/HappySans.ttf", label_font_size, new QFontBuilderConfiguration(true)); font.Options.DropShadowActive = false;*/ }
public void FillMeshTrianglesOnly(Submesh mesh, int defaultColor) { bool drawEdges = Main.threeDSettings.ShowEdges; foreach (TopoTriangle t in triangles) { mesh.AddTriangle(t.vertices[0].pos, t.vertices[1].pos, t.vertices[2].pos, (t.bad ? Submesh.MESHCOLOR_ERRORFACE : defaultColor)); } }
public void FillMesh(Submesh mesh,int defaultColor) { bool drawEdges = Main.threeDSettings.ShowEdges; foreach (TopoTriangle t in triangles) { mesh.AddTriangle(t.vertices[0].pos, t.vertices[1].pos, t.vertices[2].pos, (t.bad ? Submesh.MESHCOLOR_ERRORFACE : defaultColor)); if (drawEdges) { mesh.AddEdge(t.vertices[0].pos, t.vertices[1].pos, t.edges[0].connectedFaces == 2 ? Submesh.MESHCOLOR_EDGE : Submesh.MESHCOLOR_ERROREDGE); mesh.AddEdge(t.vertices[1].pos, t.vertices[2].pos, t.edges[1].connectedFaces == 2 ? Submesh.MESHCOLOR_EDGE : Submesh.MESHCOLOR_ERROREDGE); mesh.AddEdge(t.vertices[2].pos, t.vertices[0].pos, t.edges[2].connectedFaces == 2 ? Submesh.MESHCOLOR_EDGE : Submesh.MESHCOLOR_ERROREDGE); } else { if(t.edges[0].connectedFaces != 2) mesh.AddEdge(t.vertices[0].pos, t.vertices[1].pos, Submesh.MESHCOLOR_ERROREDGE); if (t.edges[1].connectedFaces != 2) mesh.AddEdge(t.vertices[1].pos, t.vertices[2].pos, Submesh.MESHCOLOR_ERROREDGE); if (t.edges[2].connectedFaces != 2) mesh.AddEdge(t.vertices[2].pos, t.vertices[0].pos, Submesh.MESHCOLOR_ERROREDGE); } } }
public void CutMesh(Submesh mesh, RHVector3 normal, RHVector3 point,int defaultFaceColor) { TopoPlane plane = new TopoPlane(normal, point); bool drawEdges = Main.threeDSettings.ShowEdges; foreach (TopoEdge e in edges) e.algHelper = 0; // Mark drawn edges, so we insert them only once foreach (TopoTriangle t in triangles) { int side = plane.testTriangleSideFast(t); if (side == -1) { mesh.AddTriangle(t.vertices[0].pos, t.vertices[1].pos, t.vertices[2].pos, (t.bad ? Submesh.MESHCOLOR_ERRORFACE : defaultFaceColor)); if (drawEdges) { if (t.edges[0].algHelper == 0) { mesh.AddEdge(t.vertices[0].pos, t.vertices[1].pos, t.edges[0].connectedFaces == 2 ? Submesh.MESHCOLOR_EDGE : Submesh.MESHCOLOR_ERROREDGE); t.edges[0].algHelper = 1; } if (t.edges[1].algHelper == 0) { mesh.AddEdge(t.vertices[1].pos, t.vertices[2].pos, t.edges[1].connectedFaces == 2 ? Submesh.MESHCOLOR_EDGE : Submesh.MESHCOLOR_ERROREDGE); t.edges[1].algHelper = 1; } if (t.edges[2].algHelper == 0) { mesh.AddEdge(t.vertices[2].pos, t.vertices[0].pos, t.edges[2].connectedFaces == 2 ? Submesh.MESHCOLOR_EDGE : Submesh.MESHCOLOR_ERROREDGE); t.edges[2].algHelper = 1; } } else { if (t.edges[0].algHelper == 0 && t.edges[0].connectedFaces != 2) { mesh.AddEdge(t.vertices[0].pos, t.vertices[1].pos, Submesh.MESHCOLOR_ERROREDGE); t.edges[0].algHelper = 1; } if (t.edges[1].algHelper == 0 && t.edges[1].connectedFaces != 2) { mesh.AddEdge(t.vertices[1].pos, t.vertices[2].pos, Submesh.MESHCOLOR_ERROREDGE); t.edges[1].algHelper = 1; } if (t.edges[2].algHelper == 0 && t.edges[2].connectedFaces != 2) { mesh.AddEdge(t.vertices[2].pos, t.vertices[0].pos, Submesh.MESHCOLOR_ERROREDGE); t.edges[2].algHelper = 1; } } } else if (side == 0) { plane.addIntersectionToSubmesh(mesh, t, drawEdges, (t.bad ? Submesh.MESHCOLOR_ERRORFACE : defaultFaceColor)); } } }
public void addIntersectionToSubmesh(Submesh mesh, TopoTriangle triangle, bool addEdges,int color) { int[] outside = new int[3]; int[] inside = new int[3]; int nOutside = 0, nInside = 0; int i; for (i = 0; i < 3; i++) { if (VertexDistance(triangle.vertices[i].pos) > 0) outside[nOutside++] = i; else inside[nInside++] = i; } if (nOutside != 1 && nOutside != 2) return; RHVector3[] intersections = new RHVector3[3]; int nIntersections = 0; for (int iInside = 0; iInside < nInside; iInside++) { for (int iOutside = 0; iOutside < nOutside; iOutside++) { RHVector3 v1 = triangle.vertices[inside[iInside]].pos; RHVector3 v2 = triangle.vertices[outside[iOutside]].pos; double dist1 = VertexDistance(v1); double dist2 = VertexDistance(v2); double pos = Math.Abs(dist1) / Math.Abs(dist2 - dist1); intersections[nIntersections++] = new RHVector3( v1.x+pos*(v2.x-v1.x), v1.y+pos*(v2.y-v1.y), v1.z+pos*(v2.z-v1.z) ); } } if (nInside == 2) { if (outside[0] == 1) { mesh.AddTriangle(triangle.vertices[inside[1]].pos, triangle.vertices[inside[0]].pos, intersections[1], color); mesh.AddTriangle(triangle.vertices[inside[0]].pos, intersections[0], intersections[1], color); } else { mesh.AddTriangle(triangle.vertices[inside[0]].pos, triangle.vertices[inside[1]].pos, intersections[0], color); mesh.AddTriangle(triangle.vertices[inside[1]].pos, intersections[1], intersections[0], color); } } else { if(inside[0] == 1) mesh.AddTriangle(triangle.vertices[inside[0]].pos, intersections[1], intersections[0], color); else mesh.AddTriangle(triangle.vertices[inside[0]].pos, intersections[0], intersections[1], color); } if (addEdges) { if (nInside == 2) { mesh.AddEdge(triangle.vertices[inside[0]].pos, triangle.vertices[inside[1]].pos, triangle.edges[0].connectedFaces == 2 ? Submesh.MESHCOLOR_EDGE : Submesh.MESHCOLOR_ERROREDGE); mesh.AddEdge(triangle.vertices[inside[0]].pos, intersections[0], triangle.edges[1].connectedFaces == 2 ? Submesh.MESHCOLOR_EDGE : Submesh.MESHCOLOR_ERROREDGE); mesh.AddEdge(triangle.vertices[inside[1]].pos, intersections[1], triangle.edges[2].connectedFaces == 2 ? Submesh.MESHCOLOR_EDGE : Submesh.MESHCOLOR_ERROREDGE); } else { for (int iInter = 0; iInter < nIntersections; iInter++) { mesh.AddEdge(triangle.vertices[inside[0]].pos, intersections[iInter], triangle.edges[(inside[0]+2*iInter) % 3].connectedFaces == 2 ? Submesh.MESHCOLOR_EDGE : Submesh.MESHCOLOR_ERROREDGE); } } } if (nIntersections == 2) mesh.AddEdge(intersections[0], intersections[1], Submesh.MESHCOLOR_CUT_EDGE); }
public void addIntersectionToSubmesh(Submesh mesh, TopoTriangle triangle, bool addEdges, int color) { int[] outside = new int[3]; int[] inside = new int[3]; int nOutside = 0, nInside = 0; int i; for (i = 0; i < 3; i++) { if (VertexDistance(triangle.vertices[i].pos) > 0) { outside[nOutside++] = i; } else { inside[nInside++] = i; } } if (nOutside != 1 && nOutside != 2) { return; } RHVector3[] intersections = new RHVector3[3]; int nIntersections = 0; for (int iInside = 0; iInside < nInside; iInside++) { for (int iOutside = 0; iOutside < nOutside; iOutside++) { RHVector3 v1 = triangle.vertices[inside[iInside]].pos; RHVector3 v2 = triangle.vertices[outside[iOutside]].pos; double dist1 = VertexDistance(v1); double dist2 = VertexDistance(v2); double pos = Math.Abs(dist1) / Math.Abs(dist2 - dist1); intersections[nIntersections++] = new RHVector3( v1.x + pos * (v2.x - v1.x), v1.y + pos * (v2.y - v1.y), v1.z + pos * (v2.z - v1.z) ); } } if (nInside == 2) { if (outside[0] == 1) { mesh.AddTriangle(triangle.vertices[inside[1]].pos, triangle.vertices[inside[0]].pos, intersections[1], color); mesh.AddTriangle(triangle.vertices[inside[0]].pos, intersections[0], intersections[1], color); } else { mesh.AddTriangle(triangle.vertices[inside[0]].pos, triangle.vertices[inside[1]].pos, intersections[0], color); mesh.AddTriangle(triangle.vertices[inside[1]].pos, intersections[1], intersections[0], color); } } else { if (inside[0] == 1) { mesh.AddTriangle(triangle.vertices[inside[0]].pos, intersections[1], intersections[0], color); } else { mesh.AddTriangle(triangle.vertices[inside[0]].pos, intersections[0], intersections[1], color); } } if (addEdges) { if (nInside == 2) { mesh.AddEdge(triangle.vertices[inside[0]].pos, triangle.vertices[inside[1]].pos, triangle.edges[0].connectedFaces == 2 ? Submesh.MESHCOLOR_EDGE : Submesh.MESHCOLOR_ERROREDGE); mesh.AddEdge(triangle.vertices[inside[0]].pos, intersections[0], triangle.edges[1].connectedFaces == 2 ? Submesh.MESHCOLOR_EDGE : Submesh.MESHCOLOR_ERROREDGE); mesh.AddEdge(triangle.vertices[inside[1]].pos, intersections[1], triangle.edges[2].connectedFaces == 2 ? Submesh.MESHCOLOR_EDGE : Submesh.MESHCOLOR_ERROREDGE); } else { for (int iInter = 0; iInter < nIntersections; iInter++) { mesh.AddEdge(triangle.vertices[inside[0]].pos, intersections[iInter], triangle.edges[(inside[0] + 2 * iInter) % 3].connectedFaces == 2 ? Submesh.MESHCOLOR_EDGE : Submesh.MESHCOLOR_ERROREDGE); } } } if (nIntersections == 2) { mesh.AddEdge(intersections[0], intersections[1], Submesh.MESHCOLOR_CUT_EDGE); } }