Announcements
Autodesk Community will be read-only between April 26 and April 27 as we complete essential maintenance. We will remove this banner once completed. Thanks for your understanding

Extents of parts

Andy73
Contributor Contributor
2,335 Views
8 Replies
Message 1 of 9

Extents of parts

Andy73
Contributor
Contributor
I am trying to find the outer most extents of a part. We are working in sheet base manufacturing. Range box works for most of the parts. My sticking point; if the part's workplane is not the "global" workplane. I need the return to be the total includind facedrafts ect.
0 Likes
2,336 Views
8 Replies
Replies (8)
Message 2 of 9

Anonymous
Not applicable
I don't think I quite follow what you are looking for. The API provides the
range box for the part body (SurfaceBody.RangeBox) as well as the range box
for the entire part (PartComponentDefinition.RangeBox). Do neither of these
address your needs? If not, could you be more specific about what you need?

Sanjay-

wrote in message news:5460902@discussion.autodesk.com...
I am trying to find the outer most extents of a part. We are working in
sheet base manufacturing. Range box works for most of the parts. My sticking
point; if the part's workplane is not the "global" workplane. I need the
return to be the total includind facedrafts ect.
0 Likes
Message 3 of 9

Andy73
Contributor
Contributor
Hello Sanjay;
If I have a part that is a sketched rectangle .75(Y) x 14(X) then rotated 45 deg. then extruded 7(Z); (SurfaceBody.RangeBox) MaxPoint-MinPoint gives me a return of 11.1186, 10.4298, 7. I'm looking for the extents that should give me 14, 7, .73. Now if you roteted this Part 90 deg along the longest edge I'm looking for the same return.

Thank You For Any Help
Andy
0 Likes
Message 4 of 9

Anonymous
Not applicable
Andy,

All the range boxes returned by Inventor are axes-aligned. So there isn't an
easy/direct way to get a "tight" bounding box. Computation of a tight
bounding box is non-trivial and may not even be feasible for a general case.
For simple cases, you may be able to get the facets of the part body and
manually compute a bounding box.

Sanjay-

wrote in message news:5462147@discussion.autodesk.com...
Hello Sanjay;
If I have a part that is a sketched rectangle .75(Y) x 14(X) then
rotated 45 deg. then extruded 7(Z); (SurfaceBody.RangeBox) MaxPoint-MinPoint
gives me a return of 11.1186, 10.4298, 7. I'm looking for the extents that
should give me 14, 7, .73. Now if you roteted this Part 90 deg along the
longest edge I'm looking for the same return.

Thank You For Any Help
Andy
0 Likes
Message 5 of 9

Andy73
Contributor
Contributor
Sanjay
That's what I Feared. Would there be a way to get a rangebox based on a workplane alignment, or use a matrix? I can't say I know much about either, but if I have a reason to learn.

Thank You for the Info.
Andy
0 Likes
Message 6 of 9

Anonymous
Not applicable
Hi Andy,

Sanjay and I have been discussing possible solutions to this. As he said
before, there's not a simple solution. After thinking about it some more
there may be one approach that's not too bad. The primary requirement of
this approach is that you somehow define the alignment of the part.
Conceptually you're defining a coordinate system for the rotated orientation
of the part. It would be enough to know the top or bottom face (the normal
defines the Z axis) and a linear edge that would define the primary axis (X
axis). Using these two inputs it's possible to define a coordinate system
on the part, (crossing the X vector with the Z vector will give the Y
vector).

Once you have this coordinate system you can create a matrix. This matrix
defines a transform from the model coordinate system to the defined
coordinate system. If you invert this matrix it will define a transform
from the defined coordinate system to model space. Using this inverted
matrix you can then create a derived part using this part. The API allows
you to create a derived part using any transform. The result will be that
the part is positioned in the derived part such that the defined coordinate
system lines up with the part coordinate system. The range box of the
derived part should be the size that you're looking for.

Matrix and vector math can be a bit intimidating at first. It usually takes
some effort and experimenting before the "light comes on" and everything
makes sense. I've attached the notes for a class I presented at Autodesk
University a couple of years ago that discusses some of this. Hopefully it
will be useful
--
Brian Ekins
Autodesk Inventor API


wrote in message news:5462663@discussion.autodesk.com...
Sanjay
That's what I Feared. Would there be a way to get a rangebox based on a
workplane alignment, or use a matrix? I can't say I know much about either,
but if I have a reason to learn.

Thank You for the Info.
Andy
0 Likes
Message 7 of 9

Andy73
Contributor
Contributor
Brian,Sanjay
This gives me a good direction to head thank you. This is only one project in a very large pile, I'll post how it went (it my be awhile).

