diff --git a/firebird-ng/src/app/data-pipelines/three-geometry.processor.ts b/firebird-ng/src/app/data-pipelines/three-geometry.processor.ts index 0910936..3001966 100644 --- a/firebird-ng/src/app/data-pipelines/three-geometry.processor.ts +++ b/firebird-ng/src/app/data-pipelines/three-geometry.processor.ts @@ -109,204 +109,9 @@ export function matchRulesToDetectors(ruleSets: DetectorThreeRuleSet[], detector export class ThreeGeometryProcessor { - rules: DetectorThreeRuleSet[] = [ - { - names: ["FluxBarrel_env_25", "FluxEndcapP_26", "FluxEndcapN_28"], - rules: [ - { - color: 0x373766, - - } - ] - }, - { - name: "EcalEndcapN*", - rules: [ - { - patterns: ["**/crystal_vol_0"], - color: 0xffef8b, - material: new THREE.MeshStandardMaterial({ - color: 0xffef8b, - roughness: 0.7, - metalness: 0.869, - transparent: true, - opacity: 0.8, - side: THREE.DoubleSide - }) - }, - { - patterns: ["**/inner_support*", "**/ring*"], - material: new THREE.MeshStandardMaterial({ - color: 0x19a5f5, - roughness: 0.7, - metalness: 0.869, - transparent: true, - opacity: 0.8, - side: THREE.DoubleSide - }) - } - - ] - }, - { - name: "InnerTrackerSupport_assembly_13", - rules: [ - { - material: new THREE.MeshStandardMaterial({ - color: 0xEEEEEE, - roughness: 0.7, - metalness: 0.3, - transparent: true, - opacity: 0.8, - blending: THREE.NormalBlending, - // premultipliedAlpha: true, - depthWrite: false, // Ensures correct blending - polygonOffset: true, - polygonOffsetFactor: 1, - side: THREE.DoubleSide - }), - outline: true, - outlineColor: 0x666666, - merge: true, - newName: "InnerTrackerSupport" - } - ] - }, - { - name: "DIRC_14", - rules: [ - { - patterns: ["**/*box*", "**/*prism*"], - material: new THREE.MeshPhysicalMaterial({ - color: 0xe5ba5d, - metalness: .9, - roughness: .05, - envMapIntensity: 0.9, - clearcoat: 1, - transparent: true, - //transmission: .60, - opacity: .6, - reflectivity: 0.2, - //refr: 0.985, - ior: 0.9, - side: THREE.DoubleSide, - }), - newName: "DIRC_barAndPrisms" - }, - { - patterns: ["**/*rail*"], - newName: "DIRC_rails", - color: 0xAAAACC - }, - { - patterns: ["**/*mcp*"], - newName: "DIRC_mcps" - } - ] - - }, - { - name: "VertexBarrelSubAssembly_3", - rules: [ - { - merge: true, - outline: true - } - ] - }, - { - name: "*", - rules: [ - { - merge: true, - outline: true - } - ] - } - ] - - calorimetry = new CalorimetryGeometryPrettifier(); - - - - glassMaterial = new THREE.LineBasicMaterial( { - color: 0xf1f1f1, - linewidth: 1, - linecap: 'round', //ignored by WebGLRenderer - linejoin: 'round' //ignored by WebGLRenderer - } ); - - - - params = { - alpha: 0.5, - alphaHash: true, - taa: true, - sampleLevel: 2, - }; - - vertexShader = ` - varying vec2 vUv; - void main() { - vUv = uv; - gl_Position = projectionMatrix * modelViewMatrix * vec4(position,1.0); - } - `; - fragmentShader = ` - //#extension GL_OES_standard_derivatives : enable - - varying vec2 vUv; - uniform float thickness; - - float edgeFactor(vec2 p){ - vec2 grid = abs(fract(p - 0.5) - 0.5) / fwidth(p) / thickness; - return min(grid.x, grid.y); - } - - void main() { - - float a = edgeFactor(vUv); - - vec3 c = mix(vec3(1), vec3(0), a); - - gl_FragColor = vec4(c, 1.0); - } - `; - - shaderMaterial: THREE.ShaderMaterial; - - alphaMaterial = new THREE.MeshStandardMaterial( { - color: 0xffffff, - alphaHash: this.params.alphaHash, - opacity: this.params.alpha - } ); - - - - // new MeshPhysicalMaterial({ - // color: 0xffff00, // Yellow color - // metalness: 0, - // roughness: 0, - // transmission: 0.7, // High transparency - // opacity: 1, - // transparent: true, - // reflectivity: 0.5 - // }); constructor() { - this.shaderMaterial = new THREE.ShaderMaterial({ - uniforms: { - thickness: { - value: 1.5 - } - }, - vertexShader: this.vertexShader, - fragmentShader: this.fragmentShader - }); - } - public process(detectors: Subdetector[]) { - this.processRuleSets(this.rules, detectors); } public processRuleSets(ruleSets: DetectorThreeRuleSet[], detectors: Subdetector[]) { diff --git a/firebird-ng/src/app/services/event-display.service.ts b/firebird-ng/src/app/services/event-display.service.ts index 036206a..cbabd14 100644 --- a/firebird-ng/src/app/services/event-display.service.ts +++ b/firebird-ng/src/app/services/event-display.service.ts @@ -38,8 +38,6 @@ export class EventDisplayService { private beamAnimationTime: number = 1000; // Geometry - private threeGeometryProcessor = new ThreeGeometryProcessor(); - private defaultColor: Color = new Color(0x68698D); private animateEventAfterLoad: boolean = false; private trackInfos: any | null = null; // Replace 'any' with the actual type @@ -224,79 +222,9 @@ export class EventDisplayService { disposeHierarchy(sceneGeo, /* disposeSelf= */ false); } - sceneGeo.add(threeGeometry); + this.geomService.postProcessing(threeGeometry, this.three.clipPlanes); - // Now we want to set default materials - sceneGeo.traverse((child: any) => { - if (child.type !== 'Mesh' || !child?.material?.isMaterial) { - return; - } - - // Assuming `getObjectSize` is correctly typed and available - child.userData['size'] = 1; //this.importManager.getObjectSize(child); - - // Handle the material of the child - const color = getColorOrDefault(child.material, this.defaultColor); - const side = DoubleSide; - - let opacity = threeGeometry.userData['opacity'] ?? 1; - - child.material = new MeshLambertMaterial({ - color: color, - side: side, - transparent: true, - opacity: 0.7, - blending: NormalBlending, - depthTest: true, - depthWrite: true, - clippingPlanes: this.three.clipPlanes, - clipIntersection: true, - clipShadows: false, - }); - - // Material - let name: string = child.name; - - if (!child.material?.clippingPlanes !== undefined) { - child.material.clippingPlanes = this.three.clipPlanes; - } - - if (!child.material?.clipIntersection !== undefined) { - child.material.clipIntersection = true; - } - - if (!child.material?.clipShadows !== undefined) { - child.material.clipShadows = false; - } - }); - - // HERE WE DO POSTPROCESSING STEP - this.threeGeometryProcessor.process(this.geomService.subdetectors); - - // Now we want to change the materials - sceneGeo.traverse((child: any) => { - if (!child?.material?.isMaterial) { - return; - } - - if (child.material?.clippingPlanes !== undefined) { - child.material.clippingPlanes = this.three.clipPlanes; - } - - if (child.material?.clipIntersection !== undefined) { - child.material.clipIntersection = true; - } - - if (child.material?.clipShadows !== undefined) { - child.material.clipShadows = false; - } - }); - - // TODO do we need it? - //this.three.renderer.sortObjects = false; - // FIXME This needs to be fixed, it causes a crash - // produceRenderOrder(this.scene, this.camera.position, 'ray'); } /** diff --git a/firebird-ng/src/app/services/geometry.service.ts b/firebird-ng/src/app/services/geometry.service.ts index 69e9fe9..dfa8c08 100644 --- a/firebird-ng/src/app/services/geometry.service.ts +++ b/firebird-ng/src/app/services/geometry.service.ts @@ -8,8 +8,11 @@ import {build} from 'jsroot/geom'; import {RootGeometryProcessor} from "../data-pipelines/root-geometry.processor"; import {UserConfigService} from "./user-config.service"; import {Subdetector} from "../model/subdetector"; -import {Object3D} from "three"; +import {Color, DoubleSide, MeshLambertMaterial, NormalBlending, Object3D, Plane} from "three"; import {UrlService} from "./url.service"; +import {DetectorThreeRuleSet, ThreeGeometryProcessor} from "../data-pipelines/three-geometry.processor"; +import * as THREE from "three"; +import {disposeHierarchy, getColorOrDefault} from "../utils/three.utils"; export const GROUP_CALORIMETRY = "Calorimeters"; export const GROUP_TRACKING = "Tracking"; @@ -24,6 +27,122 @@ export const ALL_GROUPS = [ GROUP_SUPPORT, ] +export const defaultRules: DetectorThreeRuleSet[] = [ + { + names: ["FluxBarrel_env_25", "FluxEndcapP_26", "FluxEndcapN_28"], + rules: [ + { + color: 0x373766, + + } + ] + }, + { + name: "EcalEndcapN*", + rules: [ + { + patterns: ["**/crystal_vol_0"], + color: 0xffef8b, + material: new THREE.MeshStandardMaterial({ + color: 0xffef8b, + roughness: 0.7, + metalness: 0.869, + transparent: true, + opacity: 0.8, + side: THREE.DoubleSide + }) + }, + { + patterns: ["**/inner_support*", "**/ring*"], + material: new THREE.MeshStandardMaterial({ + color: 0x19a5f5, + roughness: 0.7, + metalness: 0.869, + transparent: true, + opacity: 0.8, + side: THREE.DoubleSide + }) + } + + ] + }, + { + name: "InnerTrackerSupport_assembly_13", + rules: [ + { + material: new THREE.MeshStandardMaterial({ + color: 0xEEEEEE, + roughness: 0.7, + metalness: 0.3, + transparent: true, + opacity: 0.8, + blending: THREE.NormalBlending, + // premultipliedAlpha: true, + depthWrite: false, // Ensures correct blending + polygonOffset: true, + polygonOffsetFactor: 1, + side: THREE.DoubleSide + }), + outline: true, + outlineColor: 0x666666, + merge: true, + newName: "InnerTrackerSupport" + } + ] + }, + { + name: "DIRC_14", + rules: [ + { + patterns: ["**/*box*", "**/*prism*"], + material: new THREE.MeshPhysicalMaterial({ + color: 0xe5ba5d, + metalness: .9, + roughness: .05, + envMapIntensity: 0.9, + clearcoat: 1, + transparent: true, + //transmission: .60, + opacity: .6, + reflectivity: 0.2, + //refr: 0.985, + ior: 0.9, + side: THREE.DoubleSide, + }), + newName: "DIRC_barAndPrisms" + }, + { + patterns: ["**/*rail*"], + newName: "DIRC_rails", + color: 0xAAAACC + }, + { + patterns: ["**/*mcp*"], + newName: "DIRC_mcps" + } + ] + + }, + { + name: "VertexBarrelSubAssembly_3", + rules: [ + { + merge: true, + outline: true + } + ] + }, + { + name: "*", + rules: [ + { + merge: true, + outline: true + } + ] + } +] + // constants.ts export const DEFAULT_GEOMETRY = 'builtin://epic-central-optimized'; @@ -45,6 +164,11 @@ export class GeometryService { public groupsByDetName: Map; + /** for geometry post-processing */ + private threeGeometryProcessor = new ThreeGeometryProcessor(); + + private defaultColor: Color = new Color(0x68698D); + constructor(private urlService: UrlService) { this.groupsByDetName = new Map ([ ["SolenoidBarrel_assembly_0", GROUP_MAGNETS], @@ -192,6 +316,63 @@ export class GeometryService { return {rootGeometry: this.rootGeometry, threeGeometry: this.geometry}; } + public postProcessing(geometry: Object3D, clippingPlanes: Plane[]) { + let threeGeometry = this.geometry; + if (!threeGeometry) return; + + + // Now we want to set default materials + threeGeometry.traverse((child: any) => { + if (child.type !== 'Mesh' || !child?.material?.isMaterial) { + return; + } + + // Assuming `getObjectSize` is correctly typed and available + child.userData['size'] = 1; //this.importManager.getObjectSize(child); + + // Handle the material of the child + const color = getColorOrDefault(child.material, this.defaultColor); + const side = DoubleSide; + + let opacity = threeGeometry.userData['opacity'] ?? 1; + + child.material = new MeshLambertMaterial({ + color: color, + side: side, + transparent: true, + opacity: 0.7, + blending: NormalBlending, + depthTest: true, + depthWrite: true, + clippingPlanes: clippingPlanes, + clipIntersection: true, + clipShadows: false, + }); + }); + + // HERE WE DO POSTPROCESSING STEP + this.threeGeometryProcessor.processRuleSets(defaultRules, this.subdetectors); + + // Now we want to change the materials + threeGeometry.traverse((child: any) => { + if (!child?.material?.isMaterial) { + return; + } + + if (child.material?.clippingPlanes !== undefined) { + child.material.clippingPlanes = clippingPlanes; + } + + if (child.material?.clipIntersection !== undefined) { + child.material.clipIntersection = true; + } + + if (child.material?.clipShadows !== undefined) { + child.material.clipShadows = false; + } + }); + } + private stripIdFromName(name: string) { return name.replace(/_\d+$/, ''); }