How to navigate Rhino scripting documentation?

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.

The thing is that the Help for rhinoscriptsyntax is aimed at ‘casual’ and intermediate scripters, whereas the RhinoCommon API docs are aimed at more experienced programmers.

Some very simplified explanations:

Rhinoscriptsyntax is a higher level set of methods - actually “wrappers” for a bunch of RhinoCommon routines. Many rhinoscriptsyntax functions dealing with objects want existing object ID’s (GUIDs) as input and return object ID’s as output; often the methods directly add new objects to the document and return their ID’s.

RhinoCommon is much lower level, being able to create and work with ‘virtual’ geometry without necessarily adding objects to the document. It also allows access to many other non-geometry functions. As it is the basis for rhinoscriptsyntax, it can do everything rhinoscriptsyntax does, just with a lot more lines of code. As it is an object-oriented set of functions, it is a bit difficult to understand at first - not nearly as straightforward as rhinoscriptsyntax. The API docs assume you know your way around OOP.

Scriptcontext may be thought of the ‘bridge’ between RhinoCommon and the active document, allowing you to to access the object table to get objects already in the document and being able to add new ones to it. It also allows you to access other non-geometry tables in the document like layers, views etc.

The problem you stumbled on however is actually fairly subtle and could surprise even an experienced programmer.

In your example, labelOneBox() is using the RhinoCommon method GetOneObject() to get a single object in the document, and in addition, it has been filtered so you can only select polysurfaces. The method then returns an “object reference” (objref). This is in itself another sort of “wrapper” that includes a bunch of information about an object in the document - not only its ID, but also its geometry, attributes (layer, color, etc.), and other object-related info.

OTOH, in labelBoxesInVisibleLayers() you use sc.doc.Objects.FindByLayer(layer) - which does not return a single object reference, but rather a list of all the “RhinoObjects” found on that layer. “RhinoObjects” are not actually the same as object references. Rhino objects can be found in the Rhino.DocObjects namespace

The ObjRef class has a method .Brep() which tries to get the brep geometry from the object reference if it is one. The RhinoObject class does not have a method .Brep(), so it fails.

OK, that’s a very esoteric difference and yes, I understand your frustration trying to figure out why it doesn’t work. My way is to stick to simple known stuff. Since you are already in rhinoscriptsyntax, why not just use rs.ObjectsByLayer(layer) instead of sc.doc.Objects.FindByLayer(layer)? That will return a list of object ID’s and then you can start to filter for breps.

def labelBoxesInVisibleLayers():
    layers = rs.LayerNames()
    for layer in layers:
        if rs.IsLayerVisible(layer):
            obj_ids=rs.ObjectsByLayer(layer)
            if obj_ids:
                for obj_id in obj_ids:
                    #get the brep geometry from the object *if possible*
                    brep = rs.coercebrep(obj_id)
                    #only do the folllowing() if coercebrep succeeeded
                    if 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

You will note I used a ‘secret’ function rs.coercebrep(). This is one of my main criticisms of the rhinoscriptsyntax help, it does not include these ‘hidden’ helper functions. The coerce... methods (there are many) extract object types directly from various input. They are extremely handy.

I could work around this by doing the following:

import rhinoscriptsyntax as rs
import scriptcontext as sc
import Rhino

def labelBoxesInVisibleLayers():
    tol=sc.doc.ModelAbsoluteTolerance
    layers = rs.LayerNames()
    for layer in layers:
        if rs.IsLayerVisible(layer):
            obj_ids=rs.ObjectsByLayer(layer)
            if obj_ids:
                for obj_id in obj_ids:
                    if rs.IsBrep(obj_id):
                        #this gets the object, brep geometry from the object id
                        brep=sc.doc.Objects.Find(obj_id).Geometry
                        points = __boxpoints(brep,tol)
                        if points:
                            p = 0
                            for pt in points:
                                sc.doc.Objects.AddTextDot(str(p), pt)
                                p = p + 1
1 Like

I only would like to add something about one of your questions.
Just to show you how I would searc the docs to find the info I need in this case. :slight_smile:

Hers is that line:

Let’s start by the sc.doc part:

sc.doc returns a Rhino.RhinoDoc object that represents the document you’re working on.
You’ll have to learn and remember this … :neutral_face:
You can also look it up on github here, at the start of the script:

The scriptcontext.py file should also be saved on your computer, in some weird place
( Here for Rhino 6 for Windows is in:
C:\Users\kar\AppData\Roaming\McNeel\Rhinoceros\6.0\Plug-ins\IronPython (814d908a-e25c-493d-97e9-ee3861957f49)\settings\lib )

Not easy to find, I know.
Just try to remember what scriptcontext.doc is.
You probably are going to use it in most of your scripts.

After sc.doc we have Objects
But you already know that sc.doc is a Rhino.RhinoDoc object, so you can look that up in the docs:

From here (RhinoCommon API):
https://developer.rhino3d.com/api/rhinocommon/rhino

Just click on the Rhino namespace
then look for the RhinoDoc class and click on it

Here is the class:

https://developer.rhino3d.com/api/rhinocommon/rhino.rhinodoc

Now we have to find the Objects property, scrolling down.
Once we find it, we click on that propery and we are here:

https://developer.rhino3d.com/api/rhinocommon/rhino.rhinodoc/objects

We can see that the returned type is ObjectTable.
We just click on it and are sent to the ObjectTable class

https://developer.rhino3d.com/api/rhinocommon/rhino.docobjects.tables.objecttable

Here we can look for the FindByLayer method.
We have to scroll down quite a bit here … :wink:
Once we find it, we just clik on it and see this:

https://developer.rhino3d.com/api/rhinocommon/rhino.docobjects.tables.objecttable/findbylayer

Again we look for the returned type, and see that it’s an Array of RhinoObject objects.

Now we have to get the geometry (the **Brep in this case) from that object.
If we don’t already know about the right property, we can look for something that returns the object’s geometry.

The Geometry property is what we need:

https://developer.rhino3d.com/api/rhinocommon/rhino.docobjects.rhinoobject/geometry

Using that property on the RhinoObject object, we can get the Brep we need.

If we like, we can check that the GeometryBase object returned by the property is indeed a Brep object using the Python type function.

I agree that at first all this may seem quite complex …
But, after a little experience, it’s just a matter of a few clicks and some scrolling,
and you’ll be able to find the fino you need. :slight_smile:

HTH

You can also just open the main RhinoCommon API doc page and type “findbylayer” in the search box.
:wink:

That is a good attitude.

The simple answer to the first part is change your line

brep = obj.Brep()

to two lines

if obj.ObjectType==Rhino.DocObjects.ObjectType.Brep:  brep = obj.Geometry  
else: continue

Your variable rhobjs Type is Rhino.DocObjects.RhinoObject[ ] (that’s an array of Rhino Objects)
You only want the objects that are breps and skip other objects that are not breps.


This is what you need to know to figure this stuff out:

In RhinoCommon vernacular a “Brep” means Rhino.Geometry.Brep and a BrepObject means Rhino.DocObjects.BrepObject.

A Brep is just the geometry.
A BrepObject is more than just the geometry. It contains added info like what layer the Brep is on.

As an experiment I converted this script to run without any reference to rhinoscriptsyntax or
scriptcontext.

IMO there is zero advantage to using rhinoscriptsyntax and
scriptcontext.
Using rhinoscriptsyntax doesn’t make the script easier to read. It doesn’t make it more compact. And most important, Using rhinoscriptsyntax makes the script run slower.

This script sets a timer so it could be used to benchmark against a version using rhinoscriptsyntax. I did not understand the long-winded explanations of how to fix the OPs script with rhinoscriptsyntax so someone else will have to supply a rhinoscriptsyntax version to compare it with.
I did notice that stripping out all existing rhinoscriptsyntax did make it seem much faster but did not have the timer added at that point to quantify how much faster.

Here is the script: _ timing.py (2.7 KB)

This is a test file with 10 objects. Use those 10 objects to make a rectangle array of 32X32 to give the script a workout. That should be about 10,000 objects.

test_file.3dm (304.9 KB)

Yep, that’s your opinion.

