[Python] Printing Catalogue into Multiple PDFs



Hi guys,

I was wondering if someone could help me write a script to automate a very tedious workflow.

I want to keep this simple. I work by organizing multiple 2D drawings inside a grid on one single Rhino file.
What I need to do is automate the printing of each of these drawings to separate PDFs files (one for each grid cell).

Not sure which is the best direction to take: To use “Layouts” or “Print Window”.
Using Layout offers no advantage to me for this specific workflow.

CatalogueExample.3dm (753.9 KB)

Each cell should be a different pdf. You can imagine doing this with the Ctrl + P and “moving” the “Print Window” form its center to the center of each cell and saving and naming each PDF gets quite tedious. (Not to mention the select > invert > hide combo to get each individual drawing alone).

Maybe to simplify things I could first print 1 pdf with all correct settings (given that Rhino remembers used settings) and then run the script.

Any insight would mean a tremendous help!
Thanks in advance,


I prefer to use Layouts:
First you need to make layouts of your drawings:

import rhinoscriptsyntax as rs
import Rhino
i = 0
def createLayout(name):
    pageview = Rhino.RhinoDoc.ActiveDoc.Views.AddPageView(name, 34, 20)
    top_left = Rhino.Geometry.Point2d(0,0)
    bottom_right = Rhino.Geometry.Point2d(34,20)
    detail = pageview.AddDetailView(None, top_left, bottom_right, Rhino.Display.DefinedViewportProjection.Top)
    detail.DetailGeometry.IsProjectionLocked = True
    detail.DetailGeometry.SetScale(1, Rhino.RhinoDoc.ActiveDoc.ModelUnitSystem, 1, Rhino.RhinoDoc.ActiveDoc.ModelUnitSystem)
objs = rs.AllObjects()
for obj in objs:
    if rs.IsCurve(obj):
        if not rs.IsPolyline(obj):
            i = i +1

LayoutCreator.py (922 Bytes)

Then you can use this script by @stevebaer:

Export.pdf (358.9 KB)


Thank you so much @Mahdiyar, this is great! You have saved me so much time! I owe you one.

Could you explain what do the 34, 20 means in coordinates?

Also, it is possible to set a scale? Within the script, it doesnt need to ask the user for it. Sometimes my grid cells are not 1:1 and so I dont want huge sized paper pdfs.

(Rickson) #4

Layout manager still works OK.

The layout gets the boundary name, which is nice.


Hi @Mahdiyar I tried to run your script on another file and it seems it crashed.

I realized you check for all objects in the document, and then test if these are curves or polylines. On my working files I have many Make2Ds that have thousands of curves and a lot of these are polylines… So I am guessing thats why it crashed.

Maybe it is easier to just select the objects of “x” layer, say “Bounding Curves” ?

Edit: I modified the script like so and the layer selection works:

objs = rs.ObjectsByLayer("Curves", True)
for obj in objs:
    i = i +1

Still, for some reason the createLayout def is generating some weird results (even if using it without modifications) where objects are not properly zoomed at, or not zoomed at all.

Edit02: Nvm, it works if the Layout Unit is set to the same Unit as the File before running the script, for example both in meters.