better method to find part overall size??

better method to find part overall size??

Anonymous
Not applicable
2,280 Views
9 Replies
Message 1 of 10

better method to find part overall size??

Anonymous
Not applicable

Is there any better method to find the overall size of a part model? I tried Range Box method and that gives some inaccuracy if the model have loft feature and fillet on that. But if I use GetExistingFacets the size gives more accurate. At the same time in a round part model with a cut, the GetExistingFacets give inaccuracy and range box method gives better result. Below is the X, Y, Z sizes of the two models with the above mentioned methods.

Round Part (Part1)

Measured with GetExistingFacets method = 129.934196472168 x 126.422719955444 x 25

Measured with Range Box method = 130 x 126.514225996919 x 25

 

Rectangular Part (Part2)

Measured with GetExistingFacets method = 300 x 300 x 30.0000286102295

Measured with Range Box method = 300 x 300 x 30.4094903224854

Please find attached part models which I used.

2,281 Views
9 Replies
Replies (9)
Message 2 of 10

philippe.leefsma
Alumni
Alumni

Hi

 

There is no proper way to get the tightest bounding box or accurate dimensions of a model.

 

One suggestion is to use CalculateFacets with a small tolerance, you then need to iterate through each vertices and find out the min/max on each X, Y, Z coordinates.

 

Another approach would be to use "Sketch3d.IntersectionCurves.Add" with a workplane and the SurfaceBody. You would create temporary workplanes by dichotomy to get closer to the geometry and check if it produces any intersection curves.

 

I hope it helps.

 

Regards,

Philippe.



Philippe Leefsma
Developer Technical Services
Autodesk Developer Network

0 Likes
Message 3 of 10

Anonymous
Not applicable

Thank you for your valued suggestion. I am already using the CalculateFacets with minimum tolerance. I will try the "Sketch3d.IntersectionCurves.Add".  

0 Likes
Message 4 of 10

philippe.leefsma
Alumni
Alumni

What issue are you having with CalculateFacets, not accurate enough?



Philippe Leefsma
Developer Technical Services
Autodesk Developer Network

0 Likes
Message 5 of 10

jdkriek
Advisor
Advisor

Quick note, just in case you missed it:

 


Note that CalculateFacets and GetExistingFacets (or GetExistingTolerances) are completely unrelated other than they both deal in facet data. CalculateFacets facets the model and returns that result. It does not effect any information held by Inventor. It is just direct access to the internal facet generator. The GetExistingFacets/Tolerances methods access the existing facet data held by the internal scene, if any. They access the set of existing tolerances and facets currently being held. Therefore it is quite possible that existing facets at a given tolerance may not exactly match calculated facets at the same tolerance.



 

Jonathan D. Kriek
MFG Solutions Engineer
KETIV Technologies, Inc.


0 Likes
Message 6 of 10

Anonymous
Not applicable

Yes, its not accurate enough only when calculating the overall size of a round part with slot (not full circular). attachment part1.ipt, In all other casees it gives an accurate result as I required.

 

0 Likes
Message 7 of 10

philippe.leefsma
Alumni
Alumni

The following code is using GetExistingFacets to compute the bounding box and then displays it using client graphics. As you can see on the pictures, this looks pretty accurate to me...

 

bb1.png

 

bb2.png

 

bb3.png

 

