#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 { /// /// Edges belonging to this polygon. /// private List Edges { get; set; } /// /// Subdivide my edges, set their inOut tags and validate their non-colinearity. /// private void SetEdges(List vertices) { // Lexico-graphically sort my vertices. vertices.Sort(); // Sweepline to keep track of edges. SweepLine sweepLine = new SweepLine(); // Processed edges will be moved here. List processed = new List(); // Go through all the sorted vertices, test for intersections when appropriate and, // if needed, subdivide the edges. while (vertices.Count != 0) { SweepVertex acVx = vertices[0]; vertices.RemoveAt(0); if (acVx.IsLeft()) { sweepLine.Add(acVx.Edge, true); 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); } } if (nextEdge != null) { List newVertices = acVx.Edge.TrySubdivideBy(nextEdge); foreach (SweepVertex vertex in newVertices) { Utils.InsertVertexSorted(vertices, vertex); } } } else { SweepEdge prevEdge = sweepLine.PrevEdge(acVx.Edge); SweepEdge nextEdge = sweepLine.NextEdge(acVx.Edge); sweepLine.Remove(acVx.Edge); processed.Add(acVx.Edge); if (prevEdge != null && nextEdge != null) { List newVertices = prevEdge.TrySubdivideBy(nextEdge); foreach (SweepVertex vertex in newVertices) { Utils.InsertVertexSorted(vertices, vertex); } } } } Edges = processed; } /// /// Get a copy of the regions edges list. /// /// Copy of the regions edges list. internal List GetEdgeCopies() { List copies = new List(); foreach (SweepEdge edge in Edges) { copies.Add((SweepEdge)edge.Clone()); } return copies; } /// /// Instantiate a region with edges defined by a list of given line segments. /// /// /// public static Region FromSegments(List segments) { Region region = new Region(); List vertices = new List(); foreach(LineSegment2d segment in segments) { SweepEdge newEdge = new SweepEdge(segment.StartPoint, segment.EndPoint); vertices.Add(newEdge.LeftVertex); vertices.Add(newEdge.RightVertex); newEdge.ParentRegion = region; } region.SetEdges(vertices); return region; } #if DEBUG internal void Draw() { Erase(); foreach (SweepEdge edge in Edges) { edge.Draw(); } } internal void Erase() { foreach (SweepEdge edge in Edges) { edge.Erase(); } } #endif } }