root-project / jsroot

JavaScript ROOT
MIT License
187 stars 80 forks source link

TGeoPainter build method doesn't fill name and other Object3d fields #303

Closed DraTeots closed 3 months ago

DraTeots commented 4 months ago

When using build() function to convert root geometry to Object3d, I noticed that nodes name fields are empty (see the screen below - red) and some other fields are not set properly (green).

image

I believe this is the reason, that if converters ( such as root2cad or root to GLTF ) produce geometry that is hard to navigate in consequent CAD or 3D software (see the screen, Blender is an example, others show the same):

image

Here is the reference geometry:

epic_dirc_only.root.zip

The code is straight forward:

const file = await openFile(url);
const geoManager = file.readObject('default');
console.time('Build geometry');
let obj3d = build(geoManager, { numfaces: 500000000, numnodes: 5000000, dflt_colors: true, vislevel: 10});
console.timeEnd('Build geometry');
console.log(obj3d);
DraTeots commented 4 months ago

A bit naive addition/suggestion (as I can imagine reasons it is not done). Besides names and hierarchy, there is userData field that can store e.g. TGeoNode reference in Object3D

linev commented 4 months ago

I see your point - all intermediate levels of geometry hierarchy did not get names. And reason is simple - names were never used for these elements. They are not "visible" and user cannot interact with them.

Why you need them? May be you can use stack member which is assigned for each endpoint of hierarchy. This stack member is somehow short form of path to the element. One uses it for navigation, one also can produce full path to the element.

I also will check if name attribute can be assigned to the elements

linev commented 4 months ago

Besides names and hierarchy, there is userData field that can store e.g. TGeoNode reference in Object3D

Main reason is saving JavaScript resources. Geometry can be large, therefore only minimal amount of data is assigned. But I could extend build() function to assign more data to Object3D

linev commented 4 months ago

I add new parameters to build() function.

Now one can configure opt.set_names and opt.set_origin. First parameter is true by default. Names and objects are assigned to all Object3D instances.

Code available in master branch only.

DraTeots commented 4 months ago

Thank you very much!

Why you need them?

Actually in EIC they are used after GLTF export so even having node names in subsequent CAD and other software is good.

I am in particular working on event display. Full EIC geometry in TGeo now has something like 3,500,000 elements and was working on scripts pruning the geometry and optimizing the rest after it is rendered with three.js.

Thanks again for addressing this!

linev commented 4 months ago

Full EIC geometry in TGeo now has something like 3,500,000 elements and was working on scripts pruning the geometry and optimizing the rest after it is rendered with three.js.

If you have very large geometry, you probably can be interested to enable opt.instancing=0 or opt.instancing=1 when calling build() function. This allows JSROOT to use THREE.InstancedMesh. If you have many similar volumes in your geometry - it will speedup a lot creation and rendering of three.js model.

This option is semi-experimental, but really can improve large geometry display.

DraTeots commented 4 months ago

Would be very helpful if in InstancedGeometry mode some names were set to InstancedVolumes too. Maybe the volume name or the first node. Or maybe there is a mechanism already? As of now I see a list of InstancedGeometry-ies in the root of the Object3D without names.

linev commented 4 months ago

Now name, names and userData set also for InstancedMesh objects. From the beginning also stacks was set.

linev commented 3 months ago

Now this functionality available in 7.7.0 release