コード例 #1
0
        public static void test_levelset_basic()
        {
            //DMesh3 mesh = TestUtil.MakeCappedCylinder(false);
            //MeshTransforms.Scale(mesh, 1, 3, 1);
            DMesh3 mesh = TestUtil.LoadTestMesh(Program.TEST_FILES_PATH + "bunny_open_base.obj");

            AxisAlignedBox3d bounds   = mesh.CachedBounds;
            float            cellSize = (float)bounds.MaxDim / 32.0f;

            MeshSignedDistanceGrid levelSet = new MeshSignedDistanceGrid(mesh, cellSize);

            levelSet.Compute();

            Vector3i dims = levelSet.Dimensions;
            int      midx = dims.x / 2;
            int      midy = dims.y / 2;
            int      midz = dims.z / 2;

            //for ( int xi = 0; xi < dims.x; ++xi ) {
            //    System.Console.Write(levelSet[xi, yi, zi] + " ");
            //}
            for (int yi = 0; yi < dims.y; ++yi)
            {
                System.Console.Write(levelSet[midx, yi, midz] + " ");
            }
            System.Console.WriteLine();

            DMesh3     tmp    = new DMesh3();
            MeshEditor editor = new MeshEditor(tmp);

            for (int x = 0; x < dims.x; ++x)
            {
                for (int y = 0; y < dims.y; ++y)
                {
                    for (int z = 0; z < dims.z; ++z)
                    {
                        if (levelSet[x, y, z] < 0)
                        {
                            Vector3f c = levelSet.CellCenter(x, y, z);
                            editor.AppendBox(new Frame3f(c), cellSize);
                        }
                    }
                }
            }
            TestUtil.WriteTestOutputMesh(tmp, "LevelSetInterior.obj");
            TestUtil.WriteTestOutputMesh(mesh, "LevelSetInterior_src.obj");
        }
コード例 #2
0
ファイル: SetDimensionsTool.cs プロジェクト: tomleetv/gsTools
        virtual public void PreRender()
        {
            if (in_shutdown())
            {
                return;
            }

            if (scale_needs_update)
            {
                currentDims = originalDims;
                currentDims.Scale(scale_x, scale_y, scale_z);
                Vector3f s = new Vector3f((float)scale_x, (float)scale_y, (float)scale_z);

                if (use_object_frame)
                {
                    foreach (var obj in objects)
                    {
                        apply_object_scale(obj, s);
                    }
                }
                else
                {
                    foreach (var obj in objects)
                    {
                        apply_scene_scale(obj, s);
                    }
                }

                //if (objects.Count == 1) {
                //    objects[0].curLocalScale = s * objects[0].localScale;

                //    Scene.History.PushChange(
                //        new TransformSOChange(objects[0].SO, objects[0].curLocalScale), false);
                //} else {
                //    foreach (var obj in objects) {
                //        Frame3f f = obj.sceneFrame;
                //        f.Origin = s * (f.Origin - sharedOriginS) + sharedOriginS;
                //        obj.curSceneFrame = f;
                //        obj.curLocalScale = s * obj.localScale;

                //        Scene.History.PushChange(
                //            new TransformSOChange(obj.SO, obj.curSceneFrame, CoordSpace.SceneCoords, obj.curLocalScale), false);
                //    }
                //}
                scale_needs_update = false;
            }
        }
コード例 #3
0
 public PlaneIntersectionTraversal(DMesh3 mesh, double z)
 {
     this.Mesh     = mesh;
     this.Z        = z;
     this.NextBoxF = (box, depth) =>
     {
         return(Z >= box.Min.z && Z <= box.Max.z);
     };
     this.NextTriangleF = (tID) =>
     {
         AxisAlignedBox3d box = Mesh.GetTriBounds(tID);
         if (Z >= box.Min.z && z <= box.Max.z)
         {
             triangles.Add(tID);
         }
     };
 }
コード例 #4
0
        public override void postprocess_target_objects()
        {
            AxisAlignedBox3d bounds = SceneMeshes[0].CachedBounds;

            for (int k = 1; k < InputSOs.Count; ++k)
            {
                bounds.Contain(SceneMeshes[k].CachedBounds);
            }
            MaxDimension = bounds.MaxDim;

            double cell_size = ToolDefaults.DefaultVoxelSceneSizeF(new AxisAlignedBox3d(MaxDimension, MaxDimension, MaxDimension));;

            set_grid_cell_size(cell_size);
            set_mesh_cell_size(cell_size);
            set_blend_distance(5 * cell_size);
            set_min_comp_size(2.0);
        }
コード例 #5
0
        protected override Result RunCommand(RhinoDoc doc, RunMode mode)
        {
            DMesh3           mesh   = new DMesh3(MakeRemeshedCappedCylinder(1.0), true);
            AxisAlignedBox3d bounds = mesh.GetBounds();

            List <IMesh> result_meshes = new List <IMesh>();

            LaplacianMeshDeformer deformer = new LaplacianMeshDeformer(mesh);

            // constrain bottom points
            foreach (int vid in mesh.VertexIndices())
            {
                g3.Vector3d v      = mesh.GetVertex(vid);
                bool        bottom = (v.y - bounds.Min.y) < 0.01f;
                if (bottom)
                {
                    deformer.SetConstraint(vid, v, 10);
                }
            }

            // constrain one other vtx
            int ti    = MeshQueries.FindNearestTriangle_LinearSearch(mesh, new g3.Vector3d(2, 5, 2));
            int v_pin = mesh.GetTriangle(ti).a;

            g3.Vector3d cons_pos = mesh.GetVertex(v_pin);
            cons_pos += new g3.Vector3d(0.5, 0.5, 0.5);
            deformer.SetConstraint(v_pin, cons_pos, 10);


            deformer.Initialize();
            g3.Vector3d[] resultV = new g3.Vector3d[mesh.MaxVertexID];
            deformer.Solve(resultV);

            foreach (int vid in mesh.VertexIndices())
            {
                mesh.SetVertex(vid, resultV[vid]);
            }


            var rhinoMesh = GopherUtil.ConvertToRhinoMesh(mesh);

            doc.Objects.AddMesh(rhinoMesh);

            return(Result.Success);
        }
