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,
}
}
}