Automatically bake to a layer and coerce

I share your distaste for “coercing” (casting), yet that is the method recommended in official tutorials like this one for baking to layer:

How would you modify that bake to layer script to avoid using ‘rs.coercerhinoobject()’?

The not so funny thing is that extensive searching fails to find any reference to these coerce methods or what can be used in their place?

https://developer.rhino3d.com/api/RhinoCommon/search.html?SearchText=coercerhinoobject
(" Nothing found")

I eventually got most of what I wanted for bake-to-layer (with custom material), but it fails to handle groups:

I can recognize the type difference between ‘Guid’ when passing ungrouped geometry and ‘List[object]’ when passing a group. I can traverse the list object and see that it consists of type ‘Brep’ objects but so far, I have failed to find a way to get a ‘Guid’ or the ‘AttributedGeometry’ I want from the breps?

doc_object = rs.coercerhinoobject(geo)
print type(doc_object)

print type(geo)
if type(geo) is not System.Guid: #assume 'List[object]' for group
    for G in geo:
        print 'G =', type(G), type(rs.coercerhinoobject(G))

And like the coerce methods, good luck finding any reference to type ‘AttributedGeometry’ anywhere in the API docs! How the hell can that be?

https://developer.rhino3d.com/search-results.html?q=AttributedGeometry+site%3Adeveloper.rhino3d.com
(“No results were found for your query.”)

I have a hunch that even if I could bake the geometry in the group with this approach, it wouldn’t be grouped anymore, so this is probably all wrong anyway?

Really, I’d MUCH rather be focused on my GH model instead of scripting my own bake-to-layer component. All the more so because my experience with the Rhino API documentation and examples scattered throughout the forum has been utterly dreadful and frustrating.

demo_mMaterial_bake_to_layer_2020Jan29a.gh (29.4 KB)

Why are you searching in RhinoCommon api when you’re using rhinoscriptsyntax?

The source of the coerce* functions is here:
%appdata%\McNeel\Rhinoceros\6.0\Plug-ins\IronPython (814d908a-e25c-493d-97e9-ee3861957f49)\settings\lib\rhinoscript\, in the utility.py file, line 1050 or so.

scriptcontext.doc.Objects.Find(object_id) can be used in place of the other line. If the geometry is needed, then the .Geometry attribute can retrieve it.

RhinoScriptSyntax however allows Guids also typed as strings, not simpler System.Guid objects. Then it needs to add a few more tests to make that also possible. You can probably skip that in your custom-tailored function.

1 Like

I don’t want to be writing a “custom-tailored function” at all, I just want a native bake-to-layer solution that doesn’t require a plugin.

I’ve been posting on that subject for several weeks now and received virtually no help at all. Treating issues like this as “custom” scripting functions is a profound misreading of your user base.

It’s custom-tailored in the sense that Grasshopper already had a Baking functionality. You are re-creating it, tailored to your needs. That is perfectly fine and legitimate.

I also added RH-56763 so that the tutorial will not use that function any longer.

And if you would have read my initial post then you would know that retreiving a guid from rhinocommon geometry base object (or a list of them) is not possible, because attributes such as as a guid is only part of “baked” geometry.

Grasshopper has “a Baking functionality”? Where? Since when? How could I have possibly missed that in the hundreds of pages I have searched the past couple of weeks on this subject? Forum posts, tutorials, Rhino API docs - nothing.

I’m not finding real help in this thread either.

image

Come on!

You’ve gotta be kidding? This isn’t a joke. The point is to bake objects to layers without having to manually set the active layer in Rhino for each one and bake objects/layers, one at a time.

This is ridiculous. Truly a tower of babel.

You didn’t say this before and I cannot read minds. Sorry. Moving this off-topic part to your other thread.

The second thread this morning that you are splitting to disrupt the continuity of a subject…? :man_facepalming:

Damn! Aggressively buried and hidden under an obscure thread title in the Scripting forum. Wow.

Can we get back to your request…? Please. You want to automatically bake to a layer. Right? What part is not working?

So, after re-reading all the questions, I managed to get the previous sample to work. It should be doing what you are after, which I think was a problem mostly about dealing with Groups.

__author__ = "Joseph Oster, IslandCAD.com"
__version__ = "2020.01.29"

import rhinoscriptsyntax as rs
import scriptcontext
import Rhino
import System


def perform_baking(geo, layer, rM, mSrc):
    
    if geo:
        if layer is None: layer = 'Default'
        if not rs.IsLayer(layer): rs.AddLayer(layer)
        
        attributes = scriptcontext.doc.CreateDefaultAttributes()

        if rM is not None:
            matIndex = scriptcontext.doc.Materials.Add(rM)
            attributes.MaterialIndex = matIndex

        if (mSrc < 0) or (mSrc > 3): mSrc = 1 #must be 0=layer, 1=object or 2=parent
        if (mSrc == 0): #from layer
            if rM is not None:
                layerIndex = rs.LayerNames().index(layer)
                scriptcontext.doc.Layers[layerIndex].RenderMaterial = Rhino.Render.RenderMaterial.CreateBasicMaterial(rM)
            attributes.MaterialSource = Rhino.DocObjects.ObjectMaterialSource.MaterialFromLayer
        elif (mSrc == 1): #from object
            attributes.MaterialSource = Rhino.DocObjects.ObjectMaterialSource.MaterialFromObject
        else: #from parent
            attributes.MaterialSource = Rhino.DocObjects.ObjectMaterialSource.MaterialFromParent

        # add both the geo and the attributes to the Rhino doc
        rhino_id = scriptcontext.doc.Objects.Add(geo, attributes)
        print rhino_id
        rs.ObjectLayer(rhino_id, layer)
        return rhino_id

if active:
    #we change the scriptcontext
    scriptcontext.doc = Rhino.RhinoDoc.ActiveDoc
    try:
        if type(geo) is System.Guid:
            geo = ghdoc.Objects.Find(geo)
            if geo: geo = geo.Geometry
            perform_baking(geo, layer, rM, mSrc)
        else: #assume group
            ids = []
            for g in geo: ids.append(perform_baking(g, layer, rM, mSrc))
            groupName = rs.AddGroup()
            rs.AddObjectsToGroup(ids, groupName)
    finally: #put back the original Grasshopper document as default
        scriptcontext.doc = ghdoc

joseph-bake-help.gh (31.0 KB)

Have a good day.

4 Likes

I recommending installing EleFront, which has extensive controls for baking. The standard “bake” function in Grasshopper will simply keep on adding objects to Rhino, whereas Elefront will delete the previously baked objects, based on how you organise your elements. You can specify layer, colour, attributes… etc etc

1 Like

st1x

thank you very much . very interesting tool :slight_smile:
if you connect a manipulator, you can make an automatic bake with replacement.

How exactly do you do that?

what exactly ?

The replacement part… I want to replace for every bake and not just make more geometry.

I am not knocking other options (I haven’t tried them), but EleFront does it well.