Author Topic: Find holes in a AecSlab  (Read 1675 times)

0 Members and 1 Guest are viewing this topic.

mgreven

  • Guest
Find holes in a AecSlab
« on: March 20, 2012, 06:19:53 PM »
I am trying to make a routine which lists the position and size of holes in a AecSlab.
I saw there is à function called 'getholesinface' is there someone who has à example how to use this function to achieve this?

mgreven

  • Guest
Re: Find holes in a AecSlab
« Reply #1 on: September 03, 2012, 02:34:16 AM »
I did look into this problem again and found that "Holes" in AecSlabs are defined als Edges. When you look into the Face.Edges collection of the AecSlab, you also find the Edges of the Holes.

I made a function where the user selects the AecSlab and selects a point near a Edge of a Hole in the Slab. The Routine searches the nearest Edge and looks for Edges which connecting with the found Edge.
The routine is for Square Holes only and looks for Lengths which are equal.

The Routine is raw and have to be optimized:

Code: [Select]
       <CommandMethod("SlabHole-Info")> _
        Public Sub SlabHoleInfo()
            Try
                Dim Cmd As New Algemeen
                ' Connect to Current Drawing
                Dim MyDWG As Autodesk.AutoCAD.ApplicationServices.Document = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument
                Dim MyDB As Autodesk.AutoCAD.DatabaseServices.Database = MyDWG.Database
                Dim MyTransMan As Autodesk.AutoCAD.DatabaseServices.TransactionManager = MyDWG.TransactionManager
                Dim Ed As Editor = MyDWG.Editor
                Dim SlabID As ObjectId
                ' Start the Transaction...
                Using MyTrans As Autodesk.AutoCAD.DatabaseServices.Transaction = MyTransMan.StartTransaction
                    ' Ask user to select a Wall...
                    Dim EntSel As PromptEntityResult = Ed.GetEntity(vbLf + "Select Slab to work with.")
                    If EntSel.Status = PromptStatus.OK Then
                        ' Object selectet, check if it is a slab...
                        SlabID = EntSel.ObjectId
                        If SlabID.ObjectClass.DxfName.ToUpper = "AEC_SLAB" Then

                            ' slab selected, ask us to select a point near a edge...
                            Dim PntSel As PromptPointResult = Ed.GetPoint(vbLf + "Select a point near a Edge of the Hole : ")
                            If PntSel.Status = PromptStatus.OK Then

                                'Point selected...
                                Dim MySlab As ArchDbSrvcs.Slab = MyTrans.GetObject(SlabID, OpenMode.ForRead)
                                Dim MySlabHoogte As Double = MySlab.Thickness(MySlab.BaseThickness)
                                Dim ecs2wcs As Matrix3d = MySlab.Ecs
                                Dim wcs2ecs As Matrix3d = ecs2wcs.Inverse()

                                ' Set the Point the User selected...
                                Dim Userpt As New Point3d(PntSel.Value.X, PntSel.Value.Y, PntSel.Value.Z)
                                ' Convert point from WCS to ECS of the slab...
                                Userpt = Userpt.TransformBy(wcs2ecs)
                                ' Search the nearest SlabEdge...
                                Dim ObjID As Short = MySlab.Face.FindNearestEdge(New Point2d(Userpt.X, Userpt.Y))
                                Dim MyEdgeFound As Autodesk.Aec.Arch.Geometry.SlabEdge = MySlab.Face.Edge(ObjID)
                                Userpt = Userpt.TransformBy(ecs2wcs)

                                ' Get the start and endpoint of the edge...
                                Dim MyEdgeFoundStart As New Point3d(MyEdgeFound.StartPoint.X, MyEdgeFound.StartPoint.Y, (MySlab.Thickness(MySlab.BaseThickness) * -1))
                                MyEdgeFoundStart = MyEdgeFoundStart.TransformBy(MySlab.Ecs)
                                Dim MyEdgeFoundEnd As New Point3d(MyEdgeFound.EndPoint.X, MyEdgeFound.EndPoint.Y, (MySlab.Thickness(MySlab.BaseThickness) * -1))
                                MyEdgeFoundEnd = MyEdgeFoundEnd.TransformBy(MySlab.Ecs)

                                Dim MyEdgeCollection As New Collection
                                MyEdgeCollection.Add(MyEdgeFound)

                                ' Get the position of the Edge in the Face Collection...
                                Dim EdgePos As Integer
                                For i = 0 To MySlab.Face.EdgeCount - 1
                                    Dim MyEdge As Autodesk.Aec.Arch.Geometry.SlabEdge = MySlab.Face.EdgeAt(i)
                                    If MyEdge.Id = MyEdgeFound.Id Then
                                        EdgePos = i
                                    End If
                                Next

                                MsgBox("EdgePos is " & EdgePos.ToString & " van " & MySlab.Face.EdgeCount.ToString)
                                ' Search for connecting Edges after the Edge Position...
                                Dim LastEdgeStart As Point3d = MyEdgeFoundStart
                                Dim LastEdgeEnd As Point3d = MyEdgeFoundEnd

                                For i = EdgePos To MySlab.Face.EdgeCount - 1
                                    Dim MyEdge As Autodesk.Aec.Arch.Geometry.SlabEdge = MySlab.Face.EdgeAt(i)
                                    Dim StartPoint As New Point3d(MyEdge.StartPoint.X, MyEdge.StartPoint.Y, (MySlab.Thickness(MySlab.BaseThickness) * -1))
                                    Dim EndPoint As New Point3d(MyEdge.EndPoint.X, MyEdge.EndPoint.Y, (MySlab.Thickness(MySlab.BaseThickness) * -1))
                                    StartPoint = StartPoint.TransformBy(MySlab.Ecs)
                                    EndPoint = EndPoint.TransformBy(MySlab.Ecs)
                                    If StartPoint = LastEdgeStart Or StartPoint = LastEdgeEnd Or EndPoint = LastEdgeStart Or EndPoint = LastEdgeEnd Then
                                        Dim EdgeFound As Boolean = False
                                        For Each item As Autodesk.Aec.Arch.Geometry.SlabEdge In MyEdgeCollection
                                            If item.Id = MyEdge.Id Then
                                                EdgeFound = True
                                            End If
                                        Next
                                        If EdgeFound = False Then
                                            MyEdgeCollection.Add(MyEdge)
                                            LastEdgeStart = StartPoint
                                            LastEdgeEnd = EndPoint
                                        End If

                                    End If
                                Next

                                ' Seach connecting Edges before the Edge Position...
                                ''LastEdgeStart = MyEdgeFoundStart
                                ''LastEdgeEnd = MyEdgeFoundEnd
                                For i = 0 To EdgePos
                                    Dim MyEdge As Autodesk.Aec.Arch.Geometry.SlabEdge = MySlab.Face.EdgeAt(i)
                                    Dim StartPoint As New Point3d(MyEdge.StartPoint.X, MyEdge.StartPoint.Y, (MySlab.Thickness(MySlab.BaseThickness) * -1))
                                    Dim EndPoint As New Point3d(MyEdge.EndPoint.X, MyEdge.EndPoint.Y, (MySlab.Thickness(MySlab.BaseThickness) * -1))
                                    StartPoint = StartPoint.TransformBy(MySlab.Ecs)
                                    EndPoint = EndPoint.TransformBy(MySlab.Ecs)
                                    If StartPoint = LastEdgeStart Or StartPoint = LastEdgeEnd Or EndPoint = LastEdgeStart Or EndPoint = LastEdgeEnd Then
                                        Dim EdgeFound As Boolean = False
                                        For Each item As Autodesk.Aec.Arch.Geometry.SlabEdge In MyEdgeCollection
                                            If item.Id = MyEdge.Id Then
                                                EdgeFound = True
                                            End If
                                        Next
                                        If EdgeFound = False Then
                                            MyEdgeCollection.Add(MyEdge)
                                            LastEdgeStart = StartPoint
                                            LastEdgeEnd = EndPoint
                                        End If
                                    End If
                                Next

                                ' If the Edgecollection is smaller than the Slab Face.Edgecount then you have a closed Hole...
                                If MyEdgeCollection.Count < MySlab.Face.EdgeCount Then
                                    'MsgBox("Het is een gesloten sparing met " & MyEdgeCollection.Count & " zijdes")
                                    Dim EdgeLengte, EdgeLengte2 As Integer
                                    Dim HoleSides As New List(Of Integer)
                                    EdgeLengte = CInt(Cmd.DistanceBetween(MyEdgeFoundStart, MyEdgeFoundEnd))
                                    HoleSides.Add(EdgeLengte)

                                    For Each MyEdge As Autodesk.Aec.Arch.Geometry.SlabEdge In MyEdgeCollection
                                        Dim StartPoint As New Point3d(MyEdge.StartPoint.X, MyEdge.StartPoint.Y, (MySlab.Thickness(MySlab.BaseThickness) * -1))
                                        Dim EndPoint As New Point3d(MyEdge.EndPoint.X, MyEdge.EndPoint.Y, (MySlab.Thickness(MySlab.BaseThickness) * -1))
                                        Dim count As Integer = 0
                                        EdgeLengte = CInt(Cmd.DistanceBetween(StartPoint, EndPoint))
                                        For Each MyEdge2 As Autodesk.Aec.Arch.Geometry.SlabEdge In MyEdgeCollection
                                            Dim StartPoint2 As New Point3d(MyEdge2.StartPoint.X, MyEdge2.StartPoint.Y, (MySlab.Thickness(MySlab.BaseThickness) * -1))
                                            Dim EndPoint2 As New Point3d(MyEdge2.EndPoint.X, MyEdge2.EndPoint.Y, (MySlab.Thickness(MySlab.BaseThickness) * -1))
                                            EdgeLengte2 = CInt(Cmd.DistanceBetween(StartPoint2, EndPoint2))
                                            If EdgeLengte = EdgeLengte2 Then
                                                count += 1
                                            End If
                                        Next
                                        If count > 1 Then
                                            ' Check of the lengte reeds in de lijst voorkomt...
                                            Dim LgtExist As Boolean = False
                                            For Each Lgt As Integer In HoleSides
                                                If Lgt = EdgeLengte Then
                                                    LgtExist = True
                                                End If
                                            Next
                                            ' Indien de Lengte niet voorkomt in de lijst, voeg deze toe...
                                            If LgtExist = False Then
                                                HoleSides.Add(EdgeLengte)
                                            End If
                                        End If
                                    Next
                                    MsgBox("Het is een gesloten sparing met " & HoleSides.Count & " zijdes")
                                    Dim MsgStr As String = "Afmetingen : "
                                    For Each item In HoleSides
                                        MsgStr = MsgStr & item.ToString & " x "
                                    Next
                                    MsgStr = Left(MsgStr, Len(MsgStr) - 1)
                                    MsgBox(MsgStr)

                                Else
                                    MsgBox("Het is geen gesloten sparing")
                                End If

                            End If

                        End If
                    End If

                    MyTrans.Commit()
                End Using

            Catch ex As System.Exception
                MsgBox("An Error has occurred." & vbCr & ex.Message)
            Finally

            End Try

        End Sub