The RangeBox call is intended to be as fast as possible to be used as a quick way to eliminate or add an object to set of objects for further, more expensive processing. I'm fairly certain that the range box for any spline based geometry is based on the control polygon of the spline so in most cases it will be larger than the actual curve or surface. It would take me a while to dig into how Inventor is getting the size of the sheet metal part, but obviously it's doing a more expensive calculation to get a tight range box.
A way to get an accurate bounding box is to calculate your own based on a mesh representation of the body. This may seem complicated but it's really not. Below is a VBA implementation I just put together quickly to illustrate.
Public Sub t2()
Dim doc As PartDocument
Set doc = ThisDocument
Dim xWidth As Double
Dim yLength As Double
doc.ObjectVisibility.AllWorkFeatures = False
doc.ObjectVisibility.ConstructionSurfaces = False
doc.ObjectVisibility.SketchDimensions = False
doc.ObjectVisibility.Sketches = False
doc.ObjectVisibility.Sketches3D = False
Dim boundingBox As Box
Set boundingBox = doc.ComponentDefinition.SurfaceBodies.Item(1).RangeBox
xWidth = Round(Abs(boundingBox.MaxPoint.X - boundingBox.MinPoint.X), 3)
yLength = Round(Abs(boundingBox.MaxPoint.Y - boundingBox.MinPoint.Y), 3)
Debug.Print "X = " & xWidth
Debug.Print "Y = " & yLength
Set boundingBox = TightRangeBox(doc.ComponentDefinition.SurfaceBodies.Item(1))
xWidth = Round(Abs(boundingBox.MaxPoint.X - boundingBox.MinPoint.X), 3)
yLength = Round(Abs(boundingBox.MaxPoint.Y - boundingBox.MinPoint.Y), 3)
Debug.Print "Tight"
Debug.Print "X = " & xWidth
Debug.Print "Y = " & yLength
End Sub
Public Function TightRangeBox(Body As Inventor.SurfaceBody) As Inventor.Box
' Get the existing mesh of the highest resolution.
Dim tolCount As Long
Dim tols() As Double
Call Body.GetExistingFacetTolerances(tolCount, tols)
Dim i As Integer
Dim bestTol As Double
bestTol = tols(0)
For i = 1 To tolCount - 1
If tols(i) < bestTol Then
bestTol = tols(i)
End If
Next
Dim vertexCount As Long
Dim facetCount As Long
Dim vertexCoords() As Double
Dim normalVectors() As Double
Dim vertexIndices() As Long
Call Body.GetExistingFacets(bestTol, vertexCount, facetCount, vertexCoords, normalVectors, vertexIndices)
' Loop through the vertices and build up the range box.
Dim minX As Double
Dim maxX As Double
Dim minY As Double
Dim maxY As Double
Dim minZ As Double
Dim maxZ As Double
minX = vertexCoords(0)
maxX = vertexCoords(0)
minY = vertexCoords(1)
maxY = vertexCoords(1)
minZ = vertexCoords(2)
maxZ = vertexCoords(2)
For i = 1 To vertexCount - 1
If vertexCoords(i * 3) < minX Then
minX = vertexCoords(i * 3)
End If
If vertexCoords(i * 3) > maxX Then
maxX = vertexCoords(i * 3)
End If
If vertexCoords(i * 3 + 1) < minY Then
minY = vertexCoords(i * 3 + 1)
End If
If vertexCoords(i * 3 + 1) > maxY Then
maxY = vertexCoords(i * 3 + 1)
End If
If vertexCoords(i * 3 + 2) < minZ Then
minZ = vertexCoords(i * 3 + 2)
End If
If vertexCoords(i * 3 + 2) > maxZ Then
maxZ = vertexCoords(i * 3 + 2)
End If
Next
Dim newBox As Box
Set newBox = ThisApplication.TransientGeometry.CreateBox()
newBox.MinPoint = ThisApplication.TransientGeometry.CreatePoint(minX, minY, minZ)
newBox.MaxPoint = ThisApplication.TransientGeometry.CreatePoint(maxX, maxY, maxZ)
Set TightRangeBox = newBox
End Function