Setting up your ViewOrientation3D

Here is a contribution from Mario Guttman of

CASE
,
who already made various contributions here in the past.
He says:

I have been purging my 2013 code of deprecated functions in preparation for my 2014 upgrade.
One group of statements I have needed to replace are the view creations.
They were previously using the Document.Create.NewView3D method and needed converting to the View3D.CreateIsometric with a separate ViewOrientation3D object defining the view direction.

Typically, in these kind of cases, I just search your blog for the answer.
In this case I found a few references, for example your March 04, 2013 item on

What’s New in the Revit 2013 API – View API – View Creation
.
This, together with the

wikihelp entry on the View3D class
,
describe the new syntax, but they don’t really explain how you would create the values.

After searching the inner reaches of my brain for some ancient math skills I figured out the following:

Assuming that your user interface has produced two angular values (in degrees):


  /// <summary>
  /// The angle in the XY plane (azimuth),
  /// typically 0 to 360.
  /// </summary>
  double angleHorizD;
 
  /// <summary>
  /// The vertical tilt (altitude),
  /// typically -90 to 90.
  /// </summary>
  double angleVertD;

Then this utility function returns a unit vector in the specified direction:


  /// <summary>
  /// Return a unit vector in the specified direction.
  /// </summary>
  /// <param name="angleHorizD">Angle in XY plane 
  /// in degrees</param>
  /// <param name="angleVertD">Vertical tilt between 
  /// -90 and +90 degrees</param>
  /// <returns>Unit vector in the specified 
  /// direction.</returns>
  private XYZ VectorFromHorizVertAngles(
    double angleHorizD,
    double angleVertD )
  {
    // Convert degreess to radians.
 
    double degToRadian = Math.PI * 2 / 360;
    double angleHorizR = angleHorizD * degToRadian;
    double angleVertR = angleVertD * degToRadian;
 
    // Return unit vector in 3D
 
    double a = Math.Cos( angleVertR );
    double b = Math.Cos( angleHorizR );
    double c = Math.Sin( angleHorizR );
    double d = Math.Sin( angleVertR );
 
    return new XYZ( a * b, a * c, d );
  }

From this it is easy to create the ViewOrientation3D object as follows:


  XYZ eye = XYZ.Zero;
 
  XYZ forward = VectorFromHorizVertAngles(
    angleHorizD, angleVertD );
 
  XYZ up = VectorFromHorizVertAngles(
    angleHorizD, angleVertD + 90 );
 
  ViewOrientation3D viewOrientation3D
    = new ViewOrientation3D( eye, up, forward );

Although it is already explained in one of your other posts, just for completeness, here is the final step is to apply the orientation to the view:


  ViewFamilyType viewFamilyType3D
    = new FilteredElementCollector( doc )
      .OfClass( typeof( ViewFamilyType ) )
      .Cast<ViewFamilyType>()
      .FirstOrDefault<ViewFamilyType>(
        x => ViewFamily.ThreeDimensional
          == x.ViewFamily );
 
  View3D view3d = View3D.CreateIsometric(
    doc, viewFamilyType3D.Id );
 
  view3d.SetOrientation( viewOrientation3D );

I hope you find this useful.

Personally, I do indeed.

Many thanks to Mario for sharing!

Addendum

Colmag adds in
his comment below:

Thank you for sharing this info, it’s made life a whole lot easier in setting 3D view orientation.

It did take me a short while to work out the values to replicate top and bottom isometric views from each corner of the view cube, so I thought I’d share the values here for others. Looking at them listed out they are pretty obvious, but faced with a blank sheet things didn’t seem so straight forward!

  • Horizontal Angles:
    • Left Front = 45
    • Front Right = 135
    • Right Back = 225
    • Back Left = 310
  • Vertical Angles:
    • -30 = Top
    • 30 = Bottom

Many thanks to Colmag for this useful addition!

Addendum 2

K C Tang added a further simplification in
his comment below:

I found that the formula above using ( a * b, a * c, d ) to calculate the return value from VectorFromHorizVertAngles can be further simplified, because:


( a * b, a * c, d )
≡ ( a * b / a , a * c / a, d / a )
= (b, c, d/a)
= (b, c, e),

where


double e = Math.Tan( angleVertR ).

In words, the return value from VectorFromHorizVertAngles can be defined as:

  • cos (horizontal angle) for X
  • sin (horizontal angle) for Y
  • tan (vertical angle) for Z

Many thanks to K C Tang for this simplification and explanation highlighting the basic trigonometric relationships between the angles and the vectors involved so much better than the original version!


Comments

4 responses to “Setting up your ViewOrientation3D”

  1. Hi Jeramy,
    I know this is a comment on quite an old post, but I’m kinda stuck in creating (I must say one of my first) addins.
    I’m recently trying to study the View3D / setOrientation classes and objects. According to your post on the “whats new on” revit 2013 api the setOrientation object can be used to set or GET the object value of a view. (http://thebuildingcoder.typepad.com/blog/2013/03/whats-new-in-the-revit-2013-api.html)
    Now setting the viewOrientation3D is quite straightforward, but since I need to copy the orientation of an existing view to the next to create stacked floorplates in isometric views. I need to first READ the ViewOrientation3D properties before being able to set it in the next.
    Do you know how can this be done? How can one GET the activeview ViewOrientation3D properties using the setOrientation object in an active isometric view…
    Many thanks

  2. Dear David,
    How about View3D.GetOrientation?
    Here is another related article, by the way:
    http://thebuildingcoder.typepad.com/blog/2013/08/setting-a-default-3d-view-orientation.html
    Cheers, Jeremy.

  3. new XYZ.Zero;
    Remove the “new”, unless you are creating a new instance of a type.

  4. Dear Who,
    I like your moniker!
    Absolutely right you are!
    Thank you for pointing it out!
    Fixed.
    Merry Christmas and a Happy New Year to you!
    Cheers, Jeremy.

Leave a Reply

Discover more from Autodesk Developer Blog

Subscribe now to keep reading and get access to the full archive.

Continue reading