Capturing Viewports on Rhino 7 & 8

Hello, I’ve been developing a set of custom components, and I need to save viewports as images.

I tried doing this with RhinoDoc.ActiveDoc.Views.CaptureToBitmap(), and this works perfectly well enough for Rhino 8.
I have to target Rhino 7 as well however, and I found that the namespace Grasshopper.Rhinoceros.Display does not exist for it. I need this in order to access the type ModelStandardViewport, which is the input to one of my components.

Is there a way to capture viewports on Grasshopper / Rhino 7 programmatically? Or am I going about this the wrong way (in terms of not using built-in components)?

Thank you in advance for any help or insight!

EDIT: I couldn’t find any developer docs for Rhino 7 / Grasshopper. If anyone could point me to it, I would check that as well.

Krishna Sivakumar

Hey @Krishna_Sivakumar i would be curious how you did solve the viewport capture logic in rhino 8!
im in the same position but cannot figure it out myself unfortunalty.

Hi Timon!
If you’re working with C# and Rhino 8, RhinoDoc.ActiveDoc.Views will contain a list of all the active viewports.

You can iterate through the list to select the viewport you need and use .captureToBitmap() to get a bitmap screenshot.

Hey @Krishna_Sivakumar thanks for the reply!
im mainly using python for now to script as i m not yet familiar with the C# syntax.

do you maybe have a code example for this ?
i basicly just have to capture all active viewports and export them to different png files with transparent backgrond.

Thanks!

-T

Hi,

You can try this:

#! python 3

import Rhino
import os


path = "/Users/marc/Desktop"  # change the path of the output directory
img_format = ".png"


for view in Rhino.RhinoDoc.ActiveDoc.Views:
    if view is None:
        continue
    
    view_name = view.MainViewport.Name
    
    filename = f"{view_name.lower()}{img_format}"
    file_path = os.path.join(path, filename)
    print(file_path)

    bmp = view.CaptureToBitmap()
    
    if bmp is not None:
        bmp.Save(file_path)
        bmp.Dispose()
1 Like

hey @diff-arch that works like a charm!!
Nice :slight_smile:

Do you know of any way to increase the resoltion of the output PNG ?

I think it exports the exact size of the current viewports, so if you make the Rhino window bigger, you’ll also end up with larger images.
Check if the view inside the for-loop has a width and height property (i.e.; view.Width). Maybe you can manipulate that the get a bigger image, like view.Width = 1280 or similar?
I’m currently away from the computer so I can’t test it.

1 Like

This should do the trick:

#! python 3

import Rhino
import os


path = "/Users/marc/Desktop"  # change the path of the output directory
img_format = ".png"
img_width = 1920
img_height = 1080


for view in Rhino.RhinoDoc.ActiveDoc.Views:
    if view is None:
        continue
    
    view_name = view.MainViewport.Name

    view_capture = Rhino.Display.ViewCapture()
    view_capture.Width = img_width
    view_capture.Height = img_height
    view_capture.TransparentBackground = False
    
    bmp = view_capture.CaptureToBitmap(view)
    
    if bmp is not None:
        filename = f"{view_name.lower()}{img_format}"
        file_path = os.path.join(path, filename)
        #print(file_path)

        bmp.Save(file_path)
        bmp.Dispose()
1 Like

Huge!!
That is really good! I actually was able to understand the rhino common better now just following the script and how it works. Thanks!

I was also able to find the CaptureToSvg inside Rhino common.
Tried to make it work but the error involves to be:
Error running script: Rhino.Display.RhinoView value cannot be converted to Rhino.Display.ViewCaptureSettings in method System.Xml.XmlDocument CaptureToSvg(Rhino.Display.ViewCaptureSettings) [28:1]

So for my understanding and how the Rhino common describes, the CaptureToBipmap can capture the RhinoView - CaptureToSvgon the other hand needs further Viewcapture Settings.

#! python 3

import Rhino
import os


path = _filepath
img_format_png = ".png"
img_format_svg = ".svg"
img_width = 1920
img_height = 1080
img_resolution = 200


for view in Rhino.RhinoDoc.ActiveDoc.Views:
    if view is None:
        continue
    
    view_name = view.MainViewport.Name

    view_capture = Rhino.Display.ViewCapture()
    view_capture.Width = img_width
    view_capture.Height = img_height
    view_capture.TransparentBackground = False
    
    view_capture_settings = Rhino.Display.ViewCaptureSettings()
    #view_settings.Resolution = img_resolution
    
    bmp = view_capture.CaptureToBitmap(view)
    svg = view_capture.CaptureToSvg(view)
    
    if bmp is not None:
        filename = f"{view_name.lower()}{img_format_png}"
        file_path = os.path.join(path, filename)
        #print(file_path)

        bmp.Save(file_path)
        bmp.Dispose()

    if svg is not None:
        filename = f"{view_name.lower()}{img_format_svg}"
        file_path = os.path.join(path, filename)
        #print(file_path)

        svg.Save(file_path)
        svg.Dispose()

I didnt understand how i can define the defined syntax from the Rhino Common..
Can you meybe refer to it ?

otherwise i will try to increate the resolution inside.

But yeah already big help in understanding how to fix things myself :slight_smile:
-T

As you might know, a PNG is a rasterized image composed of colored pixels, whereas a SVG is a vector graphics format that is represented by more complex numerical data. A view probably represents a GPU rendered image and thus can be easily exported to JPG, PNG, etc..
To export a SVG on the other hand you need the numerical data of the geometry in your scene and a parser/exporter that translates it to the SVG specification.
SVG is also mostly meant for 2D graphics, so there’s the question how to deal with three-dimensional geometries in the Rhino scene.

1 Like

Yes :slight_smile:
I just export perfectly shaped Spehres that can be easily described by functions.
these bulbs get colors based on raytracing outcome calculations so the more rays, the bigger the geometry and the color change.

in my head the mathimatical approach is much faster and also cleaner in the output in the end.

now i feel like rhino alrays captures the view rasterize it basically a screenshot of the rhino view.

it will be sufficient but svg would be much more easy to further integrate into ArchiCAD axometries of buildings in indesign

-T

Viewport Capture is also creating some weird Artifacts that i dont know coming from