コード例 #6
0
        // [RMS] this only tests some basic cases...
        public static void test_LaplacianDeformation()
        {
            // compact version
            DMesh3 mesh = new DMesh3(TestUtil.MakeRemeshedCappedCylinder(1.0), true);

            Debug.Assert(mesh.IsCompact);
            AxisAlignedBox3d bounds = mesh.GetBounds();

            List <IMesh> result_meshes = new List <IMesh>();

            LaplacianMeshDeformer deformer = new LaplacianMeshDeformer(mesh);

            // constrain bottom points
            foreach (int vid in mesh.VertexIndices())
            {
                Vector3d v      = mesh.GetVertex(vid);
                bool     bottom = (v.y - bounds.Min.y) < 0.01f;
                if (bottom)
                {
                    deformer.SetConstraint(vid, v, 10);
                }
            }

            // constrain one other vtx
            int      ti       = MeshQueries.FindNearestTriangle_LinearSearch(mesh, new Vector3d(2, 5, 2));
            int      v_pin    = mesh.GetTriangle(ti).a;
            Vector3d cons_pos = mesh.GetVertex(v_pin);

            cons_pos += new Vector3d(0.5, 0.5, 0.5);
            deformer.SetConstraint(v_pin, cons_pos, 10);
            result_meshes.Add(TestUtil.MakeMarker(mesh.GetVertex(v_pin), 0.2f, Colorf.Red));

            deformer.Initialize();
            Vector3d[] resultV = new Vector3d[mesh.MaxVertexID];
            deformer.Solve(resultV);

            foreach (int vid in mesh.VertexIndices())
            {
                mesh.SetVertex(vid, resultV[vid]);
            }

            result_meshes.Add(mesh);
            TestUtil.WriteDebugMeshes(result_meshes, "___LAPLACIAN_result.obj");
        }
コード例 #7
0
ファイル: PolyCurveSO.cs プロジェクト: xiaodelea/frame3Sharp
        override public bool FindRayIntersection(Ray3f worldRay, out SORayHit hit)
        {
            hit = null;

            // project world ray into local coords
            FScene scene    = GetScene();
            Ray3f  sceneRay = scene.ToSceneRay(worldRay);
            Ray3f  localRay = SceneTransforms.SceneToObject(this, sceneRay);

            // also need width in local coords
            float sceneWidth = scene.ToSceneDimension(visibleWidth);
            float localWidth = SceneTransforms.SceneToObject(this, sceneWidth) * HitWidthMultiplier;

            // bounding-box hit test (would be nice to do w/o object allocation...)
            AxisAlignedBox3d hitBox = localBounds;

            hitBox.Expand(localWidth);
            IntrRay3AxisAlignedBox3 box_test = new IntrRay3AxisAlignedBox3(localRay, hitBox);

            if (box_test.Find() == false)
            {
                return(false);
            }

            // raycast against curve (todo: spatial data structure for this? like 2D polycurve bbox tree?)
            double rayHitT;

            if (CurveUtils.FindClosestRayIntersection(curve, localWidth, localRay, out rayHitT))
            {
                hit = new SORayHit();
                // transform local hit point back into world coords
                Vector3f rayPos   = localRay.PointAt((float)rayHitT);
                Vector3f scenePos = SceneTransforms.ObjectToSceneP(this, rayPos);
                hit.hitPos    = SceneTransforms.SceneToWorldP(scene, scenePos);
                hit.fHitDist  = worldRay.Project(hit.hitPos);
                hit.hitNormal = Vector3f.Zero;
                hit.hitGO     = root;
                hit.hitSO     = this;
                return(true);
            }
            return(false);
        }
コード例 #8
0
        static public bool DoClipping(ref double t0, ref double t1,
                                      Vector3D origin, Vector3D direction,
                                      AxisAlignedBox3d box, bool solid, ref int quantity,
                                      ref Vector3D point0, ref Vector3D point1,
                                      ref IntersectionType intrType)
        {
            Vector3D BOrigin = origin - box.Center;
            Vector3D extent  = box.Extents;

            double saveT0 = t0, saveT1 = t1;
            bool   notAllClipped =
                Clip(+direction.x, -BOrigin.x - extent.x, ref t0, ref t1) &&
                Clip(-direction.x, +BOrigin.x - extent.x, ref t0, ref t1) &&
                Clip(+direction.y, -BOrigin.y - extent.y, ref t0, ref t1) &&
                Clip(-direction.y, +BOrigin.y - extent.y, ref t0, ref t1) &&
                Clip(+direction.z, -BOrigin.z - extent.z, ref t0, ref t1) &&
                Clip(-direction.z, +BOrigin.z - extent.z, ref t0, ref t1);

            if (notAllClipped && (solid || t0 != saveT0 || t1 != saveT1))
            {
                if (t1 > t0)
                {
                    intrType = IntersectionType.Segment;
                    quantity = 2;
                    point0   = origin + t0 * direction;
                    point1   = origin + t1 * direction;
                }
                else
                {
                    intrType = IntersectionType.Point;
                    quantity = 1;
                    point0   = origin + t0 * direction;
                }
            }
            else
            {
                quantity = 0;
                intrType = IntersectionType.Empty;
            }

            return(intrType != IntersectionType.Empty);
        }
