Hi again,
Here is another script to speed up the “layouting” in Rhino 7. Instead of making a detail on a specific layout, aligning it to a clipping plane, making a correct scale etc. - lets reverse the process:
- Make clipping planes in 3d. It works with all directions, not only top projection. Pay attention to the orientation of the clipping plane.
- Adjust the clipping plane size, so it bounds the geometry - this will be used as the detail width and height in proper scale on the layout.
- Start the script - it will ask you to select one clipping plane you want change into a detail.
- Select the scale from the menu (or click CANCEL to provide your own)
- Select the layout you want to place the detail on.
- Pick the placement on the layout - it will be the left bottom corner of the detail.
The script will do the following:
- make a new detail in position provided by you, in selected scale.
- the name of the detail view will be the same as the name of the clipping plane (or name of the model view if clipping plane has no name)
- make the detail size the same as the clipping plane size in selected scale
- create a cPlane in the middle of the detail, oriented as clipping plane
Here is a small video:
Here is the code:
# Author: Pawel Jakub Tujakowski / kumulus.agency
# Version: 1.0
# Date: 2024.02.14
# detail_from_clippingplane.py 2024 by Pawel Jakub Tujakowski is licensed under Attribution-ShareAlike 4.0 International (https://creativecommons.org/licenses/by-sa/4.0/)
import Rhino
import scriptcontext as sc
import rhinoscriptsyntax as rs
def detail_from_clippingplane():
### VARIABLES ###
scales = ["1:1", "1:2", "1:5", "1:10", "1:20", "1:25", "1:50", "1:75", "1:100", "1:150", "1:200", "1:250", "1:400", "1:500", "1:1000", "1:2000", "1:5000"]
layoutNames = []
### SCRIPT WORKS IN MM ###
sc.doc.PageUnitSystem = Rhino.UnitSystem.Millimeters
### PICK A CLIPPING PLANE ###
frameId = rs.GetObject("Pick clipping plane for detail", rs.filter.clippingplane)
if frameId == None:
return()
### GET ALL LAYOUTS ###
page_views = sc.doc.Views.GetPageViews()
for page_view in page_views:
layoutNames.append(page_view.PageName)
### FRAME SPECIFICATIONS ###
frameName = rs.ObjectName(frameId)
if frameName == None:
frameName = rs.CurrentView()
domainU = rs.SurfaceDomain(frameId, 0)
domainV = rs.SurfaceDomain(frameId, 1)
frameBoxLL = rs.EvaluateSurface(frameId, 0, 0)
frameBoxUL = rs.EvaluateSurface(frameId, domainU[1], 0)
frameBoxUR = rs.EvaluateSurface(frameId, domainU[1], domainV[1])
frameU = rs.Distance(frameBoxUR,frameBoxUL)
frameV = rs.Distance(frameBoxUL,frameBoxLL)
midXYZ = (frameBoxUR+frameBoxLL)/2
origin = frameBoxLL
### VECTORS NEEDED FOR CONSTRUCTION PLANES ETC. ###
vectorU = rs.VectorCreate(frameBoxUL, frameBoxUR)
vectorV = rs.VectorCreate(frameBoxLL, frameBoxUL)
vectorW = rs.VectorCrossProduct(-vectorU, vectorV)
normal = rs.VectorUnitize(vectorW)
### PICK SCALE FROM LIST OR OVERRIDE ###
scale = rs.ListBox(scales, "Pick scale from the list or click CANCEL to override", "Scale", default = "1:50")
if scale == None:
scale = rs.StringBox("1:___",None,"Override scale")
if scale == None:
return()
else:
while scale.isdigit() != True :
print "Scale must be an integer!"
scale = rs.StringBox("1:___",None,"Override scale")
if scale==None:
return
else:
scale = scale.replace("1:","")
### SCALE CALCULATIONS ###
scaleMult = 1/eval(scale)
frameSU = frameU*scaleMult
frameSV = frameV*scaleMult
### SELECT LAYOUT TO PUT DETAIL ON ###
layoutName = rs.ComboListBox(layoutNames, "Select layout")
if layoutName == None:
return()
if layoutName:
for page_no in range(len(layoutNames)):
if(layoutNames[page_no] == layoutName):
layout = page_views[page_no]
### CREATE DETAIL WITH CORRECT NAME AND PLACEMENT, CREATE LOCAL CPLANE, ADD CLIPPING PLANE ###
if layout:
sc.doc.Views.ActiveView = layout
sc.doc.Views.Redraw()
basePoint = rs.GetPoint("Pick placement")
if basePoint:
detail = layout.AddDetailView(frameName, Rhino.Geometry.Point2d(basePoint.X,basePoint.Y), Rhino.Geometry.Point2d(basePoint.X+frameSU,basePoint.Y+frameSV), Rhino.Display.DefinedViewportProjection.Top)
if detail:
layout.SetActiveDetail(detail.Id)
detail.Viewport.SetCameraDirection(normal,True)
detail.Viewport.SetCameraTarget(midXYZ, True)
detail.CommitViewportChanges()
detail.DetailGeometry.IsProjectionLocked = True
detail.DetailGeometry.SetScale(1, sc.doc.ModelUnitSystem, scaleMult, sc.doc.PageUnitSystem)
detail.CommitChanges()
rs.ViewCPlane( None, rs.PlaneFromNormal(midXYZ, normal,-vectorV) )
clippingPlane = sc.doc.Objects.FindId(frameId)
clippingPlane.AddClipViewport(detail.Viewport,True)
if __name__ == "__main__":
pageview = sc.doc.Views.ActiveView
if type(pageview) == Rhino.Display.RhinoPageView:
print "This tool only works in the model space."
else:
detail_from_clippingplane()
You can also download the script here:
https://www.dropbox.com/t/kMEA3LZC7xlZbo06
Enjoy!