Thank you again
Andy
0 Likes
Message 8 of 9

Anonymous
Not applicable
Here is some code that may help with this. This is more or less along the
lines of what Brian described. You need to have the part with the body
active, and you need to select 2 edges that will define the X & Y Axis of
the bounding box. You have to be careful when selecting the 2 edges
(direction, etc.) since the sample below is not very tolerant.

Also, the sample opens a new document invisibly and closes it at the end.
Note that this will result in clearing the Undo list, so you may want to
close the document at an appropriate time.

Sanjay-

Sub TightBoundingBox()

Dim oDoc As PartDocument
Set oDoc = ThisApplication.ActiveDocument

Dim oOriginalRangeBox As Box
Set oOriginalRangeBox =
oDoc.ComponentDefinition.SurfaceBodies(1).RangeBox

Debug.Print oOriginalRangeBox.MaxPoint.X - oOriginalRangeBox.MinPoint.X
Debug.Print oOriginalRangeBox.MaxPoint.Y - oOriginalRangeBox.MinPoint.Y
Debug.Print oOriginalRangeBox.MaxPoint.Z - oOriginalRangeBox.MinPoint.Z

' Get the vector along first selection
Dim oVec1 As Vector
Set oVec1 = oDoc.SelectSet(1).Geometry.Direction.AsVector

' Get the X-Axis vector
Dim oVec2 As Vector
Set oVec2 = oDoc.ComponentDefinition.WorkAxes(1).Line.Direction.AsVector

' Create a matrix that will rotate the body such that the
' direction of the first selection coincides with X-Axis.
Dim oMat1 As Matrix
Set oMat1 = ThisApplication.TransientGeometry.CreateMatrix
Call oMat1.SetToRotateTo(oVec1, oVec2, Nothing)

' Get the vector along second selection
Set oVec1 = oDoc.SelectSet(2).Geometry.Direction.AsVector

oVec1.TransformBy oMat1

' Get the Y-Axis vector
Set oVec2 = oDoc.ComponentDefinition.WorkAxes(2).Line.Direction.AsVector

' Create a matrix that will rotate the body such that the
' direction of the second selection coincides with Y-Axis.
Dim oMat2 As Matrix
Set oMat2 = ThisApplication.TransientGeometry.CreateMatrix
Call oMat2.SetToRotateTo(oVec1, oVec2, Nothing)

' Combine the 2 matrices
oMat1.PostMultiplyBy oMat2

Dim oDerDoc As PartDocument
Set oDerDoc = ThisApplication.Documents.Add(kPartDocumentObject, ,
False)

Dim oDerCompDef As PartComponentDefinition
Set oDerCompDef = oDerDoc.ComponentDefinition

Dim oDerPartDef As DerivedPartTransformDef
Set oDerPartDef =
oDerCompDef.ReferenceComponents.DerivedPartComponents.CreateTransformDef("C:\temp\tiltedbox.ipt")

oDerPartDef.SetTransformation oMat1

oDerCompDef.ReferenceComponents.DerivedPartComponents.Add oDerPartDef

Dim oTightRangeBox As Box
Set oTightRangeBox = oDerCompDef.SurfaceBodies(1).RangeBox

Debug.Print oTightRangeBox.MaxPoint.X - oTightRangeBox.MinPoint.X
Debug.Print oTightRangeBox.MaxPoint.Y - oTightRangeBox.MinPoint.Y
Debug.Print oTightRangeBox.MaxPoint.Z - oTightRangeBox.MinPoint.Z

oDerDoc.Close

End Sub

wrote in message news:5462845@discussion.autodesk.com...
Brian,Sanjay
This gives me a good direction to head thank you. This is only one project
in a very large pile, I'll post how it went (it my be awhile).

Thank you again
Andy
0 Likes
Message 9 of 9

Andy73
Contributor
Contributor
Well here is what I crunched the code to. If anyone can think of or find a stiuition that this doesnt work please let me (keep in mind that this is for sheet parts). I'm still learning error handeling, I'd like input about this also.

Thank you
Andy


Public Sub FindExtents()




Dim opartdoc As PartDocument
Dim oCompDef As PartComponentDefinition
Dim oAssdoc As AssemblyDocument
Dim oCompAssDef As AssemblyComponentDefinition
Dim oParams As UserParameters
Dim Mx(2) As Double, Mi(2) As Double
Dim MxX As Double, MxY As Double, MxZ As Double
Dim MiX As Double, MiY As Double, MiZ As Double
Dim oDoc As Document
Dim NumberList(2) As Double

Set oDoc = ThisApplication.ActiveDocument


