As a part of a much larger program, I need to bake ModelObjects into Rhino and then retrieve the attributes from the baked objects later in the script. To do this, I’m using the ContentCache component, then retrieving these objects by looking at the active doc with a C# component.
The issue is that ContentCache does not seem to work with GrasshopperPlayer - everything else works fine if used outside of GrasshopperPlayer. Attached is an example of what I’m trying to achieve, where the user selects points, bakes the content, then retrieves the object’s attributes:
My knowledge of Grashopper is limited, but as far I know.
"Grasshopper reads the whole script and then runs it. "
If that is correct (and please correct me if wrong, so I learn my bit), it will not be able to see the mid-baked changes.
Maybe you have to use some loop component, I suppose there is something “build in” what reads in between the loop(s).
The issue is less that this is a multi-stage process and more that the ContentCache component does not work at all when running in GrasshopperPlayer. Think “we bake the points first, then during another Grasshopper solution query the objects in model space”.
The actual script that I’m working with, which writes and reads from the document in one stage, works fine outside of GrasshopperPlayer, and the staged solutions themselves work fine within GrasshopperPlayer. It is specifically that I cannot bake mid-command - my thought for now is to write my own baking script to achieve what I need.
Will keep the thread updated if I find a proper solution. Thanks again,
~CH
Figured it out. ContentCache disables itself if it’s called to push content mid-command, and it seems GHPlayer is considered a running command. To work around this, I used the following
C# script in place of ContentCache:
public class Script_Instance : GH_ScriptInstance
{
private void RunScript(object model_obj, bool is_active, ref object a)
{
// Activate only if is_active
if(!is_active) return;
// Converts object to ModelObject, ends script if conversion fails.
Grasshopper.Rhinoceros.Model.ModelObject mo = (Grasshopper.Rhinoceros.Model.ModelObject) model_obj;
if(mo == null) return;
// Extracts necessary information from mo
GeometryBase mo_geom = null;
if(!mo.CastTo<GeometryBase>(out mo_geom)) a = "Failed to convert to brep";
String mo_name = mo.Name;
String mo_layer_path = mo.Layer.Path;
Color mo_layer_color = (Color) mo.Layer.DisplayColor;
// Find mo's layer
RhinoDoc doc = RhinoDoc.ActiveDoc;
int layer_in_doc_inx = doc.Layers.FindByFullPath(mo_layer_path, true);
// Create mo's layer if necessary
if(layer_in_doc_inx == -1){
layer_in_doc_inx = doc.Layers.AddPath(mo_layer_path);
doc.Layers.FindIndex(layer_in_doc_inx).Color = mo_layer_color;
}
// Construct object attributes
Rhino.DocObjects.ObjectAttributes obj_attr = new Rhino.DocObjects.ObjectAttributes();
obj_attr.Name = mo_name;
obj_attr.LayerIndex = layer_in_doc_inx;
doc.Views.ActiveView = doc.Views.First();
// Bake
doc.Objects.Add(mo_geom, obj_attr);
}
}
Where model_obj is the ModelObject that needs to be baked and is_active connects to a button. This only bakes geometry with attributes that I needed it to bake - if there is a cast from ModelObject to RhinoObject, it would significantly better. If anyone needs elaboration for some future use, let me know.
I see on your script that you are trying to push the curve on the model before extruding it, and because ‘Content Cache’ does not touch the model while the command is getting its input the ‘Extrude’ component after it has nothing to extrude.
I understand this is a sample, but could you please add more context here?
Why do you need the geometry in the model mid-command?
The larger script is used to create large-scale assemblies and document the sub-assemblies with layouts and appropriate annotations on each detail view. I need for each sub-assembly to be isolated in on each page and for each detail view to only display the annotations needed for that view, and for everything to be visible in model space.
To accomplish this, I’m using Drafthorse to generate the layouts, baking the ModelObjects with attributes I can find later, then assigning the RhinoObjects the appropriate detail view Guids under AddHideInDetailOverride based on its ModelObject attributes. I know the ModelObject component in Grasshopper has a visibility setting for layout pages, but I also need to hide certain annotations in certain views, so it seems insufficient.
I’m not sure if it’s possible to modify the geometry in the way I need it modified before baking, so I currently need to bake as a halfway point in the process. Regarding GHPlayer, another solution in my case may be to use ContentCache and check “Keep open after command completes” as I’m using HumanUI (haven’t tested this), but looking ahead baking mid-command may become necessary if the user should need to create geometry to generate an assembly with.
For future reference on the “Keep open after command completes”, this was helpful (thanks for the post Kike).
Sorry for the verbose response, let me know if you have any other questions.
~CH