using System; using System.Collections.Generic; using ProceduralToolkit.ClipperLib; using UnityEngine; namespace ProceduralToolkit { /// /// Clipper wrapper /// public class PathClipper { /// /// If set to true, polygons returned by clipping operations will have orientations opposite to their normal orientations. /// public bool reverseSolution { get => clipper.ReverseSolution; set => clipper.ReverseSolution = value; } /// /// If set to true, polygons returned by clipping operations will be strictly simple, otherwise they may be weakly simple. /// Computationally expensive. /// public bool strictlySimple { get => clipper.StrictlySimple; set => clipper.StrictlySimple = value; } /// /// If set to true, collinear vertices in input paths will not be removed before clipping. /// public bool preserveCollinear { get => clipper.PreserveCollinear; set => clipper.PreserveCollinear = value; } private readonly Clipper clipper; /// /// Constructs a new PathClipper /// /// A set of flags controlling the corresponding properties. public PathClipper(InitOptions initOptions = 0) { clipper = new Clipper((int) initOptions); } /// /// Adds a path to a Clipper object in preparation for clipping. /// /// Vertices of the path. /// Type of the path (Subject or Clip). /// Controls whether the path is closed. Clipping paths must always be closed. /// False if the path is invalid for clipping, true otherwise. public bool AddPath(IReadOnlyList path, PolyType polyType, bool closed = true) { return clipper.AddPath(ClipperUtility.ToIntPath(path), polyType, closed); } /// /// Adds a path to a Clipper object in preparation for clipping. /// /// Vertices of the path. /// Type of the path (Subject or Clip). /// Controls whether the path is closed. Clipping paths must always be closed. /// False if the path is invalid for clipping, true otherwise. public bool AddPath(List path, PolyType polyType, bool closed = true) { return clipper.AddPath(ClipperUtility.ToIntPath(path), polyType, closed); } /// /// Adds a path to a Clipper object in preparation for clipping. /// /// Vertices of the path. /// Type of the path (Subject or Clip). /// Controls whether the path is closed. Clipping paths must always be closed. /// False if the path is invalid for clipping, true otherwise. public bool AddPath(List path, PolyType polyType, bool closed = true) { return clipper.AddPath(path, polyType, closed); } /// /// Adds paths to a Clipper object in preparation for clipping. /// /// List of paths. /// Type of the path (Subject or Clip). /// Controls whether the path is closed. Clipping paths must always be closed. /// False if all paths are invalid for clipping, true otherwise. public bool AddPaths(List> paths, PolyType polyType, bool closed = true) { return clipper.AddPaths(ClipperUtility.ToIntPaths(paths), polyType, closed); } /// /// Adds paths to a Clipper object in preparation for clipping. /// /// List of paths. /// Type of the path (Subject or Clip). /// Controls whether the path is closed. Clipping paths must always be closed. /// False if all paths are invalid for clipping, true otherwise. public bool AddPaths(List> paths, PolyType polyType, bool closed = true) { return clipper.AddPaths(paths, polyType, closed); } /// /// Performs the clipping operation. /// Can be called multiple times without reassigning subject and clip polygons /// (ie when different clipping operations are required on the same polygon sets). /// /// Type of the clipping operation. /// The List that will receive the result of the clipping operation. /// Fill rule that will be applied to the paths. /// True if the operation was successful, false otherwise. public bool Clip(ClipType clipType, ref List> output, PolyFillType fillType = PolyFillType.pftEvenOdd) { return Clip(clipType, ref output, fillType, fillType); } /// /// Performs the clipping operation. /// Can be called multiple times without reassigning subject and clip polygons /// (ie when different clipping operations are required on the same polygon sets). /// /// Type of the clipping operation. /// The List that will receive the result of the clipping operation. /// Fill rule that will be applied to the subject paths. /// Fill rule that will be applied to the clip paths. /// True if the operation was successful, false otherwise. public bool Clip(ClipType clipType, ref List> output, PolyFillType subjectFillType, PolyFillType clipFillType) { var intOutput = new List>(); bool succeeded = clipper.Execute(clipType, intOutput, subjectFillType, clipFillType); ClipperUtility.ToVector2Paths(intOutput, ref output); return succeeded; } /// /// Performs the clipping operation. /// Can be called multiple times without reassigning subject and clip polygons /// (ie when different clipping operations are required on the same polygon sets). /// /// Type of the clipping operation. /// The List that will receive the result of the clipping operation. /// Fill rule that will be applied to the paths. /// True if the operation was successful, false otherwise. public bool Clip(ClipType clipType, ref List> output, PolyFillType fillType = PolyFillType.pftEvenOdd) { return Clip(clipType, ref output, fillType, fillType); } /// /// Performs the clipping operation. /// Can be called multiple times without reassigning subject and clip polygons /// (ie when different clipping operations are required on the same polygon sets). /// /// Type of the clipping operation. /// The List that will receive the result of the clipping operation. /// Fill rule that will be applied to the subject paths. /// Fill rule that will be applied to the clip paths. /// True if the operation was successful, false otherwise. public bool Clip(ClipType clipType, ref List> output, PolyFillType subjectFillType, PolyFillType clipFillType) { return clipper.Execute(clipType, output, subjectFillType, clipFillType); } /// /// Performs the clipping operation. /// Can be called multiple times without reassigning subject and clip polygons /// (ie when different clipping operations are required on the same polygon sets). /// /// Type of the clipping operation. /// The PolyTree that will receive the result of the clipping operation. /// Fill rule that will be applied to the paths. /// True if the operation was successful, false otherwise. public bool Clip(ClipType clipType, ref PolyTree output, PolyFillType fillType = PolyFillType.pftEvenOdd) { return Clip(clipType, ref output, fillType, fillType); } /// /// Performs the clipping operation. /// Can be called multiple times without reassigning subject and clip polygons /// (ie when different clipping operations are required on the same polygon sets). /// /// Type of the clipping operation. /// The PolyTree that will receive the result of the clipping operation. /// Fill rule that will be applied to the subject paths. /// Fill rule that will be applied to the clip paths. /// True if the operation was successful, false otherwise. public bool Clip(ClipType clipType, ref PolyTree output, PolyFillType subjectFillType, PolyFillType clipFillType) { return clipper.Execute(clipType, output, subjectFillType, clipFillType); } /// /// Clears all paths from the Clipper object, allowing new paths to be assigned. /// public void Clear() { clipper.Clear(); } [Flags] public enum InitOptions : int { ReverseSolution = 1, StrictlySimple = 2, PreserveCollinear = 4, } } }