Cycle through layers and namedviews using python rhinoscriptsyntax

I am an architect, and often I have to do a similar task: I design multiple options for a project, each on a layer, in the following tree organisation:
OPTIONS
– 01
– 02
– 03

I then create a couple of named views. I will then create screen captures for each option, using each namedview. Manually, this is quite a laborious and error prone process, and I think it would benefit from being automate with a little script.

Somehow, if i loop over 1 single option and create a screenshot for each namedview, it works.

(For instance with this code):

import rhinoscriptsyntax as rs

views = rs.NamedViews()

def make_capture(option, view):
    print(view)
    rs.RestoreNamedView(view, view=None, restore_bitmap=False)    
    comm=""" -_ViewCaptureToFile C:\\Users\\vincentk\\Desktop\\200203_Massing_Study\\View{}_Option{}.png 
    _Width=1200 _Height=900 _Scale=1 
    _DrawGrid=_No _DrawWorldAxes=_No _DrawCPlaneAxes=_No 
    _TransparentBackground=_No _Enter""".format(option, view)
    rs.Command(comm,False)

for view in views:
    print(view)
    make_capture(1, view)
    rs.RestoreNamedView(view, view=None, restore_bitmap=True)

But when I create the nested loop with looping over each option, and then looping over each namedview within them, the second loop is ignored and it is only creating a screenshot for the first named view of each option.

import rhinoscriptsyntax as rs

views = rs.NamedViews()

def make_capture(option, view):
    rs.RestoreNamedView(view, view=None, restore_bitmap=False)
    comm=""" -_ViewCaptureToFile C:\\Users\\vincentk\\Desktop\\200203_Massing_Study\\View{}_Option{}.png 
    _Width=1200 _Height=900 _Scale=1 
    _DrawGrid=_No _DrawWorldAxes=_No _DrawCPlaneAxes=_No 
    _TransparentBackground=_No _Enter""".format(option, view)
    rs.Command(comm,False)

layers = rs.LayerNames()
for layer in layers:
    if 'OPTIONS::' in layer:
        print(layer)
        rs.LayerVisible(layer, visible=True, forcevisible_or_donotpersist=False)
        for view in views:
            print(view)
            make_capture(layer, view)
        rs.LayerVisible(layer, visible=False, forcevisible_or_donotpersist=False)

Anyone have any idea / experience with that problem, and could give a pointer?

PS: Also - It seems that when the scene is to heavy, the loop doesn’t wait for the image to refresh before iterating to the next loop element; the script tends to crash rhino altogether in such case, in addition to the problem mentioned above. I have tried to use time.sleep for the screen to have time to refresh, but it seems to be the source of even more freeze and crashes. Any experience, pointers with the help of time.sleep in the context of loops + heavy geometry appreciated as well! Thanks

Hi Vincent,

Disclaimer: Not testing but reading the code

I suspect the :: in layername as the filename will trow a error on windows for being an illegal character in file paths.

You might need to add an rs.Redraw() to force the view to redraw before capturing. However since do not seem to have Redrawing off it could be of no help. Yet putting everything between a

rs.EnableRedraw(True)
...
rs.EnableRedraw(False)

And only rs.Redraw() before the capture will probably speed things up.

Also iirc for the scripted command -_ViewCaptureToFile you need to pass the filename last as that fires the saving and nothing happens with the passed settings.

As for the command string encapsulating. You can use both ’ and " for string in python and escaping \ is not needed for commands. Yet putting a path for commands on double quotes can prevent paths with spaces from not being fully parsed. You can do this:

comm= ’ command argument=yes “C\my path\with spaces.png” _Enter’

HTH let us know if you still have any issue

-Willem

1 Like

Thanks!

Yes the ‘::’ was the issue in the end. The problem is that the script silently failed, so I couldnt figure it out by myself. Is there a way to make the script more verbose?

I also discovered the rs.Sleep() that i can use to wait for screen refresh (instead of time.sleep() that seems not to be good with rhino).

Thanks again.

1 Like