Is there a way to detach the Guid from referenced ModelContent to effectively make copies that, when baked, do not replace the referenced content?
I mean this both for ModelObjects and ModelLayers.
Example:
I would like to query an existing layer, then make a copy by wiring it to the “Layer (L)” of a ModelLayer component while plugging in an entirely different path, maybe a different display colour, and then bake (cache) it.
Currently, wiring a ModelLayer like this brings its Guid along with it, meaning any modifications are done to the original layer and not a copy.
I’ve had no success in setting the Guid to Empty or NewGuid, because it is “read-only” for ModelLayers.
One of the cool and uncool things depending on how you look at it with the R8 Model Objects is that if an object already has a GUID and exists in the model then if you modify this MO, it will update it in the model and move it to the new position or change it in whatever way you specfied in your script.
Please see the attached where I extract the geometry of the cube and the layer information, and then create a new Model Object with that information so that you get your original cube AND your new arrayed cubes.
I hope that makes sense? The Array cubes have their own GUIDs after being cached/added to the document now because they are now their own “new” objects.
Thank you very much for your reply and response via the .gh file!
I do think it is neat that one can directly ‘move’ and alter an existing RhinoObject this way, but at the same time I’m robbed of choice and flexibility in the matter. Before, I could also “move” by way of making-a-copy-and-deleting-the old, which incidentally is what ObjectTable.Replace Method (ObjRef, RhinoObject) does anyway!
If you look at the output of you array of cubes in your response however, they are all missing their UserText. You’d have to separately pass those on too!
… aand what’s more I don’t know what other attributes might not be accounted for.
For example, if I do go the route of passing every Output of the ModelObject and -Layer onwards and then bake, some attributes not accounted for by the current components get lost, like for example the “New Detail On” -property which was set to “Off” for the original layer. It ends up on the default mode “On”.
Because of this, I don’t know what other data and properties from the original Objects and Layers I’m losing along the way, which is kind of a bummer, as the “Pass-through” feature of these new components would be so awesome to use (as they are in EleFront)!
… so why not just use EleFront? As awesome as it is it’s never handled annotations and their style-overrides - especially in conjunction with Blocks - very well. I’ve been hoping that Native Rhino 8 Grasshopper functionality would at last come in and set everything straight, as I hope it yet will.
I think you can get what you’re looking for with almost the exact definition you posted using the native components… only you have to select “Branch Names” in the Content Cache component. When you do this, it will create a new Layer with the name of the content cache and then put everything inside of that. I modified the names of your cache and I think the layer name a little so that it matched the output that you were looking for… But, have a look at the attached definition (the native components section) and see if this bakes the way you wanted it to. Rhino 8 Comparing EleFront 5 to Native Workflow_AP.gh (36.7 KB)
I tested the definition you attached in response. It’s a step in the right direction, although with it…
I’d have to mind two places in my definition to build destination layer paths - once where I input the layer paths for attributes, and another time at the end when I bake. It is doable.
Upon baking, only the last Box and Curve in the array remains, I assume because the original Guid of the referenced objects is tied to the ModelObject Attributes and, as each new object is baked, it’s replacing its predecessor.
The new layer’s attributes are not copies of the originals unless I resort to the “wiring nightmare” from my earlier post. and even then not all attributes are accounted for in the inputs of the ModelLayer components. Same would apply to the ModelObject, as discussed above with Michael Vollrath.
Incidentally on a related subject: a while back the Cache name as stored as UserText in the baked content. This was very convenient for tracking down such content in Rhino afterwards without (or with) Grasshopper. Is the Cache name still accessible in the baked Rhino Objects’ metadata somewhere, programmatically or otherwise?
Will the new “Duplicate Content” -component also accept a blank/null name? I see in your screenshot that the last example indeed has no input for “Name” but does have something for “Parent”. Looks like there’s ZUI inputs involved. I’m just curious if inputting only “Content” alone with nothing in “Parent”, “Name” nor any other inputs will still output duplicate content?
I’d like to bump my earlier question about the Cache Name:
Yes it always duplicates, optionally you can assign a new Name or a new Parent.
On the second question, the information is also stored on the object but into the UserDictionary. Currently there is no dedicated API to query or manipulate the tracking information. Are you after something like this? Or are you asking about having some feedback on Rhino that tells you which content is tracked and the cache-name where is tracked?
I see!
It just occurred to me now that I could simply put the BakeName in myself through the regular UserText.
So I don’t need access to the CacheName nor the UserDictionary (false alarm! )
Just to explain myself:
From my EleFront workflows I’m used to querying my model for objects with BakeNames (for example for cleaning them up). Sometimes a script may go awry and there are half-baked (heh) remnants of content left over in hiding in my Rhino files and it’s easy to wrangle them by using the “SelKeyValue” -command or, upon finding one such RhinoObject using “Select objects by key and value” to find all its brothers and sisters:
You can also do something like this to pull back all the stuff was pushed under certain name, and then select it by doing right click on the component.
Is there a way to display or modify the cache name in the Rhino UI?
It’s annoying that I copied the specific baked cached object and modified it manually, and then I do not know how to keep it from the next baking.
I remember initially the cache name was written in user text, why not keep going that way? Or can have a new option to manipulate that would be very handy, thanks!
The Cache Name can be found and with Duplicate Content can be stripped from the objects. Baking the objects also will do this.
But the CacheName is not the only identifier. The ID that is went along with the objects is what will specify if an existing object is replaced or a new object created. Some of that is covered in this guide:
The logic is a bit different then Elefront. Because the ID, Cache information, attributes and all are collected into one object we can be a bit more flexible.
@scottd Thanks for the re-focus and reply. I nearly use it as the primary logic in my workflow and surely it is very clean and handy even if I can only use the partial logic you created that I talked in mind.
I re-tested for the issue that the objects created by named content pushing would be mis-deleted and it was already fixed in the lasted 8.8 RC.
I still have a scenario of interaction flexibility many times that I need to bake the objects into the Rhino with multiple temporary layers and modify them (split, trim, or boolean operation, etc.) and return them back to the Grasshopper with the same tree structure to the algorithm to move forward. Why do I have to modify them? In AEC, we still have some special situations when we figure out the standard part of the algorithm, and these special situations are a small number. They may be raised by design types or the transformation, or boolean operation issue in the Rhino, and they are not worth the time.
These unnecessary WIP objects and layers are boring and not elegant.
In my opinion, it would be more flexible and handy if given an option, maybe it is like the “record history”, assumed as “Record Cache” that will record the modification result of the cached objects when enabled. And auto-assign them with attributes including tree structure path by the base object (or maybe called ancestor).
Although a different pull may be also used later in the definition depending on the complexity of manipulation that is happening at the intermediate stage.
There are some circular logic issues that can arise if this is used too much in a definition and a solution might not converge. We are looking into how to deal with definitions that build multiple level solutions that make solving more complex.
Currently, within a definition this is how a “history” of sorts can be used. Essentially stages of development with manipulation between possible. Some might do this in a single file, but on AEC projects we have also seen this done between Multiple files and folders, building up what could be seen as a part and assembly tree that is file based. This should be possible with these new tools.
Some other issues that are worth thinking about:
Grasshopper is a functional language. One concenquesnce of this is that many of the functions that are done to an object actually result in a copy of that object, not operating on the obejct itself. This included any transformation, boolean, trim, etc… For instance the Move Transform is really a copy operation that the copied object is transformed and output. So it really is not the same object.
We can look at content cache as a way to save the current state of a Grasshopper definition at any point in time to be used later. It is not that the same object is being pushed down the pipe, but may copy. So it is not a history builder in the strictest sense, although it can be arranged to have a similar behavior.