Namespace BRepSamples
Public NotInheritable Class Containment
Private Sub New()
End Sub
'' <summary>
''
'' This sample shows how to use the BREP API to do
'' simple topographical point/boundary classification
'' on regions.
''
'' This code requires a reference to AcDbMgdBrep.dll
''
'' The sample prompts for a region object; gets a BRep
'' object representing the region; and then repeatedly
'' prompts for points, and computes and displays the
'' containment (inside, outside, or on an edge) of each
'' selected point.
''
'' A point within an inner loop is considered to be
'' 'ouside' the region's area, and so if you perform
'' this operation on a complex region with inner loops,
'' points contained within an inner loop will yield a
'' result of PointContainment.Outside.
'
'' This is the most robust means of determining if a
'' point lies within the implied boundary formed by a
'' collection of AutoCAD entites that can be used to
'' create a valid AutoCAD Region object, and is the
'' preferred means of doing simple point containment
'' testing.
''
'' You can adapt this code to perform containment tests
'' on various AutoCAD entities such as closed polylines,
'' splines, ellipses, etc., by generating a region from
'' the closed geometry, using it to do the containment
'' test, and then disposing it without having to add it
'' to a database.
''
'' Note that the sample code was designed to work with
'' regions that lie in the WCS XY plane and points that
'' lie in the same plane.
''
'' </summary>
<CommandMethod("CONTAINMENT")> _
Public Shared Sub ContainmentCommand()
Dim ed As Editor = Application.DocumentManager.MdiActiveDocument.Editor
Dim id As ObjectId = GetRegion(ed, vbLf & "Select a region: ")
If Not id.IsNull Then
Using tr As Transaction = ed.Document.TransactionManager.StartTransaction()
Try
Dim region As Region = TryCast(id.GetObject(OpenMode.ForRead), Region)
Dim ppo As New PromptPointOptions(vbLf & "Select a point: ")
ppo.AllowNone = True
While True
' loop while user continues to pick points
'' Get a point from user:
Dim ppr As PromptPointResult = ed.GetPoint(ppo)
If ppr.Status <> PromptStatus.OK Then
' no point was selected, exit
Exit While
End If
' use the GetPointContainment helper method below to
' get the PointContainment of the selected point:
Dim containment As PointContainment = GetPointContainment(region, ppr.Value)
' Display the result:
ed.WriteMessage(containment.ToString())
End While
Finally
tr.Commit()
End Try
End Using
End If
End Sub
'' <summary>
''
'' This variation performs point contianment testing
'' against any closed curve from which a simple region
' (e.g., no inner-loops) can be genreated, using the
'' Region.CreateFromCurves() API.
''
'' </summary>
<CommandMethod("CURVECONTAINMENT")> _
Public Shared Sub CurveContainmentCommand()
Dim ed As Editor = Application.DocumentManager.MdiActiveDocument.Editor
Dim id As ObjectId = GetCurve(ed, vbLf & "Select a closed Curve: ")
If Not id.IsNull Then
Using tr As Transaction = ed.Document.TransactionManager.StartTransaction()
Try
Dim curve As Curve = DirectCast(id.GetObject(OpenMode.ForRead), Curve)
If Not curve.Closed Then
ed.WriteMessage(vbLf & "Invalid selection, requires a CLOSED curve")
Return
End If
Using region As Region = RegionFromClosedCurve(curve)
Dim ppo As New PromptPointOptions(vbLf & "Select a point: ")
ppo.AllowNone = True
While True
' loop while user continues to pick points
'' Get a point from user:
Dim ppr As PromptPointResult = ed.GetPoint(ppo)
If ppr.Status <> PromptStatus.OK Then
' no point was selected, exit
Exit While
End If
' use the GetPointContainment helper method below to
' get the PointContainment of the selected point:
Dim containment As PointContainment = GetPointContainment(region, ppr.Value)
' Display the result:
ed.WriteMessage(containment.ToString())
End While
End Using
Finally
tr.Commit()
End Try
End Using
End If
End Sub
' this helper method takes a Region and a Point3d that must be
' in the plane of the region, and returns the PointContainment
' of the given point, adjusted to correctly indicate its actual
' relationship to the region (inside/on boundary edge/outside).
Public Shared Function GetPointContainment(region As Region, point As Point3d) As PointContainment
Dim result As PointContainment = PointContainment.Outside
'' Get a Brep object representing the region:
Using brep As New Brep(region)
If brep IsNot Nothing Then
' Get the PointContainment and the BrepEntity at the given point:
Using ent As BrepEntity = brep.GetPointContainment(point, result)
' GetPointContainment() returns PointContainment.OnBoundary
' when the picked point is either inside the region's area
'' or exactly on an edge.
'
'' So, to distinguish between a point on an edge and a point
'' inside the region, we must check the type of the returned
'' BrepEntity:
''
'' If the picked point was on an edge, the returned BrepEntity
'' will be an Edge object. If the point was inside the boundary,
'' the returned BrepEntity will be a Face object.
'' So if the returned BrepEntity's type is a Face, we return
'' PointContainment.Inside:
If TypeOf ent Is Autodesk.AutoCAD.BoundaryRepresentation.Face Then
result = PointContainment.Inside
End If
End Using
End If
End Using
Return result
End Function
Public Shared Function RegionFromClosedCurve(curve As Curve) As Region
If Not curve.Closed Then
Throw New ArgumentException("Curve must be closed.")
End If
Dim curves As New DBObjectCollection()
curves.Add(curve)
Using regions As DBObjectCollection = Region.CreateFromCurves(curves)
If regions Is Nothing OrElse regions.Count = 0 Then
Throw New InvalidOperationException("Failed to create regions")
End If
If regions.Count > 1 Then
Throw New InvalidOperationException("Multiple regions created")
End If
Return regions.Cast(Of Region)().First()
End Using
End Function
Public Shared Function GetPointContainment(curve As Curve, point As Point3d) As PointContainment
If Not curve.Closed Then
Throw New ArgumentException("Curve must be closed.")
End If
Dim region As Region = RegionFromClosedCurve(curve)
If region Is Nothing Then
Throw New InvalidOperationException("Failed to create region")
End If
Using region
Return GetPointContainment(region, point)
End Using
End Function
Public Shared Function GetCurve(editor As Editor, msg As String) As ObjectId
Dim peo As New PromptEntityOptions(msg)
peo.SetRejectMessage("Invalid selection: requires a closed Curve,")
peo.AddAllowedClass(GetType(Curve), False)
Dim res As PromptEntityResult = editor.GetEntity(peo)
Return If(res.Status = PromptStatus.OK, res.ObjectId, ObjectId.Null)
End Function
Public Shared Function GetRegion(editor As Editor, msg As String) As ObjectId
Dim peo As New PromptEntityOptions(msg)
peo.SetRejectMessage("Invalid selection: requires a region,")
peo.AddAllowedClass(GetType(Region), False)
Dim res As PromptEntityResult = editor.GetEntity(peo)
Return If(res.Status = PromptStatus.OK, res.ObjectId, ObjectId.Null)
End Function
End Class
End Namespace 它不会像你期望的那样工作。。。它还搜索块定义内的多行文字。
没问题,会解决的。
谢谢你抽出时间。 我仍然认为您需要发布一个DWG文件来说明实体,因为您希望您的例程能够找到它们。理想情况下,示例文件将演示应该通过测试的设置,以及不应该通过测试的设置。
页:
1
[2]