/// <summary>
        /// compute offset meshes as simple extrusions
        /// </summary>
        void compute_offset_meshes_nosdf()
        {
            if (cached_inner_sdf_offset != inner_offset)
            {
                InnerOffsetMesh = new DMesh3(cachedInputMesh);
                MeshTransforms.FromFrame(InnerOffsetMesh, cachedInputsTransform);

                MeshNormals.QuickCompute(InnerOffsetMesh);
                MeshTransforms.VertexNormalOffset(InnerOffsetMesh, inner_offset);
                Reducer reducer = new Reducer(InnerOffsetMesh);
                reducer.ReduceToTriangleCount(5000);
                InnerOffsetMeshSpatial  = new DMeshAABBTree3(InnerOffsetMesh, true);
                cached_inner_sdf_offset = inner_offset;
            }

            double max_offset = inner_offset + thickness;

            if (cached_outer_sdf_offset != max_offset)
            {
                OuterOffsetMesh = new DMesh3(cachedInputMesh);
                MeshTransforms.FromFrame(OuterOffsetMesh, cachedInputsTransform);

                MeshNormals.QuickCompute(OuterOffsetMesh);
                MeshTransforms.VertexNormalOffset(OuterOffsetMesh, max_offset);
                Reducer reducer = new Reducer(OuterOffsetMesh);
                reducer.ReduceToTriangleCount(5000);
                OuterOffsetMeshSpatial  = new DMeshAABBTree3(OuterOffsetMesh, true);
                cached_outer_sdf_offset = max_offset;
            }

            //Util.WriteDebugMesh(MeshSource.GetIMesh(), "c:\\scratch\\__OFFESTS_orig.obj");
            //Util.WriteDebugMesh(InnerOffsetMesh, "c:\\scratch\\__OFFESTS_inner.obj");
            //Util.WriteDebugMesh(OuterOffsetMesh, "c:\\scratch\\__OFFESTS_outer.obj");
        }
        void compute_trimmed_mesh()
        {
            // curve is on base leg, map to deformed leg
            // [TODO] really should be doing this via deformation, rather than nearest-point
            DCurve3 curve = new DCurve3(CurveSource.GetICurve());

            for (int i = 0; i < curve.VertexCount; ++i)
            {
                curve[i] = MeshQueries.NearestPointFrame(cachedInputMesh, cachedInputMeshSpatial, curve[i]).Origin;
            }

            TrimmedMesh = new DMesh3(cachedInputMesh);
            TrimmedMesh.EnableTriangleGroups(0);

            AxisAlignedBox3d bounds = TrimmedMesh.CachedBounds;

            // try to find seed based on raycast, which doesn't always work.
            // Note that seed is the seed for the *eroded* region, not the kept region
            Vector3d basePt  = bounds.Center + 10 * bounds.Extents.y * Vector3d.AxisY;
            int      hit_tid = cachedInputMeshSpatial.FindNearestHitTriangle(new Ray3d(basePt, -Vector3d.AxisY));
            Vector3d seed    = cachedInputMesh.GetTriCentroid(hit_tid);

            if (flip_trim_side)
            {
                basePt  = bounds.Center - 10 * bounds.Extents.y * Vector3d.AxisY;
                hit_tid = cachedInputMeshSpatial.FindNearestHitTriangle(new Ray3d(basePt, Vector3d.AxisY));
                seed    = cachedInputMesh.GetTriCentroid(hit_tid);
            }

            MeshTrimLoop trim = new MeshTrimLoop(TrimmedMesh, curve, seed, cachedInputMeshSpatial);

            trim.Trim();

            if (TrimmedMesh.HasVertexColors == false)
            {
                TrimmedMesh.EnableVertexColors(SocketVertexColor);
            }
            else
            {
                foreach (int vid in TrimmedMesh.VertexIndices())
                {
                    TrimmedMesh.SetVertexColor(vid, SocketVertexColor);
                }
            }

            MeshTransforms.FromFrame(TrimmedMesh, cachedInputsTransform);
        }