Sure, as rhinoscriptsyntax is simply a collection of RhinoCommon routines, in your logic we don’t need it at all. Everything that rhinoscriptsyntax can do can be done in RhinoCommon because it is done in RhinoCommon.

Well, I guess that’s your opinion.

obj_id=GetObjects(message=None, filter=0, group=True, preselect=False, select=False, objects=None, minimum_count=1, maximum_count=0, custom_filter=None)

vs

def GetObjects(message=None, filter=0, group=True, preselect=False, select=False, objects=None, minimum_count=1, maximum_count=0, custom_filter=None):
 
    if not preselect:
        scriptcontext.doc.Objects.UnselectAll()
        scriptcontext.doc.Views.Redraw()

    objects = rhutil.coerceguidlist(objects)
    class CustomGetObject(Rhino.Input.Custom.GetObject):
        def __init__(self, filter_function):
            self.m_filter_function = filter_function
        def CustomGeometryFilter( self, rhino_object, geometry, component_index ):
            if objects and not rhino_object.Id in objects: return False
            rc = True
            if self.m_filter_function is not None:
                try:
                    rc = self.m_filter_function(rhino_object, geometry, component_index)
                except:
                    rc = True
            return rc
    go = CustomGetObject(custom_filter)
    go.SetCommandPrompt(message or "Select objects")
    geometry_filter = __FilterHelper(filter)
    if filter>0: go.GeometryFilter = geometry_filter
    go.SubObjectSelect = False
    go.GroupSelect = group
    go.AcceptNothing(True)
    if go.GetMultiple(minimum_count,maximum_count)!=Rhino.Input.GetResult.Object: return None
    if not select and not go.ObjectsWerePreselected:
        scriptcontext.doc.Objects.UnselectAll()
        scriptcontext.doc.Views.Redraw()
    rc = []
    count = go.ObjectCount
    for i in xrange(count):
        objref = go.Object(i)
        rc.append(objref.ObjectId)
        obj = objref.Object()
        if select and obj is not None: obj.Select(select)
    go.Dispose()
    return rc

You choose…

Yes, that is true in certain circumstances. In this case the ‘no rhinoscriptsyntax’ version you posted ran in an average of about 1.8 seconds here. Substituting the pure RhinoCommon labelBoxesInVisibleLayers() definition with the one above that has some rhinoscriptsyntax methods but not coercebrep ran in around 2.3 seconds; the one using coercebrep ran in about 2.55 seconds. This probably caused by repeated conversions from object ID to object and back again.

So yes, if you are routinely making hundreds, thousands or millions of operations, shaving off a millisecond or two for each iteration becomes important. Otherwise, for more typical amounts of operations, nobody will ever notice the difference.

And, if you don’t mind writing and reading10-20 lines of code instead of one for things like GetObjects(), well, that’s your thing.

As per the OP’s original complaint, yes, the RhinoCommon documentation is much harder to read through and understand, it offers few explanations for people who don’t know what it’s all about. That’s why rhinoscriptsyntax exists, to make it easier for people to get into scripting and learn to make their own custom tools without being a programmer. Once they have mastered that, they can chose go go deeper if they want.

That’s MY opinion.

Isn’t scriptcontext.doc the preferred way to get the RhinoDoc object according to McNeel any more ?
I can see that scriptcontext.doc is what is used in rhinoscriptsyntax …

Thanks for all those answers.

I thought I had given myself an easy warm-up task – maybe I need to recalibrate.

