HSF / root_cern-To_gltf-Exporter

3 stars 6 forks source link

.root to .gltf exporter

The following is a tool that can be used to convert .root files that describe a particular geometry to GLTF format, compatible with the phoenix framework for visualization

Dependencies

The exporter is using several javascript libraries, most importantly jsroot and three.js. However, there is no need ot install them on your machine if you're happy with the default version used from the Web.

In case you want to change version, you only have to change the includes in your export script (see below)

Using the exporter

The exporter is essentially a script (written in javascript) which you will execute in your browser. To that purpose, you will write a small HTML page calling it by copy/pasting and adapting from the export_LHCb.html example

Structure of the export.html file

  1. Header
  <head>
    <script src="https://unpkg.com/three@0.139.1/build/three.js"> </script>
    <script> import * as THREE from 'three'; </script>
    <script src="https://unpkg.com/three@0.139.1/examples/js/exporters/GLTFExporter.js"> </script>
    <script src="https://root.cern/js/latest/scripts/JSRoot.core.js"> </script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/1.3.8/FileSaver.js"></script>
  </head>

This is loading the various external libraries. Copy as is unless you want to use your own, local versions

  1. Data

    import { convertGeometry } from './phoenixExport.js';
    var hide_children = [ ... ];
    var subparts = { ... };

    This is the core of the conversion, where you define what to convert and how.

The first entry hide_children defines a list of paths matching the subparts to be ignored. Paths can be string or regular expressions. Any entry in the geometry starting with one of the strings or matching of of the regular expression will be dropped as well as all its children

Here is an example of a potential hide_chidren declaration (2 strings and 1 regular expression) :

    var hide_children = [
        "_dd_Geometry_BeforeMagnetRegion_VP_Supports_lvDeliveryPipe",
        "_dd_Geometry_BeforeMagnetRegion_Rich1_lvRich1PhDetSupFrame",
        /_dd_Geometry_BeforeMagnetRegion_.*Test.*/
    ];

See export_LHCb.html for a more complete example

The subpart dictionnary defines the pieces of geometry you want to keep. Each entry is a set of volumes matching one item in the phoenix "Detector" menu :

See export_LHCb.html for a more complete example

  1. Calling the exporter code
    convertGeometry("./LHCb.root", "lhcb.gltf", 4, subparts, hide_children);

Here we call the conversion function. Parameters are :

How to run the exporter:

Two main steps :

That's it, you should be able to download the GLFT resulting file. You can then open it with phoenix

Optimizing the resulting file

There are ways to significantly reduce the size of the resulting gltf file without impacting the vizualization, mostly by cleaning up the data (e.g. dropping non significant digits) but also by using the glb format, some sort of binary version of gltf.

One easy tool to use there is gltf-pipeline, available at https://github.com/CesiumGS/gltf-pipeline. Here is an example usage :

> ls -l lhcb.gltf
-rw-r--r-- 1 sponce z5     8356678 Apr 10 18:38 lhcb.gltf
> gltf-pipeline.js -i lhcb.gltf -o lhcb-draco.gltf -d # Draco compression
> ls -l lhcb-draco.gltf
-rw-r--r-- 1 sponce z5     4697745 Apr 11 07:52 lhcb-draco.gltf
> gltf-pipeline.js -i lhcb.gltf -o lhcb-draco.glb -d -b # Draco compression + binary format
> ls -l lhcb-draco.glb
-rw-r--r-- 1 sponce z5     2690296 Apr 11 07:53 lhcb-draco.glb
> zip lhcb-draco.glb.zip lhcb-draco.glb # you can still compress it
> ls -l lhcb-draco.glb.zip
-rw-r--r-- 1 sponce z5      351963 Apr 11 07:56 lhcb-draco.glb.zip

Starting from gdml data

The gdml file can be converted to root easily. Just type this in a root prompt :

TGeoManager::LockDefaultUnits(false);
TGeoManager::SetDefaultUnits(TGeoManager::kG4Units);
TGeoManager::Import("LHCb_Upgrade.gdml")
TGeoManager::Export("LHCb_Upgrade.root")

Note the usage of kG4Units here. this sets the length unit to millimeters. Use kRootUnits for centimeters.