Using the Elefront “Deconstruct Block” component, I get multiple trees giving me valuable info on the block instances contained in my model.
Let’s call “level 1” blocks those who contain only geometry, and “level 2” blocks those who contain “Level” 1 " blocks.
Voluntarily, our block structures are never more complex than this (and it’s already tough to manage).
I hit a problem when I want to remap info from “Level 1” blocks to the “Level 2” bloc that contain s them.
For example, I’d like to have a list of the Base points of all the “Level 1” blocks contained in a certain “Level 2” block.
I know I could get this by using “Deconstruct Block” a second time on the content of my “Level 2 blocks”, but I plan to feed truckloads of blocks in my definition, and this operation is quite intense.
So since the info is already there, I’d like to re-use it… but how ?
Nope.
In fact, the problem is upstream of the “Deconstruct Block” component :
Out of the “Reference Block by Name” component, one gets either “Referenced blocks” which are instances in the model, or “Blocks” which are in fact nested in some of those instances.
The problem is that there is no way to associate those nested blocks to their containing block instance.
Lost work, missing files (server/one drive issues), someone ordered the wrong size material for stuff that needs to be on the truck this afternoon. Seems to be one of those days.
The approach shown is the one I would take (with the Filter by Type as suggested, in between the first Deconstruct and the second). Does that do what you need? Or is there an issue with that strategy?
Here’s why this approach, although logical, doesn’t seem ideal to me.
Blocks, are a way to structure geometry in an effort to limit the amount of data that has to be moved around.
Nested Blocks push the concept even further.
By performing the “Deconstruct Block” command once on All the blocks, I have, in theory, a compact description of all my block structure :
-“Baseline” blocks (those which contain no block), along with the list of geometry they contain.
-“Higher order” blocks, along with the geometry and other blocks they contain.
This is optimal, because the actual geometry is listed only once, and I can infer from this everything I need except the Base Planes of the sub-blocks.
By performing “Deconstruct block” twice (or more depending on the nesting level), you are referencing multiple times the same geometry.
It is an easy way to get the Base Plane info for sub-blocks, but at the cost of losing the very benefit of a block structure.
Maybe by just adding “Sub-Block Base Plane” output to the “Deconstruct Block” component, this would solve the issue.
I see what you’re getting at. One nuance I would highlight is that - at least in my understanding - when you deconstruct the “higher order” blocks to a single level, the geometry of the sub blocks is not processed - only the block instance, which is still very lightweight**. Only when you deconstruct the second/last time is that geometry “processed”. So I don’t think it’s the double-deconstruct that’s costing much - it’s the fact that at the end of the chain you’re paying for extracting geometry that you don’t actually care about if all you want is the plane. So I am thinking a good upgrade would be to make the Geometry output of Deconstruct Block an optional one.
On that note, at the moment the Name and Plane outputs are only One Level no matter whether you have the Recursive setting or not. Perhaps we apply the One Level or Recursive option to the Names and Planes as well, so it would output the whole list.
Will add it to the list for future releases! No promises for when though…
**The geometry within the block is not processed or loaded into memory in GH until it’s deconstructed, so it would stay light and fast. However if you preview that geometry, of course the visualization pipeline is what slows down as it parses all the nested geo.
Sadly, the component itself can’t deal with nested blocks.
Elefront and Human both almost get it right, in their own way, but it never goes all the way, and combining them is just not possible…
It’s like the issue with Elefront’s “Modify Block” : it requires to bake the block, whereas Human’s “Define Block” just changes the definition which is much better when dealing with nested blocks or blocks which don’t have a “Bakename”.
Well, frankly, if you take the good ideas in Elefront and Human, you end up with something quite acceptable.
Elefront has a great way of exploding nested blocks.
Human has the option to explode only the block info.
Elefront can reference Blocks by name, including nested instances*
Human can modify a Block definition without having to bake it
Combine all that, and you’re good, except you can’t because the classes are not compatible.
In my case, as I want to do a custom “Block manager” that displays attributes, and a 3D view of any block defined in the model, HUMAN would not allow me to display info on blocks without instances.
Here’s the prototype of the tool I am working on :
I store the attributes of low-level blocks in the geometry defined in the block. That way, I can change the attributes and have them propagate in the blocks where they are nested.
For top-level blocks, attributes are stored in the block instances, which allows to have varying attributes per instance.
This works because it is consistent with our constructive logic : low-level parts are like clones at the fabrication level, whereas welded parts can belong to different phases, so we need the possibility to have a “per instance” value for cetain keys :
Do you store attributes in User Dicitonary in the geometry inside block, or in the dictionary of sub-block definition? So I suppose you need the geometry (those inside blocks) to stay as referenced ones in Grasshopper? Honestly I think neither of Human & Elefront can do that.
Yes ! I have a cluster in my definition which looks at the attributes of all the geometry in my low-level blocks. Whatever geometry has most keys is considered the “Reference geometry” and any value changes or extra keys will be given to that geometry.
If I used the attributes of the instances for low-level blocks, it would be a nightmare to change them in all nested instances !
This is a huge weakness in the Rhino Block system, and assigning attributes to the geometry within the blocks is the only solution I found.
For Top-Level blocks, it’s another story : first, it’s much easyer to manage since they are not nested (by definition), and it makes sense in our construction process because we can have the same parts used in different construction phases, so the “PHASE” attribute can have different values for different instances of those Top-Level blocks.
The geometry coming out of Elefront’s “Deconstruct Block” component retains it’s attributes, even if transformed, EXCEPT points ; as discussed here with you and Martin.
So this is not really an issue.
I’m struggling right now to re-structure the attributes that I need to change and re-define blocks with those new attributes, but that’s another story.