Warning, /firebird/firebird-ng/src/app/data-pipelines/three-geometry.processor.ts is written in an unsupported language. File is not indexed.
0001 import * as THREE from "three";
0002 import {wildCardCheck} from "../utils/wildcard";
0003 import {CalorimetryGeometryPrettifier} from "./calorimetry.prettifier";
0004 import {editThreeNodeContent, EditThreeNodeRule} from "../utils/three-geometry-editor";
0005 import {Subdetector} from "../model/subdetector";
0006
0007
0008 export interface DetectorThreeRuleSet {
0009 names?: string[];
0010 name?: string;
0011 rules: EditThreeNodeRule[];
0012 }
0013
0014 /**
0015 * Matches which set of rules should be applied to which detectors
0016 *
0017 * - Detectors are matched based on their `sourceGeometryName` against the names specified in the rulesets.
0018 * - Rule lists are matched to detectors in the order they appear in the rulesets
0019 * - Once a rule is applied to a detector, that detector is excluded from further rule matching, ensuring each detector is processed only once.
0020 * - If both `names` and `name` are provided in a ruleset, the function treats it as a user error in JSON rule editing but processes both without raising an exception.
0021 * - If a ruleset contains a wildcard name (`"*"`), it will apply its rules to any detectors not already matched by previous rulesets. So it should be placed in
0022 *
0023 * @param {Subdetector[]} detectors - The list of detectors to which the rules will be applied.
0024 * @param {DetectorThreeRuleSet[]} ruleSets - The set of rules to be applied, processed sequentially.
0025 * @return {Map<Subdetector, EditThreeNodeRule[]>} - A map associating each detector with an array of the rules applied to it.
0026 */
0027 export function matchRulesToDetectors(ruleSets: DetectorThreeRuleSet[], detectors: Subdetector[]): Map<Subdetector, EditThreeNodeRule[]> {
0028 const unassignedDetectors = new Set(detectors);
0029 const detectorRulesMap = new Map<Subdetector, EditThreeNodeRule[]>();
0030
0031 for(let ruleSet of ruleSets) {
0032 const targets = new Set<Subdetector>();
0033 let names = new Set<string>(ruleSet.names || []);
0034
0035 // Handle possible user error where both 'name' and 'names' are provided.
0036 if (ruleSet.name) {
0037 names.add(ruleSet.name);
0038 }
0039
0040 for(let name of names) {
0041 for(let det of unassignedDetectors) {
0042 if (wildCardCheck(det.sourceGeometryName, name)) {
0043 targets.add(det);
0044 detectorRulesMap.set(det, ruleSet.rules || []);
0045 unassignedDetectors.delete(det); // Move deletion here to optimize
0046 }
0047 }
0048 }
0049 }
0050
0051 return detectorRulesMap;
0052 }
0053
0054 export class ThreeGeometryProcessor {
0055
0056 rules: DetectorThreeRuleSet[] = [
0057 {
0058 names: ["FluxBarrel_env_25", "FluxEndcapP_26", "FluxEndcapN_28"],
0059 rules: [
0060 {
0061 color: 0x373766,
0062
0063 }
0064 ]
0065 },
0066 {
0067 name: "EcalEndcapN*",
0068 rules: [
0069 {
0070 patterns: ["**/crystal_vol_0"],
0071 color: 0xffef8b,
0072 material: new THREE.MeshStandardMaterial({
0073 color: 0xffef8b,
0074 roughness: 0.7,
0075 metalness: 0.869,
0076 transparent: true,
0077 opacity: 0.8,
0078 side: THREE.DoubleSide
0079 })
0080 },
0081 {
0082 patterns: ["**/inner_support*", "**/ring*"],
0083 material: new THREE.MeshStandardMaterial({
0084 color: 0x19a5f5,
0085 roughness: 0.7,
0086 metalness: 0.869,
0087 transparent: true,
0088 opacity: 0.8,
0089 side: THREE.DoubleSide
0090 })
0091 }
0092
0093 ]
0094 },
0095 {
0096 name: "InnerTrackerSupport_assembly_13",
0097 rules: [
0098 {
0099 material: new THREE.MeshStandardMaterial({
0100 color: 0xEEEEEE,
0101 roughness: 0.7,
0102 metalness: 0.3,
0103 transparent: true,
0104 opacity: 0.8,
0105 blending: THREE.NormalBlending,
0106 // premultipliedAlpha: true,
0107 depthWrite: false, // Ensures correct blending
0108 polygonOffset: true,
0109 polygonOffsetFactor: 1,
0110 side: THREE.DoubleSide
0111 }),
0112 outline: true,
0113 outlineColor: 0x666666,
0114 merge: true,
0115 newName: "InnerTrackerSupport"
0116 }
0117 ]
0118 },
0119 {
0120 name: "DIRC_14",
0121 rules: [
0122 {
0123 patterns: ["**/*box*", "**/*prism*"],
0124 material: new THREE.MeshPhysicalMaterial({
0125 color: 0xe5ba5d,
0126 metalness: .9,
0127 roughness: .05,
0128 envMapIntensity: 0.9,
0129 clearcoat: 1,
0130 transparent: true,
0131 //transmission: .60,
0132 opacity: .6,
0133 reflectivity: 0.2,
0134 //refr: 0.985,
0135 ior: 0.9,
0136 side: THREE.DoubleSide,
0137 }),
0138 newName: "DIRC_barAndPrisms"
0139 },
0140 {
0141 patterns: ["**/*rail*"],
0142 newName: "DIRC_rails",
0143 color: 0xAAAACC
0144 },
0145 {
0146 patterns: ["**/*mcp*"],
0147 newName: "DIRC_mcps"
0148 }
0149 ]
0150
0151 },
0152 {
0153 name: "VertexBarrelSubAssembly_3",
0154 rules: [
0155 {
0156 merge: true,
0157 outline: true
0158 }
0159 ]
0160 },
0161 {
0162 name: "*",
0163 rules: [
0164 {
0165 merge: true,
0166 outline: true
0167 }
0168 ]
0169 }
0170 ]
0171
0172 calorimetry = new CalorimetryGeometryPrettifier();
0173
0174
0175
0176 glassMaterial = new THREE.LineBasicMaterial( {
0177 color: 0xf1f1f1,
0178 linewidth: 1,
0179 linecap: 'round', //ignored by WebGLRenderer
0180 linejoin: 'round' //ignored by WebGLRenderer
0181 } );
0182
0183
0184
0185 params = {
0186 alpha: 0.5,
0187 alphaHash: true,
0188 taa: true,
0189 sampleLevel: 2,
0190 };
0191
0192 vertexShader = `
0193 varying vec2 vUv;
0194 void main() {
0195 vUv = uv;
0196 gl_Position = projectionMatrix * modelViewMatrix * vec4(position,1.0);
0197 }
0198 `;
0199 fragmentShader = `
0200 //#extension GL_OES_standard_derivatives : enable
0201
0202 varying vec2 vUv;
0203 uniform float thickness;
0204
0205 float edgeFactor(vec2 p){
0206 vec2 grid = abs(fract(p - 0.5) - 0.5) / fwidth(p) / thickness;
0207 return min(grid.x, grid.y);
0208 }
0209
0210 void main() {
0211
0212 float a = edgeFactor(vUv);
0213
0214 vec3 c = mix(vec3(1), vec3(0), a);
0215
0216 gl_FragColor = vec4(c, 1.0);
0217 }
0218 `;
0219
0220 shaderMaterial: THREE.ShaderMaterial;
0221
0222 alphaMaterial = new THREE.MeshStandardMaterial( {
0223 color: 0xffffff,
0224 alphaHash: this.params.alphaHash,
0225 opacity: this.params.alpha
0226 } );
0227
0228
0229
0230 // new MeshPhysicalMaterial({
0231 // color: 0xffff00, // Yellow color
0232 // metalness: 0,
0233 // roughness: 0,
0234 // transmission: 0.7, // High transparency
0235 // opacity: 1,
0236 // transparent: true,
0237 // reflectivity: 0.5
0238 // });
0239
0240 constructor() {
0241 this.shaderMaterial = new THREE.ShaderMaterial({
0242 uniforms: {
0243 thickness: {
0244 value: 1.5
0245 }
0246 },
0247 vertexShader: this.vertexShader,
0248 fragmentShader: this.fragmentShader
0249 });
0250 }
0251
0252 public process(detectors: Subdetector[]) {
0253
0254 this.processRuleSets(this.rules, detectors);
0255
0256 //
0257 // // Add top nodes to menu
0258 // let topDetectorNodes = detectors.map(det=>det.geometry as THREE.Mesh);
0259 //
0260 // // for(let i= topLevelObj3dNodes.length - 1; i >= 0; i--) {
0261 // // console.log(`${i} : ${topLevelObj3dNodes[i].name}`);
0262 // // }
0263 //
0264 //
0265 // console.log("DISPOSING");
0266 // for(let i= topDetectorNodes.length - 1; i >= 0; i--){
0267 // let detNode = topDetectorNodes[i];
0268 // console.log(`${i} : ${topDetectorNodes[i].name}`);
0269 // detNode.name = detNode.userData["name"] = detNode.name;
0270 // // Add geometry
0271 // // uiManager.addGeometry(obj3dNode, obj3dNode.name);
0272 //
0273 // if(detNode.name == "EcalEndcapN_21") {
0274 // this.calorimetry.doEndcapEcalN(detNode);
0275 // } else if(detNode.name == "DRICH_16") {
0276 // this.calorimetry.doDRICH(detNode);
0277 // } else if(detNode.name.startsWith("DIRC")) {
0278 // this.calorimetry.doDIRC(detNode);
0279 // } else{
0280 //
0281 // // try {
0282 // // detNode.removeFromParent();
0283 // // }
0284 // // catch (e) {
0285 // // console.error(e);
0286 // // }
0287 // //
0288 // // try {
0289 // // // console.log("disposeHierarchy: ", detNode.name, detNode);
0290 // // disposeHierarchy(detNode);
0291 // // } catch (e) {
0292 // // console.error(e);
0293 // // }
0294 //
0295 // let result = mergeBranchGeometries(detNode, detNode.name + "_merged");
0296 // createOutline(result.mergedMesh);
0297 // (result.mergedMesh.material as any).onBeforeCompile = (shader: any) => {
0298 //
0299 // shader.fragmentShader = shader.fragmentShader.replace(
0300 //
0301 // '#include <output_fragment>',
0302 //
0303 // `
0304 // vec3 backfaceColor = vec3( 0.4, 0.4, 0.4 );
0305 // gl_FragColor = ( gl_FrontFacing ) ? vec4( outgoingLight, diffuseColor.a ) : vec4( backfaceColor, opacity );
0306 // `
0307 // )
0308 // };
0309 // pruneEmptyNodes(detNode);
0310 // }
0311 // }
0312 }
0313
0314 public processRuleSets(ruleSets: DetectorThreeRuleSet[], detectors: Subdetector[]) {
0315 let detRulesMap = matchRulesToDetectors(ruleSets, detectors);
0316 for (let [detector, ruleSet] of detRulesMap) {
0317 for(let rule of ruleSet) {
0318 editThreeNodeContent(detector.geometry, rule);
0319 }
0320 }
0321 }
0322 }