コード例 #9
0
        public virtual void Update()
        {
            base.begin_update();
            int start_timestamp = this.CurrentInputTimestamp;

            if (mesh_sources == null)
            {
                throw new Exception("MeshVoxelBooleanOp: must set valid MeshSource to compute!");
            }

            try {
                ResultMesh = null;

                if (source_edge_stats == null)
                {
                    source_edge_stats = new List <Vector3d>();
                    source_bounds     = AxisAlignedBox3d.Empty;
                    foreach (DMeshSourceOp op in mesh_sources)
                    {
                        Vector3d einfo = new Vector3d();
                        MeshQueries.EdgeLengthStats(op.GetDMeshUnsafe(), out einfo.x, out einfo.y, out einfo.z);
                        source_edge_stats.Add(einfo);
                        source_bounds.Contain(op.GetDMeshUnsafe().CachedBounds);
                    }
                }

                //ResultMesh = compute_blend();
                //ResultMesh = compute_blend_bounded();
                ResultMesh = compute_blend_analytic();

                if (ResultMesh.TriangleCount == 0)
                {
                    ResultMesh = base.make_failure_output(null);
                }

                base.complete_update();
            } catch (Exception e) {
                PostOnOperatorException(e);
                ResultMesh = base.make_failure_output(mesh_sources[0].GetDMeshUnsafe());
                base.complete_update();
            }
        }
コード例 #10
0
        /// <summary>
        /// when the socket is updated, shift the ground plane to be directly below it
        /// </summary>
        public static void AddRepositionGroundPlaneOnSocketEdit()
        {
            OG.OnSocketUpdated += () => {
                // compute scene-space bbox of socket mesh
                Frame3f          socketF = OG.Socket.Socket.GetLocalFrame(CoordSpace.ObjectCoords);
                AxisAlignedBox3d boundsS =
                    MeshMeasurements.Bounds(OG.Socket.Socket.Mesh, socketF.FromFrameP);

                // vertically translate bounds objects to be at same y
                //  (assumes they are xz planes!!)
                Vector3d baseS = boundsS.Center - boundsS.Extents[1] * Vector3d.AxisY;
                Vector3d baseW = OG.Scene.ToWorldP(baseS);
                foreach (var go in OG.Scene.BoundsObjects)
                {
                    Vector3f pos = go.GetPosition();
                    pos.y = (float)baseW.y;
                    go.SetPosition(pos);
                }
            };
        }
コード例 #11
0
        /// <summary>
        /// initialize points w/ known base point and up direction
        /// </summary>
        public void Initialize_KnownBasePoint(Vector3d basePointL, Vector3f upAxis)
        {
            DMeshSO TargetMeshSO = TargetSO as DMeshSO;

            // initialize w/ auto-fit box
            DMesh3         mesh    = TargetMeshSO.Mesh;
            DMeshAABBTree3 spatial = TargetMeshSO.Spatial;

            meshBounds = mesh.CachedBounds;

            create_preview_so();

            /*Frame3f frameO = TargetSO.GetLocalFrame(CoordSpace.ObjectCoords);*/

            // reproject base point onto surface in case somehow it is wrong
            Vector3f basePointUpdatedL = MeshQueries.NearestPointFrame(mesh, spatial, basePointL).Origin;
            Vector3f BasePointS        = SceneTransforms.ObjectToSceneP(TargetSO, basePointUpdatedL);

            Vector3f upAxisL   = Vector3f.AxisY;
            Vector3f topPointL = basePointUpdatedL + upAxisL * (float)meshBounds.Height;

            topPointL = MeshQueries.NearestPointFrame(mesh, spatial, topPointL).Origin;

            Vector3f TopPointS = SceneTransforms.ObjectToSceneP(TargetSO, topPointL);

            // shoot ray forward in scene, to find front point
            Vector3f forwardL = SceneTransforms.SceneToObjectN(TargetSO, -Vector3f.AxisZ);
            Frame3f  fwHitFrameL;
            bool     bHit = MeshQueries.RayHitPointFrame(mesh, spatial, new Ray3d(meshBounds.Center, forwardL), out fwHitFrameL);

            if (!bHit)
            {
                throw new Exception("SocketAlignmentTool.Initialize_KnownBasePoint: ray missed!");
            }

            Vector3f FrontPointS = SceneTransforms.ObjectToSceneP(TargetSO, fwHitFrameL.Origin);

            SetPointPosition(BasePointID, new Frame3f(BasePointS), CoordSpace.SceneCoords);
            SetPointPosition(FrontPointID, new Frame3f(FrontPointS), CoordSpace.SceneCoords);
            SetPointPosition(TopPointID, new Frame3f(TopPointS), CoordSpace.SceneCoords);
        }
コード例 #12
0
        override public void Apply()
        {
            float VerticalSpaceFudge = 10.0f;

            DMeshSO TargetMeshSO = TargetSO as DMeshSO;

            Frame3f           curFrameS = TargetSO.GetLocalFrame(CoordSpace.SceneCoords);
            TransformSOChange change    = new TransformSOChange(TargetSO,
                                                                curFrameS, lastPreviewFrameS, CoordSpace.SceneCoords);

            Scene.History.PushChange(change, false);

            Frame3f newFrameS = new Frame3f(SceneTransforms.ObjectToSceneP(TargetSO, meshBounds.Center));
            RepositionPivotChangeOp pivot1 = new RepositionPivotChangeOp(newFrameS, TargetMeshSO);

            Scene.History.PushChange(pivot1, false);

            newFrameS = TargetSO.GetLocalFrame(CoordSpace.SceneCoords);
            AxisAlignedBox3d bounds         = TargetMeshSO.Mesh.CachedBounds;
            float            h              = (float)bounds.Height;
            Vector3f         o              = newFrameS.Origin;
            Vector3f         translate      = new Vector3f(-o.x, h * 0.5f - o.y + VerticalSpaceFudge, -o.z);
            Frame3f          centeredFrameS = newFrameS.Translated(translate);

            TransformSOChange centerChange = new TransformSOChange(TargetSO,
                                                                   newFrameS, centeredFrameS, CoordSpace.SceneCoords);

            Scene.History.PushChange(centerChange, false);

            newFrameS        = TargetSO.GetLocalFrame(CoordSpace.SceneCoords);
            o                = newFrameS.Origin;
            o.y              = 0;
            newFrameS.Origin = o;

            RepositionPivotChangeOp pivot2 = new RepositionPivotChangeOp(newFrameS, TargetMeshSO);

            Scene.History.PushChange(pivot2, false);


            Scene.History.PushInteractionCheckpoint();
        }
