UNPKG

@polygonjs/polygonjs

Version:

node-based WebGL 3D engine https://polygonjs.com

121 lines (120 loc) 4.11 kB
"use strict"; import { BaseSopOperation } from "./_Base"; import { Group } from "three"; import { pushOnArrayAtEntry, addToSetAtEntry } from "../../../core/MapUtils"; import { InputCloneMode } from "../../../engine/poly/InputCloneMode"; import { isBooleanTrue } from "../../../core/BooleanValue"; import { coreObjectClassFactory } from "../../../core/geometry/CoreObjectFactory"; import { setToArray } from "../../../core/SetUtils"; const _MergeSopOperation = class extends BaseSopOperation { static type() { return "merge"; } // TODO: improvement: // for compact, I should really keep track of geometry ids, // to make sure I am not including a geometry twice, if there is a hierarchy cook(inputCoreGroups, params) { var _a; let allObjects = []; for (const inputCoreGroup of inputCoreGroups) { if (inputCoreGroup) { const objects = inputCoreGroup.allObjects(); if (isBooleanTrue(params.compact)) { for (const object of objects) { object.traverse((child) => { allObjects.push(child); }); } } else { for (const object of objects) { allObjects.push(object); } } } } if (isBooleanTrue(params.compact)) { allObjects = _MergeSopOperation.makeCompact(allObjects, params, (_a = this.states) == null ? void 0 : _a.error); } return this.createCoreGroupFromObjects(allObjects); } static makeCompact(allObjects, options, errorState) { const { preserveMaterials } = options; const materialsByObjectType = /* @__PURE__ */ new Map(); const objectsByType = /* @__PURE__ */ new Map(); const orderedObjectTypes = []; for (let object of allObjects) { object.traverse((object3d) => { if (object3d instanceof Group) { return; } const objectType = object.type; if (objectType) { if (!orderedObjectTypes.includes(objectType)) { orderedObjectTypes.push(objectType); } if (objectType) { const foundMat = materialsByObjectType.get(objectType); if (!foundMat) { materialsByObjectType.set(objectType, object.material); } pushOnArrayAtEntry(objectsByType, objectType, object); } } }); } const mergedObjects = []; orderedObjectTypes.forEach((objectType) => { const material = materialsByObjectType.get(objectType); const objects = objectsByType.get(objectType); if (objects && objects.length != 0) { if (isBooleanTrue(preserveMaterials)) { _makeCompactWithPreservedMaterials({ objects, material, objectType, mergedObjects, onError: (message) => { errorState == null ? void 0 : errorState.set(message); } }); } else { const coreObjectClass = coreObjectClassFactory(objects[0]); coreObjectClass.mergeCompact({ objects, material, objectType, mergedObjects, onError: (message) => { errorState == null ? void 0 : errorState.set(message); } }); } } }); return mergedObjects; } }; export let MergeSopOperation = _MergeSopOperation; MergeSopOperation.DEFAULT_PARAMS = { compact: false, preserveMaterials: true }; MergeSopOperation.INPUT_CLONED_STATE = InputCloneMode.FROM_NODE; const objectsByMaterial = /* @__PURE__ */ new Map(); function _makeCompactWithPreservedMaterials(options) { const { objects, objectType, mergedObjects, onError } = options; const coreObjectClass = coreObjectClassFactory(objects[0]); objectsByMaterial.clear(); for (let object of objects) { addToSetAtEntry(objectsByMaterial, object.material, object); } objectsByMaterial.forEach((objectSet, material) => { coreObjectClass.mergeCompact({ objects: setToArray(objectSet, []), material, objectType, mergedObjects, onError }); }); }