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. ///