Helvetosaur asked why I used sc.doc.Objects.FindByLayer(layer) instead of rs.ObjectsByLayer(layer). I’ve got a longish reply to this, so I might put other replies into a different post.
• The short answer is: I found the sc command via Google, and I could not find the rs equivalent. Maybe I would have preferred a clean rs command (though, in the current case, it would not have helped – according to Helvetosaur’s first reply, either I would need to know a secret function or I would need to dip into sc eventually). But let’s look at how I would try to find a RhinoScript command equivalent to FindByLayer(layer). My point is that it is currently difficult for me to find this.
• Knowing that there is an rs equivalent is a big help in searching for it, but I did not know that. (And some of the Google hits from 10 years ago, when RhinoScript was smaller, could make me doubt it.)
• Obviously a first step is to look for a RhinoScript function with the same name, FindByLayer. We know this is doomed to failure. A similar name, maybe? Still no.
• Another technique would be to scroll through Rhino - RhinoScriptSyntax to find a relevant-looking name. I want to end up with geometry, so I might look in the Geometry tab, … nope. Ditto Objects. The input is a layer, so I’ll look in the Layer tab, … nope. Maybe the objects are stored at application level, so I look in the Application tab, …nope. I’m getting frustrated at this stage: I’ve scanned more than 100 names for relevance, and I’ve got nowhere. It would not occur to me to look in the Selection tab (because nothing is going to be selected in my intended function). This technique fails, and it fails after using my time and brainpower.
• So here’s a question: how should I go looking for “the function that loops through all the objects in a layer in RhinoScript”? I’ve spent some minutes trying Google, and I’ve spent some minutes slogging through the API. What should I do instead?
• If I get some hint that objectsbylayer could be the answer, and type that into the search box Rhino - RhinoScriptSyntax, the results do not point me directly to a RhinoScript Python answer. The first hit is a VBScript answer; then come some Grasshopper forum threads. I need to open and scan through about 6 of those search results before I get a glimpse of the correct syntax. I’ve spent some minutes on this search already (and I was expecting it to be a simple step in an easy warm-up), I’m beginning to doubt that the answer even exists, so I might only open the first 5 hits.

I’d like to reach some concrete proposals for improving the documentation, rather than just moaning, so here is a suggestion: please could the search facility (for example in Rhino - RhinoScriptSyntax) have filters?: filter by API (rc,rs,sc,…), filter by language, filter by formal documentation (vs. forum posts)? I can see that it would be an impossible amount of work to categorise/tag all of the past forum posts, but for hits inside the formal documentation, it should be easy. Currently, I often read half a page before I realise that it’s VBScript and therefore of no use, or RhinoCommon. Google does not have good filters on this either. (I’d be happy to get advice on how to search better, though I would usually count my Google skills as above average. Adding “rhinoscript” in quotes to the search does not rule out VBScript; adding “python” typically sends me to RhinoCommon. Ironically, if I Google for ‘loop layer objects site:Rhino - RhinoScriptSyntax’, I get exactly one hit, which is the section of text relating to objectsbylayer – perfect! (though Google’s preview does not mention this command). But when I click on the link, I arrive at the page Rhino - RhinoScriptSyntax, and all the dropdowns are unexpanded, so I don’t see the relevant text.) You, as experts, will be much more efficient at screening out irrelevant pages than I am. As a beginner, I can tell you that the current documentation setup is horrible.

Thanks, emilio, for working through how to navigate the documentation. If I set off on a similar journey (and I probably did, in the several attempts I made before my initial post), I would have turned back defeated when I reached the stage: “The Geometry property is what we need”.

I knew I wanted a Brep object, but I did not know that it would be inside the Geometry property. Without knowing that, I would have to click on the GeometryBase class and see if it has a Brep method, … no, it doesn’t. It just “is” a Brep, or a Brep equivalent, or something. How would I know that? As you say, I could test it by getting the syntax working in an example and using Python type. Is that really the best/only way? I’m navigating down a lot of dead-ends at this stage, so testing every one by running a script is a painful way to make progress.

To some extent, that specific question is a real beginner’s question. You’ve all helped to know that Brep is just the geometry, and if I extract the geometry from an object reference then I probably have a Brep to send to __boxpoints. This is the basis for Jim’s simple answer, obj.Geometry not obj.Brep(), and he explains why. I’ve probably absorbed that lesson by now. I don’t know how many similar equivalences I need to absorb before I can navigate the API by instinct. Is there a rigorous way to find how to convert RhinoObject to Brep, so that I can apply that way to future, less basic questions? Is the only way to have an instinct about where to scroll?

1 Like

I can understand your confusion. Using Google as a search tool can be hit-and-miss for this type of stuff - I don’t find it all that reliable. I did the same as you and searched for this:

rhinoscriptsyntax get objects by layer

