/// <summary> /// Initialize the data model to the new-imported-scan state, with the given mesh (presumably loaded from file?) /// </summary> public static void InitializeScan(DMesh3 mesh) { AxisAlignedBox3d bounds = mesh.CachedBounds; Vector3d translate = -bounds.Center; double dy = 0.5 * bounds.Height; MeshTransforms.Translate(mesh, translate); ScanSO scanSO = new ScanSO(); scanSO.Create(mesh, OrthogenMaterials.ScanMaterial); OG.Scene.AddSceneObject(scanSO); Frame3f f = scanSO.GetLocalFrame(CoordSpace.SceneCoords); f.Translate((float)dy * Vector3f.AxisY); scanSO.SetLocalFrame(f, CoordSpace.SceneCoords); OG.Model.InitializeScan(scanSO); OG.Model.Workflow.SetInitialState(ScanState.Identifier); // reposition camera Vector3f c = scanSO.GetLocalFrame(CoordSpace.WorldCoords).Origin; //OG.Context.ActiveCamera.Animator().PanFocus(c); OG.Context.ActiveCamera.Manipulator().ScenePanFocus( OG.Context.Scene, OG.Context.ActiveCamera, c, false); // [TODO] this should happen via a transition, I think... // set up xforms/etc OG.Context.TransformManager.SetActiveGizmoType(AxisTransformGizmo.DefaultName); }
/// <summary> /// Generates a row of cylinders tessellated w/ different chord lengths /// eg 10x1cm : CalibrationModelGenerator.MakePrintStepSizeTest(10.0f, 10.0f, 0.1, 1.0, 10); /// </summary> public static DMesh3 MakePrintStepSizeTest(double cylDiam, double cylHeight, double lowStep, double highStep, int nSteps) { double spacing = 2.0f; float r = (float)cylDiam * 0.5f; double cx = 0.5 * (nSteps * cylDiam + (nSteps - 1) * spacing); DMesh3 accumMesh = new DMesh3(); double cur_x = -cx + cylDiam / 2; for (int k = 0; k < nSteps; ++k) { double t = (double)k / (double)(nSteps - 1); double chord_len = (1.0 - t) * lowStep + (t) * highStep; int slices = (int)((MathUtil.TwoPI * r) / chord_len); CappedCylinderGenerator cylgen = new CappedCylinderGenerator() { BaseRadius = r, TopRadius = r, Height = (float)cylHeight, Slices = slices, NoSharedVertices = false }; DMesh3 cylMesh = cylgen.Generate().MakeDMesh(); MeshTransforms.Translate(cylMesh, -cylMesh.CachedBounds.Min.y * Vector3d.AxisY); MeshTransforms.Translate(cylMesh, cur_x * Vector3d.AxisX); cur_x += cylDiam + spacing; MeshEditor.Append(accumMesh, cylMesh); } MeshTransforms.ConvertYUpToZUp(accumMesh); return(accumMesh); }
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); }
public SliceFeature(Mesh input) { MeshCheck meshCheck = new MeshCheck(); meshCheck.setMesh(input); DMesh3 mesh = meshCheck.ToUnityWatertightMesh().ToDMesh3(); if (!mesh.IsClosed()) { return; } // center mesh above origin AxisAlignedBox3d bounds = mesh.CachedBounds; Vector3d baseCenterPt = bounds.Center - bounds.Extents.z * Vector3d.AxisZ; MeshTransforms.Translate(mesh, -baseCenterPt); // create print mesh set meshes = new PrintMeshAssembly(); meshes.AddMesh(mesh, PrintMeshOptions.Default()); // create settings //MakerbotSettings settings = new MakerbotSettings(Makerbot.Models.Replicator2); //PrintrbotSettings settings = new PrintrbotSettings(Printrbot.Models.Plus); //MonopriceSettings settings = new MonopriceSettings(Monoprice.Models.MP_Select_Mini_V2); settings = new RepRapSettings(RepRap.Models.Unknown); }
public static void ExportSocket() { if (OG.Model.HasSocket() == false) { return; } string filename = null; if (ShowExportDialogInEditor || FPlatform.InUnityEditor() == false) { filename = FPlatform.GetSaveFileName("Export Socket", Path.Combine(ExportSocketPath, "socket.obj"), new string[] { "*.obj" }, "Mesh Files (*.OBJ)"); } else { filename = Path.Combine(ExportSocketPath, "socket.obj"); } if (filename == null) { return; } DMesh3 SocketMesh = new DMesh3(OG.Socket.Socket.Mesh); AxisAlignedBox3d bounds = SocketMesh.CachedBounds; MeshTransforms.Translate(SocketMesh, -bounds.Min.y * Vector3d.AxisZ); MeshTransforms.FlipLeftRightCoordSystems(SocketMesh); // convert from unity coordinate system WriteOptions opt = WriteOptions.Defaults; opt.bWriteGroups = true; StandardMeshWriter.WriteMesh(filename, SocketMesh, opt); }
internal static void test_MeshMeshCut_CutInSingleTriangle() { Console.WriteLine($"test_MeshMeshCut_CutInSingleTriangle."); var shape = test_Bool.MakeBox( center: new Vector3d(5, 5, 0), size: new Vector3d(10, 10, 2) ); var tool = test_Bool.MakeBox( center: new Vector3d(2.5, 7.5, 1), size: new Vector3d(.5, .5, .5) ); MeshTransforms.Translate(shape, new Vector3d(1, 1, 1)); MeshTransforms.Translate(tool, new Vector3d(1, 1, 1)); var error = false; DMesh3 ret; using (var c = new ConsoleColorController()) { var meshCut = new MeshMeshCut(); meshCut.Target = shape; meshCut.CutMesh = tool; meshCut.Compute(); } }
public override fMesh MakeGeometry(AxisGizmoFlags widget) { switch (widget) { case AxisGizmoFlags.AxisTranslateY: if (MyAxisTranslateY == null) { Radial3DArrowGenerator arrowGen = new Radial3DArrowGenerator() { HeadLength = 2.0f, TipRadius = 0.1f, StickLength = 1.5f, Clockwise = true }; DMesh3 mesh = arrowGen.Generate().MakeDMesh(); MeshNormals.QuickCompute(mesh); MeshTransforms.Translate(mesh, 0.5 * Vector3d.AxisY); DMesh3 flip = new DMesh3(mesh); MeshTransforms.Rotate(flip, Vector3d.Zero, Quaterniond.AxisAngleD(Vector3d.AxisX, 180)); MeshEditor.Append(mesh, flip); MyAxisTranslateY = new fMesh(mesh); } return(MyAxisTranslateY); default: return(null); } }
// 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); } }
void OrientationCentre(DMesh3 mesh) { double x = mesh.CachedBounds.Center.x * -1; double y = mesh.CachedBounds.Center.y * -1; double z = mesh.CachedBounds.Center.z * -1; MeshTransforms.Translate(mesh, x, y, z); }
protected void generate(float fDiameter, float fHeight, float fWallThickness, float fBaseThickness) { base.reset_holes(); CappedCylinderGenerator outer_cylgen = new CappedCylinderGenerator() { BaseRadius = fDiameter / 2, TopRadius = fDiameter / 2, Height = fHeight + 10, Slices = 60, Clockwise = true }; DMesh3 outer_mesh = outer_cylgen.Generate().MakeDMesh(); float fInnerDiam = fDiameter - 2 * fWallThickness; CappedCylinderGenerator inner_cylgen = new CappedCylinderGenerator() { BaseRadius = fInnerDiam / 2, TopRadius = fInnerDiam / 2, Height = fHeight + 10, Slices = 60, Clockwise = false }; DMesh3 inner_mesh = inner_cylgen.Generate().MakeDMesh(); MeshTransforms.Translate(inner_mesh, fBaseThickness * Vector3d.AxisY); DMesh3[] meshes = new DMesh3[2] { outer_mesh, inner_mesh }; foreach (DMesh3 mesh in meshes) { Remesher r = new Remesher(mesh); r.SetTargetEdgeLength(TargetEdgeLength); r.SmoothSpeedT = 0.5f; r.SetExternalConstraints(new MeshConstraints()); MeshConstraintUtil.FixAllGroupBoundaryEdges(r.Constraints, mesh, true); r.SetProjectionTarget(MeshProjectionTarget.Auto(mesh)); for (int k = 0; k < 10; ++k) { r.BasicRemeshPass(); } } Vector3d vCutPos = new Vector3d(0, fHeight, 0); Vector3d vCutNormal = Vector3d.AxisY; foreach (DMesh3 mesh in meshes) { MeshPlaneCut cut = new MeshPlaneCut(mesh, new Vector3d(0, fHeight, 0), Vector3d.AxisY); cut.Cut(); } base.set_output_meshes(inner_mesh, outer_mesh); }
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()); }
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); } }
static void Main(string[] args) { CappedCylinderGenerator cylgen = new CappedCylinderGenerator() { BaseRadius = 10, TopRadius = 5, Height = 20, Slices = 32 }; DMesh3 mesh = cylgen.Generate().MakeDMesh(); MeshTransforms.ConvertYUpToZUp(mesh); // g3 meshes are usually Y-up // center mesh above origin AxisAlignedBox3d bounds = mesh.CachedBounds; Vector3d baseCenterPt = bounds.Center - bounds.Extents.z * Vector3d.AxisZ; MeshTransforms.Translate(mesh, -baseCenterPt); // create print mesh set PrintMeshAssembly meshes = new PrintMeshAssembly(); meshes.AddMesh(mesh, PrintMeshOptions.Default()); // create settings //MakerbotSettings settings = new MakerbotSettings(Makerbot.Models.Replicator2); //PrintrbotSettings settings = new PrintrbotSettings(Printrbot.Models.Plus); //MonopriceSettings settings = new MonopriceSettings(Monoprice.Models.MP_Select_Mini_V2); RepRapSettings settings = new RepRapSettings(RepRap.Models.Unknown); // do slicing MeshPlanarSlicer slicer = new MeshPlanarSlicer() { LayerHeightMM = settings.LayerHeightMM }; slicer.Add(meshes); PlanarSliceStack slices = slicer.Compute(); // run print generator SingleMaterialFFFPrintGenerator printGen = new SingleMaterialFFFPrintGenerator(meshes, slices, settings); if (printGen.Generate()) { // export gcode GCodeFile gcode = printGen.Result; using (StreamWriter w = new StreamWriter("c:\\demo\\cone.gcode")) { StandardGCodeWriter writer = new StandardGCodeWriter(); writer.WriteFile(gcode, w); } } }
protected override void SolveInstance(IGH_DataAccess DA) { DMesh3_goo dMsh_goo = null; Rhino.Geometry.Vector3d vec = new Rhino.Geometry.Vector3d(0, 0, 0); DA.GetData(0, ref dMsh_goo); DA.GetData(1, ref vec); DMesh3 dMsh_copy = new DMesh3(dMsh_goo.Value); MeshTransforms.Translate(dMsh_copy, vec.ToVec3d()); DA.SetData(0, dMsh_copy); }
private static void TestWithCloseNumber(double closeEnough) { Console.WriteLine($"test_MeshMeshCut_rounding: {closeEnough}"); var shape = test_Bool.MakeBox( center: new Vector3d(0, 0, 0), size: new Vector3d(2, 2, 2) ); var tool = test_Bool.MakeBox( center: new Vector3d(0, 0, closeEnough), size: new Vector3d(1, 1, 1) ); MeshTransforms.Translate(shape, new Vector3d(1, 1, 1)); MeshTransforms.Translate(tool, new Vector3d(1, 1, 1)); var error = false; DMesh3 ret; using (var c = new ConsoleColorController()) { var meshCut = new MeshMeshCut(); meshCut.Target = shape; meshCut.CutMesh = tool; meshCut.Compute(); ret = meshCut.Target; if (!ret.IsClosed()) { error = TestUtil.ConsoleError("Mesh is not closed.", ret) || error; } meshCut.RemoveContained(); if (ret.IsClosed()) { error = TestUtil.ConsoleError("Mesh should not be closed.", ret) || error; } if (ret.BoundaryEdgeIndices().Count() != 8) { error = TestUtil.ConsoleError($"Mesh should have 8 open edges. It has {ret.BoundaryEdgeIndices().Count()}.", ret) || error; } } if (!error) { Console.WriteLine("ok"); } }
public static DMesh3 MakeMarker(Vector3d vPos, float fRadius, Colorf color) { DMesh3 markerMesh = new DMesh3(true, true, false); TrivialDiscGenerator gen = new TrivialDiscGenerator() { Slices = 8 }; gen.Radius = fRadius; gen.Generate(); gen.MakeMesh(markerMesh); foreach (int vid in markerMesh.VertexIndices()) { markerMesh.SetVertexColor(vid, color); } MeshTransforms.Translate(markerMesh, vPos.x, vPos.y, vPos.z); return(markerMesh); }
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); }
protected void set_output_meshes(DMesh3 inner, DMesh3 outer) { InnerMesh = inner; OuterMesh = outer; AxisAlignedBox3d bounds = OuterMesh.CachedBounds; if (InnerMesh != null) { bounds.Contain(InnerMesh.CachedBounds); } // position center-top at origin Vector3d top = bounds.Center + bounds.Extents[1] * Vector3d.AxisY; if (InnerMesh != null) { MeshTransforms.Translate(InnerMesh, -top); } MeshTransforms.Translate(OuterMesh, -top); CombinedBounds = OuterMesh.CachedBounds; if (InnerMesh != null) { CombinedBounds.Contain(InnerMesh.CachedBounds); } if (InnerMesh != null) { var innerLoops = new MeshBoundaryLoops(InnerMesh); InnerLoop = innerLoops[0]; } var outerLoops = new MeshBoundaryLoops(OuterMesh); OuterLoop = outerLoops[0]; }
// extracts all MeshFilter objects from input GameObject and appends them, then passes to // function MakeSOFunc (if null, creates basic MeshSO). Then optionally adds to Scene, // preserving existing 3D position if desired (default true) public static SceneObject ImportExistingUnityGO(GameObject go, FScene scene, bool bAddToScene = true, bool bKeepWorldPosition = true, bool bRecenterFrame = true, Func <DMesh3, SOMaterial, SceneObject> MakeSOFunc = null) { List <MeshFilter> filters = new List <MeshFilter>(); List <GameObject> children = new List <GameObject>() { go }; UnityUtil.CollectAllChildren(go, children); foreach (var cgo in children) { if (cgo.GetComponent <MeshFilter>() != null) { filters.Add(cgo.GetComponent <MeshFilter>()); } } if (filters.Count == 0) { throw new Exception("SceneUtil.ImportExistingUnityGO: no meshes!!"); } DMesh3 CombineMesh = new DMesh3(MeshComponents.VertexNormals | MeshComponents.VertexColors); MeshEditor editor = new MeshEditor(CombineMesh); int gid = 0; foreach (MeshFilter mesh in filters) { fMesh uMesh = new fMesh(mesh.sharedMesh); using (var imesh = uMesh.CreateCachedIMesh()) { editor.AppendMesh(imesh, ++gid); } } Vector3f scale = go.GetLocalScale(); AxisAlignedBox3d bounds = CombineMesh.CachedBounds; // bounds.Center is wrt local frame of input go // ie offset from origin in local coordinates // if we want to move frame to center of mesh, we have to re-center it at origin // in local coordinates if (bRecenterFrame) { MeshTransforms.Translate(CombineMesh, -bounds.Center.x, -bounds.Center.y, -bounds.Center.z); } SceneObject newSO = (MakeSOFunc != null) ? MakeSOFunc(CombineMesh, scene.DefaultMeshSOMaterial) : new DMeshSO().Create(CombineMesh, scene.DefaultMeshSOMaterial); newSO.Name = go.name; if (bAddToScene) { scene.AddSceneObject(newSO, false); } if (bKeepWorldPosition) { // compute world rotation/location. If we re-centered the mesh, we need // to offset by the transform we applied above in local coordinates // (hence we have to rotate & scale) if (go.transform.parent != null) { throw new Exception("UnitySceneUtil.ImportExistingUnityGO: Not handling case where GO has a parent transform"); } Frame3f goFrameW = UnityUtil.GetGameObjectFrame(go, CoordSpace.WorldCoords); Vector3f originW = goFrameW.Origin; if (bRecenterFrame) { originW += goFrameW.Rotation * (scale * (Vector3f)bounds.Center); // offset initial frame to be at center of mesh } // convert world frame and offset to scene coordinates Frame3f goFrameS = scene.ToSceneFrame(goFrameW); Vector3f boundsCenterS = scene.ToSceneP(originW); // translate new object to position in scene Frame3f curF = newSO.GetLocalFrame(CoordSpace.SceneCoords); curF.Origin += boundsCenterS; newSO.SetLocalFrame(curF, CoordSpace.SceneCoords); // apply rotation (around current origin) curF = newSO.GetLocalFrame(CoordSpace.SceneCoords); curF.RotateAround(curF.Origin, goFrameS.Rotation); newSO.SetLocalFrame(curF, CoordSpace.SceneCoords); // apply local scale newSO.SetLocalScale(scale); } return(newSO); }
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); }
protected virtual void DropMeshToBuildPlate(DMesh3 mesh) { MeshTransforms.Translate(mesh, new Vector3d(0, 0, mesh.CachedBounds.Extents.z - mesh.CachedBounds.Center.z)); }
async Task complete_import(string sFilename, DMesh3Builder builder, Action <string> onCompletedF) { AxisAlignedBox3d bounds = AxisAlignedBox3d.Empty; foreach (DMesh3 mesh in builder.Meshes) { bounds.Contain(mesh.CachedBounds); } Vector3d centerPt = bounds.Center; Vector3d basePt = centerPt - bounds.Height * 0.5f * Vector3d.AxisY; Vector3d vTranslate = basePt; await Task.Run(() => { foreach (DMesh3 mesh in builder.Meshes) { MeshTransforms.Translate(mesh, -vTranslate); } }); bool bFirst = (CC.Objects.PrintMeshes.Count == 0); Vector3d postTranslate = Vector3d.Zero; switch (CCPreferences.ImportTransformMode) { case CCPreferences.ImportTransformModes.AutoCenterAll: break; case CCPreferences.ImportTransformModes.AutoCenterFirst: if (bFirst) { CCState.SceneImportTransform = vTranslate; } postTranslate = vTranslate - CCState.SceneImportTransform; break; case CCPreferences.ImportTransformModes.NoAutoCenter: postTranslate = vTranslate; break; } // compact input meshes await Task.Run(() => { gParallel.ForEach(builder.Meshes, (mesh) => { MeshEditor.RemoveUnusedVertices(mesh); }); gParallel.ForEach(Interval1i.Range(builder.Meshes.Count), (k) => { if (builder.Meshes[k].IsCompact == false) { builder.Meshes[k] = new DMesh3(builder.Meshes[k], true); } }); }); string sBaseName = Path.GetFileNameWithoutExtension(sFilename); foreach (DMesh3 mesh in builder.Meshes) { PrintMeshSO meshSO = new PrintMeshSO(); meshSO.Create(mesh, CCMaterials.PrintMeshMaterial); meshSO.UpDirection = UpDirection.ZUp; Frame3f f = meshSO.GetLocalFrame(CoordSpace.ObjectCoords); f.Origin = f.Origin + (Vector3f)postTranslate; meshSO.SetLocalFrame(f, CoordSpace.ObjectCoords); // if only one mesh, we can keep a reference if (builder.Meshes.Count == 1) { meshSO.SourceFilePath = sFilename; meshSO.LastReadFileTimestamp = File.GetLastWriteTime(SourceFilePath).Ticks; } meshSO.Name = UniqueNames.GetNext(sBaseName); CCActions.AddNewPrintMesh(meshSO); } if (onCompletedF != null) { onCompletedF(sFilename); } }
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 static void test_marching_cubes_implicits() { DMesh3 mesh = TestUtil.LoadTestInputMesh("bunny_solid.obj"); MeshTransforms.Translate(mesh, -mesh.CachedBounds.Center); double meshCellsize = mesh.CachedBounds.MaxDim / 32; MeshSignedDistanceGrid levelSet = new MeshSignedDistanceGrid(mesh, meshCellsize); levelSet.ExactBandWidth = 3; levelSet.UseParallel = true; levelSet.ComputeMode = MeshSignedDistanceGrid.ComputeModes.NarrowBandOnly; levelSet.Compute(); var meshIso = new DenseGridTrilinearImplicit(levelSet.Grid, levelSet.GridOrigin, levelSet.CellSize); ImplicitOffset3d offsetMeshIso = new ImplicitOffset3d() { A = meshIso, Offset = 2.0 }; double r = 15.0; ImplicitSphere3d sphere1 = new ImplicitSphere3d() { Origin = Vector3d.Zero, Radius = r }; ImplicitSphere3d sphere2 = new ImplicitSphere3d() { Origin = r * Vector3d.AxisX, Radius = r }; ImplicitAxisAlignedBox3d aabox1 = new ImplicitAxisAlignedBox3d() { AABox = new AxisAlignedBox3d(r * 0.5 * Vector3d.One, r, r * 0.75, r * 0.5) }; ImplicitBox3d box1 = new ImplicitBox3d() { Box = new Box3d(new Frame3f(r * 0.5 * Vector3d.One, Vector3d.One.Normalized), new Vector3d(r, r * 0.75, r * 0.5)) }; ImplicitLine3d line1 = new ImplicitLine3d() { Segment = new Segment3d(Vector3d.Zero, r * Vector3d.One), Radius = 3.0 }; ImplicitHalfSpace3d half1 = new ImplicitHalfSpace3d() { Origin = Vector3d.Zero, Normal = Vector3d.One.Normalized }; ImplicitUnion3d union = new ImplicitUnion3d() { A = sphere1, B = line1 }; ImplicitDifference3d difference = new ImplicitDifference3d() { A = meshIso, B = aabox1 }; ImplicitIntersection3d intersect = new ImplicitIntersection3d() { A = meshIso, B = half1 }; ImplicitNaryUnion3d nunion = new ImplicitNaryUnion3d() { Children = new List <BoundedImplicitFunction3d>() { offsetMeshIso, sphere1, sphere2 } }; ImplicitNaryDifference3d ndifference = new ImplicitNaryDifference3d() { A = offsetMeshIso, BSet = new List <BoundedImplicitFunction3d>() { sphere1, sphere2 } }; ImplicitBlend3d blend = new ImplicitBlend3d() { A = sphere1, B = sphere2 }; BoundedImplicitFunction3d root = intersect; AxisAlignedBox3d bounds = root.Bounds(); int numcells = 64; MarchingCubes c = new MarchingCubes(); c.RootMode = MarchingCubes.RootfindingModes.LerpSteps; c.RootModeSteps = 5; c.Implicit = root; c.Bounds = bounds; c.CubeSize = bounds.MaxDim / numcells; c.Bounds.Expand(3 * c.CubeSize); c.Generate(); MeshNormals.QuickCompute(c.Mesh); TestUtil.WriteTestOutputMesh(c.Mesh, "marching_cubes_implicit.obj"); }
virtual public void PreRender() { if (in_shutdown()) { return; } if (parameters_dirty) { // offset List <GeneralPolygon2d> offset = ClipperUtil.RoundOffset(combined_all, offset_distance); // aggressively simplify after round offset... foreach (var poly in offset) { poly.Simplify(path_width); } // subtract initial and add tiny gap so these don't get merged by slicer if (SubtractSolids) { offset = ClipperUtil.Difference(offset, combined_solid); offset = ClipperUtil.MiterOffset(offset, -path_width * 0.1); } offset = CurveUtils2.FilterDegenerate(offset, 0.001); foreach (var poly in offset) { poly.Simplify(path_width * 0.02); } DMesh3 mesh = new DMesh3(); MeshEditor editor = new MeshEditor(mesh); foreach (var poly in offset) { TriangulatedPolygonGenerator polygen = new TriangulatedPolygonGenerator() { Polygon = poly }; editor.AppendMesh(polygen.Generate().MakeDMesh()); } MeshTransforms.ConvertZUpToYUp(mesh); if (mesh.TriangleCount > 0) { MeshExtrudeMesh extrude = new MeshExtrudeMesh(mesh); extrude.ExtrudedPositionF = (v, n, vid) => { return(v + Layers * layer_height * Vector3d.AxisY); }; extrude.Extrude(); MeshTransforms.Translate(mesh, -mesh.CachedBounds.Min.y * Vector3d.AxisY); } PreviewSO.ReplaceMesh(mesh, true); //Vector3d translate = scene_bounds.Point(1, -1, 1); //translate.x += spiral.Bounds.Width + PathWidth; //Frame3f sceneF = Frame3f.Identity.Translated((Vector3f)translate); //PreviewSO.SetLocalFrame(sceneF, CoordSpace.SceneCoords); parameters_dirty = false; } }
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; }
protected virtual void CenterMeshAboveOrigin(DMesh3 mesh) { MeshTransforms.Translate(mesh, new Vector3d(-mesh.CachedBounds.Center.x, -mesh.CachedBounds.Center.y, 0)); }