コード例 #13
0
        public static AxisAlignedBox3d Bounds(IMesh mesh, Func <Vector3D, Vector3D> TransformF)
        {
            AxisAlignedBox3d bounds = AxisAlignedBox3d.Empty;

            if (TransformF == null)
            {
                foreach (int vID in mesh.VertexIndices())
                {
                    bounds.Contain(mesh.GetVertex(vID));
                }
            }
            else
            {
                foreach (int vID in mesh.VertexIndices())
                {
                    Vector3D vT = TransformF(mesh.GetVertex(vID));
                    bounds.Contain(vT);
                }
            }
            return(bounds);
        }
コード例 #14
0
        public static AxisAlignedBox3d Bounds(NGonsCore.geometry3Sharp.mesh.DMesh3 mesh, Func <Vector3D, Vector3D> TransformF)
        {
            AxisAlignedBox3d bounds = AxisAlignedBox3d.Empty;

            if (TransformF == null)
            {
                foreach (Vector3D v in mesh.Vertices())
                {
                    bounds.Contain(v);
                }
            }
            else
            {
                foreach (Vector3D v in mesh.Vertices())
                {
                    Vector3D vT = TransformF(v);
                    bounds.Contain(vT);
                }
            }
            return(bounds);
        }
コード例 #15
0
        public static void MoveToPrintBed(FScene scene, DMeshSO so, bool bInteractive)
        {
            TransformSequence seq    = SceneTransforms.ObjectToSceneXForm(so);
            AxisAlignedBox3d  bounds = BoundsUtil.Bounds(so.Mesh.Vertices(), seq);

            Frame3f curFrameS = so.GetLocalFrame(CoordSpace.SceneCoords);
            float   dy        = (float)(bounds.Center.y - bounds.Extents.y);

            if (Math.Abs(dy) > MathUtil.ZeroTolerancef)
            {
                Frame3f newFrameS = curFrameS;
                newFrameS.Origin = curFrameS.Origin - dy * Vector3f.AxisY;
                TransformSOChange change = new TransformSOChange(so, curFrameS, newFrameS, CoordSpace.SceneCoords);
                change.Tags.Add("MoveToPrintBed");
                scene.History.PushChange(change, false);
                if (bInteractive)
                {
                    scene.History.PushInteractionCheckpoint();
                }
            }
        }
コード例 #16
0
        public void InitializeOnTarget(DMeshSO target, double initial_width)
        {
            AxisAlignedBox3d bounds = target.Mesh.CachedBounds;
            Vector3d         c      = bounds.Center;
            SORayHit         nearestPt;

            target.FindNearest(c, double.MaxValue, out nearestPt, CoordSpace.ObjectCoords);
            c = nearestPt.hitPos;

            Vector3d up = c + initial_width * Vector3d.AxisY;

            target.FindNearest(up, double.MaxValue, out nearestPt, CoordSpace.ObjectCoords);
            up = nearestPt.hitPos;

            Vector3d down = c - initial_width * Vector3d.AxisY;

            target.FindNearest(down, double.MaxValue, out nearestPt, CoordSpace.ObjectCoords);
            down = nearestPt.hitPos;

            SetPointPosition_Internal(StartPointID, new Frame3f(up), CoordSpace.ObjectCoords);
            SetPointPosition_Internal(EndPointID, new Frame3f(down), CoordSpace.ObjectCoords);
        }
コード例 #17
0
ファイル: Voxelize.cs プロジェクト: joelhi/g3-gh
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            int        num_cells = 128;
            DMesh3_goo dMsh_goo  = null;

            DA.GetData(0, ref dMsh_goo);
            DA.GetData(1, ref num_cells);

            DMesh3 dMsh_copy = new DMesh3(dMsh_goo.Value);
            double cell_size = dMsh_copy.CachedBounds.MaxDim / num_cells;

            DMeshAABBTree3 spatial = new DMeshAABBTree3(dMsh_copy, autoBuild: true);

            AxisAlignedBox3d  bounds   = dMsh_copy.CachedBounds;
            double            cellsize = bounds.MaxDim / num_cells;
            ShiftGridIndexer3 indexer  = new ShiftGridIndexer3(bounds.Min, cellsize);

            Bitmap3 bmp = new Bitmap3(new Vector3i(num_cells, num_cells, num_cells));

            foreach (Vector3i idx in bmp.Indices())
            {
                g3.Vector3d v = indexer.FromGrid(idx);
                bmp.Set(idx, spatial.IsInside(v));
            }

            VoxelSurfaceGenerator voxGen = new VoxelSurfaceGenerator();

            voxGen.Voxels = bmp;
            voxGen.Generate();
            DMesh3 voxMesh = voxGen.Meshes[0];

            var vecSize = dMsh_copy.CachedBounds.Extents;
            var box     = dMsh_copy.GetBounds();

            // Scale voxel mesh
            //MeshTransforms.Scale(voxMesh,)

            DA.SetData(0, voxMesh);
        }
コード例 #18
0
        public void Compute()
        {
            // figure out origin & dimensions
            AxisAlignedBox3d bounds = Mesh.CachedBounds;

            float fBufferWidth = 2 * BufferCells * (float)CellSize;

            grid_origin = (Vector3f)bounds.Min - fBufferWidth * Vector3f.One;
            Vector3f max = (Vector3f)bounds.Max + fBufferWidth * Vector3f.One;
            int      ni  = (int)((max.x - grid_origin.x) / (float)CellSize) + 1;
            int      nj  = (int)((max.y - grid_origin.y) / (float)CellSize) + 1;
            int      nk  = (int)((max.z - grid_origin.z) / (float)CellSize) + 1;

            scalar_grid = new DenseGrid3f();
            if (ComputeMode == ComputeModes.FullGrid)
            {
                make_grid_dense(grid_origin, (float)CellSize, ni, nj, nk, scalar_grid);
            }
            else
            {
                make_grid(grid_origin, (float)CellSize, ni, nj, nk, scalar_grid);
            }
        }