I got this page.

The first hit is actually the old VB Rhinoscript help, but it does get you the method. I would have thought that the Python rhinoscriptsyntax method help would show up in the first 10 or so, but no… Even after adding Python to the search term. Interesting that the second and third hits are forum posts from here.

Using the same search terms in the Rhino3d.com search box, all I get are forum posts, so no help there, even worse than Google.

Using the same search terms on developer.rhino3d.com, I get similar results, the 6th hit is the VBRhinoscript answer same as Google’s first hit above.

Of course, I asked ChatGPT (I only have the free 3.5) and got the best info:


You
With python in Rhino I need to find all the objects on a given layer - using the layer name

Chat:

In Rhino, you can use the RhinoScriptSyntax or RhinoCommon library in Python to access and manipulate objects in the 3D environment. To find all objects on a given layer using the layer name, you can follow these steps:

Using RhinoScriptSyntax (assuming you have RhinoScriptSyntax installed):

import rhinoscriptsyntax as rs

def get_objects_on_layer(layer_name):
    # Get all objects on the specified layer
    objects_on_layer = rs.ObjectsByLayer(layer_name)

    if objects_on_layer:
        print(f"Objects on layer '{layer_name}': {objects_on_layer}")
    else:
        print(f"No objects found on layer '{layer_name}'")

# Replace 'YourLayerName' with the name of the layer you are interested in
layer_name = 'YourLayerName'
get_objects_on_layer(layer_name)

Using RhinoCommon:

import Rhino

def get_objects_on_layer(layer_name):
    # Get the active Rhino document
    doc = Rhino.RhinoDoc.ActiveDoc

    # Get the layer index from the layer name
    layer_index = doc.Layers.FindByFullPath(layer_name, -1)

    if layer_index >= 0:
        # Get all objects on the specified layer
        objects_on_layer = doc.Objects.FindByLayer(layer_index)

        if objects_on_layer:
            print(f"Objects on layer '{layer_name}': {objects_on_layer}")
        else:
            print(f"No objects found on layer '{layer_name}'")
    else:
        print(f"Layer '{layer_name}' not found")

# Replace 'YourLayerName' with the name of the layer you are interested in
layer_name = 'YourLayerName'
get_objects_on_layer(layer_name)

Make sure to replace ‘YourLayerName’ with the actual name of the layer you want to query. Choose the appropriate script depending on whether you prefer to use RhinoScriptSyntax or RhinoCommon in your workflow.


So maybe that is going to replace all of the other search stuff eventually…

I agree that the current rhinoscriptsyntax online help search is quite poor - when they transferred it to the new site a couple of years ago, a lot of the search functions got removed in the process… They said they would gradually improve it but it has not really happened.

I would think that typing either ‘object’ or ‘layer’ in the search box on the rhinoscriptsyntax help page should have included ObjectsByLayer(), but no… I don’t know who to ask to look into this - @dale ?

I know that feeling … I remember it … :wink:
That’s when you need to dig though the samples on https://developer.rhino3d.com/ or to ask for help here on the forum (or to do both things :wink: ).
And it may take quite some time. At least that’s what happened to me … several years ago. :confused:

Obviously it depends on the subject of the script, but … yeah, I think that an explanation about how it all works would help a lot of people trying to learn RhinoCommon.

A few things that come to my mind are :

Rhino stores the document’s data in ‘tables’, for objects, layers, views, etc.
Using those tables’ properties and methods you can manipulate objects, layers, etc.

To reference those tables we need a Rhino.RhinoDoc object (representing the Rhino document).
We can get it by

scriptcontext.doc

