UNPKG

awatif-ui

Version:

Awatif User Interface

115 lines (96 loc) 3.38 kB
import * as THREE from "three"; import van, { State } from "vanjs-core"; import { AnalyzeOutputs, Node } from "awatif-fem"; import { Mesh } from "awatif-fem"; import { Settings } from "../settings/getSettings"; import { getTransformationMatrixBeam } from "./utils/getTransformationMatrixBeam"; import { ConstantResult } from "./resultObjects/ConstantResult"; import { LinearResult } from "./resultObjects/LinearResult"; import { IResultObject } from "./resultObjects/IResultObject"; enum ResultType { normals = "normals", shearsY = "shearsY", shearsZ = "shearsZ", torsions = "torsions", bendingsY = "bendingsY", bendingsZ = "bendingsZ", } export function frameResults( mesh: Mesh, settings: Settings, derivedNodes: State<Node[]>, deridedDisplayScale: State<number> ): THREE.Group { // init const group = new THREE.Group(); const size = 0.05 * settings.gridSize.rawVal; const resultObjects = { [ResultType.normals]: ConstantResult, [ResultType.shearsY]: ConstantResult, [ResultType.shearsZ]: ConstantResult, [ResultType.torsions]: ConstantResult, [ResultType.bendingsY]: LinearResult, [ResultType.bendingsZ]: LinearResult, }; // on settings.elementResults & deformedShape, model clear and create visuals van.derive(() => { settings.deformedShape.val; // triggers update if (settings.frameResults.val == "none") return; group.children.forEach((c) => (c as IResultObject).dispose()); group.clear(); const resultType = ResultType[settings.frameResults.rawVal as keyof typeof ResultType]; mesh.analyzeOutputs?.val[resultType]?.forEach((result, index) => { const element = mesh.elements?.rawVal[index] ?? [0, 1]; // TODO: improve this const node1 = derivedNodes.rawVal[element[0]]; const node2 = derivedNodes.rawVal[element[1]]; const length = new THREE.Vector3(...node2).distanceTo( new THREE.Vector3(...node1) ); const maxResult = findMax(mesh.analyzeOutputs?.rawVal[resultType]); const normalizedResult = result?.map( (n) => n / (maxResult === 0 ? 1 : maxResult) ); const rotation = getTransformationMatrixBeam(node1, node2); const resultObject = new resultObjects[resultType]( node1, node2, length, rotation, result ?? [0, 0], normalizedResult ?? [0, 0], [ ResultType.normals, ResultType.shearsZ, ResultType.torsions, ResultType.bendingsY, ].includes(resultType) ? true : false ); resultObject.updateScale(size * deridedDisplayScale.rawVal); group.add(resultObject); }); }); // on deridedDisplayScale update scale van.derive(() => { deridedDisplayScale.val; // trigger updates if (settings.frameResults.rawVal == "none") return; group.children.forEach((c) => (c as IResultObject).updateScale(size * deridedDisplayScale.rawVal) ); }); // on settings.elementResults update viability van.derive(() => { group.visible = settings.frameResults.val != "none"; }); return group; } function findMax(nodeOutputs: AnalyzeOutputs[ResultType]): number { let max: number = 0; nodeOutputs?.forEach((node) => { const maxInNode = Math.max(...(node ?? [0, 0])); if (maxInNode > max) max = maxInNode; }); return max; }