From 157deccc577397eaf509ecc5cdb71e0caf642675 Mon Sep 17 00:00:00 2001 From: borovec zdenek Date: Mon, 2 Sep 2024 10:08:52 +0200 Subject: [PATCH] Fix edges not carrying over pre-computed information on clone --- BooleanOperation.cs | 14 +++----- Boprs.csproj | 6 ---- Commands.cs | 4 +-- Region.cs | 80 ++++++++++++++++++--------------------------- SweepEdge.cs | 16 ++++++++- SweepVertex.cs | 7 +++- 6 files changed, 60 insertions(+), 67 deletions(-) diff --git a/BooleanOperation.cs b/BooleanOperation.cs index bc4166c..30be8fc 100644 --- a/BooleanOperation.cs +++ b/BooleanOperation.cs @@ -190,26 +190,22 @@ namespace Boprs public BooleanOperation(Region subject, Region clip, BoprType type) { List sortedVerts = new List(); - - foreach (LineSegment2d seg in subject.GetSegments()) + + foreach (SweepEdge edge in subject.GetEdgeCopies()) { - SweepEdge edge = new SweepEdge(seg.StartPoint, seg.EndPoint); - sortedVerts.Add(edge.LeftVertex); sortedVerts.Add(edge.RightVertex); } - foreach (LineSegment2d seg in clip.GetSegments()) + foreach (SweepEdge edge in clip.GetEdgeCopies()) { - SweepEdge edge = new SweepEdge(seg.StartPoint, seg.EndPoint); - sortedVerts.Add(edge.LeftVertex); sortedVerts.Add(edge.RightVertex); } - + sortedVerts.Sort(); List processed = ProcessEdges(sortedVerts); - + Result = BuildResult(processed, subject, type); } } diff --git a/Boprs.csproj b/Boprs.csproj index 6d59f07..ef2c67c 100644 --- a/Boprs.csproj +++ b/Boprs.csproj @@ -41,9 +41,6 @@ ..\..\..\..\..\Program Files\Autodesk\AutoCAD 2024\acmgd.dll - - ..\..\..\..\..\Program Files\Bricsys\BricsCAD V23 en_US\BrxMgd.dll - @@ -52,9 +49,6 @@ - - ..\..\..\..\..\Program Files\Bricsys\BricsCAD V23 en_US\TD_Mgd.dll - diff --git a/Commands.cs b/Commands.cs index 4b9226e..9bfb292 100644 --- a/Commands.cs +++ b/Commands.cs @@ -96,7 +96,7 @@ namespace Boprs AcAp.Document acDoc = AcAp.Application.DocumentManager.MdiActiveDocument; Region subject = UserCreateRegion("Enter polylines for first polygon:"); - + Region clip = UserCreateRegion("Enter polylines for second polygon:"); if(subject == null || clip == null) @@ -106,7 +106,7 @@ namespace Boprs } BoprType type = UserChooseBoprType(); - + BooleanOperation bopr = new BooleanOperation(subject, clip, type); bopr.Result.Draw(); diff --git a/Region.cs b/Region.cs index 02fff67..df3cf53 100644 --- a/Region.cs +++ b/Region.cs @@ -21,34 +21,34 @@ namespace Boprs public class Region { /// - /// Vertices belonging to this polygon. + /// Edges belonging to this polygon. /// - private List Vertices { get; } + private List Edges { get; set; } /// /// Subdivide my edges, set their inOut tags and validate their non-colinearity. /// - private void ValidateEdges() + private void SetEdges(List vertices) { // Lexico-graphically sort my vertices. - Vertices.Sort(); + 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; + // 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. - for (int i = 0; i < numVertices; i++) + while (vertices.Count != 0) { - SweepVertex acVx = Vertices[i]; + SweepVertex acVx = vertices[0]; + vertices.RemoveAt(0); if (acVx.IsLeft()) { - sweepLine.Add(acVx.Edge, false); + sweepLine.Add(acVx.Edge, true); SweepEdge prevEdge = sweepLine.PrevEdge(acVx.Edge); SweepEdge nextEdge = sweepLine.NextEdge(acVx.Edge); @@ -61,8 +61,7 @@ namespace Boprs foreach (SweepVertex vertex in newVertices) { - Utils.InsertVertexSorted(Vertices, vertex); - numVertices++; + Utils.InsertVertexSorted(vertices, vertex); } } if (nextEdge != null) @@ -71,8 +70,7 @@ namespace Boprs foreach (SweepVertex vertex in newVertices) { - Utils.InsertVertexSorted(Vertices, vertex); - numVertices++; + Utils.InsertVertexSorted(vertices, vertex); } } } @@ -82,6 +80,7 @@ namespace Boprs SweepEdge nextEdge = sweepLine.NextEdge(acVx.Edge); sweepLine.Remove(acVx.Edge); + processed.Add(acVx.Edge); if (prevEdge != null && nextEdge != null) { @@ -89,32 +88,29 @@ namespace Boprs foreach (SweepVertex vertex in newVertices) { - Utils.InsertVertexSorted(Vertices, vertex); - numVertices++; + Utils.InsertVertexSorted(vertices, vertex); } } } } + + Edges = processed; } /// - /// Get a copy of the regions vertex list. + /// Get a copy of the regions edges list. /// - /// Copy of the regions vertex list. - internal List GetSegments() + /// Copy of the regions edges list. + internal List GetEdgeCopies() { - List segments = new List(); + List copies = new List(); - foreach(SweepVertex sweepVertex in Vertices) + foreach (SweepEdge edge in Edges) { - if (sweepVertex.IsLeft()) - { - segments.Add( - new LineSegment2d(sweepVertex.Edge.LeftVertex.Point, sweepVertex.Edge.RightVertex.Point)); - } + copies.Add((SweepEdge)edge.Clone()); } - return segments; + return copies; } /// @@ -126,48 +122,36 @@ namespace Boprs { Region region = new Region(); + List vertices = new List(); + foreach(LineSegment2d segment in segments) { SweepEdge newEdge = new SweepEdge(segment.StartPoint, segment.EndPoint); - region.Vertices.Add(newEdge.LeftVertex); - region.Vertices.Add(newEdge.RightVertex); + vertices.Add(newEdge.LeftVertex); + vertices.Add(newEdge.RightVertex); newEdge.ParentRegion = region; } - region.ValidateEdges(); + region.SetEdges(vertices); return region; } - /// - /// Constructor. - /// - private Region() - { - Vertices = new List(); - } - #if DEBUG internal void Draw() { Erase(); - foreach (SweepVertex vert in Vertices) + foreach (SweepEdge edge in Edges) { - if (vert.IsLeft()) - { - vert.Edge.Draw(); - } + edge.Draw(); } } internal void Erase() { - foreach (SweepVertex vert in Vertices) + foreach (SweepEdge edge in Edges) { - if (vert.IsLeft()) - { - vert.Edge.Erase(); - } + edge.Erase(); } } #endif diff --git a/SweepEdge.cs b/SweepEdge.cs index ab8b512..cbd329d 100644 --- a/SweepEdge.cs +++ b/SweepEdge.cs @@ -44,7 +44,7 @@ namespace Boprs /// /// Line segment (edge) used while a sweep line is processing a boolean operation. /// - internal class SweepEdge + internal class SweepEdge : ICloneable { /// /// String representation of the edge. @@ -54,6 +54,20 @@ namespace Boprs return ($"({LeftVertex} -- {RightVertex})"); } + public object Clone() + { + SweepVertex left = (SweepVertex)LeftVertex.Clone(); + SweepVertex right = (SweepVertex)RightVertex.Clone(); + SweepEdge clone = new SweepEdge(LeftVertex, RightVertex) + { + TransitionInside = TransitionInside, + InsideOther = InsideOther, + Type = Type, + ParentRegion = ParentRegion, + }; + return clone; + } + /// /// Comparison of edges. /// diff --git a/SweepVertex.cs b/SweepVertex.cs index ff80d0c..6ee687b 100644 --- a/SweepVertex.cs +++ b/SweepVertex.cs @@ -18,7 +18,7 @@ namespace Boprs /// /// End point of an edge used while sweep line is processing a boolean operation. /// - internal class SweepVertex : IComparable + internal class SweepVertex : IComparable, ICloneable { /// /// String representation of the vertex. @@ -28,6 +28,11 @@ namespace Boprs return ($"({Point.X}, {Point.Y})"); } + public object Clone() + { + return new SweepVertex(Point) { Edge = Edge}; + } + /// /// Comparison of vertices. ///