Select Case oDoc.DocumentType
Case kPartDocumentObject
Set opartdoc = oDoc
Set oCompDef = opartdoc.ComponentDefinition
Dim oBody As SurfaceBody
Set oBody = opartdoc.ComponentDefinition.SurfaceBodies.Item(1)
TightBoundingBox Mi, Mx
Case Else
Exit Sub
End Select

NumberList(0) = Mx(0) - Mi(0)
NumberList(1) = Mx(1) - Mi(1)
NumberList(2) = Mx(2) - Mi(2)
NumberSort NumberList()
Set oParams = opartdoc.ComponentDefinition.Parameters.UserParameters
Dim LenBol As Boolean, WidBol As Boolean, ThiBol As Boolean
LenBol = False
WidBol = False
ThiBol = False
If oParams.Count > 0 Then
Dim iNumParams As Integer
For iNumParams = 1 To oParams.Count
Select Case oParams.Item(iNumParams).Name
Case "LENGTH"
oParams.Item(iNumParams).Value = NumberList(0)
LenBol = True
Case "WIDTH"
oParams.Item(iNumParams).Value = NumberList(1)
WidBol = True
Case "THICKNESS"
oParams.Item(iNumParams).Value = NumberList(2)
ThiBol = True
End Select
Next iNumParams
End If
If LenBol = False Then oParams.AddByValue "LENGTH", NumberList(0), kDefaultDisplayLengthUnits
If WidBol = False Then oParams.AddByValue "WIDTH", NumberList(1), kDefaultDisplayLengthUnits
If ThiBol = False Then oParams.AddByValue "THICKNESS", NumberList(2), kDefaultDisplayLengthUnits


End Sub

Sub TightBoundingBox(ByRef Mi() As Double, ByRef Mx() As Double)

Dim oDoc As PartDocument
Set oDoc = ThisApplication.ActiveDocument
Dim oTG As TransientGeometry
Set oTG = ThisApplication.TransientGeometry
Dim oOriginalRangeBox As Box
Set oOriginalRangeBox = oDoc.ComponentDefinition.SurfaceBodies(1).RangeBox

Debug.Print "start dX: " & oOriginalRangeBox.MaxPoint.X - oOriginalRangeBox.MinPoint.X & " " & _
"start dY: " & oOriginalRangeBox.MaxPoint.Y - oOriginalRangeBox.MinPoint.Y & " " & _
"start dZ: " & oOriginalRangeBox.MaxPoint.Z - oOriginalRangeBox.MinPoint.Z

Dim oBody As SurfaceBody
Set oBody = oDoc.ComponentDefinition.SurfaceBodies(1)
Dim oFace As Face
Dim oFaceIdx As Integer
oFaceIdx = GetLargestFaceIndex(oBody, oFace)
' Get the Z vector Normal to the face
Dim oVec1 As Vector, Zvec As Vector, Yvec As Vector, Xvec As Vector
Dim VecNor As UnitVector
Set VecNor = oFace.Geometry.Normal
Set Zvec = VecNor.AsVector
Set oVec1 = Zvec
' Get the Z-Axis vector
Dim oVec2 As Vector
Set oVec2 = oDoc.ComponentDefinition.WorkAxes(3).Line.Direction.AsVector
' Create a matrix that will rotate the body such that the
' direction of the Largest Face Normal coincides with Z-Axis.
Dim oMatZ As Matrix
Set oMatZ = ThisApplication.TransientGeometry.CreateMatrix
Call oMatZ.SetToRotateTo(oVec1, oVec2, Nothing)
' Get the vector along Longest Edge
Set Yvec = GetLongestEdgeVector(oFace)
Set Xvec = Zvec.CrossProduct(Yvec)
Set Yvec = Xvec.CrossProduct(Zvec)
Set oVec1 = Yvec
oVec1.TransformBy oMatZ
' Get the Y-Axis vector
Set oVec2 = oDoc.ComponentDefinition.WorkAxes(2).Line.Direction.AsVector
' Create a matrix that will rotate the body such that the
' direction of the Longest Edge coincides with Y-Axis.
Dim oMatY As Matrix
Set oMatY = ThisApplication.TransientGeometry.CreateMatrix
Call oMatY.SetToRotateTo(oVec1, oVec2, Nothing)
' Combine the 2 matrices
oMatZ.TransformBy oMatY
' Set the vector as the cross product of Zvec and Yzec
Set oVec1 = Xvec
oVec1.TransformBy oMatZ
' Get the X-Axis vector
Set oVec2 = oDoc.ComponentDefinition.WorkAxes(1).Line.Direction.AsVector
' Create a matrix that will rotate the body such that the
' direction of the second selection coincides with X-Axis.
Dim oMatX As Matrix
Set oMatX = ThisApplication.TransientGeometry.CreateMatrix
Call oMatX.SetToRotateTo(oVec1, oVec2, Nothing)
' Combine the 2 matrices
oMatZ.TransformBy oMatX

