12 Replies Latest reply on May 12, 2017 2:23 AM by roberto gennari

    Minimum Bounding Box for sketch (oriented)

    roberto gennari

       

       

       

      Hello,

      I need to calculate the minimum size box for a sketch, this to better my size solids later. It 'important that it is done at the level of sketch, not solid.

      The problem is that the sketches are not composed only lines but also by arches.

       

      If there were no strings, I could calculate the convex hull from various points of the sketch and then create a rotation matrix coinciding for each line.

       

      In my case however you have any advice on how to proceed

      Thank you all

       

      Roberto

        • Re: Minimum Bounding Box for sketch (oriented)
          Artem Taturevych

          Hi,

           

          I would recommend the following scenario:

           

          • Find the closed region of the sketch
          • Create a temporary surface body from this region
          • Find the approximate orientation of the region through its principal axes of inertia
          • Calculate the bounding box of the body by finding excess point in the directions of principle axes
            • If the principle axes do not give the right orientation you may need to probe rotate the body to find the minimum bounding box

           

          Thanks,
          Artem

            • Re: Minimum Bounding Box for sketch (oriented)
              roberto gennari

              Hi Artem,

              thanks for the reply.

               

              If I understand it should:

              • Find the closed region of the sketch

                        (cross each entity of the sketch and create for each of them a CreateTrimmedCurve)

              • Create a temporary surface body from this region

                        (Create a planar surface with CreatePlanarSurface2 and cut it with the arrayCurves  planeSurf.CreateTrimmedSheet(trimCurves).

               

              • Find the approximate orientation of the region through its principal axes of inertia

                        (For my small experience I would not know how to do and why)

               

              • Calculate the bounding box of the body by finding excess point in the directions of principle axes
              • (Can I use GetBox (IFace2)?)

               

              • If the principle axes do not give the right orientation you may need to probe rotate the body to find the minimum bounding box

               

              Thanks for your expertise

               

              Have a nice day

              • Re: Minimum Bounding Box for sketch (oriented)
                roberto gennari

                Hi Artem,

                I wrote the code to create the temporary surface and works very well, see image.

                 

                Can you help me in the next step:

                • Find the approximate orientation of the region through its principal axes of inertia

                 

                Thanks

                Roberto

                • Re: Minimum Bounding Box for sketch (oriented)
                  roberto gennari

                  Hi,

                  now I got to this point in the code:

                  - I created the temporary surface

                  - I have the center of the surface (for the rotation)

                   

                   

                  Now I should create a rotation matrix for each step and derive the dimensions of the box.

                   

                   

                  Having never used the MathTransform, you could you help please?

                   

                   

                  Thanks a lot

                  Roberto

                  • Re: Minimum Bounding Box for sketch (oriented)
                    roberto gennari

                    Hallo,

                    I tried to write the code for rotate the temporary surface and check the two bounding box.

                    The results ara not correct becouse the two boxs are the same.

                     

                    I also have another question:

                    For temporary surface appears graphic change or not

                     

                    Thanks a lot

                     

                    This is my code:

                     

                     

                            Dim RetVal As Integer

                            planeSurf =swModeler.CreatePlanarSurface2((ptArr), (dirArr), (startArr))

                     

                            Dim profileBody As Body2

                            profileBody =planeSurf.CreateTrimmedSheet4((trimCurves), False)

                     

                            RetVal = profileBody.Display3(swPart,255, swTempBodySelectOptions_e.swTempBodySelectable)

                     

                            Dim Box() As Double = TryCast(profileBody.GetBodyBox, Double()) 'x,y,z,x1,y1,z1 

                            '

                            Dim values As Object

                            Dim selmgr As SelectionMgr

                            selmgr = swModel.SelectionManager

                            '

                            'Get the value from the schetch

                            Dim boolstatus As Boolean = swModel.Extension.SelectByID2(swFeat.Name, "SKETCH", 0, 0, 0, False, 0, Nothing, 0)

                            '

                            values = swModel.Extension.GetSectionProperties2(selmgr.GetSelectedObject(1))

                            '

                            For i = 0 To UBound(values)

                                Debug.Print("[" & i & "]" & values(i))

                            Next i

                            '

                            ' Transform with angle

                            Dim mathUtil As MathUtility

                     

                            Dim aXform As MathTransform

                            Dim basePt As MathPoint

                            Dim nPts(2) As Double

                            Dim vData As Object

                            Dim xAxis As MathVector

                            Dim ret As Boolean

                            '

                            mathUtil = swApp.GetMathUtility

                            '

                            nPts(0) = values(2)

                            nPts(1) = values(3)

                            nPts(2) = values(4)

                            vData = nPts

                            '

                            basePt = mathUtil.CreatePoint(vData)

                            '

                            nPts(0) = values(21)

                            nPts(1) = values(22)

                            nPts(2) = values(23)

                            vData = nPts

                            '

                            xAxis = mathUtil.CreateVector(vData)

                            aXform = mathUtil.CreateTransformRotateAxis(basePt, xAxis, 3.1416159 / 2)

                            Ret = profileBody.ApplyTransform(aXform)

                     

                            'Get Second box

                            Box = TryCast(profileBody.GetBodyBox, Double()) 'x,y,z,x1,y1,z1 

                     

                     

                     

                     

                     

                     

                     

                      • Re: Minimum Bounding Box for sketch (oriented)
                        Artem Taturevych

                        I think you need to hide (IBody2::Hide) and show (IBody2::Display) to see the result of the transformation. But I would recommend to not rotate the body with the transform rather rotate the XY vectors and calculate the extreme points in new directions. This is more performance effective.

                         

                        Thanks,

                        Artem

                          • Re: Minimum Bounding Box for sketch (oriented)
                            roberto gennari

                            Hi Artem,

                            thanks for you help, I have great respect for you.

                             

                            I wrote the code for the rotation by following your advice, it works but it's perfected.

                            In fact turning the surface body, the process is very slow, but I do not know how to do

                            to rotate with the carrier as you say.

                             

                            What do you think about the box? I have created a rectangle and then I rotated angle, but is not sure of the millet way to do it.

                             

                             

                            Thank you

                            Roberto

                             

                            This the code:

                             

                            Dim RetVal As Integer

                                    planeSurf = swModeler.CreatePlanarSurface2((ptArr),(dirArr), (startArr))

                             

                                    Dim profileBody As Body2

                                    profileBody =planeSurf.CreateTrimmedSheet4((trimCurves), False)

                             

                                    RetVal = profileBody.Display3(swPart,255, swTempBodySelectOptions_e.swTempBodySelectable)

                             

                                    Dim Box() As Double = TryCast(profileBody.GetBodyBox, Double()) 'x,y,z,x1,y1,z1 

                                    '

                                    swModel.ClearSelection2(True)

                                    '

                                    Dim values As Object

                                    Dim selmgr As SelectionMgr

                                    selmgr = swModel.SelectionManager

                                    '

                                    Dim boolstatus As Boolean = swModel.Extension.SelectByID2(swFeat.Name, "SKETCH",0, 0, 0, False, 0, Nothing, 0)

                                    '

                                    values = swModel.Extension.GetSectionProperties2(selmgr.GetSelectedObject(1))

                                    '

                                    For i = 0 To UBound(values)

                                        Debug.Print("[" & i & "]" & values(i))

                                    Next i

                                    '

                                    ' Transform with angle

                                    Dim mathUtil As MathUtility

                             

                                    Dim aXform As MathTransform

                                    Dim basePt As MathPoint

                                    Dim nPts(2) As Double

                                    Dim vData As Object

                                    Dim xAxis As MathVector

                                    Dim ret As Boolean

                                    '

                                    mathUtil = swApp.GetMathUtility

                                    '

                                    nPts(0) = values(2)

                                    nPts(1) = values(3)

                                    nPts(2) = values(4)

                                    vData = nPts

                                    '

                                    basePt = mathUtil.CreatePoint(vData)

                                    '

                                    nPts(0) = values(21)

                                    nPts(1) = values(22)

                                    nPts(2) = values(23)

                                    vData = nPts

                             

                                    swModel.ClearSelection2(True)

                             

                                    xAxis = mathUtil.CreateVector(vData)

                             

                                    Dim angle As Double = 0

                                    Dim min_Area As Double

                                    Dim angolo As Double

                             

                             

                                    profileBody.Hide(swPart)

                             

                                    Dim Arraypoint(6) As Double

                             

                                    For Z As Integer = 0 To 180

                                        aXform = mathUtil.CreateTransformRotateAxis(basePt, xAxis, angle)

                                        ret = profileBody.ApplyTransform(aXform)

                                        Box = TryCast(profileBody.GetBodyBox, Double()) 'x,y,z,x1,y1,z1 

                             

                                        Dim Lunghezza As Double = (Box(0) - Box(3)) * 1000

                                        Dim Larghezza As Double = (Box(1) - Box(4)) * 1000

                             

                                        Dim area As Double = (Lunghezza) * (Larghezza)

                                        If Z = 0 Then

                                            min_Area = area

                                        End If

                                        '

                                        If area < min_Area Then

                                            min_Area = area

                                            angolo = CDbl(Z)

                                            Arraypoint(0) = Box(0)

                                            Arraypoint(1) = Box(1)

                                            Arraypoint(2) = Box(2)

                                            Arraypoint(3) = Box(3)

                                            Arraypoint(4) = Box(4)

                                            Arraypoint(5) = Box(5)

                                            Arraypoint(6) = angolo

                                        End If

                                        angle = ((1 * PI) / 180)

                                    Next

                             

                                    boolstatus = swModel.Extension.SelectByID2("Piano frontale", "PLANE", 0, 0, 0, False, 0, Nothing, 0)

                             

                                    swModel.SketchManager.InsertSketch(True)

                                    swModel.SetAddToDB(True)

                                    swModel.SetDisplayWhenAdded(False)

                                  
                                    swModel.FeatureManager.EnableFeatureTree = False

                                    '

                                    Dim vSkLines As Object

                                    vSkLines = swModel.SketchManager.CreateCornerRectangle(Arraypoint(0), Arraypoint(1), Arraypoint(2), Arraypoint(3), Arraypoint(4), Arraypoint(5))

                             

                                    swModel.ClearSelection2(True)

                                    Dim SelData As SelectData

                                    selmgr = swModel.SelectionManager

                                    SelData = selmgr.CreateSelectData

                                    boolstatus = swModel.Extension.SelectByID2("Line1", "SKETCHSEGMENT", 0, 0, 0, False, 0, Nothing, 0)

                                    Dim sketchSegment As SketchSegment

                                    sketchSegment = selmgr.GetSelectedObject6(1, -1)

                                    boolstatus = sketchSegment.SelectChain(False, Nothing)

                                    swModel.Extension.RotateOrCopy(False, 1, True, basePt.ArrayData(0), basePt.ArrayData(1), 0, 0, 0, 1, ((179 - Arraypoint(6)) * PI) / 180)

                             

                                    swModel.SetAddToDB(False)

                                    swModel.SetDisplayWhenAdded(True)
                                     swModel.FeatureManager.EnableFeatureTree = True

                             

                                    swModel.SketchManager.InsertSketch(False)

                                         boolstatus = swModel.EditRebuild3()

                              • Re: Minimum Bounding Box for sketch (oriented)
                                roberto gennari

                                Hallo,

                                I resume this discussion because I have not yet been able to write the correct code to get the minimum size of a free form surface.

                                I worked with a rotation matrix and GetExtremePoint for get the point, ma it is wrong.

                                I attach the following code after creating a temporary surface, could you look at my code please to understand where I'm wrong?

                                Thanks a lot

                                 

                                             
                                Dim startArr(2) As Double

                                Dim endArr(2 )As Double

                                Dim ptArr(2) As Double

                                Dim dirArr(2) As Double

                                 

                                ptArr(0) = 0.0#

                                ptArr(1) = 0.0#

                                ptArr(2) = 0.0#

                                dirArr(0) = 0.0#

                                dirArr(1) = 0.0#

                                dirArr(2) = 1.0#

                                startArr(0) = 1.0#

                                startArr(1) = 0.0#

                                startArr(2) = 0.0#

                                 

                                swPart = swApp.ActiveDoc

                                 

                                Dim RetVal As Integer

                                planeSurf = swModeler.CreatePlanarSurface2((ptArr), (dirArr), (startArr))

                                Dim profileBody As Body2

                                profileBody = planeSurf.CreateTrimmedSheet4((trimCurves), False)

                                 

                                RetVal = profileBody.Display3(swPart,255, swTempBodySelectOptions_e.swTempBodySelectable)

                                 

                                'Calculate the bounding box of surface

                                Dim Box() As Double = TryCast(profileBody.GetBodyBox, Double()) 'x,y,z,x1,y1,z1 

                                        '

                                swModel.ClearSelection2(True)

                                 

                                Dim values As Object

                                Dim selmgr As SelectionMgr

                                 

                                selmgr = swModel.SelectionManager

                                 

                                Dim boolstatus As Boolean = swModel.Extension.SelectByID2(swFeat.Name, "SKETCH", 0, 0, 0, False, 0, Nothing, 0)

                                        '

                                values = swModel.Extension.GetSectionProperties2(selmgr.GetSelectedObject(1))

                                For i = 0 To UBound(values)

                                Debug.Print("[" & i & "]" & values(i))

                                Next i

                                 

                                Dim mathUtil As MathUtility

                                Dim basePt As MathPoint

                                Dim nPts(2) As Double

                                Dim vData As Object

                                 

                                mathUtil = swApp.GetMathUtility

                                nPts(0) = values(2)

                                nPts(1) = values(3)

                                nPts(2) = values(4)

                                vData = nPts

                                 

                                basePt = mathUtil.CreatePoint(vData)

                                 

                                Dim MyFace As Face2

                                Dim swSurf As Surface

                                MyFace = profileBody.GetFirstFace

                                swSurf = MyFace.GetSurface

                                 

                                Dim vEvalData As Object

                                vEvalData = swSurf.EvaluateAtPoint(values(2), values(3), values(4))

                                Dim normal(2) As Double

                                Dim dir1(2) As Double

                                Dim dir2(2) As Double

                                 

                                'find normal and X and Y vectors at the selected point

                                normal(0) = vEvalData(0) : normal(1) = vEvalData(1) : normal(2) = vEvalData(2)
                                dir1(0) = vEvalData(3) : dir1(1) = vEvalData(4) : dir1(2) = vEvalData(5)
                                 
                                dir2(0) = vEvalData(6) : dir2(1) = vEvalData(7) : dir2(2) = vEvalData(8)

                                Dim swNormalVec As MathVector

                                Dim swDir1Vec As MathVector

                                Dim swDir2Vec As MathVector

                                 

                                swNormalVec = mathUtil.CreateVector(normal)

                                swDir1Vec = mathUtil.CreateVector(dir1)

                                swDir2Vec = mathUtil.CreateVector(dir2)

                                 

                                Dim swOrigin As MathPoint

                                swOrigin = mathUtil.CreatePoint(nPts)

                                Dim valori As Boolean

                                Dim Outx As Double

                                Dim Outy As Double

                                Dim Outz As Double

                                 

                                Dim ANGLE_STEP As Double = 1

                                swModel.ClearSelection2(True)

                                swModel.SketchManager.Insert3DSketch(True)

                                swModel.SketchManager.AddToDB = True

                                 

                                For angle = 0 To 360 Step ANGLE_STEP

                                   Dim Lung As Double

                                   Dim swRotTransform As MathTransform

                                   'create rotation transform around the selection point and normal vector at angle

                                   swRotTransform = mathUtil.CreateTransformRotateAxis(swOrigin, swNormalVec, angle * PI / 180)

                                 

                                   Dim swTransformedDir1 As MathVector


                                   'Transform original vector

                                   swTransformedDir1 = swDir1Vec.MultiplyTransform(swRotTransform)

                                   valori = profileBody.GetExtremePoint(swTransformedDir1.ArrayData(0),swTransformedDir1.ArrayData(1), swTransformedDir1.ArrayData(2), Outx, Outy, Outz)

                                   'Calculate the length of vector

                                   Lung = Sqrt((values(2) - Outx) ^ 2 + (values(3) - Outy) ^ 2)

                                   'Now draw the line for see the result

                                   DrawLine(swOrigin, swTransformedDir1, Lung)

                                 

                                Next

                                swModel.SketchManager.AddToDB = False

                                swModel.SketchManager.Insert3DSketch(True)

                                swApp = Nothing

                                End Sub

                                 

                                Sub DrawLine(ByVal point As MathPoint, ByVal vector As MathVector, ByVal lungh As Double)

                                Dim vPt1 As Object

                                Dim vPt2 As Object

                                Dim swPt As MathPoint

                                Dim swVec As MathVector

                                 

                                vPt1 = point.ArrayData

                                 

                                swVec = vector.Normalise

                                swVec = swVec.Scale(lungh)

                                swPt = point.AddVector(swVec)

                                vPt2 = swPt.ArrayData  
                                swModel.SketchManager.CreateLine(vPt1(0), vPt1(1), vPt1(2), vPt2(0),
                                vPt2(1), vPt2(2))

                                 

                                End Sub