@shapediver/sdk.sdtf-v1
Version:
Official sdTF SDK for TypeScript
158 lines • 8.16 kB
JavaScript
;
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, offsets];
}
}
exports.SdtfWriteableComponentPostProcessor = SdtfWriteableComponentPostProcessor;
//# sourceMappingURL=SdtfWriteableComponentPostProcessor.js.map