Dim oDerDoc As PartDocument
Set oDerDoc = ThisApplication.Documents.Add(kPartDocumentObject, , False)
Dim oDerCompDef As PartComponentDefinition
Set oDerCompDef = oDerDoc.ComponentDefinition
Dim oDerPartDef As DerivedPartTransformDef
Set oDerPartDef = oDerCompDef.ReferenceComponents.DerivedPartComponents.CreateTransformDef _
(oDoc.FullFileName)

oDerPartDef.SetTransformation oMatZ
oDerCompDef.ReferenceComponents.DerivedPartComponents.Add oDerPartDef
Dim oTightRangeBox As Box
Set oTightRangeBox = oDerCompDef.SurfaceBodies(1).RangeBox
oTightRangeBox.GetBoxData Mi, Mx
Debug.Print " End dX: " & oTightRangeBox.MaxPoint.X - oTightRangeBox.MinPoint.X & " " & _
"End dY: " & oTightRangeBox.MaxPoint.Y - oTightRangeBox.MinPoint.Y & " " & _
"End dZ: " & oTightRangeBox.MaxPoint.Z - oTightRangeBox.MinPoint.Z


oDerDoc.Close

End Sub


Public Function GetLargestFaceIndex(oBody As SurfaceBody, oFace As Face) As Integer

Dim FaceCount As Integer, N As Integer, X As Integer, I As Integer
FaceCount = oBody.Faces.Count
Dim oFace1 As Face, oFace2 As Face
Do
I = 1
X = I
Set oFace1 = oBody.Faces(I)
If oFace1.SurfaceType = kPlaneSurface Then
For N = I + 1 To FaceCount
Set oFace2 = oBody.Faces(N)
If oFace2.SurfaceType = kPlaneSurface Then
If oFace2.Evaluator.Area > oFace1.Evaluator.Area Then
Set oFace1 = oFace2
X = N
End If
End If
Next N
End If
I = I + 1
Loop While N <= FaceCount
If oFace1.SurfaceType <> kPlaneSurface Then
For N = 2 To FaceCount
Set oFace2 = oBody.Faces(N)
If oFace2.Evaluator.Area > oFace1.Evaluator.Area Then
Set oFace1 = oFace2
X = N
End If
Next N
End If
Set oFace = oFace1
GetLargestFaceIndex = X
End Function



Public Function GetLongestEdgeVector(oFace As Face) As Vector


Dim EdgeCount As Integer, N As Integer, X As Integer
Dim Pt1() As Double, Pt2() As Double
Dim Len1 As Double, Len2 As Double
EdgeCount = oFace.Edges.Count
Dim oEdge1 As Edge, oEdge2 As Edge
Set oEdge1 = oFace.Edges(1)
oEdge1.Evaluator.GetEndPoints Pt1, Pt2
Len1 = Sqr(((Pt1(0) - Pt2(0)) ^ 2) + ((Pt1(1) - Pt2(1)) ^ 2) + ((Pt1(2) - Pt2(2)) ^ 2))
X = 1
For N = 2 To EdgeCount
Set oEdge2 = oFace.Edges(N)
oEdge2.Evaluator.GetEndPoints Pt1, Pt2
Len2 = Sqr(((Pt1(0) - Pt2(0)) ^ 2) + ((Pt1(1) - Pt2(1)) ^ 2) + ((Pt1(2) - Pt2(2)) ^ 2))
If Len2 > Len1 Then
Set oEdge1 = oEdge2
X = N
End If
Next N
Dim oTG As TransientGeometry
Set oTG = ThisApplication.TransientGeometry
Dim TempVec As UnitVector
oEdge1.Evaluator.GetEndPoints Pt1, Pt2
Set TempVec = oTG.CreateUnitVector(Pt2(0) - Pt1(0), Pt2(1) - Pt1(1), Pt2(2) - Pt1(2))
Set GetLongestEdgeVector = TempVec.AsVector


End Function

Public Function NumberSort(ByRef NumberList() As Double) As Double

Dim I As Integer, N As Integer, X As Double
For I = 0 To UBound(NumberList) - 1
For N = I + 1 To UBound(NumberList)
If NumberList(I) < NumberList(N) Then
X = NumberList(I)
NumberList(I) = NumberList(N)
NumberList(N) = X
End If
Next N
Next I


End Function