Hi there,
I’m trying to figure out how to access usertext info for a selected object inside a block. The block is created by a separate user and I am inserting their file (embed/link) into my model. I would like to be able to access the usertext data in the objects in the imported block.
In Python I thought that:
rs.GetObject(filter=28)
would work, but instead the block and all of its objects are ignored.
Besides exploding the block (which I don’t want to do because it will break the link) is there some other way to get into the block and allow the user to manually select an object (using rs.GetObject() or another command) to query the usertext?
I can’t post the model, but you can replicate my struggle by:
make a box, and explode it
make that set of six surfaces a block
try using rs.GetObject(filter=28) to select one of the surfaces in the new block => unless there is another way to select a single object in a block this is where I’m running into a wall. rs.GetObject(filter=28) seems to ignore all of the objects inside the block.
If I can get past step 3 and grab the GUID of a single object inside the block then I’m golden. I’ve already got the script written and working to extract usertext from an object and manipulate it.
The GetObject function will only select top level objects. Thus if you have a block, you can only select the block, not it’s components. Thus, the process will be to 1.) Select the block and, 2.) Get the objects that make up the block’s definition.
For example:
import rhinoscriptsyntax as rs
def TestNavArch():
# Select a block instance
block_id = rs.GetObject("Select block", rs.filter.instance)
if block_id is None: return
# Get the name of the block definition
block_name = rs.BlockInstanceName(block_id)
if block_name is None: return
# Get the block definition's objects
object_ids = rs.BlockObjects(block_name)
if object_ids is None: return
# Do something useful...
for id in object_ids:
print rs.ObjectType(id)
Your example along with another topic I found got me to the solution. I’m not sure how to link to it to help others in case they have a similar problem but the title of the topic is:
Add Object to Block Python (bypass block edit)
The ExtractObjectsFromBlock.rvb file gave me the code I needed. I just needed to convert to python syntax.
What I didn’t realize is that rs.GetObjects() has a filter array that only allows you to pick certain objects. So using your code I can get a list of those objects and then call GetObjects to only select the subobjects in the block.
Actually I spoke to soon. I overlooked the obvious and successfully used Willem’s code to EXTRACT new surfaces from the block and then access the usertext data on those surfaces. But the thing is I don’t want to create new surfaces because that breaks the link from the inserted block.
What I’m realizing is that I’d like to be able to collect the object GUIDs per Dale’s code and then run GetObjects, filtering on those objects so that I can select one of them inside the block. The problem seems to be that though I’m filtering on the objects, because they are inside a block GetObjects wont find them. They are behind a wall.
I’m looking for a way to look through the wall and see whats there but not actually modify any of the objects. Is that possible?
So I’ve done some more thinking and digging and realized that what I’m looking to do is basically select a sub-object within the block. I just found out about the sub-object filter (Not sure how I’ve gone so long not knowing about it), but it basically is what I want, except it doesn’t seem to work with blocks. I tried playing in the WIP and it seems like I can select sub-objects in blocks, but the sub-objects won’t reveal their user text unless the block is copied and exploded like in Willem’s code.
Dale, is there a way to work with the list of object_ids that is returned by rs.BlockObjects()? If I could just find a way to figure out which GUID I want to query I’d be golden. having the user select from a list might work for a block with 20 items or less but my blocks have 1000+ items, so I need a way for them to select with their mouse. Is there a way to discern from where the mouse was clicked, what object might have been selected in object_ids?
go = Rhino.Input.Custom.GetObject()
#insert script to run your GetObject command
objref = go.Object(0) #Output from the GetObject command
part = objref.ObjectId
if rs.IsBlockInstance(part):
part = objref.InstanceDefinitionPart()
part = str(rs.coerceguid(part))
attids = rs.GetUserText(part)
My current issue is that I’m using Linked blocks and when the linked block is updated the GUIDs get screwed up in my working model and I lose the link to the object in the block. I haven’t tried recently so maybe there has been a change to how blocks are handled but right now I’m assuming it is still a problem. (As an aside if you can use a worksession then the links work)