Back to home page

EIC code displayed by LXR

 
 

    


Warning, /firebird/firebird-ng/src/app/utils/three-geometry-editor.ts is written in an unsupported language. File is not indexed.

0001 import {Color, Material, Mesh, Object3D} from "three";
0002 import {createOutline, disposeOriginalMeshesAfterMerge, findObject3DNodes, pruneEmptyNodes} from "./three.utils";
0003 import {mergeBranchGeometries, mergeMeshList, MergeResult} from "./three-geometry-merge";
0004 import * as THREE from "three";
0005 import {ColorRepresentation} from "three/src/math/Color";
0006 
0007 export enum EditThreeNodeActions {
0008 
0009   Merge,   /** Merge children matching patterns (if patterns are provided) or all meshes of the node*/
0010 
0011 }
0012 
0013 export interface EditThreeNodeRule {
0014 
0015   patterns?: string[] | string;
0016   merge?: boolean;
0017   newName?: string;
0018   deleteOrigins?: boolean;
0019   cleanupNodes?: boolean;
0020   outline?: boolean;
0021   outlineThresholdAngle?: number;
0022   /** [degrees] */
0023   outlineColor?: ColorRepresentation;
0024   material?: Material;
0025   color?: ColorRepresentation;
0026 
0027 }
0028 
0029 function mergeWhatever(node: Object3D, rule: EditThreeNodeRule): MergeResult | undefined {
0030 
0031   let newName = !rule.newName ? node.name + "_merged" : rule.newName;
0032 
0033   if (!rule.patterns) {
0034     // If user provided patterns only children matching patterns (search goes over whole branch) will be merged,
0035     // But if no patterns given, we will merge whole node
0036     return mergeBranchGeometries(node, newName, rule.material);  // Children auto removed
0037   }
0038 
0039   // If we are here, we need to collect what to merge first
0040 
0041   let mergeSubjects = [];
0042   // merge whole node
0043   if (typeof rule.patterns === "string") {
0044     rule.patterns = [rule.patterns];
0045   }
0046 
0047   for (const pattern of rule.patterns) {
0048     mergeSubjects.push(...findObject3DNodes(node, pattern, "Mesh").nodes);
0049   }
0050 
0051   let result = mergeMeshList(mergeSubjects, node, newName, rule.material);
0052   const deleteOrigins = rule?.deleteOrigins ?? true;
0053   if (result && deleteOrigins) {
0054     disposeOriginalMeshesAfterMerge(result);
0055   }
0056   return result;
0057 }
0058 
0059 
0060 export function editThreeNodeContent(node: Object3D, rule: EditThreeNodeRule) {
0061   let {
0062     patterns,
0063     deleteOrigins = true,
0064     cleanupNodes = true,
0065     outline = true,
0066     outlineThresholdAngle = 40,
0067     outlineColor,
0068     material,
0069     color,
0070     merge = true,
0071     newName = ""
0072   } = rule;
0073 
0074   let targetMeshes: Mesh[] = [];
0075 
0076   if (merge) {
0077     // Existing merge logic
0078     let result = mergeWhatever(node, rule);
0079     if (!result) {
0080       console.warn("didn't find children to merge. Patterns:");
0081       console.log(patterns)
0082       return;
0083     }
0084     targetMeshes = [result.mergedMesh];
0085   } else {
0086     // New logic for when merge is false
0087     // Find all meshes that match the patterns, similar to mergeWhatever
0088     if (!patterns) {
0089       // If no patterns given, collect all meshes with geometry in the node
0090       node.traverse((child) => {
0091         if ((child as any)?.geometry) {
0092           targetMeshes.push(child as Mesh);
0093         }
0094       });
0095     } else {
0096       // If patterns are given, find all meshes that match
0097       if (typeof patterns === "string") {
0098         patterns = [patterns];
0099       }
0100 
0101       for (const pattern of patterns) {
0102         targetMeshes.push(...findObject3DNodes(node, pattern, "Mesh").nodes);
0103       }
0104     }
0105   }
0106 
0107   // Apply operations to each target mesh
0108   for (const targetMesh of targetMeshes) {
0109     if (color !== undefined && color !== null) {
0110       if (targetMesh.material) {
0111         (targetMesh.material as any).color = new Color(color);
0112       }
0113     }
0114 
0115     if (outline) {
0116       createOutline(targetMesh, {color: outlineColor, thresholdAngle: outlineThresholdAngle});
0117     }
0118   }
0119 
0120   if (cleanupNodes) {
0121     pruneEmptyNodes(node);
0122   }
0123 }