Inventor Customization

Inventor Customization

Reply
Active Contributor
Robert..F
Posts: 49
Registered: ‎07-09-2012
Message 1 of 4 (564 Views)
Accepted Solution

Camera rotation within an assembly

564 Views, 3 Replies
08-28-2012 01:08 PM

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?

 

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.

Active Contributor
Robert..F
Posts: 49
Registered: ‎07-09-2012
Message 2 of 4 (550 Views)

Re: Camera rotation within an assembly

08-30-2012 10:39 AM in reply to: Robert..F

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

 

ADN Support Specialist
philippe.leefsma
Posts: 676
Registered: ‎06-02-2009
Message 3 of 4 (528 Views)

Re: Camera rotation within an assembly

09-04-2012 01:33 AM in reply to: Robert..F

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.



Philippe Leefsma
Developer Technical Services
Autodesk Developer Network

Active Contributor
Robert..F
Posts: 49
Registered: ‎07-09-2012
Message 4 of 4 (508 Views)

Re: Camera rotation within an assembly

09-14-2012 03:59 AM in reply to: philippe.leefsma

Thanks.  This is enough to get me started.

Post to the Community

Have questions about Autodesk products? Ask the community.

New Post
Announcements
Do you have 60 seconds to spare? The Autodesk Community Team is revamping our site ranking system and we want your feedback! Please click here to launch the 5 question survey. As always your input is greatly appreciated.