public static void TestIsoCurve() { var meshSO = OG.Scan.SO; DMesh3 mesh = new DMesh3(meshSO.Mesh); DMeshAABBTree3 spatial = new DMeshAABBTree3(mesh, true); AxisAlignedBox3d bounds = mesh.CachedBounds; Frame3f plane = new Frame3f(bounds.Center); Func <Vector3d, double> planeSignedDistanceF = (v) => { return((v - plane.Origin).Dot(plane.Y)); }; Func <Vector3d, double> sphereDistF = (v) => { double d = v.Distance(plane.Origin); return(d - 50.0); }; MeshIsoCurves iso = new MeshIsoCurves(mesh, sphereDistF); iso.Compute(); DGraph3Util.Curves curves = DGraph3Util.ExtractCurves(iso.Graph); foreach (DCurve3 c in curves.Loops) { List <Vector3d> verts = new List <Vector3d>(c.Vertices); for (int i = 0; i < verts.Count; ++i) { verts[i] = verts[i] + 0.5 * mesh.GetTriNormal(spatial.FindNearestTriangle(verts[i])); } DebugUtil.EmitDebugCurve("curve", verts.ToArray(), true, 1, Colorf.Red, Colorf.Red, meshSO.RootGameObject, false); } foreach (DCurve3 c in curves.Paths) { List <Vector3d> verts = new List <Vector3d>(c.Vertices); for (int i = 0; i < verts.Count; ++i) { verts[i] = verts[i] + 0.5 * mesh.GetTriNormal(spatial.FindNearestTriangle(verts[i])); } DebugUtil.EmitDebugCurve("curve", verts.ToArray(), false, 1, Colorf.Blue, Colorf.Blue, meshSO.RootGameObject, false); } //foreach ( Segment3d seg in iso.Graph.Segments()) { // Vector3d a = seg.P0 + 1.0 * mesh.GetTriNormal(spatial.FindNearestTriangle(seg.P0)); // Vector3d b = seg.P1 + 1.0 * mesh.GetTriNormal(spatial.FindNearestTriangle(seg.P1)); // DebugUtil.EmitDebugLine("seg", a, b, 1.0f, Colorf.Red, meshSO.RootGameObject, false); //} }
void update() { MeshIsoCurves iso = new MeshIsoCurves(SO.Mesh, (v) => { return((v - frameL.Origin).Dot(frameL.Z)); }); iso.Compute(); graph = iso.Graph; localCurves = DGraph3Util.ExtractCurves(graph); // ugh need xform seq for to/from world... if (OutputSpace == CoordSpace.WorldCoords) { foreach (DCurve3 c in localCurves.Loops) { for (int i = 0; i < c.VertexCount; ++i) { c[i] = SceneTransforms.TransformTo((Vector3f)c[i], SO, CoordSpace.ObjectCoords, OutputSpace); } } foreach (DCurve3 c in localCurves.Paths) { for (int i = 0; i < c.VertexCount; ++i) { c[i] = SceneTransforms.TransformTo((Vector3f)c[i], SO, CoordSpace.ObjectCoords, OutputSpace); } } } else if (OutputSpace == CoordSpace.SceneCoords) { TransformSequence xform = SceneTransforms.ObjectToSceneXForm(SO); foreach (DCurve3 c in localCurves.Loops) { for (int i = 0; i < c.VertexCount; ++i) { c[i] = xform.TransformP(c[i]); } } foreach (DCurve3 c in localCurves.Paths) { for (int i = 0; i < c.VertexCount; ++i) { c[i] = xform.TransformP(c[i]); } } } }
private static bool compute_plane_curves(DMesh3 mesh, DMeshAABBTree3 spatial, double z, bool is_solid, out Polygon2d[] loops, out PolyLine2d[] curves) { Func <Vector3d, double> planeF = (v) => { return(v.z - z); }; // find list of triangles that intersect this z-value PlaneIntersectionTraversal planeIntr = new PlaneIntersectionTraversal(mesh, z); spatial.DoTraversal(planeIntr); List <int> triangles = planeIntr.triangles; // compute intersection iso-curves, which produces a 3D graph of undirected edges MeshIsoCurves iso = new MeshIsoCurves(mesh, planeF) { WantGraphEdgeInfo = true }; iso.Compute(triangles); DGraph3 graph = iso.Graph; if (graph.EdgeCount == 0) { loops = new Polygon2d[0]; curves = new PolyLine2d[0]; return(false); } // if this is a closed solid, any open spurs in the graph are errors if (is_solid) { DGraph3Util.ErodeOpenSpurs(graph); } // [RMS] debug visualization //DGraph2 graph2 = new DGraph2(); //Dictionary<int, int> mapV = new Dictionary<int, int>(); //foreach (int vid in graph.VertexIndices()) // mapV[vid] = graph2.AppendVertex(graph.GetVertex(vid).xy); //foreach (int eid in graph.EdgeIndices()) // graph2.AppendEdge(mapV[graph.GetEdge(eid).a], mapV[graph.GetEdge(eid).b]); //SVGWriter svg = new SVGWriter(); //svg.AddGraph(graph2, SVGWriter.Style.Outline("black", 0.05f)); //foreach (int vid in graph2.VertexIndices()) { // if (graph2.IsJunctionVertex(vid)) // svg.AddCircle(new Circle2d(graph2.GetVertex(vid), 0.25f), SVGWriter.Style.Outline("red", 0.1f)); // else if (graph2.IsBoundaryVertex(vid)) // svg.AddCircle(new Circle2d(graph2.GetVertex(vid), 0.25f), SVGWriter.Style.Outline("blue", 0.1f)); //} //svg.Write(string.Format("c:\\meshes\\EXPORT_SLICE_{0}.svg", z)); // extract loops and open curves from graph DGraph3Util.Curves c = DGraph3Util.ExtractCurves(graph, false, iso.ShouldReverseGraphEdge); loops = new Polygon2d[c.Loops.Count]; for (int li = 0; li < loops.Length; ++li) { DCurve3 loop = c.Loops[li]; loops[li] = new Polygon2d(); foreach (Vector3d v in loop.Vertices) { loops[li].AppendVertex(v.xy); } } curves = new PolyLine2d[c.Paths.Count]; for (int pi = 0; pi < curves.Length; ++pi) { DCurve3 span = c.Paths[pi]; curves[pi] = new PolyLine2d(); foreach (Vector3d v in span.Vertices) { curves[pi].AppendVertex(v.xy); } } return(true); }
void extract_topology() { var graph = new DGraph3(); // add vertices to graph, and store mappings int[] mapV = new int[Mesh.MaxVertexID]; int[] mapVFrom = new int[AllVertices.Count]; foreach (int vid in AllVertices) { int new_vid = graph.AppendVertex(Mesh.GetVertex(vid)); mapV[vid] = new_vid; mapVFrom[new_vid] = vid; } // add edges to graph. graph-to-mesh eid mapping is stored via graph edge-group-id int[] mapE = new int[Mesh.MaxEdgeID]; foreach (int eid in AllEdges) { Index2i ev = Mesh.GetEdgeV(eid); int new_a = mapV[ev.a]; int new_b = mapV[ev.b]; int new_eid = graph.AppendEdge(new_a, new_b, eid); mapE[eid] = new_eid; } // extract the graph topology DGraph3Util.Curves curves = DGraph3Util.ExtractCurves(graph, true); // reconstruct mesh spans / curves / junctions from graph topology int NP = curves.PathEdges.Count; Spans = new EdgeSpan[NP]; for (int pi = 0; pi < NP; ++pi) { List <int> pathE = curves.PathEdges[pi]; for (int k = 0; k < pathE.Count; ++k) { pathE[k] = graph.GetEdgeGroup(pathE[k]); } Spans[pi] = EdgeSpan.FromEdges(Mesh, pathE); } int NL = curves.LoopEdges.Count; Loops = new EdgeLoop[NL]; for (int li = 0; li < NL; ++li) { List <int> loopE = curves.LoopEdges[li]; for (int k = 0; k < loopE.Count; ++k) { loopE[k] = graph.GetEdgeGroup(loopE[k]); } Loops[li] = EdgeLoop.FromEdges(Mesh, loopE); } JunctionVertices = new HashSet <int>(); foreach (int gvid in curves.JunctionV) { JunctionVertices.Add(mapVFrom[gvid]); } }