Hi,
is there a way through the API to get what is the currently active (selected) Selection Set?
I did not find any possible way in the doc to achieve that.
Thanks for any hint.
Luca
Solved! Go to Solution.
Solved by xiaodong_liang. Go to Solution.
Thanks for the quick reply... unfortunately that is not what I am looking for.
The code you mention returns the current selection. I need to retrieve what Selection Set is currently selected in the tree of all sets. See for example in the attached image an example hierarchy of selection sets (image taken from the Training Labs). Imagine the user has just clicked on the "Search Set" entry: how can I retrieve that?
In other words: what I need is not the current selection. I really need to know what entries in the tree of Selection Sets are currently active.
Thanks,
Luca
Hi @luca_vezza,
I checked the documentation, including hidden API. Unfortunately, it looks no such API to know current SelectionSet.
it is not either reliable to compare the explicit selected items because two SelectionSets might have the same selected items.
I logged a wishlist as #NW-54322
Thanks Xiaodong.
We'll wait, hoping this gets implemented...
Luca
PS
(Tagging your reply as solution for now).
Same requirement/issue for me.
For Document SavedViewpoints, we have the event d.SavedViewpoints.CurrentSavedViewpointChanged
But for Document SelectionSets, no such event, nor even a CurentSelectionSet that we could check on idle.
I browse through low-level API, and it seems it's the same internally:
there is SavedItem LcOpKernelEx.GetCurrentSavedView();
but no SavedItem LcOpKernelEx.GetCurrentSelectionSet();
It would really really be great to have such event/functions.
Coherency + we can finally use SlectionSets in a reliable way.
Thanks to push internally.
I really needed this, so I digged 48h until I found a way that works more or less reliably 😉
I will give a 3 lines version to let anyone interested start, actual production code need more check, caching etc.
My full code include much more stuff so hard to share it in full...
Also remember, this is TOTALLY NOT DOCUMENTED, so at your own risks...
var selectionSetsDockPane = Application.Plugins.FindPlugin(@"SelectionSetsDockPane.Navisworks")?.LoadedPlugin as Autodesk.Navisworks.Roamer.SelectionSets.View.SelectionSetsDockPane;
var selectionSetsPaneVM = selectionSetsDockPane?.PrivateProperty<Autodesk.Navisworks.Roamer.SelectionSets.VM.SelectionSetsPaneVM>("VM");
var selected = selectionSetsPaneVM?.SelectedSavedItems;
Quick explanation:
1/ we find the Navisworsk native plugin that handle the SelectionSets
2/ we use reflection to get the internal object that handle the caching of the tree
3/ we get the ObservableCollection<SetsItemVM> of selected items
From there, we can:
- iterate through the SetsItemVM, calling ResolvedSavedItem on each to get the actual SavedItem
- subscribe to the ObservableCollection CollectionChanged event to get informed of changes
Comments:
1/ you will have to add a few references to your projects, navisworks.roamer.plugin, navisworks.gui.roamer at least, browse to your Navisworks installation folder and choose the DLLs with same name, here mine but not sure you need all of these
2/ CollectionChanged events are raised in a quite complicated manner, for exemple when you click on another item, you will get called twice, once with both items and once with the finally selected one. This allows to handle multiple items selection so make sense.
I forgot to provide the extension to access private fields of an object 😉
Here it is:
static public class InstanceAccessExtensions
{
static public T PrivateField<T>(this object o, string fieldName) where T : class
{
Type t = o.GetType();
//Create binding flag that will describe the type of object you try to access
//the following can be used in most cases.
var bindingFlags = BindingFlags.Instance | BindingFlags.NonPublic;
FieldInfo finfo = t.GetField(fieldName, bindingFlags);
Debug.Assert(finfo != null);
return (T)finfo?.GetValue(o);
}
static public T PrivateProperty<T>(this object o, string fieldName) where T : class
{
Type t = o.GetType();
//Create binding flag that will describe the type of object you try to access
//the following can be used in most cases.
var bindingFlags = BindingFlags.Instance | BindingFlags.NonPublic;
PropertyInfo pinfo = t.GetProperty(fieldName, bindingFlags);
Debug.Assert(pinfo != null);
return (T)pinfo?.GetValue(o);
}
}
Can't find what you're looking for? Ask the community or share your knowledge.