Private Sub FindRangeBoxWithFacet()

    Dim doc As Document
    Set doc = ThisApplication.ActiveDocument
    
    ' Set a reference to component definition of the active document.
    ' This assumes that a part or assembly document is active.
    Dim compdef As ComponentDefinition
    Set compdef = ThisApplication.ActiveDocument.ComponentDefinition
      
    ' Delete any graphics, if they exist.
    On Error Resume Next
    Dim oExistingGraphicsData As GraphicsDataSets
    Set oExistingGraphicsData = doc.GraphicsDataSetsCollection.item("RangeBoxGraphics")
    If Err.Number = 0 Then
        On Error GoTo 0
        Dim oExistingGraphics As clientGraphics
        Set oExistingGraphics = compdef.ClientGraphicsCollection.item("RangeBoxGraphics")
        oExistingGraphics.Delete
        oExistingGraphicsData.Delete
        ThisApplication.ActiveView.Update
    End If
 
    Dim aoRanges As box
    On Error Resume Next
    
    ' Set a reference to the body of the part.
    Dim oBody As SurfaceBody
    Set oBody = compdef.SurfaceBodies(1)

    Dim iVertexCount As Long
    Dim iFacetCount As Long
    Dim adVertexCoords() As Double
    Dim adNormalVectors() As Double
    Dim aiVertexIndices() As Long
    
    ' Determine the highest tolerance of the existing facet sets.
    Dim ToleranceCount As Long
    Dim ExistingTolerances() As Double
    Call oBody.GetExistingFacetTolerances(ToleranceCount, ExistingTolerances)
    
    Dim i As Long
    Dim BestTolerance As Double
    For i = 0 To ToleranceCount - 1
        If i = 0 Then
            BestTolerance = ExistingTolerances(i)
        ElseIf ExistingTolerances(i) < BestTolerance Then
            BestTolerance = ExistingTolerances(i)
        End If
    Next

    Call oBody.GetExistingFacets(BestTolerance, iVertexCount, iFacetCount, _
    adVertexCoords, adNormalVectors, aiVertexIndices)
    
    Dim cn As Long
    Dim minPt As point
    Dim maxPt As point

    For cn = LBound(adVertexCoords) To UBound(adVertexCoords) Step 3
        ' The Range box can be identified by the fact that the aoRanges
        ' variable will still be Nothing.
        If aoRanges Is Nothing Then
            'Initialize the range box with the first vertex
            Set aoRanges = ThisApplication.TransientGeometry.CreateBox
            Dim firstPt() As Double
            firstPt(0) = adVertexCoords(cn)
            firstPt(1) = adVertexCoords(cn + 1)
            firstPt(2) = adVertexCoords(cn + 2)
            Call aoRanges.PutBoxData(firstPt, firstPt)
        Else
            Set minPt = aoRanges.minPoint
            Set maxPt = aoRanges.maxPoint
    
            If (minPt.X > adVertexCoords(cn)) Then
                minPt.X = adVertexCoords(cn)
            End If
            If (minPt.Y > adVertexCoords(cn + 1)) Then
                minPt.Y = adVertexCoords(cn + 1)
            End If
            If (minPt.Z > adVertexCoords(cn + 2)) Then
                minPt.Z = adVertexCoords(cn + 2)
            End If
            aoRanges.minPoint = minPt
            If (maxPt.X < adVertexCoords(cn)) Then
                maxPt.X = adVertexCoords(cn)
            End If
            If (maxPt.Y < adVertexCoords(cn + 1)) Then
                maxPt.Y = adVertexCoords(cn + 1)
            End If
            If (maxPt.Z < adVertexCoords(cn + 2)) Then
                maxPt.Z = adVertexCoords(cn + 2)
            End If
            aoRanges.maxPoint = maxPt
        End If
    Next
    
    ' Check to see if range box graphics information already exists.
    Dim oClientGraphics As clientGraphics
    Dim oLineGraphics As lineGraphics
    Dim oBoxNode As GraphicsNode
    Dim oGraphicsData As GraphicsDataSets
    Set oGraphicsData = doc.GraphicsDataSetsCollection.item("RangeBoxGraphics")
    If Err Then
        Err.clear
        
        ' Set a reference to the transient geometry object for user later.
        Dim oTransGeom As TransientGeometry
        Set oTransGeom = ThisApplication.TransientGeometry
    
        ' Create a graphics data set object.  This object contains all of the
        ' information used to define the graphics.
        Dim oDataSets As GraphicsDataSets
        Set oDataSets = doc.GraphicsDataSetsCollection.Add("RangeBoxGraphics")
        
        ' Create a coordinate set.
        Dim oCoordSet As GraphicsCoordinateSet
        Set oCoordSet = oDataSets.CreateCoordinateSet(1)
        
        ' Create the client graphics for this compdef.
        Set oClientGraphics = compdef.ClientGraphicsCollection.Add("RangeBoxGraphics")
        
        ' Create a graphics node.
        Set oBoxNode = oClientGraphics.AddNode(1)
        oBoxNode.Selectable = False
        
        ' Create line graphics.
        Set oLineGraphics = oBoxNode.AddLineGraphics
        
        oLineGraphics.CoordinateSet = oCoordSet
    Else
        Set oCoordSet = oGraphicsData.ItemById(1)
        Set oBoxNode = compdef.ClientGraphicsCollection.item("RangeBoxGraphics").ItemById(1)
    End If
    
    Dim dBoxLines() As Double
    ReDim dBoxLines(1 To 12 * 6) As Double
 
    Dim minPoint(1 To 3) As Double
    Dim maxPoint(1 To 3) As Double
    Call aoRanges.GetBoxData(minPoint, maxPoint)
    
    ' Line 1
    dBoxLines(1) = minPoint(1)
    dBoxLines(2) = minPoint(2)
    dBoxLines(3) = minPoint(3)
    dBoxLines(4) = maxPoint(1)
    dBoxLines(5) = minPoint(2)
    dBoxLines(6) = minPoint(3)
    
    ' Line 2
    dBoxLines(7) = minPoint(1)
    dBoxLines(8) = minPoint(2)
    dBoxLines(9) = minPoint(3)
    dBoxLines(10) = minPoint(1)
    dBoxLines(11) = maxPoint(2)
    dBoxLines(12) = minPoint(3)
 
    ' Line 3
    dBoxLines(13) = minPoint(1)
    dBoxLines(14) = minPoint(2)
    dBoxLines(15) = minPoint(3)
    dBoxLines(16) = minPoint(1)
    dBoxLines(17) = minPoint(2)
    dBoxLines(18) = maxPoint(3)
 
    ' Line 4
    dBoxLines(19) = maxPoint(1)
    dBoxLines(20) = maxPoint(2)
    dBoxLines(21) = maxPoint(3)
    dBoxLines(22) = minPoint(1)
    dBoxLines(23) = maxPoint(2)
    dBoxLines(24) = maxPoint(3)
 
    ' Line 5
    dBoxLines(25) = maxPoint(1)
    dBoxLines(26) = maxPoint(2)
    dBoxLines(27) = maxPoint(3)
    dBoxLines(28) = maxPoint(1)
    dBoxLines(29) = minPoint(2)
    dBoxLines(30) = maxPoint(3)
 
    ' Line 6
    dBoxLines(31) = maxPoint(1)
    dBoxLines(32) = maxPoint(2)
    dBoxLines(33) = maxPoint(3)
    dBoxLines(34) = maxPoint(1)
    dBoxLines(35) = maxPoint(2)
    dBoxLines(36) = minPoint(3)
 
    ' Line 7
    dBoxLines(37) = minPoint(1)
    dBoxLines(38) = maxPoint(2)
    dBoxLines(39) = minPoint(3)
    dBoxLines(40) = maxPoint(1)
    dBoxLines(41) = maxPoint(2)
    dBoxLines(42) = minPoint(3)
 
    ' Line 8
    dBoxLines(43) = minPoint(1)
    dBoxLines(44) = maxPoint(2)
    dBoxLines(45) = minPoint(3)
    dBoxLines(46) = minPoint(1)
    dBoxLines(47) = maxPoint(2)
    dBoxLines(48) = maxPoint(3)
 
    ' Line 9
    dBoxLines(49) = maxPoint(1)
    dBoxLines(50) = minPoint(2)
    dBoxLines(51) = maxPoint(3)
    dBoxLines(52) = maxPoint(1)
    dBoxLines(53) = minPoint(2)
    dBoxLines(54) = minPoint(3)
 
    ' Line 10
    dBoxLines(55) = maxPoint(1)
    dBoxLines(56) = minPoint(2)
    dBoxLines(57) = maxPoint(3)
    dBoxLines(58) = minPoint(1)
    dBoxLines(59) = minPoint(2)
    dBoxLines(60) = maxPoint(3)
 
    ' Line 11
    dBoxLines(61) = minPoint(1)
    dBoxLines(62) = minPoint(2)
    dBoxLines(63) = maxPoint(3)
    dBoxLines(64) = minPoint(1)
    dBoxLines(65) = maxPoint(2)
    dBoxLines(66) = maxPoint(3)
 
    ' Line 12
    dBoxLines(67) = maxPoint(1)
    dBoxLines(68) = minPoint(2)
    dBoxLines(69) = minPoint(3)
    dBoxLines(70) = maxPoint(1)
    dBoxLines(71) = maxPoint(2)
    dBoxLines(72) = minPoint(3)
 
    ' Assign the points into the coordinate set.
    Call oCoordSet.PutCoordinates(dBoxLines)
    
    ' Update the display.
    ThisApplication.ActiveView.Update
