Hi @ShynnSup, if you find multiple polylines, you would get multiple centroids but can only set the camera target to one of it or the average of all centroids. Below are two simplified examples the first zooms to all polylines found on a specific layer.
import Rhino
import scriptcontext
import rhinoscriptsyntax as rs
def DoSomething():
# get the layer
layer_name = rs.GetLayer("Select Layer", None, False)
if not layer_name: return
# get all objects on the layer
obj_ids = rs.ObjectsByLayer(layer_name)
if not obj_ids: return
# filter out polylines
polyline_ids = [obj_id for obj_id in obj_ids if rs.IsPolyline(obj_id)]
if not polyline_ids: return
# zoom to polylines bounding box
bounding_box = rs.BoundingBox(polyline_ids)
rs.ZoomBoundingBox(bounding_box)
DoSomething()
The second example sets the current views camera target to the average polyline’s center point without changing the camera location:
def DoSomething():
layer_name = rs.GetLayer("Select Layer", None, False)
if not layer_name: return
idx = scriptcontext.doc.Layers.FindByFullPath(layer_name, True)
oes = Rhino.DocObjects.ObjectEnumeratorSettings()
oes.ObjectTypeFilter = Rhino.DocObjects.ObjectType.Curve
oes.LayerIndexFilter = idx
rh_objs = scriptcontext.doc.Objects.FindByFilter(oes)
if not rh_objs: return
point, count = Rhino.Geometry.Point3d.Origin, 0
for rh_obj in rh_objs:
rc, polyline = rh_obj.Geometry.TryGetPolyline()
if rc:
point += polyline.CenterPoint()
count += 1
center = Rhino.Geometry.Point3d.Divide(point, count)
rs.ViewCameraTarget(None, None, center)
DoSomething()
import Rhino
import scriptcontext
import rhinoscriptsyntax as rs
# Generate a layout with a single detail view that zooms
# to a list of objects
def AddLayout():
scriptcontext.doc.PageUnitSystem = Rhino.UnitSystem.Millimeters
page_views = scriptcontext.doc.Views.GetPageViews()
page_number = 1
if page_views: page_number = len(page_views) + 1
pageview = scriptcontext.doc.Views.AddPageView("A0_{0}".format(page_number), 1189, 841)
if pageview:
top_left = Rhino.Geometry.Point2d(20,821)
bottom_right = Rhino.Geometry.Point2d(1169, 20)
detail = pageview.AddDetailView("ModelView", top_left, bottom_right, Rhino.Display.DefinedViewportProjection.Top)
if detail:
pageview.SetActiveDetail(detail.Id)
detail.Viewport.ZoomBoundingBox(bounding_box)
detail.DetailGeometry.IsProjectionLocked = True
detail.DetailGeometry.SetScale(1, scriptcontext.doc.ModelUnitSystem, 1, scriptcontext.doc.PageUnitSystem)
# Commit changes tells the document to replace the document's detail object
# with the modified one that we just adjusted
detail.CommitChanges()
pageview.SetPageAsActive()
scriptcontext.doc.Views.ActiveView = pageview
scriptcontext.doc.Views.Redraw()
# get the layer
layer_name = rs.GetLayer("Select Layer", None, False)
# get all objects on the layer
obj_ids = rs.ObjectsByLayer(layer_name)
# zoom to polylines bounding box
bounding_box = rs.BoundingBox(obj_ids)
The error that I am getting right now is: Message: expected BoundingBox, got list. Line 19.
Basically I am inputting all bounding boxes into
detail.Viewport.ZoomBoundingBox(bounding_box)
When I need to loop through the list, so that it cycles through each Bounding Box each time the function AddLayout runs…
Any ideas on how to solve this?
Thanks in advance,
Shynn
I read that it is advised to work with RhinoCommon to avoid those kind of things, thats why I wanted to get the bounding box with RhinnoCommon syntax. But this works too!
Any idea why the first Layout is wrong? (Not zooming to the bounding box).
Guys any idea why the latest script fails for the first layout created? The first layout is always out of focus. You can test for just one curve and it will become more evident.