コード例 #19
0
ファイル: Actions_View.cs プロジェクト: tomleetv/Cotangent
        public static void FitCurrentSelectionToView()
        {
            AxisAlignedBox3d fitBox = AxisAlignedBox3d.Zero;

            if (CC.ActiveScene.Selected.Count == 0)
            {
                fitBox = CC.Objects.GetPrintMeshesBounds(false);
            }
            else
            {
                fitBox = AxisAlignedBox3d.Empty;
                foreach (var so in CC.ActiveScene.Selected)
                {
                    fitBox.Contain(so.GetBoundingBox(CoordSpace.SceneCoords).ToAABB());
                }
            }

            double height = 3 * fitBox.Height;

            if (height < 10.0f)
            {
                height = 10.0f;
            }
            double   width  = 1.5 * Math.Sqrt(fitBox.Width * fitBox.Width + fitBox.Depth * fitBox.Depth);
            Vector3d center = fitBox.Center;

            if (width > height)
            {
                CC.ActiveScene.ActiveCamera.Animator().AnimateFitWidthToView((Vector3f)center, (float)width, CoordSpace.SceneCoords, 0.5f);
            }
            else
            {
                CC.ActiveScene.ActiveCamera.Animator().AnimateFitHeightToView((Vector3f)center, (float)height, CoordSpace.SceneCoords, 0.5f);
            }

            UpdateViewClippingBounds();
        }
コード例 #20
0
        public static void CalculateUVs(this DMesh3 dMesh)
        {
            dMesh.EnableVertexUVs(Vector2f.Zero);
            OrthogonalPlaneFit3 orth          = new OrthogonalPlaneFit3(dMesh.Vertices());
            Frame3f             frame         = new Frame3f(orth.Origin, orth.Normal);
            AxisAlignedBox3d    bounds        = dMesh.CachedBounds;
            AxisAlignedBox2d    boundsInFrame = new AxisAlignedBox2d();

            for (int i = 0; i < 8; i++)
            {
                boundsInFrame.Contain(frame.ToPlaneUV((Vector3f)bounds.Corner(i), 3));
            }
            Vector2f min    = (Vector2f)boundsInFrame.Min;
            float    width  = (float)boundsInFrame.Width;
            float    height = (float)boundsInFrame.Height;

            for (int i = 0; i < dMesh.VertexCount; i++)
            {
                Vector2f UV = frame.ToPlaneUV((Vector3f)dMesh.GetVertex(i), 3);
                UV.x = (UV.x - min.x) / width;
                UV.y = (UV.y - min.y) / height;
                dMesh.SetVertexUV(i, UV);
            }
        }
コード例 #21
0
        override public bool FindRayIntersection(Ray3f ray, out SORayHit hit)
        {
            hit = null;

            Ray     sceneRay = GetScene().ToSceneRay(ray);
            Frame3f frameL   = GetLocalFrame(CoordSpace.ObjectCoords);
            Ray     localRay = frameL.ToFrame(sceneRay);

            float sceneWidth = GetScene().ToSceneDimension(visibleWidth);

            AxisAlignedBox3d hitBox = localBounds;

            hitBox.Expand(sceneWidth * 0.5f);
            Bounds hitBounds = new Bounds((Vector3)hitBox.Center, (Vector3)hitBox.Diagonal);

            if (hitBounds.IntersectRay(localRay) == false)
            {
                return(false);
            }

            double rayHitT;

            //if (CurveUtils.FindClosestRayIntersection(curve, sceneWidth * 0.5f, localRay, out rayHitT)) {
            if (CurveUtils.FindClosestRayIntersection(curve, sceneWidth, localRay, out rayHitT))
            {
                hit           = new SORayHit();
                hit.fHitDist  = (float)rayHitT;
                hit.hitPos    = localRay.GetPoint(hit.fHitDist);
                hit.hitPos    = GetScene().ToWorldP(frameL.FromFrameP(hit.hitPos));
                hit.hitNormal = Vector3.zero;
                hit.hitGO     = root;
                hit.hitSO     = this;
                return(true);
            }
            return(false);
        }
コード例 #22
0
        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];
        }
コード例 #23
0
ファイル: DebugGizmos.cs プロジェクト: SilvieM/PaintSTL
        public static void DrawBoundingBox(AxisAlignedBox3d bounds, Transform transform)
        {
            var min              = bounds.Min.toVector3();
            var max              = bounds.Max.toVector3();
            var bottomRightBack  = new Vector3(max.x, min.y, min.z);
            var bottomRightFront = new Vector3(max.x, max.y, min.z);
            var bottomLeftFront  = new Vector3(min.x, max.y, min.z);
            var topRightBack     = new Vector3(max.x, min.y, max.z);
            var topLeftBack      = new Vector3(min.x, min.y, max.z);
            var topLeftFront     = new Vector3(min.x, max.y, max.z);

            DrawLine(min, topLeftBack, transform);
            DrawLine(min, bottomLeftFront, transform);
            DrawLine(min, bottomRightBack, transform);
            DrawLine(max, bottomRightFront, transform);
            DrawLine(max, topLeftFront, transform);
            DrawLine(max, topRightBack, transform);
            DrawLine(topLeftBack, topRightBack, transform);
            DrawLine(bottomLeftFront, bottomRightFront, transform);
            DrawLine(topLeftFront, bottomLeftFront, transform);
            DrawLine(topRightBack, bottomRightBack, transform);
            DrawLine(topLeftBack, topLeftFront, transform);
            DrawLine(bottomRightBack, bottomRightFront, transform);
        }
