Baking List Of Views

Hi everyone,

I’m working on a python script that adds named views to the document by receiving an input from the query Viewports node in Rhino 8.

I am using the new Rhino 8 viewport nodes to create orthographic and axonometric views of referenced objects in GH.

I have all the view set as I would like them but struggling to get the script to add them to the doc as expected.

One problem is my script isn’t adding the full set of views to the list to be baked (I think the flaw is in my for loop under def main.

Another problem is the script is not respecting the camera positions/extents/or projection type. It simply creates whatever view is current in the active viewport.

Any help or leads is greatly appreciated,

Thank you!

Graph Space:

Current Method (Manual):
Right click on View node and “Bake”
image

Desired Result (Automated):

Current Script:

import Rhino
import rhinoscriptsyntax as rs
import scriptcontext as sc

dm = Rhino.Display.DisplayModeDescription.FindByName("Rendered")  # Specify the display mode

sc.doc = Rhino.RhinoDoc.ActiveDoc

# Define the function that creates a named view
def create_named_view(view_name, view):
    view.Viewport.DisplayMode = dm  # Set the display mode of the view (optional)
    Rhino.RhinoDoc.ActiveDoc.NamedViews.Restore(view_name, view.ActiveViewportID)  # Create the named view


# Define the main script
def main(view_list, activate):
    if activate:
        named_views = Rhino.RhinoDoc.ActiveDoc.NamedViews
        for view_name in view_list:
            print view_name
            rs.AddNamedView(view_name)
            print "Added view: "

# Provide input parameters here
view_list = Views  # List of view names to check
activate = Activate  # Activate the script (True) or deactivate it (False)

print view_list
#print activate

# Call the main script
main(view_list, activate)

sc.doc = ghdoc

Hi Michael,

I’m not familiar with all the details, but maybe this is of help:

The function create_named_view doesn’t appear to be called anywhere in the script. Is something else using it?

If you look in the output from the component you’ve marked Ref, and have conveniently attached a text panel called View Name List to show N from it (which is connected to Views on the Python component), there are multiple repeated COLUMN DETAIL 01_Front. If the problem is that in the top right txt panel, that all you’re seeing there is Added View: \n COLUMN DETAIL 01_Front, the Python Component could be working correctly, but it will still do that, it’s just processing the list of duplicates it was given.

Maybe the views are being created, but the references to them aren’t being stored, so Ref never gets them?

Double check your inputs are on list mode too, if a for loop is intentional. Writing a Python component to be a simple in/out function, and letting Grasshopper handle the loop is another possibility.

1 Like

Hi James,

Thanks for your response. I caught that name duplicate issue and had corrected it but forgot to update the attached image in this post.

You can see here when I print view_name on line 20 I do output a list of the 6 orthographic views per object and when I run the script it does create 6 views per object, named correctly.

However, it creates them all as the same view (current viewport) instead of referencing the camera data from the view names.

Also good catch on the function not being called, I commented it out and it isn’t needed for the script it was a leftover.

I guess now I’m stuck on how to extract the view data from the views I already created and create the named views with those unique camera positions/projections for each item in the list.

I have all the camera data in the view, I guess I just need to research how to implement this camera data in the script:

Thanks for your help!

1 Like

I’m getting closer with this bit of code, I’m able to extract the camera locations, targets, etc from the Rhino Model Views but still unsure of how to feed this info into creating a new named view.

Any ideas?
Model Space: (retrieved data as expected, illustrated here by displaying the camera vectors)

Graph Space:

Code thus far:

import Rhino
import System
import rhinoscriptsyntax as rs
import scriptcontext as sc

ids = []
cam_locs = []
cam_tgts = []
orthos = []

def get_view_info(V, A):
    for view_info in V:
        # Get GH View Properties
        ids.append(view_info.Id)
        cam_locs.append(view_info.CameraLocation)
        cam_tgts.append(view_info.TargetPoint)
        orthos.append(view_info.IsParallelProjection)

    sc.doc.Views.Redraw()

get_view_info(V, A)

print cam_tgts

def add_named_views(VN, ids, A):
    for name, id in zip(VN, ids):
        viewport = sc.doc.Views.Find(id)
        if viewport:
            rs.AddNamedView(name, viewport.Id.ToString())  # Pass viewport ID as a string
    return

# Call the function to add the named views
if A:
    add_named_views(VN, ids, A)

sc.doc = ghdoc

L = cam_locs
T = cam_tgts
P = orthos
ID = ids

Thank you all for the help!

1 Like

How about something like this?
BakeModelView.gh (8.2 KB)

1 Like

Thank you so much @AndyPayne ! I was hoping it was this simple but couldn’t figure out how to make the view info work for me.

Much appreciated!

Here’s the code I ended up with:

import Rhino
import rhinoscriptsyntax as rs
import scriptcontext as sc

CVs = Rhino.RhinoDoc.ActiveDoc.NamedViews
Current_View_Names = []
for cv in CVs:
    Current_View_Names.append(cv.Name)

def bake_views():
    for name, view in zip(N, V):
        # Get/Set Viewport Info
        viewport = Rhino.Display.RhinoViewport() 
        viewport.Name = name
        viewport.SetViewProjection(view, False)

        if name in Current_View_Names:
            # Check If The Existing Named View Has Changed Camera Position At All
            exv_index = CVs.FindByName(name)
            existing_view = CVs[exv_index]
            if existing_view.Viewport.CameraLocation != view.CameraLocation and existing_view.Viewport.CameraDirection != view.CameraDirection:
                # Remove existing view
                sc.doc = Rhino.RhinoDoc.ActiveDoc
                rs.DeleteNamedView(name)

                # Add the new view
                Rhino.RhinoDoc.ActiveDoc.NamedViews.Add(Rhino.DocObjects.ViewInfo(viewport))
                
                #Refresh The Viewport If It Is Currently The Modifed View
                if rs.CurrentView() == name:
                    rs.RestoreNamedView(name)
                sc.doc = ghdoc
        else:
            # Add View(s) To Document
            Rhino.RhinoDoc.ActiveDoc.NamedViews.Add(Rhino.DocObjects.ViewInfo(viewport))

    return V

if B:
    bake_views()

I expanded the code to accept a boolean allowing it to be “active” and if a named view does not exist, it adds it, if a named view camera changes its position, it updates the current named views by deleting the changed views and readding it. Ideally I would like to keep the view and just modify the required settings but wasn’t having any luck there.

Graph Space:

I think you don’t need to delete the existing view if it already exists. I think it should simply update the named view with the new view info if there’s already one with that name in the store Named Views table.

Thanks @AndyPayne , I thought so too but didn’t seem to get that working. It does appear to update the view but only if I manually double click/activate the Named View from inside the Rhino Named View List