Skip to content

Commit

Permalink
Rules for Three geometry editing
Browse files Browse the repository at this point in the history
  • Loading branch information
DraTeots committed Jun 3, 2024
1 parent 7ee2a71 commit 7b0363d
Show file tree
Hide file tree
Showing 8 changed files with 354 additions and 104 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,14 @@ export class CalorimetryGeometryPrettifier {
//console.log(crystals);

// Merge crystals together
let mergeResult: MergeResult = mergeMeshList(crystals, node, "crystals");


let mergeResult = mergeMeshList(crystals, node, "crystals");

if(!mergeResult) {
console.warn("didn't find crystals")
return;
}
disposeOriginalMeshesAfterMerge(mergeResult)

// outline crystals
Expand All @@ -36,6 +43,10 @@ export class CalorimetryGeometryPrettifier {
});

mergeResult = mergeMeshList([innerSupport, ring], node, "support", supportMaterial);
if(!mergeResult) {
console.warn("didn't find crystals")
return;
}
disposeOriginalMeshesAfterMerge(mergeResult);


Expand All @@ -54,6 +65,10 @@ export class CalorimetryGeometryPrettifier {
let aeroGel = findObject3DNodes(node, "**/*aerogel*", "Mesh").nodes[0];
sensors.push(aeroGel);
let mergeResult = mergeMeshList(sensors, node, "sensors");
if(!mergeResult) {
console.warn("didn't find aerogel & cooling")
return;
}
disposeOriginalMeshesAfterMerge(mergeResult)

let filter = findObject3DNodes(node, "**/*filter*", "Mesh").nodes[0];
Expand All @@ -79,6 +94,10 @@ export class CalorimetryGeometryPrettifier {

// Merge crystals together
mergeResult = mergeMeshList(mirrors, node, "mirrors", mirrorsMaterial);
if(!mergeResult) {
console.warn("didn't find mirrors")
return;
}
disposeOriginalMeshesAfterMerge(mergeResult)

// Cleanup. Removing useless nodes that were left without geometries speeds up overall rendering
Expand Down Expand Up @@ -113,19 +132,31 @@ export class CalorimetryGeometryPrettifier {


let mergeResult = mergeMeshList(barsPrisms, node, "barsPrisms", barMat);
if(!mergeResult) {
console.warn("didn't find barPrisms")
return;
}
disposeOriginalMeshesAfterMerge(mergeResult);

createOutline(mergeResult.mergedMesh);

// Rails
let rails = findObject3DNodes(node, "**/*rail*", "Mesh").nodes;
mergeResult = mergeMeshList(rails, node, "rails");
if(!mergeResult) {
console.warn("didn't find rails")
return;
}
disposeOriginalMeshesAfterMerge(mergeResult);
createOutline(mergeResult.mergedMesh);

// MCPs
let mcps = findObject3DNodes(node, "**/*mcp*", "Mesh").nodes;
mergeResult = mergeMeshList(mcps, node, "mcps");
if(!mergeResult) {
console.warn("didn't find mcps")
return;
}
disposeOriginalMeshesAfterMerge(mergeResult);

// Cleanup. Removing useless nodes that were left without geometries speeds up overall rendering
Expand Down
113 changes: 92 additions & 21 deletions firebird-ng/src/app/geometry.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,14 @@ import {
editGeoNodes,
findGeoManager, findGeoNodes, findSingleGeoNode, GeoAttBits,
GeoNodeEditRule, printAllGeoBitsStatus,
EditActions, removeGeoNode, testGeoBit
EditActions, removeGeoNode, testGeoBit, getGeoNodesByLevel
} from './utils/cern-root.utils';
import {build} from 'jsrootdi/geom';
import {BehaviorSubject} from "rxjs";
import {RootGeometryProcessor} from "./root-geometry.processor";
import {UserConfigService} from "./user-config.service";
import {Subdetector} from "./model/subdetector";
import {Object3D} from "three";

// constants.ts
export const DEFAULT_GEOMETRY = 'epic-central-optimized';
Expand All @@ -23,14 +25,32 @@ export const DEFAULT_GEOMETRY = 'epic-central-optimized';
})
export class GeometryService {

rootGeometryProcessor = new RootGeometryProcessor();
public rootGeometryProcessor = new RootGeometryProcessor();

/** Collection of subdetectors */
public subdetectors: Subdetector[] = [];

/** TGeoManager if available */
public rootGeometry: any|null = null;

/** Main/entry/root THREEJS geometry tree node with the whole geometry */
public geometry: Object3D|null = null;

public groupsByDetName: Map<string, string>;



constructor(private settings: UserConfigService) {
this.groupsByDetName = new Map<string,string> ([
["hello", "world"]
])

}


async loadGeometry() {
async loadGeometry(): Promise<{rootGeometry: any|null, threeGeometry: Object3D|null}> {

this.subdetectors = [];
//let url: string = 'assets/epic_pid_only.root';
//let url: string = 'https://eic.github.io/epic/artifacts/tgeo/epic_dirc_only.root';
// let url: string = 'https://eic.github.io/epic/artifacts/tgeo/epic_full.root';
Expand All @@ -40,36 +60,87 @@ export class GeometryService {
this.settings.selectedGeometry.value:
'https://eic.github.io/epic/artifacts/tgeo/epic_full.root';

console.time('[GeoSrv]: Total load geometry time');
console.log(`[GeoSrv]: Loading file ${url}`)
console.time('[GeometryService]: Total load geometry time');
console.log(`[GeometryService]: Loading file ${url}`)

console.time('[GeoSrv]: Open root file');
console.time('[GeometryService]: Open root file');
const file = await openFile(url);
// >oO debug console.log(file);
console.timeEnd('[GeoSrv]: Open root file');
console.timeEnd('[GeometryService]: Open root file');


console.time('[GeoSrv]: Reading geometry from file');
const rootGeoManager = await findGeoManager(file) // await file.readObject(objectName);
console.time('[GeometryService]: Reading geometry from file');
this.rootGeometry = await findGeoManager(file) // await file.readObject(objectName);
// >oO
console.log(rootGeoManager);
console.timeEnd('[GeoSrv]: Reading geometry from file');
console.log("Got TGeoManager. For inspection:")
console.log(this.rootGeometry);
console.timeEnd('[GeometryService]: Reading geometry from file');


console.time('[GeoSrv]: Root geometry pre-processing');
this.rootGeometryProcessor.process(rootGeoManager);
console.time('[GeoSrv]: Root geometry pre-processing');
console.time('[GeometryService]: Root geometry pre-processing');
this.rootGeometryProcessor.process(this.rootGeometry);
console.time('[GeometryService]: Root geometry pre-processing');

analyzeGeoNodes(rootGeoManager, 1);
analyzeGeoNodes(this.rootGeometry, 1);

//
console.time('[GeoSrv]: Build geometry');
let rootObject3d = build(rootGeoManager, { numfaces: 500000000, numnodes: 50000000, instancing:-1, dflt_colors: false, vislevel: 100, doubleside:true, transparency:true});
console.timeEnd('[GeoSrv]: Build geometry');
// >oO console.log(geo);
console.time('[GeometryService]: Build geometry');
this.geometry = build(this.rootGeometry,
{
numfaces: 500000000,
numnodes: 500000000,
instancing:-1,
dflt_colors: false,
vislevel: 200,
doubleside:true,
transparency:true
});
console.timeEnd('[GeometryService]: Build geometry');

// Validate the geometry
if(!this.geometry) {
throw new Error("Geometry is null or undefined after TGeoPainter.build");
}

if(!this.geometry.children.length) {
throw new Error("Geometry is converted but empty. Anticipated 'world_volume' but got nothing");
}

if(!this.geometry.children[0].children.length) {
throw new Error("Geometry is converted but empty. Anticipated array of top level nodes (usually subdetectors) but got nothing");
}

// We now know it is not empty array
console.time('[GeometryService]: Map root geometry to threejs geometry');
let topDetectorNodes = this.geometry.children[0].children;
for(const topNode of topDetectorNodes) {

// Process name
const originalName = topNode.name;
const name = this.stripIdFromName(originalName); // Remove id in the end EcalN_21 => Ecal

const rootGeoNodes = getGeoNodesByLevel(this.rootGeometry, 1).map(obj=>obj.geoNode);
const rootNode = rootGeoNodes.find(obj => obj.fName === originalName);

let subdetector: Subdetector = {
sourceGeometry: rootNode,
sourceGeometryName: rootNode?.fName ?? "",
geometry: topNode,
name: this.stripIdFromName(originalName),
groupName: this.groupsByDetName.get(name) || ""
}
console.log(subdetector.name, subdetector);
this.subdetectors.push(subdetector);
}
console.timeEnd('[GeometryService]: Map root geometry to threejs geometry');


console.timeEnd('[GeometryService]: Total load geometry time');
return {rootGeometry: this.rootGeometry, threeGeometry: this.geometry};
}

console.timeEnd('[GeoSrv]: Total load geometry time');
return {rootGeoManager, rootObject3d};
private stripIdFromName(name: string) {
return name.replace(/_\d+$/, '');
}
}

17 changes: 12 additions & 5 deletions firebird-ng/src/app/main-display/main-display.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,11 @@ export class MainDisplayComponent implements OnInit {

async loadGeometry(initiallyVisible=true, scale=10) {

let {rootGeoManager, rootObject3d} = await this.geomService.loadGeometry();

let {rootGeometry, threeGeometry} = await this.geomService.loadGeometry();
if(!threeGeometry) return;


let threeManager = this.eventDisplay.getThreeManager();
let uiManager = this.eventDisplay.getUIManager();
let openThreeManager: any = threeManager;
Expand All @@ -103,12 +107,12 @@ export class MainDisplayComponent implements OnInit {

// Set geometry scale
if (scale) {
rootObject3d.scale.setScalar(scale);
threeGeometry.scale.setScalar(scale);
}

// Add root geometry to scene
// console.log("CERN ROOT converted to Object3d: ", rootObject3d);
sceneGeometry.add(rootObject3d);
sceneGeometry.add(threeGeometry);



Expand All @@ -129,7 +133,7 @@ export class MainDisplayComponent implements OnInit {

child.material.dispose(); // Dispose the old material if it's a heavy object

let opacity = rootObject3d.userData.opacity ?? 1;
let opacity = threeGeometry.userData["opacity"] ?? 1;
let transparent = opacity < 1;

child.material = new MeshPhongMaterial({
Expand Down Expand Up @@ -162,7 +166,7 @@ export class MainDisplayComponent implements OnInit {
});

// HERE WE DO POSTPROCESSING STEP
this.threeGeometryProcessor.process(rootObject3d);
this.threeGeometryProcessor.process(this.geomService.subdetectors);

// Now we want to change the materials
sceneGeometry.traverse( (child: any) => {
Expand Down Expand Up @@ -458,6 +462,9 @@ export class MainDisplayComponent implements OnInit {
jsonGeometry = jsonGeom;
this.eventDisplay
.getLoadingManager().itemLoaded("MyGeometry");
}).catch(reason=> {
console.error("ERROR LOADING GEOMETRY");
console.log(reason);
});


Expand Down
23 changes: 23 additions & 0 deletions firebird-ng/src/app/model/subdetector.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import {Object3D} from "three";

/**
* Subdetector describes one of the main detectors like "TOF" or "Some Calorimeter" providing
* convenient interface to its geometry and some additional data not solely covered by three.js geometry
*/
export interface Subdetector {

/** If available, the original geometry component, that was used for this subdetector, like ROOT geometry or GLTF */
sourceGeometry: any | null;

/** If available, a name of a node/part of source geometry that is responsible for this class */
sourceGeometryName: string;

/** ThreeJS geometry of the subdetector */
geometry: Object3D;

/** Name of the detector (may differ from geometry node name) */
name: string;

/** The name of the detectors group. Might be in */
groupName: string;
}
8 changes: 7 additions & 1 deletion firebird-ng/src/app/root-geometry.processor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,12 +75,17 @@ export class RootGeometryProcessor {
namePattern: "*/EcalBarrelScFi*",
editRules: [
{pattern: "*/fiber_grid*", action: EditActions.Remove},
{pattern: "*", action: EditActions.SetGeoBit, geoBit: GeoAttBits.kVisDaughters},
{pattern: "*/*layer*", action: EditActions.SetGeoBit, geoBit: GeoAttBits.kVisThis},
{pattern: "*/*layer*", action: EditActions.UnsetGeoBit, geoBit: GeoAttBits.kVisNone},
{pattern: "*/*layer*", action: EditActions.UnsetGeoBit, geoBit: GeoAttBits.kVisDaughters},
]
},
{
namePattern: "*/EcalBarrelImaging*",
editRules: [
{pattern: "*/stav*", action: EditActions.RemoveChildren},
{pattern: "*", action: EditActions.SetGeoBit, geoBit: GeoAttBits.kVisDaughters},
]
},
{
Expand Down Expand Up @@ -139,7 +144,8 @@ export class RootGeometryProcessor {
{pattern: "*/suppbar*", action: EditActions.Remove},
{pattern: "*/component*3", action: EditActions.RemoveSiblings},
]
}
},

]

public process(rootGeoManager:any):any {
Expand Down
Loading

0 comments on commit 7b0363d

Please sign in to comment.