コード例 #24
0
        public static DMesh3 MineCraft(DMesh3 mesh, int num_cells, out double scalefactor)
        {
            DMeshAABBTree3 spatial = new DMeshAABBTree3(mesh, autoBuild: true);


            AxisAlignedBox3d bounds   = mesh.CachedBounds;
            double           cellsize = bounds.MaxDim / num_cells;

            scalefactor = cellsize;

            ShiftGridIndexer3 indexer = new ShiftGridIndexer3(bounds.Min, cellsize);

            Bitmap3 bmp = new Bitmap3(new Vector3i(num_cells, num_cells, num_cells));

            foreach (Vector3i idx in bmp.Indices())
            {
                g3.Vector3d v = indexer.FromGrid(idx);
                if (spatial.IsInside(v))
                {
                    bmp.Set(idx, true);
                }
                else
                {
                    bmp.Set(idx, false);
                }
            }

            VoxelSurfaceGenerator voxGen = new VoxelSurfaceGenerator();

            voxGen.Voxels = bmp;
            voxGen.Generate();

            DMesh3 voxMesh = voxGen.Meshes[0];

            return(voxMesh);
        }
コード例 #25
0
        /// <summary>
        /// Slice the meshes and return the slice stack.
        /// </summary>
        public PlanarSliceStack Compute()
        {
            if (Meshes.Count == 0)
            {
                return(new PlanarSliceStack());
            }

            Interval1d zrange = Interval1d.Empty;

            foreach (var meshinfo in Meshes)
            {
                zrange.Contain(meshinfo.bounds.Min.z);
                zrange.Contain(meshinfo.bounds.Max.z);
            }
            if (SetMinZValue != double.MinValue)
            {
                zrange.a = SetMinZValue;
            }

            // construct layers
            List <PlanarSlice> slice_list = new List <PlanarSlice>();

            double cur_layer_z = zrange.a;
            int    layer_i     = 0;

            while (cur_layer_z < zrange.b)
            {
                double     layer_height = get_layer_height(layer_i);
                double     z            = cur_layer_z;
                Interval1d zspan        = new Interval1d(z, z + layer_height);
                if (SliceLocation == SliceLocations.EpsilonBase)
                {
                    z += 0.01 * layer_height;
                }
                else if (SliceLocation == SliceLocations.MidLine)
                {
                    z += 0.5 * layer_height;
                }

                PlanarSlice slice = SliceFactoryF(zspan, z, layer_i);
                slice.EmbeddedPathWidth = OpenPathDefaultWidthMM;
                slice_list.Add(slice);

                layer_i++;
                cur_layer_z += layer_height;
            }
            int NH = slice_list.Count;

            if (NH > MaxLayerCount)
            {
                throw new Exception("MeshPlanarSlicer.Compute: exceeded layer limit. Increase .MaxLayerCount.");
            }

            PlanarSlice[] slices = slice_list.ToArray();

            // determine if we have crop objects
            bool have_crop_objects = false;

            foreach (var mesh in Meshes)
            {
                if (mesh.options.IsCropRegion)
                {
                    have_crop_objects = true;
                }
            }

            // assume Resolve() takes 2x as long as meshes...
            TotalCompute = (Meshes.Count * NH) + (2 * NH);
            Progress     = 0;

            // compute slices separately for each mesh
            for (int mi = 0; mi < Meshes.Count; ++mi)
            {
                if (Cancelled())
                {
                    break;
                }

                DMesh3           mesh         = Meshes[mi].mesh;
                PrintMeshOptions mesh_options = Meshes[mi].options;

                // [TODO] should we hang on to this spatial? or should it be part of assembly?
                DMeshAABBTree3   spatial = new DMeshAABBTree3(mesh, true);
                AxisAlignedBox3d bounds  = Meshes[mi].bounds;

                bool is_cavity   = mesh_options.IsCavity;
                bool is_crop     = mesh_options.IsCropRegion;
                bool is_support  = mesh_options.IsSupport;
                bool is_closed   = (mesh_options.IsOpen) ? false : mesh.IsClosed();
                var  useOpenMode = (mesh_options.OpenPathMode == OpenPathsModes.Default) ?
                                   DefaultOpenPathMode : mesh_options.OpenPathMode;

                // each layer is independent so we can do in parallel
                gParallel.ForEach(Interval1i.Range(NH), (i) =>
                {
                    if (Cancelled())
                    {
                        return;
                    }

                    double z = slices[i].Z;
                    if (z < bounds.Min.z || z > bounds.Max.z)
                    {
                        return;
                    }

                    // compute cut
                    Polygon2d[] polys; PolyLine2d[] paths;
                    compute_plane_curves(mesh, spatial, z, is_closed, out polys, out paths);

                    // if we didn't hit anything, try again with jittered plane
                    // [TODO] this could be better...
                    if ((is_closed && polys.Length == 0) || (is_closed == false && polys.Length == 0 && paths.Length == 0))
                    {
                        double jitterz = slices[i].LayerZSpan.Interpolate(0.75);
                        compute_plane_curves(mesh, spatial, jitterz, is_closed, out polys, out paths);
                    }

                    if (is_closed)
                    {
                        // construct planar complex and "solids"
                        // (ie outer polys and nested holes)
                        PlanarComplex complex = new PlanarComplex();
                        foreach (Polygon2d poly in polys)
                        {
                            complex.Add(poly);
                        }

                        PlanarComplex.FindSolidsOptions options
                            = PlanarComplex.FindSolidsOptions.Default;
                        options.WantCurveSolids            = false;
                        options.SimplifyDeviationTolerance = 0.001;
                        options.TrustOrientations          = true;
                        options.AllowOverlappingHoles      = true;

                        PlanarComplex.SolidRegionInfo solids   = complex.FindSolidRegions(options);
                        List <GeneralPolygon2d> solid_polygons = ApplyValidRegions(solids.Polygons);

                        if (is_support)
                        {
                            add_support_polygons(slices[i], solid_polygons, mesh_options);
                        }
                        else if (is_cavity)
                        {
                            add_cavity_polygons(slices[i], solid_polygons, mesh_options);
                        }
                        else if (is_crop)
                        {
                            add_crop_region_polygons(slices[i], solid_polygons, mesh_options);
                        }
                        else
                        {
                            add_solid_polygons(slices[i], solid_polygons, mesh_options);
                        }
                    }
                    else if (useOpenMode != OpenPathsModes.Ignored)
                    {
                        // [TODO]
                        //   - does not really handle clipped polygons properly, there will be an extra break somewhere...
                        List <PolyLine2d> all_paths = new List <PolyLine2d>(paths);
                        foreach (Polygon2d poly in polys)
                        {
                            all_paths.Add(new PolyLine2d(poly, true));
                        }

                        List <PolyLine2d> open_polylines = ApplyValidRegions(all_paths);
                        foreach (PolyLine2d pline in open_polylines)
                        {
                            if (useOpenMode == OpenPathsModes.Embedded)
                            {
                                slices[i].AddEmbeddedPath(pline);
                            }
                            else
                            {
                                slices[i].AddClippedPath(pline);
                            }
                        }
                    }

                    Interlocked.Increment(ref Progress);
                });  // end of parallel.foreach
            } // end mesh iter

            // resolve planar intersections, etc
            gParallel.ForEach(Interval1i.Range(NH), (i) =>
            {
                if (Cancelled())
                {
                    return;
                }

                if (have_crop_objects && slices[i].InputCropRegions.Count == 0)
                {
                    // don't resolve, we have fully cropped this layer
                }
                else
                {
                    slices[i].Resolve();
                }

                Interlocked.Add(ref Progress, 2);
            });

            // discard spurious empty slices
            int last = slices.Length - 1;

            while (slices[last].IsEmpty && last > 0)
            {
                last--;
            }
            int first = 0;

            if (DiscardEmptyBaseSlices || have_crop_objects)
            {
                while (slices[first].IsEmpty && first < slices.Length)
                {
                    first++;
                }
            }

            PlanarSliceStack stack = SliceStackFactoryF();

            for (int k = first; k <= last; ++k)
            {
                stack.Add(slices[k]);
            }

            if (SupportMinZTips)
            {
                stack.AddMinZTipSupportPoints(MinZTipMaxDiam, MinZTipExtraLayers);
            }

            return(stack);
        }
