/// <summary> /// this runs inside SO.SafeMeshRead /// </summary> private object LockedComputeMeshBoundaryData(DMesh3 mesh) { ComponentData data = new ComponentData(); data.timestamp = mesh.ShapeTimestamp; MeshConnectedComponents comp = new MeshConnectedComponents(mesh); comp.FindConnectedT(); if (comp.Count == 1) { return(data); } // [TODO] // - a very common case is a huge mesh with a few floaters. We // should have a way to handle this w/o having to create all // these spatial data structures for the huge mesh! We can // do a quick sort based on bounding boxes, and for very // small submeshes we could use non-fast WN, etc, etc... DSubmesh3Set subMeshes = new DSubmesh3Set(mesh, comp); MeshSpatialSort sort = new MeshSpatialSort(); foreach (var submesh in subMeshes) { sort.AddMesh(submesh.SubMesh, submesh); } sort.Sort(); foreach (var solid in sort.Solids) { foreach (var cavity in solid.Cavities) { data.InteriorMeshes.Add(cavity.Mesh); } if (solid.Outer.InsideOf.Count > 0) { data.InteriorMeshes.Add(solid.Outer.Mesh); } } // reverse orientation so that shading and culling works gParallel.ForEach(data.InteriorMeshes, (m) => { m.ReverseOrientation(true); }); return(data); }
public static void test_sort_mesh_components() { DMesh3 mesh = TestUtil.LoadTestInputMesh("bunny_nested_spheres.obj"); MeshConnectedComponents components = new MeshConnectedComponents(mesh); components.FindConnectedT(); DSubmesh3Set componentMeshes = new DSubmesh3Set(mesh, components); LocalProfiler p = new LocalProfiler(); p.Start("sort"); MeshSpatialSort sorter = new MeshSpatialSort(); foreach (DSubmesh3 submesh in componentMeshes) { sorter.AddMesh(submesh.SubMesh, submesh); } sorter.Sort(); p.Stop("sort"); System.Console.WriteLine(p.AllTimes()); DMesh3 resultMesh = new DMesh3(); foreach (var solid in sorter.Solids) { if (solid.Outer.InsideOf.Count == 0) { MeshEditor.Append(resultMesh, solid.Outer.Mesh); } } TestUtil.WriteTestOutputMesh(resultMesh, "mesh_components.obj"); }