I have a Space object in AutoCAD Architecture and I need to extract its contour to export to another data format. The problems appear when the Space object has "holes". I also don't know how to calculate the points on an arc.
A profile is simply a collection of closed outlines called Ring, which is defined in 2D. The first one is the outer most ring. Others are holes in the profile. To obtain the profile information, follow the steps:
In case a segment is an arc, you can get bulge information from each segment or use EvaluatePoint() method to obtain a point on an arc if needed. Below is a sample code written in VB.NET that demonstrates this.
'' first, get the basic objects
Dim ed As Editor = Application.DocumentManager.MdiActiveDocument.Editor
Dim db As Database = HostApplicationServices.WorkingDatabase
Dim tm As TransactionManager = db.TransactionManager
Dim tr As Transaction = tm.StartTransaction()
'' select a space
Dim selOpt As New Autodesk.AutoCAD.EditorInput.PromptEntityOptions("Select a space")
selOpt.SetRejectMessage("Not a space")
selOpt.AddAllowedClass(GetType(Space), True)
Dim selRes As PromptEntityResult = ed.GetEntity(selOpt)
If selRes.Status <> PromptStatus.OK Then
ed.WriteMessage("failed to get a space")
Exit Sub
End If
'' we got a space. Open it for read.
Dim pSpace As Space = tr.GetObject(selRes.ObjectId, AcDb2.OpenMode.ForRead)
Try
'' get a base profile
Dim pProfile As Profile = pSpace.BaseProfile
Dim ecsEnt As Matrix3d = pSpace.Ecs
'' loop through the rings. The first one is outer most rings.
For Each aRing As Ring In pProfile.Rings
For Each aSeg As Segment2d In aRing.Segments
'' once you come to this point,
'' you can get information about each line segment.
'' here we draw a temporary drawings. see the helper function below.
displaySegment(aSeg, ecsEnt)
Next
Next
tr.Commit()
Catch ex As Exception
ed.WriteMessage("Error in ShowSpaceProfile: " + ex.Message + vbLf)
tr.Abort()
Finally
tr.Dispose()
End Try
End Sub
'' a helper function to display a segment in a temporary graphics
Sub displaySegment(ByVal aSeg As Segment2d, ByVal ecsEnt As Matrix3d)
Dim ed As Editor = Application.DocumentManager.MdiActiveDocument.Editor
Dim pt1 As New Point3d(aSeg.StartPoint.X, aSeg.StartPoint.Y, 0.0)
Dim pt2 As New Point3d(aSeg.EndPoint.X, aSeg.EndPoint.Y, 0.0)
pt1 = pt1.TransformBy(ecsEnt)
'' draw a temporary graphics depending on if the given a segment is a line or curve.
'' if you have an arc, you can use bulge, or evaluate sub-divided points.
If aSeg.IsCurveCircularArc2d Then
Dim n As Integer = 10 '' number of divisions to draw arc as a collection of lines.
Dim dt As Double = (aSeg.EndParameter - aSeg.StartParameter) / n
For i As Integer = 1 To n
Dim pt As Point2d = aSeg.EvaluatePoint(i * dt)
pt2 = New Point3d(pt.X, pt.Y, 0.0)
pt2 = pt2.TransformBy(ecsEnt)
ed.DrawVector(pt1, pt2, 1, True)
pt1 = pt2
Next
Else
pt2 = pt2.TransformBy(ecsEnt)
ed.DrawVector(pt1, pt2, 5, True)
End If
End Sub