For example the ObjectTable is returned by the Objects property.
( https://developer.rhino3d.com/api/rhinocommon/rhino.rhinodoc/objects )

BTW The classes that define the tables are in the Rhino.DocObjects.Tables namespace.

The objects we see on the screen are represented by objects of the … RhinoObject class.
( objects contained in the ObjectTable, as we already said )
A RhinoObject has a property called Attributes ( Layer, Color etc ),
and another one called Geometry for geometry data.
… and a lot more things, obviously …

There are also ObjRef objects, which

Represents a reference to a Rhino object.

They are useful sometimes.
There is an ObjRef constructor that uses a RhinoObject object.
RhinoObject and ObjRef (along with other stuff) are contained into the
Rhino.DocObjects namespace.

Geometry objects (classes and structs) are defined in the Rhino.Geometry namespace.
You’ll have to dig there to discover properties and method you can use to manipulate geometry data.
( As well as searching the samples and ansking here, obviously )

RhinoCommon input classes are contained into the Rhino.Input namespace (simpler) and into the Rhino.Input.Custom namespace (more complex and powerful).
rhinoscriptsyntax input is usually much more simple, but also much less powerful.
Rhino.Input.Custom classes are very powerful IMO, you can do what regular Rhino command do with them, but there’s quite a few thing to learn there to understand how that works.

… I don’t remember much more for now … sorry … :confused:

HTH

Emilio, that’s fantastic, thank you! Something like this belongs in the help files.

Helvetosaur: It seems that “rhinoscriptsyntax” is a good filter to use for Google (possibly better than “rhinoscript” and/or “python”), and AI may be a better tool altogether.

The script we are now discussing had its GetObject on two lines which could be stuffed into one line if you wanted.
IMO your very long one-line version is incomprehensible.

edit: I am just assuming your version is the rhinosyntax version of the same thing, but as I said its incomprehensible…

I agree, the RhinoCommon documentation is close to non-existent, but it is much easier to explain and understand than Rhinosyntax. In theory the names are supposed to be self-explanatory and once you learn what they actually mean they are, but a little help for beginners who don’t know the definition of the words would go a long way.

The OP is having trouble with the definition of a Brep vs BrepObject and who can blame him.

That’s because it’s copied directly out of the Help and I didn’t want to modify it for fear of being accused of having done so… It shows all the options possible and there is a scroll bar in discourse to read it.

You are comparing apples to oranges. What I posted is actually the full RhinoCommon rhinoscriptsyntax method for GetObjects() - you can check for yourself in the library file - and what is needed if you want to include all the options that the rhinoscriptsyntax one-liner offers.

Don’t agree here. What may be obvious to you about RhinoCommon and OOP is not obvious at all to beginners.

You prove my point exactly with the above statement, there is no such confusion like that in rhinoscriptsyntax, as pretty much all the methods either work just with object ids or strings (names).

There was very little that was obvious to me about Rhino Common when I started.
I agree that McNeel has provided more rhinosyntax explanations and certainly a lot more example code. But I still say your better off not learning rhinosyntax.

I think you are just as confused about Brep vs BrepObject as the OP and that is one of the consequence of using Rhinosyntax. You are also confused about what is an Objref.

An Objref is a pointer to a RhinoObject. Its a pointer that comes with a free game of GoFish. You can ask the Objref for a Brep and if the Objref points to a BrepObject it will give you the Brep geometry that comes with that BrepObject. To play that game, you program it like this:

brep = objref.Brep()

From that line you either get the Brep Geometry or you get nothing.
The problem with using that method is that if at some point you may want to know what layer your “brep” is on or what color it is. That information is not available because with only your variable named “brep” you don’t have access to that info. You may have kept your “brep” or passed it to another function but the ObjRef that gave you the geometry may be long gone.

If you replace the above line with this:

    brep_obj = objref.Object()
    if obj.ObjectType==Rhino.DocObjects.ObjectType.Brep:  brep = brep_obj.Geometry

Now you have both the BrepObject and the Brep. (assuming this objref was indeed pointing to a BrepObject).
You have two variables The one named “brep_obj” has all the info and attributes like which layer it is tied to , its name (if any), its ID, color etc. Your “brep_obj” also gives you access to the Brep geometry as can be seen in the code above.
The variable named “brep” has just the geometry.

None of the above has anything to do with using Rhinosyntax per se.
Users of Rhino Common can be just as confused about Brep vs BrepObject vs ObjRef as Rhinosyntax users. Its just that Rhinosyntax users’ confusion tends to be permanent.

That statement is about as BS as the rest of your arguments… completely made up with no cause effect relationship that you can prove. I’m done here.