I can’t begin to tell you how unhelpful I find the Rhino scripting documentation. I think I must be approaching it wrong somehow. Can you tell me how I should be approaching it?
Here is an example: I want to take the Python routine __boxpoints helpfully provided here PythonScript equivalent of IsBox and BoxPoints? and apply it to all the boxes in the visible layers. Here is my attempt:
import rhinoscriptsyntax as rs
import scriptcontext as sc
import Rhino
def __boxpoints(brep, tol):
if brep and brep.IsBox():
verts = brep.DuplicateVertices()
if len(verts) == 8:
# Since the vertices can be in any order,
# cook up their bounding box and return
# them in some logical order
face = brep.Faces[0]
u = face.Domain(0).Min
v = face.Domain(1).Min
rc, plane = face.FrameAt(u, v)
points = Rhino.Geometry.PointCloud(verts)
w2p = Rhino.Geometry.Transform.ChangeBasis(Rhino.Geometry.Plane.WorldXY, plane)
bbox = points.GetBoundingBox(w2p)
corners = Rhino.Geometry.PointCloud(bbox.GetCorners())
p2w = Rhino.Geometry.Transform.ChangeBasis(plane, Rhino.Geometry.Plane.WorldXY)
corners.Transform(p2w)
return corners.GetPoints()
return None
def labelBoxesInVisibleLayers():
layers = rs.LayerNames()
for layer in layers:
if rs.IsLayerVisible(layer):
rhobjs = sc.doc.Objects.FindByLayer(layer)
for obj in rhobjs:
brep = obj.Brep()
points = __boxpoints(brep, sc.doc.ModelAbsoluteTolerance)
if points:
p = 0
for pt in points:
sc.doc.Objects.AddTextDot(str(p), pt)
p = p + 1
def labelOneBox():
filter = Rhino.DocObjects.ObjectType.PolysrfFilter
rc, objref = Rhino.Input.RhinoGet.GetOneObject("Select polysurface", False, filter)
if not objref or rc != Rhino.Commands.Result.Success:
return
brep = objref.Brep()
if not brep:
return
points = __boxpoints(brep, sc.doc.ModelAbsoluteTolerance)
if points:
i = 0
for pt in points:
sc.doc.Objects.AddTextDot(str(i), pt)
i = i + 1
labelOneBox()
labelBoxesInVisibleLayers()
The original function labelOneBox works, but my new function labelBoxesInVisibleLayers fails with error “Message: ‘BrepObject’ object has no attribute ‘Brep’” at the command “brep = obj.Brep()”.
At this stage, I am interested to know how to fix this. But really, I would like to know how to learn how to fix this myself.
It seems that obj in labelBoxesInVisibleLayers is of a different type from objref in labelOneBox – and that is fair enough, because one is an element of the collection returned by sc.doc.Objects.FindByLayer, and the other is from Rhino.Input.RhinoGet.GetOneObject. How do I find the documentation for FindByLayer? – specifically, the Python, scriptcontext version of FindByLayer? (If I google for any term in any Rhino script, it seems to be my job to detect whether I have landed by chance on the correct language and API. Go on, try googling “rhino findbylayer” and tell me how it helps in debugging sc.doc.Objects.FindByLayer,)
I can find some documentation of the other command (https://developer.rhino3d.com/api/rhinocommon/rhino.input.rhinoget), but I have no idea how to find the properties of the object it returns, to learn why it has a .Brep() method. I have no idea how to find the equivalent of Objects.FindByLayer in RhinoCommon. I could go on at some length about the depth of my confusion, but you probably get the idea.
Any answer that involves Rhino - Rhino.Python Guides is unlikely to be helpful – I have tried that page repeatedly and it does nothing but give me patronising introductions to vanilla Python.