OmarSuliman 发表于 2022-7-6 22:54:29

第二个是找出点是在区域对象的内侧还是外侧,我也试过了。
 
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

fuccaro 发表于 2022-7-6 22:56:44

它不会像你期望的那样工作。。。它还搜索块定义内的多行文字。

OmarSuliman 发表于 2022-7-6 22:59:37

 
没问题,会解决的。
谢谢你抽出时间。

SEANT 发表于 2022-7-6 23:04:32

我仍然认为您需要发布一个DWG文件来说明实体,因为您希望您的例程能够找到它们。理想情况下,示例文件将演示应该通过测试的设置,以及不应该通过测试的设置。
页: 1 [2]
查看完整版本: 获取块参照内的多行文字