Recreate block layer structure

Hi All!!!

I would like to recreate the layer structure of an embedded block in a separate layer.

I’m currently creating a separate layer for each block, calling it Block_ + “Block_name” and putting all instances of that block in it.

Now I would like to recreate the block layers as a sublayer of Block_ + “Block_name”

basic example:

  • A block called window_frame.
    If you open the block you have two objects, the frame that is in the metal layer and the glass that is in the glass layer.

I would like to recreate those two layer under the layer
Block_Window_frame
— glass
— metal

and finally move the correspondent objects of the block inside those new sublayers

All blocks are pre flattened, it means I dont have blocks inside other blocks.
Thanks in advance to anyone who will give me a help! :slight_smile:

guys do you have any idea if this is possible?
@emilio @pascal

Hi Andrea,

Here is a script you could try - it should do what you described, I tested on a simple case file, assuming there are no nested blocks in the file as you said.
Also the script does not purge the original layers that are empty after moving blocks and block instances to the new layers, easy to add there if needed.
I was not clear what you want to do with the instances themselves so for now the script moves them all to new new parent layers. See if that helps.

OrganizeBlockLayers.rvb (1.3 KB)

–jarek

2 Likes

Thanks man!

i would have preferred it in python but i will study it asap and try to convert it .

Update:
@Jarek , It’s exactly what I need!
Thanks :smiley:

After Almost one year I am facing an Error with this script:

image

It usually works, but lately with some files I get this error.
Unfortunately I can’t share the files because they are under NDA, but I could use some help to understand the possible causes of this error.
Unfortunately I don’t understand so much about vb scripts, I would be a little more comfortable with a python version but I tried to translate it without success :frowning:

Does anyone have any idea what the causes might be?

hard to tell without a sample file; the script is rather simple.
Did you modify anything in the code from the file attached earlier?

The error code says we are trying to get upper bound from a variable that is not an array, but line 33 in the code is just a comment line so I am a bit confused. I would need more info to help.

I rewrote the script in python, problem solved :slight_smile:
The only thing I am missing is the “MatchLayer” at the end… there is no rs.MatchLayer in rhinoscriptsyntax?
I could match each layer attribute one at time, but I don’t really need that part.

def organizeBlockLayers():
    if not rs.BlockNames():
        print "no blocks"
    else:
        redraw = rs.EnableRedraw(False)
        blocks = rs.ObjectsByType(4096,True,0)
        blockinstancenames = set(map(rs.BlockInstanceName,blocks))
        print blockinstancenames
        for blockinstancename in blockinstancenames:
            layername = "__Block__" + blockinstancename 
            if not rs.IsLayer(layername):
                rs.AddLayer(layername)
            rs.ObjectLayer(rs.BlockInstances(blockinstancename),layername)
            for blockobject in rs.BlockObjects(blockinstancename):
                blockobjectlayer = rs.LayerName(rs.ObjectLayer(blockobject))
                newlayername = (layername + "::" + blockobjectlayer.split("::")[-1])
                if not rs.IsLayer(newlayername):
                    rs.AddLayer(newlayername)
                    #rs.MatchLayer(rs.ObjectLayer(blockobject), newlayername)
                rs.ObjectLayer(blockobject,newlayername)
        rs.EnableRedraw(redraw)

This is my result in python, maybe it can help someone! :wink:

1 Like

Not sure what you want by MatchLayer, but if you are just trying to change the layer of one object to that of another object, you just use rs.ObjectLayer().

rs.ObjectLayer(object_to_match,rs.ObjectLayer(object_to_match_to))

MatchLayer in RhinoScript matches properties between layers (color, material, linetype etc).
It is indeed missing from rhinoscriptsyntax in Python, as many other methods; I guess the project of 1:1 methods accessibility has been (sadly) abandoned a while ago, so without RhinoCommon it is not possible to translate all RhinoScript scripts into Python just by using rhinoscriptsyntax methods.

FWIW, here is a MatchLayer definition for Python/RhinoCommon:

import rhinoscriptsyntax as rs
import scriptcontext as sc
import Rhino

def MatchLayer(source_layer_name,target_layer_name):
    layers=sc.doc.Layers
    u_idx=Rhino.RhinoMath.UnsetIntIndex
    src_idx=sc.doc.Layers.FindByFullPath(source_layer_name,u_idx)
    targ_idx=sc.doc.Layers.FindByFullPath(target_layer_name,u_idx)
    if src_idx != u_idx and targ_idx != u_idx and src_idx != targ_idx:
        layers[targ_idx].Color=layers[src_idx].Color
        layers[targ_idx].PlotColor=layers[src_idx].PlotColor
        layers[targ_idx].PlotWeight=layers[src_idx].PlotWeight
        layers[targ_idx].LinetypeIndex=layers[src_idx].LinetypeIndex
        layers[targ_idx].RenderMaterialIndex=layers[src_idx].RenderMaterialIndex
        layers[targ_idx].CommitChanges()
1 Like