Bake with attributes via GH player?

I am trying to package a GH definition given to me to run as an alias or toolbar button via GrasshopperPlayer - because I’m going to pass it on to other people who don’t know how to use GH. I’m running into the problem that the GH definition was made using Elefront to attribute colors to the geometry and bake it (with a simple “bake” button).

In my various attempts to try to trigger the Elefront bake at the end of the GHPlayer I either get nothing or many copies of the same curves. If I use the normal ContextBake component I get everything correct, but of course only on the active layer and color by layer.

Anyone have a suggestion as to how to do this easily?

A secondary problem is that the thing runs terribly slowly, I have to wait 2-3 seconds between each of the command line prompts for input - there are 7, each a number. The definition isn’t all that complex, I’m wondering if the use of several plug-ins including Elefront and OpenNest are responsible for the slowdown… Edit: it appears that nesting may be the culprit.

Hey Mitch,

Max had a similar question I think - with your skills this should be a doddle, this was my somewhat cumbersome solution to it.

-Sash

Does something like this work for you?

Interesting idea, but no unfortunately - although the colors are right, I get 15 identical curves output for each item. I guess as there are seven “GetNumber” user inputs each with a default value on the command line to confirm, maybe one ‘original’ plus two additional copies for each input item…

Just testing some more stuff in case I need to add my own colors and bake via a Python script component. What I don’t understand is why with this one, I am still getting two duplicate curves:


TestPlayRectangle.gh (5.6 KB)

I suspect it still has to do with the fact that there are two command line inputs and every time you input one it makes a new curve, so 2 inputs=2 copies… Edit - nope that’s not the reason, I added a third Get Number input for the rectangle radius and it still only makes two curves. So I’m baffled.

image

TestPlayRectangle-3Inputs.gh (6.3 KB)

Edit:
I might add that if I put in all fixed values instead of the Get Number components, it only (correctly) bakes one curve. But if I add even just one Get Number component to the mix, I get two curves output. Seems buggy to me.

Here’s another cool one. Fixed values for the rectangle length/width/radius, but a Get Point for the location…

Watch the video… :stuck_out_tongue_winking_eye:

None of this happens if I use the Context Bake component to bake the geometry instead of the Python scripted bake - then I get only one copy of the geometry added to the file. But it doesn’t have any attributes. :sob:

Testing with the original file you posted above:

Added some global variables to the script and a Context Print component.

import scriptcontext as sc
import Rhino

"""
GH doc to Rhino doc
sc.doc = Rhino.RhinoDoc.ActiveDoc

Rhino doc to GH doc
sc.doc = ghdoc
"""

if "iterCount" not in globals():
    iterCount = 1
if "messages" not in globals():
    messages = []

attrs=Rhino.DocObjects.ObjectAttributes()
attrs.ObjectColor=col
attrs.ColorSource=Rhino.DocObjects.ObjectColorSource.ColorFromObject

sc.doc = Rhino.RhinoDoc.ActiveDoc
retVal = sc.doc.Objects.AddCurve(crv,attrs)

messages.append("iterCount: {}".format(iterCount))
messages.append("crv: {}".format(crv))
messages.append("col: {}".format(col))
messages.append("retVal: {}".format(retVal))
messages.append("")

sc.doc = ghdoc
iterCount += 1
a = messages

TestPlayRectangle_re-01.gh (8.3 KB)

Here’s the output from the Context Print component:

Looks like the script runs 5 times and successfully bakes the curve 2 times.

Modified the code above to store the value returned from the sc.doc.Objects.AddCurve() function and only bake the curve if the stored value equals System.Guid.Empty

import scriptcontext as sc
import Rhino
import System

"""
GH doc to Rhino doc
sc.doc = Rhino.RhinoDoc.ActiveDoc

Rhino doc to GH doc
sc.doc = ghdoc
"""

if "iterCount" not in globals():
    iterCount = 1
if "messages" not in globals():
    messages = []
if "retVal" not in globals():
    retVal = System.Guid.Empty
    
attrs=Rhino.DocObjects.ObjectAttributes()
attrs.ObjectColor=col
attrs.ColorSource=Rhino.DocObjects.ObjectColorSource.ColorFromObject

sc.doc = Rhino.RhinoDoc.ActiveDoc
if retVal == System.Guid.Empty:
    retVal = sc.doc.Objects.AddCurve(crv,attrs)

messages.append("iterCount: {}".format(iterCount))
messages.append("crv: {}".format(crv))
messages.append("col: {}".format(col))
messages.append("retVal: {}".format(retVal))

sc.doc = ghdoc
a = messages
iterCount += 1

TestPlayRectangle_re-02.gh (8.7 KB)

Now the curve is only baked to the Rhino document 1 time (same value in retVal variable on the last 2 iterations).

Stripped out unnecessary code and deleted the Context Print component.

import scriptcontext as sc
import Rhino
import System

"""
GH doc to Rhino doc
sc.doc = Rhino.RhinoDoc.ActiveDoc

Rhino doc to GH doc
sc.doc = ghdoc
"""

if "retVal" not in globals():
    retVal = System.Guid.Empty
    
attrs=Rhino.DocObjects.ObjectAttributes()
attrs.ObjectColor=col
attrs.ColorSource=Rhino.DocObjects.ObjectColorSource.ColorFromObject

sc.doc = Rhino.RhinoDoc.ActiveDoc
if retVal == System.Guid.Empty:
    retVal = sc.doc.Objects.AddCurve(crv,attrs)

sc.doc = ghdoc

TestPlayRectangle_re-03.gh (7.3 KB)

It would be nice to get some information about the reason for these multiple iterations of the GHPython Script component. Is there a way to detect the final iteration (perhaps if all of its inputs have been solved)?

-Kevin

2 Likes

Nice investigation and workaround, thanks!

Seems to me the GHPlayer stuff is not quite ready for prime-time… It also doesn’t seem to play nicely with the OpenNest component that is in this definition I got, probably also because it is causing it to try to solve the nesting arrangement many times on each input, so it slows down to a crawl. I guess it’s fine for simple stuff, but a context bake with attributes is really necessary.

I think whatever is possible with Elefront should be turned into native Grasshopper components.

2 Likes

I use Elefront with GH player successfully. I use a get string component at the bottom of my GH definition connected to the bake component. Since it is at the bottom, the whole script is calculated before the bake component receives the “true” to bake. Of course, you could also use a get integer to bake. When running multiple GH scripts in a macro, you need to open GH and open at least a blank GH document to get Elefront to work.

2 Likes

I’m hoping to add attributes as a native type to GH1 in Rhino 8. This would allow for a new context bake component that includes attributes.

Probably not with respect to the custom python scripts you are adding. It sounds like you need some ways from scripting to identify if you are currently running inside of a GH player command and if you are in the final baking phase of the command. Does that seem correct?

I’m not familiar with this component, but if the inputs haven’t changed during the running of a command I wouldn’t expect it to need to resolve on every input.

1 Like

Maybe… I was simply using the Python script to test baking with attributes because the Elefront component supplied in the GH definition was baking like 15 copies of the same object when I ran it via GHPlayer.

I don’t know, it is just a theory at this point as something is slowing everything to a crawl and OpenNest looked like the likely culprit - the timer widget showed that it was consuming 1 second under normal non-GHPlayer operation - by and large the slowest part of the definition. The effect of running the same definition with GHPlayer made each of the seven numerical inputs (Get Number) take 4-5 seconds to resolve and move on to the next one, so it was trying to calculate something in between. As it’s a complicated definition that was not written by me, I would have to take it completely apart to figure out where the hangup is.