protected virtual List <PolyLine2d> ApplyValidRegions(List <PolyLine2d> plinesIn) { if (ValidRegions == null || ValidRegions.Count == 0) { return(plinesIn); } List <PolyLine2d> clipped = new List <PolyLine2d>(); foreach (var pline in plinesIn) { clipped.AddRange(ClipperUtil.ClipAgainstPolygon(ValidRegions, pline, true)); } return(clipped); }
/// <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); } }