Hello,
I am developing the API to automation assemblies and have run into a bit of a snag. I'm having trouble understanding how the camera upvector can be changed to minipulate the view. I'm attempting to rotate the front view 180 degrees around the z-axis - similar to clicking the rotate arrows on the view cube - and then set that position as the front view. I've found some examples of people changing the camera position but I don't have a clear underanding of how to do what I want to do. Here is my code:
Sub ViewChange() Dim oTG As Inventor.TransientGeometry = _invApp.TransientGeometry Dim oCamera As Inventor.Camera = _invApp.ActiveView.Camera oCamera.ViewOrientationType = ViewOrientationTypeEnum.kFrontViewOrientation oCamera.ApplyWithoutTransition() Dim zAxis As Inventor.Vector = oCamera.Target.VectorTo(oCamera.Eye) Dim oMatrix As Inventor.Matrix = oTG.CreateMatrix oMatrix.SetToRotation(PI, zAxis, _invApp.ActiveView.Camera.Target) _invApp.ActiveView.Camera.UpVector.TransformBy(oMatrix) oCamera.ApplyWithoutTransition() _invApp.ActiveView.SetCurrentAsFront() End Sub
Can anyone point me in the right direction?
Solved! Go to Solution.
Solved by philippe.leefsma. Go to Solution.
I actually found a work around where I unground the base part, roate it around the z-axis, then reground it before adding the remaining components. This is enough to keep me moving forward but I'd really like to understand how to move the camera around 3D space. Here is the code for my workaround:
'' Define a matrix that is used to rotate '' the base part 180 degrees Dim oMatrix As Matrix = oTG.CreateMatrix oMatrix.SetToRotation(PI, oTG.CreateVector(0, 0, 1), _ oTG.CreatePoint(0, 0, 0)) Try oOcc = oOccs.Add(path & FileName, oPos) oOcc.Grounded = False oOcc.SetTransformWithoutConstraints(oMatrix) oOcc.Grounded = True Catch MsgBox("An Error occured adding " & FileName & ".") Exit Sub End Try
Hi Robert,
Modifying the camera and rotating the occurrence itself are two different things.
When you want to modify the camera properties, you need to store the camera object in a variable then modify it, not directly modifying the camera as you do with "_invApp.ActiveView.Camera.UpVector.TransformBy"
Here is a sample that illustrates how to rotate the camera inside a part or assembly. Concerning working with the up vector, it is no different in Inventor than in other 3d graphic programming. You may want to check an OpenGL tutorial on manipulating camera if you are not familliar with the concept.
Also I don't think it is possible to redefine a predefined view as you mention "and then set that position as the front view".
Public Sub RotateCamMacro() Dim pi As Double pi = Math.Atn(1) * 4 'Rotation speed in Rad/Sec Dim rotSpeedRad As Double rotSpeedRad = 40 * pi / 180 'Get part document Dim doc As Document Set doc = ThisApplication.ActiveDocument 'Get range box center point Dim centerPoint As point Set centerPoint = GetRangeBoxCenter(doc) 'Set camera orientation Call SetCameraOrientation( _ centerPoint, _ ViewOrientationTypeEnum.kIsoTopRightViewOrientation) 'Get Inventor camera Dim camera As Inventor.camera Set camera = ThisApplication.ActiveView.camera Dim totalRot As Double totalRot = 0 Dim offsetRad As Double Dim rotAxis As vector Set rotAxis = ThisApplication.TransientGeometry.CreateVector(0, 1, 0) Dim upVector As UnitVector Set upVector = ThisApplication.TransientGeometry.CreateUnitVector(0, 1, 0) Dim hiTimer As New hiTimer hiTimer.ElapsedSeconds Do While (totalRot < 2 * pi) offsetRad = hiTimer.ElapsedSeconds * rotSpeedRad RotateCam camera, offsetRad, rotAxis, centerPoint, upVector totalRot = totalRot + offsetRad Loop Call SetCameraOrientation( _ centerPoint, _ ViewOrientationTypeEnum.kIsoTopRightViewOrientation) End Sub Public Function GetRangeBoxCenter(ByVal doc As Document) As point Dim minPoint As point Set minPoint = doc.ComponentDefinition.RangeBox.minPoint Dim maxPoint As point Set maxPoint = doc.ComponentDefinition.RangeBox.maxPoint Set 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 SetCameraOrientation( _ ByVal targetPoint As point, _ ByVal viewOrientation As ViewOrientationTypeEnum) Dim camera As Inventor.camera Set camera = ThisApplication.ActiveView.camera camera.ViewOrientationType = viewOrientation camera.target = targetPoint Call camera.Fit Call camera.ApplyWithoutTransition End Sub Public Sub RotateCam( _ camera As camera, _ ByVal offsetRad As Double, _ rotAxis As vector, _ center As point, _ upVector As UnitVector) Dim matrix As matrix Set matrix = ThisApplication.TransientGeometry.CreateMatrix Call matrix.SetToRotation(offsetRad, rotAxis, center) Dim newEye As point Set newEye = camera.eye Call newEye.TransformBy(matrix) camera.eye = newEye camera.upVector = upVector Call camera.ApplyWithoutTransition End Sub
Here is the code of my timer class:
Option Explicit Private Declare Function GetTickCount Lib "kernel32" () As Long Private Declare Function QueryPerformanceFrequency Lib "kernel32" (lpFrequency As Currency) As Long Private Declare Function QueryPerformanceCounter Lib "kernel32" (lpPerformanceCount As Currency) As Long Private dtStart As Long Private mHiFreq As Currency Private mHiStartTime As Currency Public Function ElapsedSeconds() As Double Dim elapsed As Double Dim dtEnd As Long dtEnd = GetTickCount elapsed = (dtEnd - dtStart) * 0.001 dtStart = dtEnd ElapsedSeconds = elapsed End Function Public Sub start() QueryPerformanceFrequency (mFreq) QueryPerformanceCounter (mStartTime) ElapsedSeconds End Sub Public Property Get HiElapsedSeconds() As Double Dim NewTime As Currency QueryPerformanceCounter (NewTime) HiElapsedSeconds = (NewTime - mStartTime) / mFreq mStartTime = NewTime End Property
I hope it helps.
Regards,
Philippe.