engine_components
engine_components copied to clipboard
Highlight elements by globalId or expressId (without using click-event)
Description 📝
At the moment there is no direct way to highlight an element by the globalId or expressId. The FragmentClassifier only provides methods to "select" byEntity, byStorey etc.
The click-events are able to select explicit elements, but I didn't find a way (docu and chat) to select elements by calling some functionallity.
Suggested solution 💡
Maybe it can be done by some extension in the FragmentClasssifier to use it also for the visibility.
Function byGlobalId
Alternative ⛕
No response
Additional context ☝️
If I missed some docu or function calls, I am sorry.
Validations ✅
- [X] Read the docs.
- [X] Check that there isn't already an issue that requests the same feature to avoid creating a duplicate.
There is a pull request with same idea #247
At the moment this pull request is only "creating" a group with elements which are inside "group.data"
In my test szenario this is not always the case
Hi @TobiasSeum!
I'm a bit confused. You're talking about selecting, but mentioning FragmentClassifier 🤔 Shouldn't it be FragmentHighlighter?
Hi @HoyosJuan of course its just a suggestion. I had the impression that for many visual functions you need FragmentIdMaps. If you have a way to build them with globalIds, you have more generic tool to work with.
Hey @TobiasSeum I needed this functionality last week, and have come up with this (with great help of people from https://people.thatopen.com/)
async highlightByExpressID(expressID) { const model = this.model as FragmentsGroup const fragmentMap = model.getFragmentMap([expressID]) const fragments = this.model.keyFragments const properties = this.model.properties const fragmentManager = await this._components.tools.get(OBC.FragmentManager) for (const fragmentID in fragments) { const fragment = fragmentManager.list[fragments[fragmentID]] const model = fragment.mesh.parent if (!(model instanceof FragmentsGroup && model.properties )) { continue } if(fragment.items.includes(expressID)) { const fragmentIdMap = this.createFragmentIdMap(fragment, expressID) as OBC.FragmentIdMap this.highlighter.highlightByID("select", fragmentIdMap) } } } createFragmentIdMap(fragment, expressID) { const id = fragment.id const mySet = new Set([expressID]); const myObject = { [id]: mySet }; return myObject }
So, in ifc.js we had a nice interface to create subsets by expressIDs, and don't we have now something similar? This seems to me a huge hole in the API.
@fedelaport That's what the highlighter does: https://docs.thatopen.com/Tutorials/FragmentHighlighter
I don't see a way to simply make a group of parts by global or express ID @HoyosJuan. And then highlight, hide or whatever. Maybe it's my lack of knowledge of the library. IDK. We are migrating from ifc.js and we are currently implementing our features through our custom functions to make our FragmentIdMaps. But now I am considering extending the FragmentClassifier ourselves.
Starting from @thatopen/[email protected], you can use the map FragmentsGroup.globalToExpressId. That way, you could map any globalID to an expressID and perform all highlighting operations as normal (using highlightByID). Closing this!
BTW @fedelaport the reason the highlighter doesn't clone things now is performance. I'm going to implement cloning logic to fragments. Once we have that in place, creating a logic similar to the previous subset thing (by cloning a fragment and then isolating the IDs) should be quite easy. Feel free to create a feature issue and I'll let you know when it's in place.