コード例 #26
0
        protected virtual void update_level_set()
        {
            double unsigned_offset = Math.Abs(offset_distance);

            if (cached_sdf == null ||
                unsigned_offset > cached_sdf_max_offset ||
                grid_cell_size != cached_sdf.CellSize)
            {
                DMesh3 meshIn      = MeshSource.GetDMeshUnsafe();
                int    exact_cells = (int)(unsigned_offset / grid_cell_size) + 1;

                // only use spatial DS if we are computing enough cells
                DMeshAABBTree3 use_spatial = GenerateClosedMeshOp.MeshSDFShouldUseSpatial(
                    input_spatial, exact_cells, grid_cell_size, input_mesh_edge_stats.z);
                MeshSignedDistanceGrid sdf = new MeshSignedDistanceGrid(meshIn, grid_cell_size, use_spatial)
                {
                    ExactBandWidth = exact_cells
                };
                if (use_spatial != null)
                {
                    sdf.NarrowBandMaxDistance = unsigned_offset + grid_cell_size;
                    sdf.ComputeMode           = MeshSignedDistanceGrid.ComputeModes.NarrowBand_SpatialFloodFill;
                }

                sdf.CancelF = is_invalidated;
                sdf.Compute();
                if (is_invalidated())
                {
                    return;
                }
                cached_sdf            = sdf;
                cached_sdf_max_offset = unsigned_offset;
                cached_sdf_bounds     = meshIn.CachedBounds;
            }

            var           iso = new DenseGridTrilinearImplicit(cached_sdf.Grid, cached_sdf.GridOrigin, cached_sdf.CellSize);
            MarchingCubes c   = new MarchingCubes();

            c.Implicit = iso;
            c.IsoValue = offset_distance;
            c.Bounds   = cached_sdf_bounds;
            c.CubeSize = mesh_cell_size;
            c.Bounds.Expand(offset_distance + 3 * c.CubeSize);
            c.RootMode      = MarchingCubes.RootfindingModes.LerpSteps;
            c.RootModeSteps = 5;

            c.CancelF = is_invalidated;
            c.Generate();
            if (is_invalidated())
            {
                return;
            }

            Reducer r = new Reducer(c.Mesh);

            r.FastCollapsePass(c.CubeSize * 0.5, 3, true);
            if (is_invalidated())
            {
                return;
            }

            if (min_component_volume > 0)
            {
                MeshEditor.RemoveSmallComponents(c.Mesh, min_component_volume, min_component_volume);
            }
            if (is_invalidated())
            {
                return;
            }

            ResultMesh = c.Mesh;
        }
