Group to block


#1

Hi!

I found a useful script that converts blocks to groups. Is there also a solution that does the opposite?

Regards,
Thomas


#2

Dunno… maybe the following works for you? --Mitch
Edited - updated

import rhinoscriptsyntax as rs
import Rhino

def onegroup_filt(rhino_object, geometry, component_index):
    return rhino_object.GroupCount==1
    
def GetSingleGroup(obj):
    og=rs.ObjectGroups(obj)
    if og and len(og)==1:
        return og[0]
    
def ConvertGroupToBlock():
    msg="Select group of objects to convert to block"
    err_msg="Too many groups found!"
    g_objs=rs.GetObjects(msg,group=True,preselect=True,custom_filter=onegroup_filt)
    name=GetSingleGroup(g_objs[0])
    if name:
        for i,obj in enumerate(g_objs,1):
            if GetSingleGroup(obj) != name:
                print err_msg ; return
    else:
        print err_msg ; return
        
    origin=rs.coerce3dpoint([0,0,0])
    msg="Block instance insertion point? (Enter for World Origin)"
    insert_pt=rs.GetPoint(msg)
    if not insert_pt: insert_pt=origin
    block=rs.AddBlock(g_objs,origin,name,delete_input=True)
    rs.InsertBlock(block,insert_pt)
    
ConvertGroupToBlock()

#3

Thanks, would it be possible to convert multiple groups at once?


#4

I avoided that to maximize the chances of success… As you know any object can be a member of more than one group - possibly even nested groups. So asking the user to select a single group at a time and excluding any object that was in several groups is how I approached not possibly creating a mess…

I’ll have a look to see if there’s a reliable way to screen all possible selected groups to make sure they’re unique and not nested…

–Mitch


#5

You can try this one… All bets are off if objects are in nested or overlapping groups… Use at your own risk.

import rhinoscriptsyntax as rs

def onegroup_filt(rhino_object, geometry, component_index):
    return rhino_object.GroupCount==1
    
def ConvertGroupsToBlocks():
    msg="Select group of objects to convert to block"
    objs=rs.GetObjects(msg,group=True,preselect=True,custom_filter=onegroup_filt)
    if not objs: return
    group_set=set()
    for obj in objs:
        obj_g_names=rs.ObjectGroups(obj)
        for g_name in obj_g_names:
            group_set.add(g_name)
    all_obj_groups=list(group_set)
    
    #all_obj_groups should now contain unique list of groups
    for group in all_obj_groups:
        g_objs=rs.ObjectsByGroup(group)
        origin=rs.coerce3dpoint([0,0,0])
        block=rs.AddBlock(g_objs,origin,group,delete_input=True)
        rs.InsertBlock(block,origin)
    
ConvertGroupsToBlocks()

Scaling by item
#6

Haha thanks!

I’m sure we don’t have nested or overlapping groups.
As always all production companies use autocad, so we need the grouped parts to be blocks…