예제 #3
0
        public IOWriteResult RunBackgroundWrite()
        {
            // transform meshes
            gParallel.ForEach(Interval1i.Range(ExportMeshes.Length), (i) => {
                if (MeshFrames[i].Origin != Vector3f.Zero || MeshFrames[i].Rotation != Quaternionf.Identity)
                {
                    MeshTransforms.FromFrame(ExportMeshes[i], MeshFrames[i]);
                }

                MeshTransforms.FlipLeftRightCoordSystems(ExportMeshes[i]);

                if (ExportYUp == false)
                {
                    MeshTransforms.ConvertYUpToZUp(ExportMeshes[i]);
                }
            });


            List <WriteMesh> writeMeshes = new List <WriteMesh>();

            for (int i = 0; i < ExportMeshes.Length; ++i)
            {
                writeMeshes.Add(new WriteMesh(ExportMeshes[i]));
            }


            WriteOptions options = WriteOptions.Defaults;

            options.bWriteBinary = true;
            options.ProgressFunc = BackgroundProgressFunc;

            StandardMeshWriter writer = new StandardMeshWriter();
            IOWriteResult      result = writer.Write(WritePath, writeMeshes, options);

            return(result);
        }
예제 #4
0
            public void Compute()
            {
                int N = meshToScene.Length;

                slicer = new MeshPlanarSlicerPro()
                {
                    LayerHeightMM = CC.Settings.LayerHeightMM,
                    // [RMS] 1.5 here is a hack. If we don't leave a bit of space then often the filament gets squeezed right at
                    //   inside/outside transitions, which is bad. Need a better way to handle.
                    OpenPathDefaultWidthMM = CC.Settings.NozzleDiameterMM * 1.5,
                    SetMinZValue           = 0,
                    SliceFactoryF          = PlanarSlicePro.FactoryF
                };
                if (CC.Settings.OpenMode == PrintSettings.OpenMeshMode.Clipped)
                {
                    slicer.DefaultOpenPathMode = PrintMeshOptions.OpenPathsModes.Clipped;
                }
                else if (CC.Settings.OpenMode == PrintSettings.OpenMeshMode.Embedded)
                {
                    slicer.DefaultOpenPathMode = PrintMeshOptions.OpenPathsModes.Embedded;
                }
                else if (CC.Settings.OpenMode == PrintSettings.OpenMeshMode.Ignored)
                {
                    slicer.DefaultOpenPathMode = PrintMeshOptions.OpenPathsModes.Ignored;
                }

                if (CC.Settings.StartLayers > 0)
                {
                    int    start_layers       = CC.Settings.StartLayers;
                    double std_layer_height   = CC.Settings.LayerHeightMM;
                    double start_layer_height = CC.Settings.StartLayerHeightMM;
                    slicer.LayerHeightF = (layer_i) => {
                        return((layer_i < start_layers) ? start_layer_height : std_layer_height);
                    };
                }

                try {
                    assembly = new PrintMeshAssembly();
                    for (int k = 0; k < N; ++k)
                    {
                        DMesh3            mesh     = meshCopies[k];
                        Frame3f           mapF     = meshToScene[k];
                        PrintMeshSettings settings = meshSettings[k];

                        PrintMeshOptions options = new PrintMeshOptions();
                        options.IsSupport    = (settings.ObjectType == PrintMeshSettings.ObjectTypes.Support);
                        options.IsCavity     = (settings.ObjectType == PrintMeshSettings.ObjectTypes.Cavity);
                        options.IsCropRegion = (settings.ObjectType == PrintMeshSettings.ObjectTypes.CropRegion);
                        options.IsOpen       = false;
                        if (settings.OuterShellOnly)
                        {
                            options.IsOpen = true;
                        }
                        options.OpenPathMode = PrintMeshSettings.Convert(settings.OpenMeshMode);
                        options.Extended     = new ExtendedPrintMeshOptions()
                        {
                            ClearanceXY = settings.Clearance,
                            OffsetXY    = settings.OffsetXY
                        };

                        Vector3f scale = localScale[k];
                        MeshTransforms.Scale(mesh, scale.x, scale.y, scale.z);
                        MeshTransforms.FromFrame(mesh, mapF);
                        MeshTransforms.FlipLeftRightCoordSystems(mesh);
                        MeshTransforms.ConvertYUpToZUp(mesh);

                        MeshAssembly decomposer = new MeshAssembly(mesh);
                        decomposer.HasNoVoids = settings.NoVoids;
                        decomposer.Decompose();

                        assembly.AddMeshes(decomposer.ClosedSolids, options);

                        PrintMeshOptions openOptions = options.Clone();
                        assembly.AddMeshes(decomposer.OpenMeshes, openOptions);
                    }

                    if (slicer.Add(assembly) == false)
                    {
                        throw new Exception("error adding PrintMeshAssembly to Slicer!!");
                    }

                    // set clip box
                    Box2d clip_box = new Box2d(Vector2d.Zero,
                                               new Vector2d(CC.Settings.BedSizeXMM / 2, CC.Settings.BedSizeYMM / 2));
                    slicer.ValidRegions = new List <GeneralPolygon2d>()
                    {
                        new GeneralPolygon2d(new Polygon2d(clip_box.ComputeVertices()))
                    };

                    result  = slicer.Compute();
                    Success = true;
                } catch (Exception e) {
                    DebugUtil.Log("GeometrySlicer.Compute: exception: " + e.Message);
                    Success = false;
                }

                Finished = true;
            }
        /// <summary>
        /// compute SDF for the scan object, and then compute offset iso-contours
        /// </summary>
        void compute_offset_meshes()
        {
            int sdf_cells  = 128;
            int mesh_cells = 128;

            double max_offset = inner_offset + thickness;

            if (max_offset > cached_sdf_max_offset)
            {
                DMesh3 meshIn = new DMesh3(MeshSource.GetIMesh(), MeshHints.IsCompact, MeshComponents.None);
                MeshTransforms.FromFrame(meshIn, cachedInputsTransform);

                // [RMS] reduce this mesh? speeds up SDF quite a bit...
                Reducer r = new Reducer(meshIn);
                r.ReduceToTriangleCount(2500);

                double cell_size           = meshIn.CachedBounds.MaxDim / sdf_cells;
                int    exact_cells         = (int)((max_offset) / cell_size) + 1;
                MeshSignedDistanceGrid sdf = new MeshSignedDistanceGrid(meshIn, cell_size)
                {
                    ExactBandWidth = exact_cells
                };
                sdf.Compute();
                cached_sdf            = sdf;
                cached_sdf_max_offset = max_offset;
                cached_sdf_bounds     = meshIn.CachedBounds;

                cached_inner_sdf_offset = 0;
                cached_outer_sdf_offset = 0;
            }

            if (cached_inner_sdf_offset != inner_offset || cached_outer_sdf_offset != max_offset)
            {
                var iso = new DenseGridTrilinearImplicit(cached_sdf.Grid, cached_sdf.GridOrigin, cached_sdf.CellSize);

                MarchingCubes c = new MarchingCubes()
                {
                    Implicit = iso
                };
                c.Bounds   = cached_sdf_bounds;
                c.CubeSize = c.Bounds.MaxDim / mesh_cells;
                c.Bounds.Expand(max_offset + 3 * c.CubeSize);

                if (cached_inner_sdf_offset != inner_offset)
                {
                    c.IsoValue = inner_offset;
                    c.Generate();
                    InnerOffsetMesh = c.Mesh;
                    Reducer reducer = new Reducer(InnerOffsetMesh);
                    reducer.ReduceToEdgeLength(c.CubeSize / 2);
                    InnerOffsetMeshSpatial  = new DMeshAABBTree3(InnerOffsetMesh, true);
                    cached_inner_sdf_offset = inner_offset;
                }

                if (cached_outer_sdf_offset != max_offset)
                {
                    c.IsoValue = inner_offset + thickness;
                    c.Generate();
                    OuterOffsetMesh = c.Mesh;
                    Reducer reducer = new Reducer(OuterOffsetMesh);
                    reducer.ReduceToEdgeLength(c.CubeSize / 2);
                    OuterOffsetMeshSpatial  = new DMeshAABBTree3(OuterOffsetMesh, true);
                    cached_outer_sdf_offset = max_offset;
                }
            }

            //Util.WriteDebugMesh(MeshSource.GetIMesh(), "c:\\scratch\\__OFFESTS_orig.obj");
            //Util.WriteDebugMesh(InnerOffsetMesh, "c:\\scratch\\__OFFESTS_inner.obj");
            //Util.WriteDebugMesh(OuterOffsetMesh, "c:\\scratch\\__OFFESTS_outer.obj");
        }