Message 1 of 10

Not applicable
03-04-2021
04:49 AM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
Hi all,
I'm attempting to create a script that find the largest face, then rotates the part clockwise in reference to that face. The code works, but rotates the part seemingly randomly.
I have taken the following approach:
- Get the largest face and set it to the Front View
- Find the largest face normal
- Set the Rotational Axis and Up Vector to the largest face normal (this is probably a mistake)
My questions are:
- What should the relationship of the Rotational Axis and Up Vector be to the largest face normal if I want the part to rotate clockwise in 90 degree increments?
- How can I represent that in my code?
Here is the code that I have cobbled together so far. It should work in any part file.
Thanks!
Sub Main()
Dim oDoc As PartDocument = ThisApplication.ActiveDocument
RotateCamMacro(oDoc, GetFaceNormal(getLargestAreaFace(oDoc)))
End Sub
Function getLargestAreaFace(oDoc As PartDocument) As Face
Dim maxarea As Double: maxarea = 0
Dim oface As Face
Dim ofacemax As Face
For Each oface In oDoc.ComponentDefinition.SurfaceBodies.Item(1).Faces
If oface.SurfaceType <> kCylinderSurface Then
If oface.Evaluator.Area > maxarea Then
maxarea = oface.Evaluator.Area
ofacemax = oface
End If
End If
Next
Dim oSSet As SelectSet = oDoc.SelectSet
Call oSSet.Clear
Call oSSet.Select(ofacemax)
ThisApplication.CommandManager.ControlDefinitions.Item("AppLookAtCmd").Execute
ThisApplication.CommandManager.ControlDefinitions("AppViewCubeViewFrontCmd").Execute
getLargestAreaFace = ofacemax
End Function
' Utility function that given a face returns a normal. This is only useful
' for planar faces, since they have a consistent normal anywhere on the face.
Function GetFaceNormal(InputFace As Face) As UnitVector
Dim eval As SurfaceEvaluator
eval = InputFace.Evaluator
' Get the center of the parametric range.
Dim center(1) As Double
center(0) = (eval.ParamRangeRect.MinPoint.X + eval.ParamRangeRect.MaxPoint.X) / 2
center(1) = (eval.ParamRangeRect.MinPoint.Y + eval.ParamRangeRect.MaxPoint.Y) / 2
' Calculate the normal.
Dim normal(2) As Double
Call eval.GetNormal(center, normal)
' Create a unit vector to pass back the result.
GetFaceNormal = ThisApplication.TransientGeometry.CreateUnitVector(normal(0), normal(1), normal(2))
End Function
Public Sub RotateCamMacro(doc As PartDocument, oVector As UnitVector)
doc.Activate
'Rotation speed in Rad/Sec
Dim rotSpeedRad As Double
rotSpeedRad = 40 * PI / 180
'Get range box center point
Dim centerPoint As Point
centerPoint = GetRangeBoxCenter(doc)
'Get Inventor camera
Dim camera As Inventor.Camera
camera = ThisApplication.ActiveView.Camera
Dim totalRot As Double
totalRot = 0
'Issue is probably here-----------------------------------
Dim rotAxis As Vector
rotAxis = oVector.AsVector
Dim upVector As UnitVector
upVector = oVector
'--------------------------------------------------------
Dim offsetRad As Double
Do While (totalRot < 0.5 * PI)
offsetRad = 0.05 * rotSpeedRad
RotateCam (camera, offsetRad, rotAxis, centerPoint, upVector)
totalRot = totalRot + offsetRad
Loop
End Sub
Public Function GetRangeBoxCenter(ByVal doc As Document) As Point
Dim minPoint As Point
minPoint = doc.ComponentDefinition.RangeBox.minPoint
Dim maxPoint As Point
maxPoint = doc.ComponentDefinition.RangeBox.maxPoint
GetRangeBoxCenter = ThisApplication.TransientGeometry.CreatePoint( _
(minPoint.X + maxPoint.X) * 0.5, _
(minPoint.Y + maxPoint.Y) * 0.5, _
(minPoint.Z + maxPoint.Z) * 0.5)
End Function
Public Sub RotateCam( _
camera As Camera, _
ByVal offsetRad As Double, _
rotAxis As Vector, _
center As Point, _
upVector As UnitVector)
Dim matrix As Matrix
matrix = ThisApplication.TransientGeometry.CreateMatrix
Call matrix.SetToRotation(offsetRad, rotAxis, center)
Dim newEye As Point
newEye = camera.eye
Call newEye.TransformBy(matrix)
camera.eye = newEye
camera.upVector = upVector
Call camera.ApplyWithoutTransition
End Sub
Solved! Go to Solution.