public override bool BuildOnMesh(DMesh3Builder meshBuilder) { var doorCopy = new DMesh3(Mesh, bCompact: true); if (FrontNormal == -Vector3d.AxisZ) { // trick to prevent 180 rotation FrontNormal += new Vector3d(0.0000001, 0.0, 0.0); } var meshWidth = doorCopy.GetBounds().Width; var meshHeight = doorCopy.GetBounds().Height; var widthScale = WidthLimit / meshWidth; var heightScale = HeightLimit / meshHeight; Quaterniond orientingQuaternion = new Quaterniond(Vector3d.AxisZ, FrontNormal); MeshTransforms.Rotate(doorCopy, Vector3d.Zero, orientingQuaternion); MeshTransforms.Scale(doorCopy, Math.Min(widthScale, heightScale)); MeshTransforms.Translate(doorCopy, Origin); meshBuilder.AppendNewMesh(doorCopy); meshBuilder.SetActiveMesh(0); return(true); }
void bake_hole_mesh() { CavityPreviewSO.EditAndUpdateMesh((mesh) => { MeshTransforms.Scale(mesh, new Vector3d(HoleSize, HoleSize, (float)CurHoleDepth), Vector3d.Zero); }, GeometryEditTypes.VertexDeformation); CavityPreviewSO.SetLocalScale(Vector3f.One); }
private static void LoadAssetsAsMeshes(IList <Asset> assets, int trianglesLimit, double scale, Dictionary <Asset, DMesh3> destination) { if (destination == null) { return; } var meshBuilder = new DMesh3Builder() { NonManifoldTriBehavior = DMesh3Builder.AddTriangleFailBehaviors.DiscardTriangle }; var objReader = new OBJFormatReader(); var reader = new StandardMeshReader() { MeshBuilder = meshBuilder, ReadInvariantCulture = true }; //reader.AddFormatHandler(objReader); foreach (var asset in assets) { //var isMeshLoaded = objReader.ReadFile(asset.OpenAssetFile(), meshBuilder, null, new ParsingMessagesHandler((s, o) => {; })); var isMeshLoaded = reader.Read(asset.OpenAssetFile(), asset.FileFormat.ToString(), ReadOptions.Defaults); if (isMeshLoaded.code == IOCode.Ok) { var mesh = meshBuilder.Meshes.Last(); Reducer r = new Reducer(mesh) { PreserveBoundaryShape = true, }; r.ReduceToTriangleCount(trianglesLimit); MeshTransforms.Scale(mesh, scale); destination[asset] = mesh; } } }
// Use this for initialization void Start() { meshGO = GameObject.Find("sample_mesh"); Mesh unityMesh = meshGO.GetComponent <MeshFilter>().mesh; startMesh = g3UnityUtils.UnityMeshToDMesh(unityMesh); double height = startMesh.CachedBounds.Height; // find path to sample file if (LoadSampleMesh) { string curPath = Application.dataPath; string filePath = Path.Combine(curPath, Path.Combine("..\\sample_files", SampleFileName)); // load sample file, convert to unity coordinate system, translate and scale to origin startMesh = StandardMeshReader.ReadMesh(filePath); if (startMesh == null) { startMesh = new Sphere3Generator_NormalizedCube().Generate().MakeDMesh(); } if (FlipLeftRight) { MeshTransforms.FlipLeftRightCoordSystems(startMesh); } MeshTransforms.Scale(startMesh, height / startMesh.CachedBounds.Height); MeshTransforms.Translate(startMesh, -startMesh.CachedBounds.Center); MeshNormals.QuickCompute(startMesh); g3UnityUtils.SetGOMesh(meshGO, startMesh); } }
public override OpStatus Apply() { Target.EditAndUpdateMesh( (mesh) => { MeshTransforms.Scale(mesh, LocalScale.x, LocalScale.y, LocalScale.z); Target.SetLocalScale(Vector3f.One); }, GeometryEditTypes.VertexDeformation ); return(OpStatus.Success); }
public override OpStatus Revert() { Target.EditAndUpdateMesh( (mesh) => { MeshTransforms.Scale(mesh, 1.0 / LocalScale.x, 1.0 / LocalScale.y, 1.0 / LocalScale.z); Target.SetLocalScale(LocalScale); }, GeometryEditTypes.VertexDeformation ); return(OpStatus.Success); }
public static void test_AABBTree_TriTriDist() { System.Console.WriteLine("test_AABBTree_TriTriDist()"); Sphere3Generator_NormalizedCube gen = new Sphere3Generator_NormalizedCube() { Radius = 1, EdgeVertices = 6 }; DMesh3 sphereMesh = gen.Generate().MakeDMesh(); Reducer reducer = new Reducer(sphereMesh); reducer.ReduceToTriangleCount(77); Random r = new Random(31337); for (int iter = 0; iter < 1000; ++iter) { DMesh3 sphere1 = new DMesh3(sphereMesh), sphere2 = new DMesh3(sphereMesh); Vector3d[] pts = TestUtil.RandomPoints3(3, r, Vector3d.Zero, 100); Vector3d p1 = pts[0], p2 = pts[1]; double r1 = 5, r2 = 10; MeshTransforms.Scale(sphere1, r1); MeshTransforms.Translate(sphere1, p1); MeshTransforms.Scale(sphere2, r2); MeshTransforms.Translate(sphere2, p2); DMeshAABBTree3 tree1 = new DMeshAABBTree3(sphere1, true); DMeshAABBTree3 tree2 = new DMeshAABBTree3(sphere2, true); double sphere_dist = p1.Distance(p2) - (r1 + r2); double distBrute = double.MaxValue; Index2i nearestBrute = MeshQueries.FindNearestTriangles_LinearSearch(sphere1, sphere2, out distBrute); DistTriangle3Triangle3 qBrute = MeshQueries.TrianglesDistance(sphere1, nearestBrute.a, sphere2, nearestBrute.b); double distTree = double.MaxValue; Index2i nearestTree = tree1.FindNearestTriangles(tree2, null, out distTree); DistTriangle3Triangle3 qTree = MeshQueries.TrianglesDistance(sphere1, nearestTree.a, sphere2, nearestTree.b); double distTree2 = double.MaxValue; Index2i nearestTree2 = tree2.FindNearestTriangles(tree1, null, out distTree2); // pairs are unstable if we are on an edge if (qBrute.Triangle0BaryCoords.x < 0.99 && qBrute.Triangle0BaryCoords.y < 0.99 && qBrute.Triangle0BaryCoords.z < 0.99 && qBrute.Triangle1BaryCoords.x < 0.99 && qBrute.Triangle1BaryCoords.y < 0.99 && qBrute.Triangle1BaryCoords.z < 0.99) { Util.gDevAssert(nearestBrute.a == nearestTree.a && nearestBrute.b == nearestTree.b); Util.gDevAssert(nearestBrute.b == nearestTree2.a && nearestBrute.a == nearestTree.b); } Util.gDevAssert(Math.Abs(distBrute - distTree) < MathUtil.Epsilonf && Math.Abs(distBrute - distTree2) < MathUtil.Epsilonf); } }
public static void test_AABBTree_TriTriIntr() { System.Console.WriteLine("test_AABBTree_TriTriIntr()"); Sphere3Generator_NormalizedCube gen = new Sphere3Generator_NormalizedCube() { Radius = 1, EdgeVertices = 25 }; DMesh3 sphereMesh = gen.Generate().MakeDMesh(); Reducer reducer = new Reducer(sphereMesh); reducer.ReduceToTriangleCount(77); int hit_count = 0; Random r = new Random(31337); for (int iter = 0; iter < 5000; ++iter) { DMesh3 sphere1 = new DMesh3(sphereMesh), sphere2 = new DMesh3(sphereMesh); Vector3d[] pts = TestUtil.RandomPoints3(3, r, Vector3d.Zero, 10); // at 10, about half of the spheres intersect Vector3d p1 = pts[0], p2 = pts[1]; double r1 = 5, r2 = 10; double eps = (r1 + r2) * 0.5 * 0.001; MeshTransforms.Scale(sphere1, r1); MeshTransforms.Translate(sphere1, p1); MeshTransforms.Scale(sphere2, r2); MeshTransforms.Translate(sphere2, p2); DMeshAABBTree3 tree1 = new DMeshAABBTree3(sphere1, true); DMeshAABBTree3 tree2 = new DMeshAABBTree3(sphere2, true); bool spheres_intersect = p1.Distance(p2) < (r1 + r2 + 2 * eps); if (spheres_intersect && p1.Distance(p2) + Math.Min(r1, r2) < Math.Max(r1, r2) * 0.9) { spheres_intersect = false; } Index2i hitBrute = MeshQueries.FindIntersectingTriangles_LinearSearch(sphere1, sphere2); bool bHitBrute = hitBrute != Index2i.Max; if (bHitBrute) { hit_count++; } // [RMS] not reliable because of tesselation //Util.gDevAssert(bHitBrute == spheres_intersect); bool bHitTree1 = tree1.TestIntersection(tree2); bool bHitTree2 = tree2.TestIntersection(tree1); Util.gDevAssert(bHitBrute == bHitTree1 && bHitTree1 == bHitTree2); } System.Console.WriteLine(hit_count.ToString()); }
protected override void SolveInstance(IGH_DataAccess DA) { DMesh3_goo dMsh_goo = null; Rhino.Geometry.Vector3d sFact = new Rhino.Geometry.Vector3d(1, 1, 1); Point3d origin = new Point3d(0, 0, 0); DA.GetData(0, ref dMsh_goo); DA.GetData(1, ref sFact); DA.GetData(2, ref origin); DMesh3 dMsh_copy = new DMesh3(dMsh_goo.Value); MeshTransforms.Scale(dMsh_copy, sFact.ToVec3d(), origin.ToVec3d()); DA.SetData(0, dMsh_copy); }
async Task process_and_complete_import(string sFilename, DMesh3Builder builder, double targetHeight, int reduceToCount, Action <string> onCompletedF) { CCStatus.BeginOperation("processing"); await Task.Run(() => { if (targetHeight > 0.001 && Math.Abs(targetHeight - Bounds.Height) > 0.001) { double scaleH = targetHeight / Bounds.Height; Vector3d o = Bounds.Center - Bounds.Extents.y *Vector3d.AxisY; foreach (var mesh in builder.Meshes) { MeshTransforms.Scale(mesh, scaleH *Vector3d.One, o); } } }); await Task.Run(() => { if (reduceToCount != -1 && reduceToCount < TriCount) { foreach (var mesh in builder.Meshes) { if (mesh.TriangleCount < 10) { continue; } double tri_fraction = (double)mesh.TriangleCount / (double)TriCount; int NT = (int)(tri_fraction *reduceToCount); if (NT < 10) { NT = 10; } Reducer r = new Reducer(mesh); r.ReduceToTriangleCount(NT); } } }); CCStatus.EndOperation("processing"); await complete_import(sFilename, builder, onCompletedF); }
public override bool BuildOnMesh(DMesh3Builder meshBuilder) { DMesh3 windowCopy = null; BuildingTask = Task.Run(() => { windowCopy = new DMesh3(Mesh, bCompact: true); //var windowCopy = Mesh; if (FrontNormal == -Vector3d.AxisZ) { // trick to prevent 180 rotation FrontNormal += new Vector3d(0.0000001, 0.0, 0.0); } var meshWidth = windowCopy.GetBounds().Width; var meshHeight = windowCopy.GetBounds().Height; var widthScale = WidthLimit / meshWidth; var heightScale = HeightLimit / meshHeight; var selectedScale = Math.Min(widthScale, heightScale); Quaterniond orientingQuaternion = new Quaterniond(Vector3d.AxisZ, FrontNormal); MeshTransforms.Rotate(windowCopy, Vector3d.Zero, orientingQuaternion); MeshTransforms.Scale(windowCopy, selectedScale); MeshTransforms.Translate(windowCopy, Origin); //MeshTransforms.Translate(windowCopy, Origin + Vector3d.AxisY * meshHeight * selectedScale * 0.6); }).ContinueWith(t => { lock (meshBuilder) { meshBuilder.AppendNewMesh(windowCopy); meshBuilder.SetActiveMesh(0); } }); return(true); }
// Use this for initialization void Start() { // find path to sample file string curPath = Application.dataPath; string filePath = Path.Combine(curPath, Path.Combine("..\\sample_files", "bunny_solid.obj")); // load sample file, convert to unity coordinate system, translate and scale to origin startMesh = StandardMeshReader.ReadMesh(filePath); if (startMesh == null) { startMesh = new Sphere3Generator_NormalizedCube().Generate().MakeDMesh(); } MeshTransforms.FlipLeftRightCoordSystems(startMesh); MeshTransforms.Translate(startMesh, -startMesh.CachedBounds.Center); MeshTransforms.Scale(startMesh, 8.0 / startMesh.CachedBounds.MaxDim); // load wireframe shader Material wireframeShader = g3UnityUtils.SafeLoadMaterial("wireframe_shader/Wireframe"); // create initial mesh meshGO = g3UnityUtils.CreateMeshGO("start_mesh", startMesh, wireframeShader); }
virtual protected DMesh3 make_bunny() { if (cached_bunny == null) { // [RMS] yiiiiiikes MemoryStream stream = FResources.LoadBinary("meshes/unit_height_bunny"); if (stream != null) { cached_bunny = StandardMeshReader.ReadMesh(stream, "obj"); MeshTransforms.ConvertZUpToYUp(cached_bunny); MeshTransforms.FlipLeftRightCoordSystems(cached_bunny); } else { cached_bunny = make_shape_sphere(); MeshTransforms.Scale(cached_bunny, 1 / ShapeHeight); } } DMesh3 mesh = new DMesh3(cached_bunny); MeshTransforms.Scale(mesh, ShapeHeight); return(mesh); }
// exports svg w/ different containments of point set (created by slicing mesh) public static void containment_demo_svg() { DMesh3 mesh = TestUtil.LoadTestInputMesh("bunny_solid.obj"); MeshTransforms.Scale(mesh, 4); AxisAlignedBox3d meshBounds = mesh.CachedBounds; Vector3d origin = meshBounds.Center; origin -= 0.2 * meshBounds.Height * Vector3d.AxisY; Frame3f plane = new Frame3f(origin, new Vector3d(1, 3, 0).Normalized); MeshPlaneCut cut = new MeshPlaneCut(mesh, plane.Origin, plane.Z); cut.Cut(); AxisAlignedBox2d polyBounds = AxisAlignedBox2d.Empty; List <Polygon2d> polys = new List <Polygon2d>(); foreach (EdgeLoop loop in cut.CutLoops) { Polygon2d poly = new Polygon2d(); foreach (int vid in loop.Vertices) { poly.AppendVertex(mesh.GetVertex(vid).xz); } poly.Rotate(new Matrix2d(90, true), Vector2d.Zero); polys.Add(poly); polyBounds.Contain(poly.Bounds); } SVGWriter svg = new SVGWriter(); var polyStyle = SVGWriter.Style.Outline("red", 1.0f); var contStyle = SVGWriter.Style.Outline("black", 1.0f); for (int k = 0; k < 3; ++k) { double shift = (k == 2) ? 1.4f : 1.1f; Vector2d tx = (k - 1) * (polyBounds.Width * shift) * Vector2d.AxisX; List <Vector2d> pts = new List <Vector2d>(); foreach (Polygon2d poly in polys) { var p2 = new Polygon2d(poly).Translate(tx); pts.AddRange(p2.Vertices); svg.AddPolygon(p2, polyStyle); } if (k == 0) { ConvexHull2 hull = new ConvexHull2(pts, 0.001, QueryNumberType.QT_DOUBLE); svg.AddPolygon(hull.GetHullPolygon(), contStyle); } else if (k == 1) { ContMinBox2 contbox = new ContMinBox2(pts, 0.001, QueryNumberType.QT_DOUBLE, false); svg.AddPolygon(new Polygon2d(contbox.MinBox.ComputeVertices()), contStyle); } else if (k == 2) { ContMinCircle2 contcirc = new ContMinCircle2(pts); svg.AddCircle(contcirc.Result, contStyle); } } svg.Write(TestUtil.GetTestOutputPath("contain_demos.svg")); }
static void run_single_process() { int done_count = 0; int MAX_COUNT = 10000; bool VERBOSE = false; TimeSpan TIMEOUT = TimeSpan.FromSeconds(30); int failed_count = 0; double MAX_DIM_MM = 50; int MAX_TRI_COUNT = 250000; HashSet <string> completed = File.Exists(CACHE_FILENAME) ? new HashSet <string>(File.ReadAllLines(CACHE_FILENAME)) : new HashSet <string>(); string[] files = Directory.GetFiles("E:\\Thingi10K\\closed"); SafeListBuilder <string> result_strings = new SafeListBuilder <string>(); SafeListBuilder <string> processed_files = new SafeListBuilder <string>(); gParallel.ForEach(files, (filename) => { int i = done_count; if (i > MAX_COUNT) { return; } Interlocked.Increment(ref done_count); if (i % 10 == 0) { System.Console.WriteLine("started {0} / {1}", i, files.Length); } if (completed.Contains(filename)) { return; } // save progress on this run if (i % 10 == 0) { write_output(result_strings); lock (completed) { write_completed(completed, CACHE_FILENAME); } } DMesh3 mesh = StandardMeshReader.ReadMesh(filename); AxisAlignedBox3d bounds = mesh.CachedBounds; MeshTransforms.Scale(mesh, MAX_DIM_MM / bounds.MaxDim); Vector3d basePt = mesh.CachedBounds.Point(0, 0, -1); MeshTransforms.Translate(mesh, -basePt); if (mesh.TriangleCount > MAX_TRI_COUNT) { Reducer r = new Reducer(mesh); r.ReduceToTriangleCount(MAX_TRI_COUNT); mesh = new DMesh3(mesh, true); } StringBuilder builder = new StringBuilder(); builder.Append(filename); builder.Append(','); builder.Append(mesh.TriangleCount.ToString()); builder.Append(','); var start = DateTime.Now; if (VERBOSE) { System.Console.WriteLine(builder.ToString()); } if (VERBOSE) { System.Console.WriteLine(mesh.CachedBounds.ToString()); } GCodeInfo gcinfo = GenerateGCodeForFileWithTimeout2(filename, TIMEOUT); if (gcinfo.exception != null) { System.Console.WriteLine(filename + " : " + gcinfo.exception.Message); Interlocked.Increment(ref failed_count); } if (gcinfo.completed) { builder.Append("OK"); } else if (gcinfo.completed == false && gcinfo.timed_out) { builder.Append("TIMEOUT"); } else if (gcinfo.completed == false) { builder.Append("FAILED"); } builder.Append(','); var end = DateTime.Now; builder.Append(((int)(end - start).TotalSeconds).ToString()); builder.Append(','); builder.Append(gcinfo.SliceCount.ToString()); builder.Append(','); builder.Append(gcinfo.GCodeLines.ToString()); builder.Append(','); builder.Append(gcinfo.GCodeBytes.ToString()); builder.Append(','); builder.Append(gcinfo.TotalLength.ToString()); builder.Append(','); if (VERBOSE) { System.Console.WriteLine(builder.ToString()); } result_strings.SafeAdd(builder.ToString()); lock (completed) { completed.Add(filename); } }); write_output(result_strings); }
static void Main(string[] args) { GCodeInfo info = new GCodeInfo(); string filename = args[0]; DMesh3 mesh = StandardMeshReader.ReadMesh(filename); AxisAlignedBox3d bounds = mesh.CachedBounds; MeshTransforms.Scale(mesh, MAX_DIM_MM / bounds.MaxDim); Vector3d basePt = mesh.CachedBounds.Point(0, 0, -1); MeshTransforms.Translate(mesh, -basePt); if (mesh.TriangleCount > MAX_TRI_COUNT) { Reducer r = new Reducer(mesh); r.ReduceToTriangleCount(MAX_TRI_COUNT); mesh = new DMesh3(mesh, true); } var start = DateTime.Now; bool ENABLE_SUPPORT_ZSHIFT = true; try { // configure settings MakerbotSettings settings = new MakerbotSettings(Makerbot.Models.Replicator2); //MonopriceSettings settings = new MonopriceSettings(Monoprice.Models.MP_Select_Mini_V2); //PrintrbotSettings settings = new PrintrbotSettings(Printrbot.Models.Plus); settings.ExtruderTempC = 200; settings.Shells = 2; settings.InteriorSolidRegionShells = 0; settings.SparseLinearInfillStepX = 10; settings.ClipSelfOverlaps = false; settings.GenerateSupport = true; settings.EnableSupportShell = true; PrintMeshAssembly meshes = new PrintMeshAssembly(); meshes.AddMesh(mesh); // slice meshes MeshPlanarSlicerPro slicer = new MeshPlanarSlicerPro() { LayerHeightMM = settings.LayerHeightMM, SliceFactoryF = PlanarSlicePro.FactoryF }; slicer.Add(meshes); PlanarSliceStack slices = slicer.Compute(); info.SliceCount = slices.Count; info.SliceBounds = slices.Bounds; // run print generator SingleMaterialFFFPrintGenPro printGen = new SingleMaterialFFFPrintGenPro(meshes, slices, settings); if (ENABLE_SUPPORT_ZSHIFT) { printGen.LayerPostProcessor = new SupportConnectionPostProcessor() { ZOffsetMM = 0.2f } } ; printGen.AccumulatePathSet = true; printGen.Generate(); GCodeFile genGCode = printGen.Result; info.PathBounds = printGen.AccumulatedPaths.Bounds; info.ExtrudeBounds = printGen.AccumulatedPaths.ExtrudeBounds; info.TotalLength = CurveUtils.ArcLength(printGen.AccumulatedPaths.AllPositionsItr()); info.GCodeLines = genGCode.LineCount; // write to in-memory string StandardGCodeWriter writer = new StandardGCodeWriter(); using (MemoryStream membuf = new MemoryStream()) { using (StreamWriter w = new StreamWriter(membuf)) { writer.WriteFile(genGCode, w); info.GCodeBytes = (int)membuf.Length; } } // try to force destructor error printGen = null; genGCode = null; GC.Collect(); } catch (Exception e) { System.Console.WriteLine("EXCEPTION:" + e.Message); return; } var end = DateTime.Now; int seconds = (int)(end - start).TotalSeconds; System.Console.WriteLine("{0},{1},{2},{3},{4},{5},{6},{7},", filename, mesh.TriangleCount, "OK", seconds, info.SliceCount, info.GCodeLines, info.GCodeBytes, (int)info.TotalLength); }
public void Compute() { int N = meshToScene.Length; slicer = new MeshPlanarSlicerPro() { LayerHeightMM = CC.Settings.LayerHeightMM, // [RMS] 1.5 here is a hack. If we don't leave a bit of space then often the filament gets squeezed right at // inside/outside transitions, which is bad. Need a better way to handle. OpenPathDefaultWidthMM = CC.Settings.NozzleDiameterMM * 1.5, SetMinZValue = 0, SliceFactoryF = PlanarSlicePro.FactoryF }; if (CC.Settings.OpenMode == PrintSettings.OpenMeshMode.Clipped) { slicer.DefaultOpenPathMode = PrintMeshOptions.OpenPathsModes.Clipped; } else if (CC.Settings.OpenMode == PrintSettings.OpenMeshMode.Embedded) { slicer.DefaultOpenPathMode = PrintMeshOptions.OpenPathsModes.Embedded; } else if (CC.Settings.OpenMode == PrintSettings.OpenMeshMode.Ignored) { slicer.DefaultOpenPathMode = PrintMeshOptions.OpenPathsModes.Ignored; } if (CC.Settings.StartLayers > 0) { int start_layers = CC.Settings.StartLayers; double std_layer_height = CC.Settings.LayerHeightMM; double start_layer_height = CC.Settings.StartLayerHeightMM; slicer.LayerHeightF = (layer_i) => { return((layer_i < start_layers) ? start_layer_height : std_layer_height); }; } try { assembly = new PrintMeshAssembly(); for (int k = 0; k < N; ++k) { DMesh3 mesh = meshCopies[k]; Frame3f mapF = meshToScene[k]; PrintMeshSettings settings = meshSettings[k]; PrintMeshOptions options = new PrintMeshOptions(); options.IsSupport = (settings.ObjectType == PrintMeshSettings.ObjectTypes.Support); options.IsCavity = (settings.ObjectType == PrintMeshSettings.ObjectTypes.Cavity); options.IsCropRegion = (settings.ObjectType == PrintMeshSettings.ObjectTypes.CropRegion); options.IsOpen = false; if (settings.OuterShellOnly) { options.IsOpen = true; } options.OpenPathMode = PrintMeshSettings.Convert(settings.OpenMeshMode); options.Extended = new ExtendedPrintMeshOptions() { ClearanceXY = settings.Clearance, OffsetXY = settings.OffsetXY }; Vector3f scale = localScale[k]; MeshTransforms.Scale(mesh, scale.x, scale.y, scale.z); MeshTransforms.FromFrame(mesh, mapF); MeshTransforms.FlipLeftRightCoordSystems(mesh); MeshTransforms.ConvertYUpToZUp(mesh); MeshAssembly decomposer = new MeshAssembly(mesh); decomposer.HasNoVoids = settings.NoVoids; decomposer.Decompose(); assembly.AddMeshes(decomposer.ClosedSolids, options); PrintMeshOptions openOptions = options.Clone(); assembly.AddMeshes(decomposer.OpenMeshes, openOptions); } if (slicer.Add(assembly) == false) { throw new Exception("error adding PrintMeshAssembly to Slicer!!"); } // set clip box Box2d clip_box = new Box2d(Vector2d.Zero, new Vector2d(CC.Settings.BedSizeXMM / 2, CC.Settings.BedSizeYMM / 2)); slicer.ValidRegions = new List <GeneralPolygon2d>() { new GeneralPolygon2d(new Polygon2d(clip_box.ComputeVertices())) }; result = slicer.Compute(); Success = true; } catch (Exception e) { DebugUtil.Log("GeometrySlicer.Compute: exception: " + e.Message); Success = false; } Finished = true; }
void update_mesh() { clear_mesh(); AxisAlignedBox3i bounds = grid.Extents; Vector3i minCorner = bounds.Min; Vector3f cornerXYZ = grid.ToXYZ(minCorner); Bitmap3d bmp; try { bmp = new Bitmap3d(bounds.Diagonal + Vector3i.One); } catch (Exception e) { Debug.Log("update_mesh: exception allocating grid of size " + bounds.Diagonal); throw e; } foreach (Vector3i idx in grid.GridIndices(MinSamples)) { Vector3i bidx = idx - minCorner; try { bmp.Set(bidx, true); } catch (Exception e) { Debug.Log("bad index is " + bidx + " grid dims " + bmp.Dimensions); throw e; } } // get rid of one-block tubes, floaters, etc. // todo: use a queue instead of passes? or just descend into // nbrs when changing one block? one pass to compute counts and // then another to remove? (yes that is a good idea...) bmp.Filter(2); bmp.Filter(2); bmp.Filter(2); bmp.Filter(2); bmp.Filter(2); bmp.Filter(2); VoxelSurfaceGenerator gen = new VoxelSurfaceGenerator() { Voxels = bmp, Clockwise = false, MaxMeshElementCount = 65000, ColorSourceF = (idx) => { idx = idx + minCorner; return(grid.GetColor(idx)); } }; gen.Generate(); List <DMesh3> meshes = gen.Meshes; List <fMeshGameObject> newMeshGOs = new List <fMeshGameObject>(); foreach (DMesh3 mesh in meshes) { MeshTransforms.Scale(mesh, grid.GridStepSize); MeshTransforms.Translate(mesh, cornerXYZ); Mesh m = UnityUtil.DMeshToUnityMesh(mesh, false); fMeshGameObject meshGO = GameObjectFactory.CreateMeshGO("gridmesh", m, false, true); meshGO.SetMaterial(MaterialUtil.CreateStandardVertexColorMaterialF(Colorf.White)); newMeshGOs.Add(meshGO); } CurrentMeshGOs = newMeshGOs; }
// Use this for initialization public override void Awake() { // if we need to auto-configure Rift vs Vive vs (?) VR, we need // to do this before any other F3 setup, because MainCamera will change // and we are caching that in a lot of places... if (AutoConfigVR) { VRCameraRig = gs.VRPlatform.AutoConfigureVR(); } // restore any settings SceneGraphConfig.RestorePreferences(); // set up some defaults // this will move the ground plane down, but the bunnies will be floating... //SceneGraphConfig.InitialSceneTranslate = -4.0f * Vector3f.AxisY; SceneGraphConfig.DefaultSceneCurveVisualDegrees = 0.35f; SceneGraphConfig.DefaultPivotVisualDegrees = 2.3f; SceneGraphConfig.DefaultAxisGizmoVisualDegrees = 25.0f; // make curves easier to click PolyCurveSO.DefaultHitWidthMultiplier = 2.0f; SceneOptions options = new SceneOptions(); options.UseSystemMouseCursor = true; options.EnableTransforms = true; options.EnableCockpit = true; options.CockpitInitializer = new SetupOrthoGenCockpit(); options.MouseCameraControls = new MayaCameraHotkeys() { MousePanSpeed = 5.0f, MouseZoomSpeed = 5.0f }; options.SpatialCameraRig = VRCameraRig; options.Use2DCockpit = true; options.ConstantSize2DCockpit = true; FPlatform.EditorPixelScaleFactor = 1.0f; // very verbose options.LogLevel = 2; context = new FContext(); OG.Context = context; OrthogenUI.ActiveContext = context; context.Start(options); DebugUtil.Log("started context"); // Set up standard scene lighting if enabled if (options.EnableDefaultLighting) { GameObject lighting = GameObject.Find("SceneLighting"); if (lighting == null) { lighting = new GameObject("SceneLighting"); } SceneLightingSetup setup = lighting.AddComponent <SceneLightingSetup>(); setup.Context = context; setup.LightDistance = 30.0f; // related to total scene scale... } //GameObjectFactory.CurveRendererSource = new VectrosityCurveRendererFactory(); // set up ground plane geometry (optional) GameObject boundsObject = GameObject.Find("Bounds"); if (boundsObject != null) { context.Scene.AddWorldBoundsObject(boundsObject); } /* * ORTHOGEN-SPECIFIC SETUP STARTS HERE */ // set up scene and tools like Orthogen wants them OGActions.InitializeUsageContext(OGActions.UsageContext.OrthoVRApp); //OGActions.InitializeUsageContext(OGActions.UsageContext.NiaOrthogenApp); OrthogenMaterials.InitializeMaterials(); OGActions.InitializeF3Scene(context); OGActions.InitializeF3Tools(context); OGActions.PostConfigureTools_Demo(); OGActions.ConfigurePlatformInput_Mouse(); /* * optional things specific to demo app */ // ground plane stays below socket as it is updated DemoActions.AddRepositionGroundPlaneOnSocketEdit(); /* * import sample mesh */ // load sample mesh string assetPath = Application.dataPath; string samplesPath = Path.Combine(assetPath, "..", "sample_files"); //string sampleFile = Path.Combine(samplesPath, "sample_socket_off.obj"); //string sampleFile = Path.Combine(samplesPath, "sample_socket_1.obj"); //string sampleFile = Path.Combine(samplesPath, "scan_1_raw.obj"); string sampleFile = Path.Combine(samplesPath, "scan_1_remesh.obj"); DMesh3 mesh = StandardMeshReader.ReadMesh(sampleFile); if (mesh.HasVertexColors == false) { mesh.EnableVertexColors(Colorf.Silver); } // read sample file from Resources instead //MemoryStream sampleFileStream = FResources.LoadBinary("sample_socket_1"); //DMesh3 mesh = StandardMeshReader.ReadMesh(sampleFileStream, "obj"); double scale = Units.MetersTo(Units.Linear.Millimeters); // this mesh is in meters, so scale to mm MeshTransforms.FlipLeftRightCoordSystems(mesh); // convert to unity coordinate system MeshTransforms.Scale(mesh, scale); // initialize the datamodel OGActions.BeginSocketDesignFromScan(Context, mesh); // set up my UI tests/etc configure_unity_ui(); // dgraph tests //DGTest.test(Debug.Log); }
public static void test_arrangement_demo() { DMesh3 mesh = TestUtil.LoadTestInputMesh("spheres_and_planes.obj"); MeshTransforms.Scale(mesh, 8); AxisAlignedBox3d meshBounds = mesh.CachedBounds; Vector3d origin = meshBounds.Center; double simplify_thresh = 5.0; Frame3f plane = new Frame3f(origin, Vector3d.AxisY); MeshPlaneCut cut = new MeshPlaneCut(mesh, plane.Origin, plane.Z); cut.Cut(); Arrangement2d builder = new Arrangement2d(new AxisAlignedBox2d(1024.0)); // insert all cut edges HashSet <Vector2d> srcpts = new HashSet <Vector2d>(); foreach (EdgeLoop loop in cut.CutLoops) { Polygon2d poly = new Polygon2d(); foreach (int vid in loop.Vertices) { poly.AppendVertex(mesh.GetVertex(vid).xz); } poly.Simplify(simplify_thresh, 0.01, true); foreach (Vector2d v in poly.Vertices) { srcpts.Add(v); } builder.Insert(poly); } foreach (EdgeSpan span in cut.CutSpans) { PolyLine2d pline = new PolyLine2d(); foreach (int vid in span.Vertices) { pline.AppendVertex(mesh.GetVertex(vid).xz); } pline.Simplify(simplify_thresh, 0.01, true); foreach (Vector2d v in pline) { srcpts.Add(v); } builder.Insert(pline); } SVGWriter svg = new SVGWriter(); svg.AddGraph(builder.Graph); var vtx_style = SVGWriter.Style.Outline("red", 1.0f); foreach (int vid in builder.Graph.VertexIndices()) { Vector2d v = builder.Graph.GetVertex(vid); if (srcpts.Contains(v) == false) { svg.AddCircle(new Circle2d(v, 2), vtx_style); } } svg.Write(TestUtil.GetTestOutputPath("arrangement.svg")); }
// Use this for initialization public override void Awake() { // if we need to auto-configure Rift vs Vive vs (?) VR, we need // to do this before any other F3 setup, because MainCamera will change // and we are caching that in a lot of places... if (AutoConfigVR) { VRCameraRig = gs.VRPlatform.AutoConfigureVR(); } // restore any settings SceneGraphConfig.RestorePreferences(); // set up some defaults // this will move the ground plane down, but the bunnies will be floating... //SceneGraphConfig.InitialSceneTranslate = -4.0f * Vector3f.AxisY; SceneGraphConfig.DefaultSceneCurveVisualDegrees = 0.5f; SceneGraphConfig.DefaultPivotVisualDegrees = 2.3f; SceneGraphConfig.DefaultAxisGizmoVisualDegrees = 25.0f; PolyCurveSO.DefaultHitWidthMultiplier = 2.5f; SceneOptions options = new SceneOptions(); options.UseSystemMouseCursor = false; options.Use2DCockpit = false; options.EnableTransforms = true; options.EnableCockpit = true; options.EnableDefaultLighting = false; options.CockpitInitializer = new SetupOrthoVRCockpit(); options.MouseCameraControls = new MayaCameraHotkeys() { MousePanSpeed = 5.0f, MouseZoomSpeed = 5.0f }; options.SpatialCameraRig = VRCameraRig; // very verbose options.LogLevel = 2; // hacks for stuff #if F3_ENABLE_TEXT_MESH_PRO SceneGraphConfig.TextLabelZOffset = -0.01f; #else SceneGraphConfig.TextLabelZOffset = -0.3f; #endif context = new FContext(); OG.Context = context; OrthogenUI.ActiveContext = context; context.Start(options); // Set up standard scene lighting if enabled if (options.EnableDefaultLighting) { GameObject lighting = GameObject.Find("SceneLighting"); if (lighting == null) { lighting = new GameObject("SceneLighting"); } SceneLightingSetup setup = lighting.AddComponent <SceneLightingSetup>(); setup.Context = context; setup.ShadowLightCount = 0; setup.AdjustShadowDistance = false; setup.LightDistance = 1000.0f; // related to total scene scale... } // override sun so that it doesn't stick to one of the scene lights RenderSettings.sun = GameObject.Find("SunLight").GetComponent <Light>(); //GameObjectFactory.CurveRendererSource = new VectrosityCurveRendererFactory(); // set up ground plane geometry (optional) GameObject boundsObject = GameObject.Find("Bounds"); if (boundsObject != null) { context.Scene.AddWorldBoundsObject(boundsObject); } /* * ORTHOGEN-SPECIFIC SETUP STARTS HERE */ // set up scene and tools like Orthogen wants them OGActions.InitializeVRUsageContext(); OrthogenMaterials.InitializeMaterials(); OrthogenMaterials.ScanMaterial = new UnitySOMaterial(MaterialUtil.SafeLoadMaterial("scan_material")); //OrthogenMaterials.RectifiedLegMaterial = OrthogenMaterials.ScanMaterial; OGActions.InitializeF3Scene(context); OGActions.InitializeF3Tools(context); OGActions.InitializeF3VRTools(context); OGActions.PostConfigureTools_Demo(); OGActions.ConfigurePlatformInput_VR(); /* * optional things specific to demo app */ // ground plane stays below socket as it is updated DemoActions.AddRepositionGroundPlaneOnSocketEdit(); /* * import sample mesh */ bool do_scan_demo = true; // load sample mesh string assetPath = Application.dataPath; string samplesPath = Path.Combine(assetPath, "..", "sample_files"); //string sampleFile = Path.Combine(samplesPath, "sample_socket_off.obj"); string sampleFile = Path.Combine(samplesPath, "sample_socket_1.obj"); if (do_scan_demo) { sampleFile = Path.Combine(samplesPath, "scan_1_remesh.obj"); } if (File.Exists(sampleFile) == false) { sampleFile = Path.Combine(samplesPath, "sample_socket_1.obj"); } DMesh3 mesh = StandardMeshReader.ReadMesh(sampleFile); // read sample file from Resources instead //MemoryStream sampleFileStream = FResources.LoadBinary("sample_socket_1"); //DMesh3 mesh = StandardMeshReader.ReadMesh(sampleFileStream, "obj"); if (mesh.HasVertexColors == false) { mesh.EnableVertexColors(Colorf.Silver); } // transform to our coordinate system double scale = Units.MetersTo(Units.Linear.Millimeters); // this mesh is in meters, so scale to mm MeshTransforms.FlipLeftRightCoordSystems(mesh); // convert to unity coordinate system MeshTransforms.Scale(mesh, scale); if (do_scan_demo) { OGActions.SetSizeMode(OGActions.SizeModes.RealSize); } else { OGActions.SetSizeMode(OGActions.SizeModes.DemoSize); } // initialize the datamodel OGActions.BeginSocketDesignFromScan(Context, mesh); // set up my UI tests/etc configure_unity_ui(); // [RMS] do this next frame because SteamVR needs a chance to set up and position the cockpit OGActions.RecenterVRView(true); add_vr_head(context); // dgraph tests //DGTest.test(Debug.Log); }