using System.Collections.Generic; using ProceduralToolkit.ClipperLib; using UnityEngine; namespace ProceduralToolkit { /// /// ClipperOffset wrapper /// public class PathOffsetter { /// /// Maximum distance in multiples of delta that vertices can be offset from their original positions before squaring is applied. /// Only relevant when JoinType = jtMiter. /// public double arcTolerance { get => clipperOffset.ArcTolerance; set => clipperOffset.ArcTolerance = value; } /// /// Maximum acceptable imprecision when arcs are approximated in an offsetting operation. /// Only relevant when JoinType = jtRound and/or EndType = etRound. /// public double miterLimit { get => clipperOffset.MiterLimit; set => clipperOffset.MiterLimit = value; } private readonly ClipperOffset clipperOffset; /// /// Constructs a new PathOffsetter /// /// /// Maximum distance in multiples of delta that vertices can be offset from their original positions before squaring is applied. /// Only relevant when JoinType = jtMiter. /// /// /// Maximum acceptable imprecision when arcs are approximated in an offsetting operation. /// Only relevant when JoinType = jtRound and/or EndType = etRound. /// public PathOffsetter(double miterLimit = 2.0, double arcTolerance = 0.25) { clipperOffset = new ClipperOffset(miterLimit, arcTolerance); } /// /// Adds a path to a ClipperOffset object in preparation for offsetting. /// /// Vertices of the path. /// See http://www.angusj.com/delphi/clipper/documentation/Docs/Units/ClipperLib/Types/JoinType.htm /// See http://www.angusj.com/delphi/clipper/documentation/Docs/Units/ClipperLib/Types/EndType.htm public void AddPath(IReadOnlyList path, JoinType joinType = JoinType.jtMiter, EndType endType = EndType.etClosedPolygon) { clipperOffset.AddPath(ClipperUtility.ToIntPath(path), joinType, endType); } /// /// Adds a path to a ClipperOffset object in preparation for offsetting. /// /// Vertices of the path. /// See http://www.angusj.com/delphi/clipper/documentation/Docs/Units/ClipperLib/Types/JoinType.htm /// See http://www.angusj.com/delphi/clipper/documentation/Docs/Units/ClipperLib/Types/EndType.htm public void AddPath(List path, JoinType joinType = JoinType.jtMiter, EndType endType = EndType.etClosedPolygon) { clipperOffset.AddPath(ClipperUtility.ToIntPath(path), joinType, endType); } /// /// Adds a path to a ClipperOffset object in preparation for offsetting. /// /// Vertices of the path. /// See http://www.angusj.com/delphi/clipper/documentation/Docs/Units/ClipperLib/Types/JoinType.htm /// See http://www.angusj.com/delphi/clipper/documentation/Docs/Units/ClipperLib/Types/EndType.htm public void AddPath(List path, JoinType joinType = JoinType.jtMiter, EndType endType = EndType.etClosedPolygon) { clipperOffset.AddPath(path, joinType, endType); } /// /// Adds paths to a ClipperOffset object in preparation for offsetting. /// /// List of paths. /// See http://www.angusj.com/delphi/clipper/documentation/Docs/Units/ClipperLib/Types/JoinType.htm /// See http://www.angusj.com/delphi/clipper/documentation/Docs/Units/ClipperLib/Types/EndType.htm public void AddPaths(List> paths, JoinType joinType = JoinType.jtMiter, EndType endType = EndType.etClosedPolygon) { clipperOffset.AddPaths(ClipperUtility.ToIntPaths(paths), joinType, endType); } /// /// Adds paths to a ClipperOffset object in preparation for offsetting. /// /// List of paths. /// See http://www.angusj.com/delphi/clipper/documentation/Docs/Units/ClipperLib/Types/JoinType.htm /// See http://www.angusj.com/delphi/clipper/documentation/Docs/Units/ClipperLib/Types/EndType.htm public void AddPaths(List> paths, JoinType joinType = JoinType.jtMiter, EndType endType = EndType.etClosedPolygon) { clipperOffset.AddPaths(paths, joinType, endType); } /// /// Performs the offset operation. /// Can be called multiple times, offsetting the same paths by different amounts (ie using different deltas). /// /// The List that will receive the result of the offset operation. /// /// The amount to which the supplied paths will be offset. /// Positive values expand polygons and negative values shrink them. /// Scaled by . /// public void Offset(ref List> output, double delta) { var intOutput = new List>(); clipperOffset.Execute(ref intOutput, delta*ClipperUtility.ClipperScale); ClipperUtility.ToVector2Paths(intOutput, ref output); } /// /// Performs the offset operation. /// Can be called multiple times, offsetting the same paths by different amounts (ie using different deltas). /// /// The List that will receive the result of the offset operation. /// /// The amount to which the supplied paths will be offset. /// Positive values expand polygons and negative values shrink them. /// Not scaled. /// public void Offset(ref List> output, double delta) { clipperOffset.Execute(ref output, delta); } /// /// Performs the offset operation. /// Can be called multiple times, offsetting the same paths by different amounts (ie using different deltas). /// /// The PolyTree that will receive the result of the offset operation. /// /// The amount to which the supplied paths will be offset. /// Positive values expand polygons and negative values shrink them. /// Not scaled. /// public void Offset(ref PolyTree output, double delta) { clipperOffset.Execute(ref output, delta); } /// /// Clears all paths from the ClipperOffset object, allowing new paths to be assigned. /// public void Clear() { clipperOffset.Clear(); } } }