End Sub

 

Regards,

Philippe.

 



Philippe Leefsma
Developer Technical Services
Autodesk Developer Network

0 Likes
Message 8 of 10

Anonymous
Not applicable

Thank you Philippe thank you verymuch.

I am using the same method to get the overall sizes. If I run the code immediately after opening the document I get one result and if change some dimensions or create some additional features the result changes. Again I save the document, close and open again I get the old result. My issue is I have an Add-In which updates the values on save after any change to the model. And at this point of time I get a different value. See the result which I got in my run,

 

1st Run - immediatly after opening the document

Highest Facet Tolerance : 1.01730170481997E-03
X Value : 129.997892379761, Y Value : 126.514024734497, Z Value : 25

2nd Run - after changing inner slot dimension

Highest Facet Tolerance : 9.15571534337971E-03
X Value : 129.934196472168, Y Value : 126.422719955444, Z Value : 25

3rd Run - after closing and opening with the changed inner slot dimension

Highest Facet Tolerance : 1.01730170481997E-03
X Value : 129.997892379761, Y Value : 126.514024734497, Z Value : 25

0 Likes
Message 9 of 10

philippe.leefsma
Alumni
Alumni

Did you try to call Document.Update after you did changes to make sure the model has been rebuilt?



Philippe Leefsma
Developer Technical Services
Autodesk Developer Network

0 Likes
Message 10 of 10

Anonymous
Not applicable

Yes, Document update call is used in the beginning, before defining the existing tolerance. 

Dim oPartDoc As PartDocument
    Set oPartDoc = ThisApplication.ActiveDocument
    oPartDoc.Update
    Dim oBody As SurfaceBody
    Set oBody = oPartDoc.ComponentDefinition.SurfaceBodies.Item(1)

    Dim lTolCount As Long
    Dim adExistingTols() As Double
    Call oBody.GetExistingFacetTolerances(lTolCount, adExistingTols)
    
    Dim dFacettol As Double

     Dim i As Long
    For i = 0 To lTolCount - 1
        If i = 0 Then
            dFacettol = adExistingTols(i)
        ElseIf adExistingTols(i) < dFacettol Then
            dFacettol = adExistingTols(i)
        End If
    Next
    Debug.Print "Highest Facet Tolerance : " & dFacettol

 

0 Likes