diff --git a/Boprs.csproj b/Boprs.csproj
index ef2c67c..34f83ee 100644
--- a/Boprs.csproj
+++ b/Boprs.csproj
@@ -18,7 +18,7 @@
full
false
bin\Debug\
- TRACE;DEBUG;ACAD24
+ TRACE;DEBUG;BCAD
prompt
4
@@ -41,6 +41,9 @@
..\..\..\..\..\Program Files\Autodesk\AutoCAD 2024\acmgd.dll
+
+ ..\..\..\..\..\Program Files\Bricsys\BricsCAD V24 en_US\BrxMgd.dll
+
@@ -49,10 +52,14 @@
+
+ ..\..\..\..\..\Program Files\Bricsys\BricsCAD V24 en_US\TD_Mgd.dll
+
+
diff --git a/Commands.cs b/Commands.cs
index 9bfb292..2519f9d 100644
--- a/Commands.cs
+++ b/Commands.cs
@@ -55,6 +55,8 @@ namespace Boprs
segs.Add(new LineSegment2d(asLine.StartPoint.To2d(), asLine.EndPoint.To2d()));
}
}
+
+ asPoly.Erase();
}
acTrans.Commit();
}
diff --git a/Contour.cs b/Contour.cs
new file mode 100644
index 0000000..50f9432
--- /dev/null
+++ b/Contour.cs
@@ -0,0 +1,84 @@
+#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;
+using AcAp = Bricscad.ApplicationServices;
+#endif
+using System;
+using System.Collections.Generic;
+
+namespace Boprs
+{
+ ///
+ /// Simple closed polygon.
+ ///
+ public class Contour
+ {
+ ///
+ /// Parent of this contour, null if external.
+ ///
+ public Contour Parent { get; internal set; }
+
+ ///
+ /// Vertices of the contour.
+ ///
+ public List Vertices { get; }
+
+ ///
+ /// Are the vertices of the contour arranged in clockwise manner?
+ ///
+ /// true if the contour is clockwise, false if counter-clockwise.
+ public bool IsClockwise()
+ {
+ throw new NotImplementedException();
+ }
+
+ ///
+ /// Reverse the orientation of the contour.
+ ///
+ public void Reverse()
+ {
+ throw new NotImplementedException();
+ }
+
+ ///
+ /// Constructor.
+ ///
+ public Contour()
+ {
+ Vertices = new List();
+ }
+
+#if DEBUG
+ internal void Draw(Color color = null)
+ {
+ AcAp.Document acDoc = AcAp.Application.DocumentManager.MdiActiveDocument;
+ Database acDb = acDoc.Database;
+
+ using (Transaction acTrans = acDb.TransactionManager.StartTransaction())
+ {
+ // Open the BlockTableRecord
+ BlockTable acBlkTbl = (BlockTable)acTrans.GetObject(acDb.BlockTableId, OpenMode.ForRead);
+ BlockTableRecord acBlkTblRec =
+ (BlockTableRecord)acTrans.GetObject(acBlkTbl[BlockTableRecord.ModelSpace], OpenMode.ForWrite);
+
+ for(int i = 0; i < Vertices.Count; i++)
+ {
+ Line asLine = new Line(Vertices[i].To3d(), Vertices[(i + 1) % Vertices.Count].To3d());
+ acBlkTblRec.AppendEntity(asLine);
+ acTrans.AddNewlyCreatedDBObject(asLine, true);
+ }
+
+ acTrans.Commit();
+ }
+ }
+#endif
+ }
+}
diff --git a/Region.cs b/Region.cs
index df3cf53..a4ed208 100644
--- a/Region.cs
+++ b/Region.cs
@@ -25,6 +25,8 @@ namespace Boprs
///
private List Edges { get; set; }
+ private List Contours { get; set; }
+
///
/// Subdivide my edges, set their inOut tags and validate their non-colinearity.
///
@@ -97,6 +99,105 @@ namespace Boprs
Edges = processed;
}
+ ///
+ /// Find the index of an un-processed vertex with the same position as the one on specified index.
+ ///
+ /// Index of the current vertex.
+ /// List of vertices.
+ /// Mask for processed vertices.
+ /// Index of an unprocessed neighbour with the same position.
+ private int NextPos(int pos, List vertices, bool[] processed)
+ {
+ int newPos = pos + 1;
+ while(newPos < vertices.Count && Utils.DoubleEquals(vertices[pos].Point.GetDistanceTo(vertices[newPos].Point), 0))
+ {
+ if (!processed[newPos])
+ {
+ return newPos;
+ }
+ else
+ {
+ newPos++;
+ }
+ }
+ newPos = pos - 1;
+ while (newPos >= 0 && Utils.DoubleEquals(vertices[pos].Point.GetDistanceTo(vertices[newPos].Point), 0))
+ {
+ if (!processed[newPos])
+ {
+ return newPos;
+ }
+ else
+ {
+ newPos--;
+ }
+ }
+ throw new Exception("Hit contour dead end (non-connected edge).");
+ }
+
+ ///
+ /// Compute my closed contours.
+ ///
+ private void ComputeContours()
+ {
+ // Gather all vertices of the region.
+ List vertices = new List();
+ foreach (SweepEdge edge in Edges)
+ {
+ vertices.Add(edge.LeftVertex);
+ vertices.Add(edge.RightVertex);
+ }
+
+ // Lexico-graphically sort the vertices.
+ vertices.Sort();
+
+ // Sweepline to keep track of edges.
+ SweepLine sweepLine = new SweepLine();
+
+ bool[] processed = new bool[vertices.Count];
+ List contours = new List();
+
+ for(int i = 0; i < vertices.Count; i++)
+ {
+ SweepVertex acVx = vertices[i];
+
+ if (acVx.IsLeft())
+ {
+ sweepLine.Add(acVx.Edge, false);
+ }
+ else
+ {
+ sweepLine.Remove(acVx.Edge);
+ }
+
+ if (processed[i])
+ {
+ continue;
+ }
+ processed[i] = true;
+
+ // We should be guaranteed to always hit left endpoint leading us on a counter clockwise path.
+ Contour contour = new Contour();
+ contours.Add(contour);
+
+ Point2d target = acVx.Point;
+
+ int pos = i;
+ while (!Utils.DoubleEquals(vertices[pos].OtherVertex().Point.GetDistanceTo(target), 0))
+ {
+ int otherPos = vertices.IndexOf(vertices[pos].OtherVertex());
+ pos = NextPos(otherPos, vertices, processed);
+
+ contour.Vertices.Add(vertices[pos].Point);
+ processed[pos] = true;
+
+ processed[otherPos] = true;
+ }
+ processed[vertices.IndexOf(vertices[pos].OtherVertex())] = true;
+ }
+ Contours = contours;
+ }
+
///
/// Get a copy of the regions edges list.
///
@@ -113,6 +214,15 @@ namespace Boprs
return copies;
}
+ ///
+ /// Get a copy of the contours of the polygon.
+ ///
+ /// List of copies of the regions contours.
+ public List GetContourCopies()
+ {
+ throw new NotImplementedException();
+ }
+
///
/// Instantiate a region with edges defined by a list of given line segments.
///
@@ -133,6 +243,7 @@ namespace Boprs
}
region.SetEdges(vertices);
+ region.ComputeContours();
return region;
}
@@ -140,18 +251,9 @@ namespace Boprs
#if DEBUG
internal void Draw()
{
- Erase();
-
- foreach (SweepEdge edge in Edges)
+ foreach (Contour contour in Contours)
{
- edge.Draw();
- }
- }
- internal void Erase()
- {
- foreach (SweepEdge edge in Edges)
- {
- edge.Erase();
+ contour.Draw();
}
}
#endif
diff --git a/SweepVertex.cs b/SweepVertex.cs
index 6ee687b..59290d4 100644
--- a/SweepVertex.cs
+++ b/SweepVertex.cs
@@ -119,6 +119,15 @@ namespace Boprs
return this == Edge.LeftVertex;
}
+ ///
+ /// Returns the other vertex associated with my edge.
+ ///
+ /// Other vertex of my edge.
+ internal SweepVertex OtherVertex()
+ {
+ return IsLeft() ? Edge.RightVertex : Edge.LeftVertex;
+ }
+
///
/// Constructor.
///