[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,
Shynn

1 Like

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
    pageview.SetActiveDetail(detail.Id)
    detail.DetailGeometry.SetScale(1, Rhino.RhinoDoc.ActiveDoc.ModelUnitSystem, 1, Rhino.RhinoDoc.ActiveDoc.ModelUnitSystem)
    detail.CommitChanges()
objs = rs.AllObjects()
rs.EnableRedraw(False)
for obj in objs:
    if rs.IsCurve(obj):
        if not rs.IsPolyline(obj):
            rs.SelectObject(obj)
            rs.HideObject(rs.InvertSelectedObjects())
            createLayout(str(i))
            i = i +1
    rs.ShowObjects(objs)
rs.Command("_Show")

LayoutCreator.py (922 Bytes)

Then you can use this script by @stevebaer:

Export.pdf (358.9 KB)

2 Likes

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

PD:
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.

Layout manager still works OK.

The layout gets the boundary name, which is nice.

1 Like

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)
rs.EnableRedraw(False)
for obj in objs:
    rs.HideObject(rs.InvertSelectedObjects())
    createLayout(str(i))
    i = i +1
    rs.ShowObjects(objs)
rs.Command("_Show")

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.

I think the last step for this to work is to sort the curves along the x axis and y axis, so that the layout is created in order no? How would that be in Python?