#if ACAD24
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Colors;
using AcAp = Autodesk.AutoCAD.ApplicationServices;
#elif BCAD
using Bricscad.EditorInput;
using Teigha.Geometry;
using Teigha.DatabaseServices;
using Teigha.Colors;
#endif
using System;
using System.Collections.Generic;
namespace Boprs
{
///
/// Geometric region used for boolean operations calculations.
///
public class Region
{
///
/// Vertices belonging to this polygon.
///
private List Vertices { get; }
///
/// Subdivide my edges, set their inOut tags and validate their non-colinearity.
///
private void ValidateEdges()
{
// Lexico-graphically sort my vertices.
Vertices.Sort();
// Sweepline to keep track of edges.
SweepLine sweepLine = new SweepLine();
// Current number of vertices in the list.
// Will be increased if subdivision occurs.
int numVertices = Vertices.Count;
// Go through all the sorted vertices, test for intersections when appropriate and,
// if needed, subdivide the edges.
for (int i = 0; i < numVertices; i++)
{
SweepVertex acVx = Vertices[i];
if (acVx.IsLeft())
{
sweepLine.Add(acVx.Edge, false);
SweepEdge prevEdge = sweepLine.PrevEdge(acVx.Edge);
SweepEdge nextEdge = sweepLine.NextEdge(acVx.Edge);
acVx.Edge.SetTransitionInside(prevEdge);
if (prevEdge != null)
{
List newVertices = acVx.Edge.TrySubdivideBy(prevEdge);
foreach (SweepVertex vertex in newVertices)
{
Utils.InsertVertexSorted(Vertices, vertex);
numVertices++;
}
}
if (nextEdge != null)
{
List newVertices = acVx.Edge.TrySubdivideBy(nextEdge);
foreach (SweepVertex vertex in newVertices)
{
Utils.InsertVertexSorted(Vertices, vertex);
numVertices++;
}
}
}
else
{
SweepEdge prevEdge = sweepLine.PrevEdge(acVx.Edge);
SweepEdge nextEdge = sweepLine.NextEdge(acVx.Edge);
sweepLine.Remove(acVx.Edge);
if (prevEdge != null && nextEdge != null)
{
List newVertices = prevEdge.TrySubdivideBy(nextEdge);
foreach (SweepVertex vertex in newVertices)
{
Utils.InsertVertexSorted(Vertices, vertex);
numVertices++;
}
}
}
}
}
///
/// Get a copy of the regions vertex list.
///
/// Copy of the regions vertex list.
internal List GetSegments()
{
List segments = new List();
foreach(SweepVertex sweepVertex in Vertices)
{
if (sweepVertex.IsLeft())
{
segments.Add(
new LineSegment2d(sweepVertex.Edge.LeftVertex.Point, sweepVertex.Edge.RightVertex.Point));
}
}
return segments;
}
///
/// Instantiate a region with edges defined by a list of given line segments.
///
///
///
public static Region FromSegments(List segments)
{
Region region = new Region();
foreach(LineSegment2d segment in segments)
{
SweepEdge newEdge = new SweepEdge(segment.StartPoint, segment.EndPoint);
region.Vertices.Add(newEdge.LeftVertex);
region.Vertices.Add(newEdge.RightVertex);
newEdge.ParentRegion = region;
}
region.ValidateEdges();
return region;
}
///
/// Constructor.
///
private Region()
{
Vertices = new List();
}
#if DEBUG
internal void Draw()
{
Erase();
foreach (SweepVertex vert in Vertices)
{
if (vert.IsLeft())
{
vert.Edge.Draw();
}
}
}
internal void Erase()
{
foreach (SweepVertex vert in Vertices)
{
if (vert.IsLeft())
{
vert.Edge.Erase();
}
}
}
#endif
}
}