Issue: RH8 rs.TransformObjects() makes object attributes disappear

Hi There,

I am using a mechanism in my scripts that goes down the block tree recursively and executes a function on each object. When I create copies of objects that are children of linked blocks, which in turn are nested inside an embedded block in my file, I see that object attributes are lost (e.g. layer, attribute user texts, etc…)

I’ve made a recording and added my files and script below

steps to reproduce: open attached file “main.3dm”, select the block and run the attached script
expected behaviour: copies are added to the doc with identical attributes as the objects in the source file
actual behaviour: copies are added to the doc, but objectLayer is set to currently active and Attribute User Texts are lost

This issue also occurs in RH7 and RH6.

main.3dm (51.4 KB)
linked_block.3dm (43.6 KB)

#! python3
import rhinoscriptsyntax as rs

def traverse(block_name, my_func, result=None, parent_xform = rs.XformIdentity()):

    if result is None:
    block_objects = rs.BlockObjects(block_name)
    for obj in block_objects:
        if rs.IsBlockInstance(obj):
            child_block_name = rs.BlockInstanceName(obj)
            xform = rs.BlockInstanceXform(obj)
            traverse(child_block_name, my_func, result, xform * parent_xform)
        my_func(obj, result, parent_xform)
    return result

def main():

    # let user select the input
    obj = rs.GetObject("select block with nested linked instances", filter=rs.filter.instance, preselect=True)
    if not obj:

    block_name = rs.BlockInstanceName(obj)

    def create_transformed_copy(obj, result, parent_xform):
            function to create a copy of objects that are not instances 
            @param obj: GUID object ref
            @param result: list of function result
            @param parent_xform: parent transformation matrix
            return None 
        if not rs.IsBlockInstance(obj):
            copy = rs.TransformObject(obj, parent_xform, True)

    # recursively run this function on all objects in tree
    result = traverse( block_name, create_transformed_copy)

if __name__ == '__main__':

Hi @timcastelijn,

Sorry I feel asleep on this.

The reason the transformed/copied objects have lost their attributes is that the objects are from a reference file (linked block).

When you try to copy an object that is from a reference file, Rhino must add the copy to the current document, as the reference file is read-only. Rhino objects in the current document cannot reference properties (layer, material, linetype, etc.) in reference files. Thus, when the copy is added to the current document, it is assigned default attributes.

Knowing this, your script can check to see if the source object is a reference object:


and copy whatever attribute properties you need after the transformation. I’ve modified your script to copy attribute user strings. (1.9 KB)

Hope this helps.

– Dale