Esempio n. 1
0
        protected virtual List <GeneralPolygon2d> make_solid(GeneralPolygon2d poly, bool bIsSupportSolid)
        {
            // always do a self-union of outer polygon. This allows Clipper to clean up many
            // problems in input polygons, eg self-intersections and other junk
            GeneralPolygon2d        gouter        = new GeneralPolygon2d(poly.Outer);
            List <GeneralPolygon2d> resolvedSolid =
                ClipperUtil.Union(gouter, gouter, MIN_AREA);

            // solid may contain overlapping holes. We need to resolve these before continuing,
            // otherwise those overlapping regions will be filled by Clipper even/odd rules
            foreach (Polygon2d hole in poly.Holes)
            {
                GeneralPolygon2d holePoly = new GeneralPolygon2d(hole);
                resolvedSolid = ClipperUtil.PolygonBoolean(resolvedSolid, holePoly, ClipperUtil.BooleanOp.Difference, MIN_AREA);
            }

            if (bIsSupportSolid == false && Thickened != null)
            {
                // Subtract away any clearance solids
                foreach (var pair in Thickened)
                {
                    if (pair.Key != poly)
                    {
                        resolvedSolid = ClipperUtil.Difference(resolvedSolid, pair.Value);
                    }
                }
            }
            return(filter_solids(resolvedSolid));
        }
Esempio n. 2
0
        virtual protected void cache_brim_polys()
        {
            combined_solid   = new List <GeneralPolygon2d>();
            combined_support = new List <GeneralPolygon2d>();
            subtract         = new List <GeneralPolygon2d>();

            Frame3f cutPlane = new Frame3f((float)layer_height * 0.5f * Vector3f.AxisY, Vector3f.AxisY);

            foreach (var so in CC.Objects.PrintMeshes)
            {
                if (so.Settings.ObjectType == PrintMeshSettings.ObjectTypes.Ignored)
                {
                    continue;
                }
                SOSectionPlane section = new SOSectionPlane(so);
                section.UpdateSection(cutPlane, CoordSpace.SceneCoords);
                List <GeneralPolygon2d> solids = section.GetSolids();

                // [TODO] should subtract holes explicitly here, like we do in slicer?

                if (so.Settings.ObjectType == PrintMeshSettings.ObjectTypes.Cavity)
                {
                    subtract = ClipperUtil.Union(solids, subtract);
                }
                else if (so.Settings.ObjectType == PrintMeshSettings.ObjectTypes.Support)
                {
                    combined_support = ClipperUtil.Union(solids, combined_support);
                }
                else if (so.Settings.ObjectType == PrintMeshSettings.ObjectTypes.Solid)
                {
                    combined_solid = ClipperUtil.Union(solids, combined_solid);
                }
            }
            if (subtract.Count > 0)
            {
                combined_solid = ClipperUtil.Difference(combined_solid, subtract);
            }

            combined_all = ClipperUtil.Union(combined_solid, combined_support);
            combined_all = CurveUtils2.FilterDegenerate(combined_all, 0.001);

            foreach (var poly in combined_all)
            {
                poly.Simplify(path_width * 0.02);
            }
        }
Esempio n. 3
0
        protected override List <GeneralPolygon2d> make_solid(GeneralPolygon2d poly, bool bIsSupportSolid)
        {
            List <GeneralPolygon2d> solid = base.make_solid(poly, bIsSupportSolid);

            if (bIsSupportSolid == false && Thickened != null)
            {
                // subtract clearance solids
                foreach (var pair in Thickened)
                {
                    if (pair.Key != poly)
                    {
                        solid = ClipperUtil.Difference(solid, pair.Value);
                    }
                }
            }
            return(solid);
        }
Esempio n. 4
0
        protected virtual List <GeneralPolygon2d> remove_cavity(List <GeneralPolygon2d> solids, GeneralPolygon2d cavity)
        {
            double offset = 0;

            if (Cavity_Clearances.ContainsKey(cavity))
            {
                offset = Cavity_Clearances[cavity];
            }
            if (Cavity_Offsets.ContainsKey(cavity))
            {
                offset += Cavity_Offsets[cavity];
            }
            if (Math.Abs(offset) > 0.0001)
            {
                var offset_cavities = ClipperUtil.MiterOffset(cavity, offset, MIN_AREA);
                return(ClipperUtil.Difference(solids, offset_cavities, MIN_AREA));
            }
            else
            {
                return(ClipperUtil.Difference(solids, cavity, MIN_AREA));
            }
        }
