UNPKG

@shapediver/sdk.sdtf-v1

Version:
158 lines 8.16 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.SdtfWriteableComponentPostProcessor = void 0; const SdtfWriteableAsset_1 = require("./components/SdtfWriteableAsset"); const SdtfWriteableBuffer_1 = require("./components/SdtfWriteableBuffer"); const ISdtfWriteableComponentList_1 = require("./ISdtfWriteableComponentList"); const SdtfWriteableComponentFactory_1 = require("./SdtfWriteableComponentFactory"); class SdtfWriteableComponentPostProcessor { constructor(integrations) { this.integrations = integrations; this.factory = new SdtfWriteableComponentFactory_1.SdtfWriteableComponentFactory(); } optimize(asset) { const clonedAsset = SdtfWriteableAsset_1.SdtfWriteableAsset.clone(asset); let componentList = (0, ISdtfWriteableComponentList_1.writeableComponentListFromAsset)(clonedAsset); this.processDataComponents(componentList.attributes.flatMap((a) => Object.values(a.entries))); this.processDataComponents(componentList.items); this.postProcessDataComponents([ ...componentList.attributes.flatMap((a) => Object.values(a.entries)), ...componentList.items, ]); componentList = (0, ISdtfWriteableComponentList_1.writeableComponentListFromAsset)(clonedAsset); this.complementTypeHints(componentList); this.removeDuplicatedTypeHints(componentList); this.resolveBuffers(componentList); return componentList; } processDataComponents(components) { components.forEach((component) => { const integration = this.integrations.find((i) => { var _a, _b; return i.isTypeHintSupported((_b = (_a = component.typeHint) === null || _a === void 0 ? void 0 : _a.name) !== null && _b !== void 0 ? _b : ''); }); if (!integration) return; integration.getWriter(this.factory).writeComponent(component); }); } postProcessDataComponents(components) { this.integrations.forEach((integration) => { const supportedComponents = components.filter((component) => { var _a, _b; return integration.isTypeHintSupported((_b = (_a = component.typeHint) === null || _a === void 0 ? void 0 : _a.name) !== null && _b !== void 0 ? _b : ''); }); if (supportedComponents.length === 0) return; integration.getWriter(this.factory).postProcessComponents(supportedComponents); }); } complementTypeHints(componentList) { const complement = (base, list) => { var _a, _b; if (((_a = base.typeHint) === null || _a === void 0 ? void 0 : _a.name) !== undefined) return; if (list.length === 0) return; let typeHintName = (_b = list[0].typeHint) === null || _b === void 0 ? void 0 : _b.name; if (typeHintName === undefined) return; if (list.every((i) => { var _a; return ((_a = i.typeHint) === null || _a === void 0 ? void 0 : _a.name) === typeHintName; })) { base.typeHint = this.factory.createTypeHint(typeHintName); componentList.typeHints.push(base.typeHint); } }; componentList.nodes.forEach((node) => complement(node, node.items)); componentList.chunks.forEach((chunk) => complement(chunk, chunk.nodes)); } removeDuplicatedTypeHints(componentList) { const uniqueTypeHints = []; componentList.typeHints.forEach((typeHint) => { if (!uniqueTypeHints.find(this.areTypeHintsSimilar.bind(this, typeHint))) uniqueTypeHints.push(typeHint); }); const replaceTypeHints = (component) => { if (!component.typeHint || uniqueTypeHints.find((typeHint) => typeHint.componentId === component.typeHint.componentId)) return; component.typeHint = uniqueTypeHints.find((typeHint) => this.areTypeHintsSimilar(typeHint, component.typeHint)); }; componentList.attributes.forEach((a) => Object.values(a.entries).forEach((e) => replaceTypeHints(e))); componentList.chunks.forEach((c) => replaceTypeHints(c)); componentList.items.forEach((i) => replaceTypeHints(i)); componentList.nodes.forEach((n) => replaceTypeHints(n)); componentList.typeHints = Object.values(uniqueTypeHints); } areTypeHintsSimilar(t1, t2) { var _a, _b; const nAdditionalPropertiesT1 = Object.entries((_a = t1.additionalProperties) !== null && _a !== void 0 ? _a : {}), nAdditionalPropertiesT2 = Object.entries((_b = t2.additionalProperties) !== null && _b !== void 0 ? _b : {}); if (t1.name !== t2.name || nAdditionalPropertiesT1.length !== nAdditionalPropertiesT2.length) return false; for (let i = 0; i < nAdditionalPropertiesT1.length; i++) { const [key, value] = nAdditionalPropertiesT1[i]; if (t2.additionalProperties[key] !== value) return false; } return true; } resolveBuffers(componentList) { const bufferViewsPerUri = {}; componentList.bufferViews.forEach((bufferView) => { var _a; if (!bufferView.buffer) return; const uri = (_a = bufferView.buffer.uri) !== null && _a !== void 0 ? _a : ''; if (!bufferViewsPerUri[uri]) bufferViewsPerUri[uri] = []; bufferViewsPerUri[uri].push(bufferView); }); const mergedBuffers = []; Object.entries(bufferViewsPerUri).forEach(([uri, bufferViews]) => { const [mergedBuffer, offsets] = this.mergeBuffers(uri, bufferViews.map((bv) => bv.buffer)); bufferViews.forEach((bufferView, i) => { var _a; bufferView.byteOffset = offsets[i]; bufferView.byteLength = (_a = bufferView.buffer.data.byteLength) !== null && _a !== void 0 ? _a : 0; bufferView.buffer = mergedBuffer; }); mergedBuffers.push(mergedBuffer); }); componentList.buffers = mergedBuffers; } mergeBuffers(uri, buffers) { const merged = new SdtfWriteableBuffer_1.SdtfWriteableBuffer(); merged.uri = uri; merged.additionalProperties = {}; Object.assign(merged.additionalProperties, ...buffers.map((b) => b.additionalProperties)); const [mergedData, offsetsPerBuffer] = this.mergeBufferData(buffers); merged.byteLength = mergedData.byteLength; merged.data = mergedData; return [merged, offsetsPerBuffer]; } mergeBufferData(buffers) { var _a, _b; const roundToNextMultipleOfFour = (value) => { const diff = value % 4; return diff === 0 ? value : value + 4 - diff; }; let offsets = [0], lastBufferLength = (_b = (_a = buffers[0].data) === null || _a === void 0 ? void 0 : _a.byteLength) !== null && _b !== void 0 ? _b : 0; if (buffers.length > 0) { lastBufferLength = roundToNextMultipleOfFour(lastBufferLength); for (let i = 1; i < buffers.length; i++) { let bufferLength = 0; const data = buffers[i].data; if (data) { if (i === buffers.length - 1) bufferLength = data.byteLength; else bufferLength = roundToNextMultipleOfFour(data.byteLength); } offsets.push(offsets[i - 1] + lastBufferLength); lastBufferLength = bufferLength; } } const merged = new Uint8Array(offsets[offsets.length - 1] + lastBufferLength); buffers.forEach((buffer, i) => { const data = buffer.data ? new Uint8Array(buffer.data) : new Uint8Array(0); merged.set(data, offsets[i]); }); return [merged.buffer, offsets]; } } exports.SdtfWriteableComponentPostProcessor = SdtfWriteableComponentPostProcessor; //# sourceMappingURL=SdtfWriteableComponentPostProcessor.js.map