let’s say I wanted to take the current selection in the model and check if I selected sub-objects (especially then figuring out which block it originates from, trying this approach:
My code for reading the sub-objects is this one, but I always just am able to get back the top-level object.
ObjectEnumeratorSettings settings = new ObjectEnumeratorSettings();
settings.SelectedObjectsFilter = true;
settings.SubObjectSelected = true;
settings.
var selection = Document.Objects.FindByFilter(settings);
foreach (RhinoObject obj in selection)
{
var instanceObject = obj as InstanceObject;
if (instanceObject != null)
{
ObjRef oRef = new ObjRef(obj);
if (!oRef.GeometryComponentIndex.IsUnset())
{
var subObject = instanceObject.SubObjectFromComponentIndex(oRef.GeometryComponentIndex);
// ... Other code here
}
}
}
the following script (via scripteditor ) will duplicate all geometry sub-Selected from blocks…
hope this helps as a starting point
… not sure if there is a more direct / simpler way or if this is the approach the api wants us to do it…
// #! csharp
using System;
using Rhino;
using Rhino.DocObjects;
using Rhino.Geometry;
ObjectEnumeratorSettings settings = new ObjectEnumeratorSettings();
settings.SelectedObjectsFilter = true;
settings.SubObjectSelected = true;
var selection = __rhino_doc__.Objects.FindByFilter(settings);
foreach (RhinoObject obji in selection)
{
// check if Instance and cast
if (obji.ObjectType == ObjectType.InstanceReference && obji is InstanceObject instance )
{
// get the transform
Transform xform = instance.InstanceXform;
// iterate all subselections
foreach( ComponentIndex ci in obji.GetSelectedSubObjects())
{
if (ci.ComponentIndexType == ComponentIndexType.InstanceDefinitionPart)
{
// next line - maybe do stepwise for better debugging / errorhandling
GeometryBase geo = instance.InstanceDefinition.GetObjects()[ci.Index].Geometry;
GeometryBase geoNew = geo.Duplicate();
if (geoNew.Transform(xform))
{
__rhino_doc__.Objects.Add(geoNew);
}
}
}
}
}
This does somehow not work for me. @dale may I ask what is the ComponentIndex referring to when I am picking an object from a nested block?
The ci.ComponentIndexType == ComponentIndexType.InstanceDefinitionPart is true, but I have no idea how to make use of it!
@dale
When working in a model I want to read the currently selected objects.
No problem at all when no subobjects are selected.
In case subobjects are selected (and in my particual case it would be parts of nested blocks), I would like I am trying to find out which block the selected objects belongs to.
I just saw that @lars has answered this question some time ago here.
I tried this a few days ago though and it did not work.
(Might try this again right now).
Let’s say I subselect the red panel (which is a block) inside the main block, my aim would be to get the id of the selected panel.
This works fine when I do it with a GetObject() object, yet for me it does not work when I do it like this:
ObjectEnumeratorSettings xsettings = new ObjectEnumeratorSettings();
settings.ReferenceObjects = true;
settings.ActiveObjects = true;
settings.SelectedObjectsFilter = true;
settings.SubObjectSelected = true;
var test = Document.Objects.FindByFilter(settings);
foreach (var rhObj in test)
{
RhinoObject subObject = null;
ObjRef obj = new ObjRef(rhObj);
var instanceObject = obj.Object() as InstanceObject;
if (instanceObject != null)
{
if (!obj.GeometryComponentIndex.IsUnset())
{
subObject = instanceObject.SubObjectFromComponentIndex(obj.GeometryComponentIndex);
}
}
if (subObject != null)
{
// here I have methods for finding out which block the item belongs to
}
}
Ideally I would like the name of the InstanceDefinition that contains the subselected geometry.
This seem impossible, at least from what I understood.
So it would be sufficient for me to get the GUID or RhinoObject that this geometry belongs to.
This woudl come close to this one. If this is not possible it would be the id of the RhinoObject that I subselected.
@dale thanks!
This gives me the superior block’s definition’s name.
The result is: “Panel and profile”.
The desired result would be to get back the rhino-object’s id that I selected. Using this I can find out which block it belongs to and get the following result: “Profile”.
The purpose of this is to be able to select items from nested blocks and to assign user-texts to it’s definition without having to open the blockeditor every time, searching for the block’s name, …
@dale
Just a last question here.
Do you think it’s possible to retrieve the “parent” object’s ID here as well?
Referring to the schematic picture this would mean:
I now successfully got the definition “Panel” and would like to get the “Panel and profile” instance’s Id.
I am trying to assing user data to objects.
My aim is that I want to avoid that my colleauges always have to go to the block editor, searching for nested definitions to assign user data.
What I am talking about is
assigning user data to block definitions (= the parts descriptions themselves)
assigning user data to instanciations of the definitions
This is of course totally easy on the top level.
Assigning to the block definition itself is totally sovled with your solution!
The (really) last challenge is that if a sub-object is selected we want to assign user-data to the selected instance. This might even mean that you have the same definition instanciated on the same level multiple times, but only one of them gets a specific value, e.g. color or something similar for production.
I already have a code doing this and this work perfectly fine when I use the GetObject() class.
Somehow it does not work with the filter that gets the selected objects. You might say that you wanna see this code, but I would not wanna steal any of your time for this (honestly).
So in short - if you sub-select the red object in the attache file:
Is it possible to return the id of the instance object: 719127a1-0482-4292-9022-5a8f322beeac.
I am really sorry for the confusion, honestly nested blocks have been both toruting and fascinating me big time…
The result of this will ease at least 8 peoples’ daily life also big time, so it is worth getting on your nerves
After some investigating, we looks like we will need to add something addition to RhinoCommon for you to get the owning sub-instance object of a selected sub-object in an instance object (if that’s clear).
When selecting sub-objects in an instance object, Rhino hands the developer the actual underlying object, as that is what most devs are looking for. There is no clear way to just get the selected sub-object as a instance object.