Esempio n. 5
0
        /// <summary>
        /// Convert assembly of polygons, polylines, etc, into a set of printable solids and paths
        /// </summary>
        public virtual void Resolve()
        {
            // combine solids, process largest-to-smallest
            if (InputSolids.Count > 0)
            {
                GeneralPolygon2d[] solids = InputSolids.ToArray();

                solids = process_input_polys_before_sort(solids);

                // sort by decreasing weight
                double[] weights = new double[solids.Length];
                for (int i = 0; i < solids.Length; ++i)
                {
                    weights[i] = sorting_weight(solids[i]);
                }
                Array.Sort(weights, solids); Array.Reverse(solids);

                solids = process_input_polys_after_sort(solids);

                Solids = new List <GeneralPolygon2d>();
                for (int k = 0; k < solids.Length; ++k)
                {
                    // convert this polygon into the solid we want to use
                    List <GeneralPolygon2d> resolvedSolid = make_solid(solids[k], false);

                    // now union in with accumulated solids
                    if (Solids.Count == 0)
                    {
                        Solids.AddRange(resolvedSolid);
                    }
                    else
                    {
                        Solids = combine_solids(Solids, resolvedSolid);
                    }
                }
            }

            // subtract input cavities
            foreach (var cavity in InputCavities)
            {
                Solids = remove_cavity(Solids, cavity);
            }

            // subtract thickened embedded paths from solids
            if (EmbeddedPaths.Count > 0 && EmbeddedPathWidth == 0)
            {
                throw new Exception("PlanarSlice.Resolve: must set embedded path width!");
            }
            foreach (var path in EmbeddedPaths)
            {
                Polygon2d thick_path = make_thickened_path(path, EmbeddedPathWidth);
                Solids = ClipperUtil.Difference(Solids, new GeneralPolygon2d(thick_path), MIN_AREA);
                Paths.Add(path);
            }

            // cleanup
            Solids = filter_solids(Solids);

            // subtract solids from clipped paths
            foreach (var path in ClippedPaths)
            {
                List <PolyLine2d> clipped = ClipperUtil.ClipAgainstPolygon(Solids, path);
                foreach (var cp in clipped)
                {
                    Paths.Add(cp);
                }
            }

            // combine support solids, while also subtracting print solids and thickened paths
            if (InputSupportSolids.Count > 0)
            {
                // make assembly of path solids
                // [TODO] do we need to boolean these?
                List <GeneralPolygon2d> path_solids = null;
                if (Paths.Count > 0)
                {
                    path_solids = new List <GeneralPolygon2d>();
                    foreach (var path in Paths)
                    {
                        path_solids.Add(new GeneralPolygon2d(make_thickened_path(path, EmbeddedPathWidth)));
                    }
                }

                foreach (var solid in InputSupportSolids)
                {
                    // convert this polygon into the solid we want to use
                    List <GeneralPolygon2d> resolved = make_solid(solid, true);

                    // now subtract print solids
                    resolved = ClipperUtil.PolygonBoolean(resolved, Solids, ClipperUtil.BooleanOp.Difference, MIN_AREA);

                    // now subtract paths
                    if (path_solids != null)
                    {
                        resolved = ClipperUtil.PolygonBoolean(resolved, path_solids, ClipperUtil.BooleanOp.Difference, MIN_AREA);
                    }

                    // now union in with accumulated support solids
                    if (SupportSolids.Count == 0)
                    {
                        SupportSolids.AddRange(resolved);
                    }
                    else
                    {
                        SupportSolids = ClipperUtil.PolygonBoolean(SupportSolids, resolved, ClipperUtil.BooleanOp.Union, MIN_AREA);
                    }
                }

                SupportSolids = filter_solids(SupportSolids);
            }

            // apply crop regions
            if (InputCropRegions.Count > 0)
            {
                // combine crop regions
                var CropRegions = make_solid(InputCropRegions[0], false);
                for (int k = 1; k < InputCropRegions.Count; ++k)
                {
                    CropRegions = combine_solids(CropRegions, make_solid(InputCropRegions[k], false));
                }

                Solids = ClipperUtil.Intersection(CropRegions, Solids, MIN_AREA);
                Solids = filter_solids(Solids);
                List <PolyLine2d> cropped_paths = new List <PolyLine2d>();
                foreach (var path in Paths)
                {
                    cropped_paths.AddRange(ClipperUtil.ClipAgainstPolygon(CropRegions, path, true));
                }
                // TODO: filter paths

                SupportSolids = ClipperUtil.Intersection(CropRegions, SupportSolids, MIN_AREA);
                SupportSolids = filter_solids(SupportSolids);
            }
        }
Esempio n. 6
0
        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;
            }
        }
Esempio n. 7
0
 protected virtual List <GeneralPolygon2d> remove_cavity(List <GeneralPolygon2d> solids, GeneralPolygon2d cavity)
 {
     return(ClipperUtil.Difference(solids, cavity, MIN_AREA));
 }