Fix edges not carrying over pre-computed information on clone
This commit is contained in:
parent
0431c3ca2e
commit
157deccc57
6 changed files with 60 additions and 67 deletions
|
@ -190,26 +190,22 @@ namespace Boprs
|
|||
public BooleanOperation(Region subject, Region clip, BoprType type)
|
||||
{
|
||||
List<SweepVertex> sortedVerts = new List<SweepVertex>();
|
||||
|
||||
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<SweepEdge> processed = ProcessEdges(sortedVerts);
|
||||
|
||||
|
||||
Result = BuildResult(processed, subject, type);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,9 +41,6 @@
|
|||
<Reference Include="acmgd">
|
||||
<HintPath>..\..\..\..\..\Program Files\Autodesk\AutoCAD 2024\acmgd.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="BrxMgd">
|
||||
<HintPath>..\..\..\..\..\Program Files\Bricsys\BricsCAD V23 en_US\BrxMgd.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
|
@ -52,9 +49,6 @@
|
|||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="TD_Mgd">
|
||||
<HintPath>..\..\..\..\..\Program Files\Bricsys\BricsCAD V23 en_US\TD_Mgd.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="BooleanOperation.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();
|
||||
|
|
80
Region.cs
80
Region.cs
|
@ -21,34 +21,34 @@ namespace Boprs
|
|||
public class Region
|
||||
{
|
||||
/// <summary>
|
||||
/// Vertices belonging to this polygon.
|
||||
/// Edges belonging to this polygon.
|
||||
/// </summary>
|
||||
private List<SweepVertex> Vertices { get; }
|
||||
private List<SweepEdge> Edges { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Subdivide my edges, set their inOut tags and validate their non-colinearity.
|
||||
/// </summary>
|
||||
private void ValidateEdges()
|
||||
private void SetEdges(List<SweepVertex> 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<SweepEdge> processed = new List<SweepEdge>();
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a copy of the regions vertex list.
|
||||
/// Get a copy of the regions edges list.
|
||||
/// </summary>
|
||||
/// <returns>Copy of the regions vertex list.</returns>
|
||||
internal List<LineSegment2d> GetSegments()
|
||||
/// <returns>Copy of the regions edges list.</returns>
|
||||
internal List<SweepEdge> GetEdgeCopies()
|
||||
{
|
||||
List <LineSegment2d> segments = new List<LineSegment2d>();
|
||||
List<SweepEdge> copies = new List<SweepEdge>();
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -126,48 +122,36 @@ namespace Boprs
|
|||
{
|
||||
Region region = new Region();
|
||||
|
||||
List<SweepVertex> vertices = new List<SweepVertex>();
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor.
|
||||
/// </summary>
|
||||
private Region()
|
||||
{
|
||||
Vertices = new List<SweepVertex>();
|
||||
}
|
||||
|
||||
#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
|
||||
|
|
16
SweepEdge.cs
16
SweepEdge.cs
|
@ -44,7 +44,7 @@ namespace Boprs
|
|||
/// <summary>
|
||||
/// Line segment (edge) used while a sweep line is processing a boolean operation.
|
||||
/// </summary>
|
||||
internal class SweepEdge
|
||||
internal class SweepEdge : ICloneable
|
||||
{
|
||||
/// <summary>
|
||||
/// 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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Comparison of edges.
|
||||
/// </summary>
|
||||
|
|
|
@ -18,7 +18,7 @@ namespace Boprs
|
|||
/// <summary>
|
||||
/// End point of an edge used while sweep line is processing a boolean operation.
|
||||
/// </summary>
|
||||
internal class SweepVertex : IComparable
|
||||
internal class SweepVertex : IComparable, ICloneable
|
||||
{
|
||||
/// <summary>
|
||||
/// 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};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Comparison of vertices.
|
||||
/// </summary>
|
||||
|
|
Loading…
Reference in a new issue