Exemple #1
0
        /// <summary>
        /// Convert the input polygons to a set of paths.
        /// If FilterSelfOverlaps=true, then the paths will be clipped against
        /// themselves, in an attempt to avoid over-printing.
        /// </summary>
        public virtual FillCurveSet2d ShellPolysToPaths(List <GeneralPolygon2d> shell_polys, int nShell)
        {
            FillCurveSet2d paths = new FillCurveSet2d();

            FillTypeFlags flags = FillTypeFlags.PerimeterShell;

            if (nShell == 0 && ShellType == ShellTypes.ExternalPerimeters)
            {
                flags = FillTypeFlags.OutermostShell;
            }
            else if (ShellType == ShellTypes.InternalShell)
            {
                flags = FillTypeFlags.InteriorShell;
            }
            else if (ShellType == ShellTypes.BridgeShell)
            {
                flags = FillTypeFlags.BridgeSupport;
            }

            if (FilterSelfOverlaps == false)
            {
                foreach (GeneralPolygon2d shell in shell_polys)
                {
                    paths.Append(shell, flags);
                }
                return(paths);
            }

            int outer_shell_edgegroup = 100;

            foreach (GeneralPolygon2d shell in shell_polys)
            {
                PathOverlapRepair repair = new PathOverlapRepair();
                repair.OverlapRadius = SelfOverlapTolerance;
                repair.Add(shell, outer_shell_edgegroup);

                // Ideally want to presreve outermost shell of external perimeters.
                // However in many cases internal holes are 'too close' to outer border.
                // So we will still apply to those, but use edge filter to preserve outermost loop.
                // [TODO] could we be smarter about this somehow?
                if (PreserveOuterShells && nShell == 0 && ShellType == ShellTypes.ExternalPerimeters)
                {
                    repair.PreserveEdgeFilterF = (eid) => { return(repair.Graph.GetEdgeGroup(eid) == outer_shell_edgegroup); }
                }
                ;

                repair.Compute();

                DGraph2Util.Curves c = DGraph2Util.ExtractCurves(repair.GetResultGraph());

                foreach (var polygon in c.Loops)
                {
                    paths.Append(polygon, flags);
                }
                foreach (var polyline in c.Paths)
                {
                    if (polyline.ArcLength < DiscardTinyPerimterLengthMM)
                    {
                        continue;
                    }
                    if (polyline.Bounds.MaxDim < DiscardTinyPerimterLengthMM)
                    {
                        continue;
                    }
                    paths.Append(new FillPolyline2d(polyline)
                    {
                        TypeFlags = flags
                    });
                }
            }
            return(paths);
        }
Exemple #2
0
        /// <summary>
        /// Convert the input polygons to a set of paths.
        /// If FilterSelfOverlaps=true, then the paths will be clipped against
        /// themselves, in an attempt to avoid over-printing.
        /// </summary>
        public virtual FillCurveSet2d ShellPolysToPaths(List <GeneralPolygon2d> shell_polys, int nShell)
        {
            FillCurveSet2d paths = new FillCurveSet2d();

            IFillType currentFillType = nShell == 0 ? firstShellFillType ?? fillType : fillType;

            if (FilterSelfOverlaps == false)
            {
                foreach (var shell in shell_polys)
                {
                    paths.Append(new FillLoop <FillSegment>(shell.Outer.Vertices)
                    {
                        FillType = currentFillType, PerimeterOrder = nShell
                    });
                    foreach (var hole in shell.Holes)
                    {
                        paths.Append(new FillLoop <FillSegment>(hole.Vertices)
                        {
                            FillType = currentFillType, PerimeterOrder = nShell, IsHoleShell = true
                        });;
                    }
                }
                return(paths);
            }

            int outer_shell_edgegroup = 100;

            foreach (GeneralPolygon2d shell in shell_polys)
            {
                PathOverlapRepair repair = new PathOverlapRepair();
                repair.OverlapRadius = SelfOverlapTolerance;
                repair.Add(shell, outer_shell_edgegroup);

                // Ideally want to presreve outermost shell of external perimeters.
                // However in many cases internal holes are 'too close' to outer border.
                // So we will still apply to those, but use edge filter to preserve outermost loop.
                // [TODO] could we be smarter about this somehow?
                if (PreserveOuterShells && nShell == 0)
                {
                    repair.PreserveEdgeFilterF = (eid) => { return(repair.Graph.GetEdgeGroup(eid) == outer_shell_edgegroup); }
                }
                ;

                repair.Compute();

                DGraph2Util.Curves c = DGraph2Util.ExtractCurves(repair.GetResultGraph());

                #region Borrow nesting calculations from PlanarSlice to enforce winding direction

                PlanarComplex complex = new PlanarComplex();
                foreach (Polygon2d poly in c.Loops)
                {
                    complex.Add(poly);
                }

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

                PlanarComplex.SolidRegionInfo solids = complex.FindSolidRegions(options);
                foreach (var polygon in solids.Polygons)
                {
                    polygon.EnforceCounterClockwise();
                    paths.Append(new FillLoop <FillSegment>(polygon.Outer.Vertices)
                    {
                        FillType       = currentFillType,
                        PerimeterOrder = nShell
                    });
                    foreach (var hole in polygon.Holes)
                    {
                        paths.Append(new FillLoop <FillSegment>(hole.Vertices)
                        {
                            FillType       = currentFillType,
                            PerimeterOrder = nShell,
                            IsHoleShell    = true,
                        });
                    }
                }

                #endregion Borrow nesting calculations from PlanarSlice to enforce winding direction

                foreach (var polyline in c.Paths)
                {
                    if (polyline.ArcLength < DiscardTinyPerimeterLengthMM)
                    {
                        continue;
                    }
                    if (polyline.Bounds.MaxDim < DiscardTinyPerimeterLengthMM)
                    {
                        continue;
                    }
                    paths.Append(new FillCurve <FillSegment>(polyline)
                    {
                        FillType = currentFillType, PerimeterOrder = nShell
                    });
                }
            }
            return(paths);
        }