コード例 #27
0
        /// <summary>
        /// this variant use a lazy-evaluation version of the grid, and continuation-MC,
        /// so the marching cubes pulls values from the grid that are evaluated on-the-fly.
        /// In theory this should be comparable or faster than the narrow-band version,
        /// practice it is 10-20% slower...?? possible reasons:
        ///    - spinlock contention
        ///    - lots of duplicate grid evaluations because CachingDenseGridTrilinearImplicit does not use locking
        ///
        /// However, because it can re-use grid values, changing the isovalue is
        /// *much* faster and so it makes sense if the mesh is not closed...
        /// </summary>
        protected virtual void update_winding_fast()
        {
            DMesh3 meshIn = MeshSource.GetDMeshUnsafe();

            if (spatialPro == null || spatial_timestamp != meshIn.ShapeTimestamp)
            {
                spatialPro = new DMeshAABBTreePro(meshIn, true);
                spatialPro.FastWindingNumber(Vector3d.Zero);
                spatial_timestamp = meshIn.ShapeTimestamp;
            }
            if (is_invalidated())
            {
                return;
            }

            if (cached_lazy_mwn_grid == null ||
                grid_cell_size != cached_lazy_mwn_grid.CellSize)
            {
                // figure out origin & dimensions
                AxisAlignedBox3d bounds       = meshIn.CachedBounds;
                float            fBufferWidth = 2 * (float)grid_cell_size;
                Vector3d         origin       = (Vector3f)bounds.Min - fBufferWidth * Vector3f.One;
                Vector3f         max          = (Vector3f)bounds.Max + fBufferWidth * Vector3f.One;
                int ni = (int)((max.x - origin.x) / (float)grid_cell_size) + 1;
                int nj = (int)((max.y - origin.y) / (float)grid_cell_size) + 1;
                int nk = (int)((max.z - origin.z) / (float)grid_cell_size) + 1;

                var grid = new CachingDenseGridTrilinearImplicit(origin, grid_cell_size, new Vector3i(ni, nj, nk));
                grid.AnalyticF = new WindingField(spatialPro);

                cached_lazy_mwn_grid = grid;
                cached_mwn_bounds    = meshIn.CachedBounds;
            }

            WindingFieldImplicit iso = new WindingFieldImplicit(cached_lazy_mwn_grid, winding_iso);

            MarchingCubesPro c = new MarchingCubesPro();

            c.Implicit = iso;
            c.Bounds   = cached_mwn_bounds;
            c.CubeSize = mesh_cell_size;
            c.Bounds.Expand(3 * c.CubeSize);
            c.RootMode      = MarchingCubesPro.RootfindingModes.Bisection;
            c.RootModeSteps = 10;

            c.CancelF = is_invalidated;
            c.GenerateContinuation(meshIn.Vertices());
            if (is_invalidated())
            {
                return;
            }

            Reducer r = new Reducer(c.Mesh);

            r.FastCollapsePass(c.CubeSize * 0.5, 3, true);
            if (is_invalidated())
            {
                return;
            }

            if (min_component_volume > 0)
            {
                MeshEditor.RemoveSmallComponents(c.Mesh, min_component_volume, min_component_volume);
            }
            if (is_invalidated())
            {
                return;
            }

            // reproject - if we want to do this, we need to create spatial and meshIn above!
            gParallel.ForEach(c.Mesh.VertexIndices(), (vid) => {
                if (is_invalidated())
                {
                    return;
                }
                Vector3d v = c.Mesh.GetVertex(vid);
                int tid    = spatialPro.FindNearestTriangle(v, grid_cell_size * MathUtil.SqrtTwo);
                if (tid != DMesh3.InvalidID)
                {
                    var query = MeshQueries.TriangleDistance(meshIn, tid, v);
                    if (v.Distance(query.TriangleClosest) < grid_cell_size)
                    {
                        c.Mesh.SetVertex(vid, query.TriangleClosest);
                    }
                }
            });

            if (is_invalidated())
            {
                return;
            }

            ResultMesh = c.Mesh;
        }
コード例 #28
0
        /// <summary>
        /// Sample analytic winding number into grid in narrow-band around target isovalue,
        /// and then extract using marching cubes.
        ///
        /// TODO: don't need to discard current grid when isovalue changes, just need to
        ///   re-run the front propagation part of mwn.Compute()!
        ///   If this is done, then use this instead of update_winding_fast() for open meshes
        /// </summary>
        protected virtual void update_winding()
        {
            DMesh3 meshIn = MeshSource.GetDMeshUnsafe();

            if (spatialPro == null || spatial_timestamp != meshIn.ShapeTimestamp)
            {
                spatialPro = new DMeshAABBTreePro(meshIn, true);
                spatialPro.FastWindingNumber(Vector3d.Zero);
                spatial_timestamp = meshIn.ShapeTimestamp;
            }
            if (is_invalidated())
            {
                return;
            }

            if (cached_mwn_grid == null ||
                grid_cell_size != cached_mwn_grid.CellSize ||
                (float)winding_iso != cached_mwn_grid.IsoValue)
            {
                Func <Vector3d, double> fastWN = (q) => { return(spatialPro.FastWindingNumber(q)); };
                var mwn = new MeshScalarSamplingGrid(meshIn, grid_cell_size, fastWN)
                {
                    IsoValue = (float)winding_iso
                };
                mwn.CancelF = is_invalidated;
                mwn.Compute();
                if (is_invalidated())
                {
                    return;
                }
                cached_mwn_grid   = mwn;
                cached_mwn_bounds = meshIn.CachedBounds;
            }

            MarchingCubes c = new MarchingCubes();

            c.Implicit = new SampledGridImplicit(cached_mwn_grid);
            c.IsoValue = 0.0;
            c.Bounds   = cached_mwn_bounds;
            c.CubeSize = mesh_cell_size;
            c.Bounds.Expand(3 * c.CubeSize);
            c.RootMode      = MarchingCubes.RootfindingModes.Bisection;
            c.RootModeSteps = 10;

            c.CancelF = is_invalidated;
            c.Generate();
            if (is_invalidated())
            {
                return;
            }

            Reducer r = new Reducer(c.Mesh);

            r.FastCollapsePass(c.CubeSize * 0.5, 3, true);
            if (is_invalidated())
            {
                return;
            }

            if (min_component_volume > 0)
            {
                MeshEditor.RemoveSmallComponents(c.Mesh, min_component_volume, min_component_volume);
            }
            if (is_invalidated())
            {
                return;
            }

            // reproject - if we want to do this, we need to create spatial and meshIn above!
            gParallel.ForEach(c.Mesh.VertexIndices(), (vid) => {
                if (is_invalidated())
                {
                    return;
                }
                Vector3d v = c.Mesh.GetVertex(vid);
                int tid    = spatialPro.FindNearestTriangle(v, grid_cell_size * MathUtil.SqrtTwo);
                if (tid != DMesh3.InvalidID)
                {
                    var query = MeshQueries.TriangleDistance(meshIn, tid, v);
                    if (v.Distance(query.TriangleClosest) < grid_cell_size)
                    {
                        c.Mesh.SetVertex(vid, query.TriangleClosest);
                    }
                }
            });

            if (is_invalidated())
            {
                return;
            }

            ResultMesh = c.Mesh;
        }
コード例 #29
0
ファイル: Program.cs プロジェクト: VB6Hobbyst7/gsSliceToolPro
        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);
        }
コード例 #30
0
ファイル: Program.cs プロジェクト: VB6Hobbyst7/gsSliceToolPro
        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);
        }