Saving Appearance & Visibilities overrides in viewpoints (throwing NullReferenceExceptions)

Saving Appearance & Visibilities overrides in viewpoints (throwing NullReferenceExceptions)

steve.alberts
Participant Participant
2,607 Views
5 Replies
Message 1 of 6

Saving Appearance & Visibilities overrides in viewpoints (throwing NullReferenceExceptions)

steve.alberts
Participant
Participant

Hi all,

 

I am trying to save color & visibility overrides from a Navisworks viewpoint, so that they can be reopened later. Unfortunately I have run into some issues with this. It doesn't seem to happen by default in the API, even after changing the Viewpoint Defaults settings to be saving appearances & visibilities.

(So I do see that this has effect when I manually save a viewpoint in Navisworks, but it fails to work when I try the same via the API). 

 

I found out that the SaveViewpoint class contains properties to check whether these overrides are set, but unfortunately they're read only and their getters are throwing NullReferenceExceptions. See the below screenshots. 

 

stevealberts_0-1634825431558.png

stevealberts_1-1634825640645.png

Is there any way to make this work, so that I can use the GetAppearanceOverrides and GetVisibilityOverrides methods to save those overrides? (Those two methods seem to depend on the above properties, and give the same nullreferenceexceptions when I call them)

 

Another suggestion I've found is to try and use the

InwOpView.ApplyHideAttribs
InwOpView.ApplyMaterialAttribs
properties to apply the overrides, but I haven't been able to figure out how to convert my Navisworks API viewpoint to the old InwOpView type. 

Any suggestions would be much appreciated! I am currently working with Navisworks 2020, but ultimately this solution has to work for 2019--2022. Thanks in advance!

0 Likes
2,608 Views
5 Replies
Replies (5)
Message 2 of 6

burkhard.walger
Contributor
Contributor

Hi steve,

my program has to do this too and I discovered that it is impossible to have the options switched on that allow to save the overrides with a saved viewpoint by just using the C# API. You have to use the COM API for that:

using Autodesk.Navisworks.Api;
using Autodesk.Navisworks.Api.ComApi;
using Autodesk.Navisworks.Api.Interop.ComApi;
...
public static void saveCurrentView(string name)
{
  // The COM state manager
  var state = ComApiBridge.State;
  // Get the index of the saved viewpoint in the list of saved viewpoints if any
  var index = Application.ActiveDocument.SavedViewpoints.Value.IndexOfDisplayName(name);
  // Create a new saved viewpoint ...
  var saved_view = (InwOpView) state.ObjectFactory(nwEObjectType.eObjectType_nwOpView);
  saved_view.name = name;
  // Switch on saving of visibility and ...
  saved_view.ApplyHideAttribs = true;
  // ... appearance overrides
  saved_view.ApplyMaterialAttribs = true;
  // Capture the current viewpoint
  var current_viewpoint = (InwNvViewPoint2) ((InwOpAnonView) state.CurrentView).ViewPoint.Copy();
  // Set the current viewpoint to the new saved viewpoint
  saved_view.anonview.ViewPoint = current_viewpoint;
  if (index < 0) // Was not available
    // Add it to the list of saved viewpoints
    state.SavedViews().Add(saved_view);
  else
  {
    // As COM does indexing based one it has to be incremented
    index++;
    // Save it to the list by indexing
    state.SavedViews().Replace(index,saved_view);
  }
}

 This works on NW 2023 too. I hope that still helps.

Message 3 of 6

alexisDVJML
Collaborator
Collaborator

@burkhard.walger Thanks for this very useful piece of code, particularly the use of 

state.SavedViews()
Main Scientist, Full Stack Developer & When Time Permits Director of IDIGO ► On your marks, Set, Go
0 Likes
Message 4 of 6

alexisDVJML
Collaborator
Collaborator

@burkhard.walger 

var index = Application.ActiveDocument.SavedViewpoints.Value.IndexOfDisplayName(name);

Your sample code is based on the SavedViewPoint being at the root of the Document SavedItems, right?

In my case, I need to modify the list of SavedViewPoint MaterialOverrides of SavedViewPoint that are not at the root level.
Modifying MaterialOverrides directly is possible but it does not modify the actual list of the SavedViewPoint.

Can't find way to replace these. So was thinking of using your technique to recreate a new SavedViewpoint usign current view that have correct items material override, and eure it get ApplyMaterialAttribs set using your method.


I just can't find how to go back and forth between SavedViewpoint/SavedGroup high level class and InwOpView class you use so I can replace my original SavedViewPoint in its parent.

 

Any tips in the right direction will be appreciated 😉

Main Scientist, Full Stack Developer & When Time Permits Director of IDIGO ► On your marks, Set, Go
0 Likes
Message 5 of 6

burkhard.walger
Contributor
Contributor

@alexisDVJMLEssentially you have two options:

  • Traverse the saved viewpoints folder tree via COM interop
  • Convert the InwOpView to a SavedViewpoint and traverse the tree by .NET API means

Traverse via COM:

 

 

public static void TraverseSavedViews(InwOpState10 state, InwSavedViewsColl view_coll, string name) 
{
  var index = 1;    
  foreach (InwOpSavedView item in view_coll) // Over all subitems
  {
    switch (item.Type)
    {
      case  nwESavedViewType.eSavedViewType_View : // It's a saved viewpoint ...
      {
        var view = (InwOpView) item; // ... so we can cast it to a saved viewpoint
        if (name.Equals(view.name)) // It's the one we look for
        {
          var saved_view = (InwOpView) state.ObjectFactory(nwEObjectType.eObjectType_nwOpView);
          saved_view.name = name;
          // Do viewpoint capture as shown
          view_coll.Replace(index,saved_view);
          return;
        }
      }
      break;
      case nwESavedViewType.eSavedViewType_Folder : // It's a folder ...
      {
        var folder = (InwOpFolderView) item;  // ... so we can traverse its subfolders
        TraverseSavedViews(state, folder.SavedViews(), name);
      }   
      break;
      case nwESavedViewType.eSavedViewType_Anim   : // It's an animation
      case nwESavedViewType.eSavedViewType_Cut    : // Whatever
      break;
    }
    index++;
  }
}

 

 

This is recursive as you can see. You call it with:

 

 

var state = ComApiBridge.State;
TraverseSavedViews(state, state.SavedViews(),"MySavedItemName");

 

 

 I leave it as an exercise to you to implement the case the saved viewpoint with this name does not exist. In this case you have to decide to which folder the item should be added anyway.

 

Beware: the code is not tested thoroughly!

 

To convert an InwOpView to a SavedViewpoint you could do following:

In COM context

  • Add it with a unique GUID Name to the list of saved viewpoints as shown

With .NET API means

  • Read to a copy and rename it
  • Save this to the target folder
  • Delete the GUID named saved viewpoint

This until someone comes up with a more elegant way to do it.

Message 6 of 6

alexisDVJML
Collaborator
Collaborator

Thanks!

Main Scientist, Full Stack Developer & When Time Permits Director of IDIGO ► On your marks, Set, Go
0 Likes