awv3
Version:
⚡ AWV3 embedded CAD
887 lines (753 loc) • 38.9 kB
JavaScript
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = undefined;
var _getIterator2 = require('babel-runtime/core-js/get-iterator');
var _getIterator3 = _interopRequireDefault(_getIterator2);
var _values = require('babel-runtime/core-js/object/values');
var _values2 = _interopRequireDefault(_values);
var _regenerator = require('babel-runtime/regenerator');
var _regenerator2 = _interopRequireDefault(_regenerator);
var _asyncToGenerator2 = require('babel-runtime/helpers/asyncToGenerator');
var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2);
var _promise = require('babel-runtime/core-js/promise');
var _promise2 = _interopRequireDefault(_promise);
var _toConsumableArray2 = require('babel-runtime/helpers/toConsumableArray');
var _toConsumableArray3 = _interopRequireDefault(_toConsumableArray2);
var _extends2 = require('babel-runtime/helpers/extends');
var _extends3 = _interopRequireDefault(_extends2);
var _getPrototypeOf = require('babel-runtime/core-js/object/get-prototype-of');
var _getPrototypeOf2 = _interopRequireDefault(_getPrototypeOf);
var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
var _createClass2 = require('babel-runtime/helpers/createClass');
var _createClass3 = _interopRequireDefault(_createClass2);
var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn');
var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2);
var _inherits2 = require('babel-runtime/helpers/inherits');
var _inherits3 = _interopRequireDefault(_inherits2);
var _three = require('three');
var THREE = _interopRequireWildcard(_three);
var _memoize = require('lodash/memoize');
var _memoize2 = _interopRequireDefault(_memoize);
var _cloneDeep = require('lodash/cloneDeep');
var _cloneDeep2 = _interopRequireDefault(_cloneDeep);
var _throttle = require('lodash/throttle');
var _throttle2 = _interopRequireDefault(_throttle);
var _lifecycle = require('./lifecycle.js');
var _lifecycle2 = _interopRequireDefault(_lifecycle);
var _helpers = require('./helpers');
var _connections = require('./store/connections');
var _globals = require('./store/globals');
var _plugins = require('./store/plugins');
var _error = require('../core/error');
var _base = require('../communication/base');
var _base2 = _interopRequireDefault(_base);
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* @class Connection manages a local or remote connection to a running ClassCAD instances.
ClassCAD will then drive the tree-state and cause visual actions, models, meshes, movement, etc.
In theory a ClassCAD instance is not needed, results could be fed statically using parse or stream.
*/
var Connection = function (_Lifecycle) {
(0, _inherits3.default)(Connection, _Lifecycle);
function Connection() {
var session = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : (0, _error.halt)('connection must be initialized with a session');
var props = arguments[1];
(0, _classCallCheck3.default)(this, Connection);
var _this = (0, _possibleConstructorReturn3.default)(this, (Connection.__proto__ || (0, _getPrototypeOf2.default)(Connection)).call(this, session, _connections.actions, function (state) {
return state.connections[_this.id];
}, (0, _extends3.default)({
name: 'Part'
}, props, {
connected: false,
activeFeature: undefined,
defaultFeatureVisibility: false,
undo: { count: 0, current: 0 },
messages: [],
plugins: [],
tree: { '1': { id: 1, name: '', class: '', parent: null }, root: 1 },
managed: false
})));
_this.updateView = (0, _throttle2.default)(function () {
var _this$pool$view$contr;
var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : _this.session.options.updateView,
_ref$focus = _ref.focus,
focus = _ref$focus === undefined ? true : _ref$focus,
_ref$zoom = _ref.zoom,
zoom = _ref$zoom === undefined ? true : _ref$zoom,
_ref$rotate = _ref.rotate,
rotate = _ref$rotate === undefined ? false : _ref$rotate,
_ref$layers = _ref.layers,
layers = _ref$layers === undefined ? false : _ref$layers;
_this.pool.view.updateBounds();
focus && _this.pool.view.controls.focus();
zoom && _this.pool.view.controls.zoom();
rotate && (_this$pool$view$contr = _this.pool.view.controls).rotate.apply(_this$pool$view$contr, (0, _toConsumableArray3.default)(rotate));
_this.pool.update();
layers && _this.session.showLayer(_this.session.layerNames);
}, _this.session.options.throttle);
_this._get = (0, _memoize2.default)(function (key) {
var state = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _this.getState().tree;
if (_this.store) {
var obj = state[key];
if (obj) {
obj = (0, _cloneDeep2.default)(state[key]);
if (obj.children) obj.children = obj.children.map(function (item) {
return _this._get(item, state);
});
if (obj.members) {
for (var _key in obj.members) {
var member = obj.members[_key];
if (_key !== 'mateSystem' && member.type === 'id') {
obj.members[_key] = _this._get(member.value, state);
} else if (member.type === 'array') {
_this._resolveArray(member.members, state);
}
}
}
}
return obj;
}
});
_this.pool = new session.options.pool((0, _extends3.default)({
session: session,
name: 'connection.pool.' + _this.name
}, session.options.materials));
_this.primitives = {};
_this.waiting = {};
_this.featurePlugins = {};
_this.sequence = _promise2.default.resolve();
// Observe tree changes to clear cache
_this.observe(function (state) {
return state.tree;
}, function () {
return _this._get.cache.clear();
});
// Observe root
_this.observe(function (state) {
return state.tree.root;
}, function (root) {
return _this._observeLink(root);
});
// Observe active feature
_this.observe(function (state) {
return state.activeFeature;
}, function (feature, oldFeature) {
if (oldFeature) {
var data = _this.featurePlugins[oldFeature];
_this.store.dispatch(_plugins.actions.update(data.plugin.id, { enabled: false, collapsed: true }));
if (!data.pluginPrototype.persistent) {
_this._destroyFeatures(oldFeature);
}
}
if (feature) {
var _data = _this.featurePlugins[feature];
if (_data.pluginPrototype.persistent) {
_this.store.dispatch(_plugins.actions.update(_data.plugin.id, { enabled: true, collapsed: false }));
_this.activeFeaturePlugin = _data.plugin;
} else {
_this.activeFeaturePlugin = _this._instanciateFeature(feature);
_this.store.dispatch(_plugins.actions.update(_this.activeFeaturePlugin.id, { enabled: true, collapsed: false }));
}
}
});
// Connect to server
if (_this.session.options.url && _this.session.options.protocol) {
_this.connect(_this.session.options.url);
}
return _this;
}
(0, _createClass3.default)(Connection, [{
key: 'defer',
value: function () {
var _ref2 = (0, _asyncToGenerator3.default)(_regenerator2.default.mark(function _callee3(func) {
var _this2 = this;
return _regenerator2.default.wrap(function _callee3$(_context3) {
while (1) {
switch (_context3.prev = _context3.next) {
case 0:
return _context3.abrupt('return', new _promise2.default(function () {
var _ref3 = (0, _asyncToGenerator3.default)(_regenerator2.default.mark(function _callee2(resolve) {
return _regenerator2.default.wrap(function _callee2$(_context2) {
while (1) {
switch (_context2.prev = _context2.next) {
case 0:
_context2.next = 2;
return _this2.sequence;
case 2:
requestIdleCallback((0, _asyncToGenerator3.default)(_regenerator2.default.mark(function _callee() {
return _regenerator2.default.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
_context.t0 = resolve;
_context.next = 3;
return func();
case 3:
_context.t1 = _context.sent;
return _context.abrupt('return', (0, _context.t0)(_context.t1));
case 5:
case 'end':
return _context.stop();
}
}
}, _callee, _this2);
})));
case 3:
case 'end':
return _context2.stop();
}
}
}, _callee2, _this2);
}));
return function (_x5) {
return _ref3.apply(this, arguments);
};
}()));
case 1:
case 'end':
return _context3.stop();
}
}
}, _callee3, this);
}));
function defer(_x4) {
return _ref2.apply(this, arguments);
}
return defer;
}()
}, {
key: 'undo',
value: function undo() {
var factory = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.session.options.materials.factory;
return this.store.dispatch(this.actions.request(this.id, undefined, factory, 'undo'));
}
}, {
key: 'redo',
value: function redo() {
var factory = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.session.options.materials.factory;
return this.store.dispatch(this.actions.request(this.id, undefined, factory, 'redo'));
}
}, {
key: 'request',
value: function request(command) {
var factory = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.session.options.materials.factory;
return this.store.dispatch(this.actions.request(this.id, command, factory));
}
}, {
key: 'stream',
value: function stream(url) {
var factory = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.session.options.materials.factory;
return this.store.dispatch(this.actions.stream(this.id, url, factory));
}
}, {
key: 'parse',
value: function parse(blob) {
var factory = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.session.options.materials.factory;
return this.store.dispatch(this.actions.parse(this.id, blob, factory));
}
}, {
key: 'connect',
value: function connect(url) {
return this.store.dispatch(this.actions.connect(this.id, url, this.session.options.protocol));
}
}, {
key: 'setTree',
value: function setTree(payload) {
this.store.dispatch(_connections.actions.destroyTree(this.id));
this.store.dispatch(_connections.actions.setTree(this.id, payload));
}
}, {
key: 'patchTree',
value: function patchTree(payload) {
return this.store.dispatch(this.actions.patchTree(this.id, payload));
}
}, {
key: 'resolveTree',
value: function resolveTree(args) {
var _this3 = this;
if (!args) return;
args = Array.isArray(args) ? args : [args];
var result = args.map(function (key) {
return _this3._get(key, _this3.getState().tree);
});
return result;
}
}, {
key: 'removePrimitives',
value: function removePrimitives() {
(0, _values2.default)(this.primitives).forEach(function (item) {
return item.destroy();
});
this.primitives = {};
this.updateView();
}
}, {
key: '_observeLink',
value: function _observeLink(id, parent, instance) {
var _this4 = this;
var tree = this.getState().tree;
var object = tree[id];
switch (object.class) {
case 'CC_Assembly':
//console.log("observing", object.name)
return this._observeAssembly(id, parent, instance);
case 'CC_Part':
case 'CC_SheetPart':
var container = this._observePart(id, parent, instance);
this.defer(function () {
return _this4._observeFeatures(id, container);
});
return container;
}
}
}, {
key: '_observeAssembly',
value: function _observeAssembly(root) {
var _this5 = this;
var parent = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.pool;
var instance = arguments[2];
var instances = {};
var container = new this.session.options.objectPrototype({ session: this.session });
container.name = 'Assembly';
container.userData = { id: instance };
parent.add(container);
this.observe(
// selector
function (state) {
return (state.tree[root] || {}).instances;
},
// onChange
function () {
var _ref5 = (0, _asyncToGenerator3.default)(_regenerator2.default.mark(function _callee4() {
for (var _len = arguments.length, args = Array(_len), _key2 = 0; _key2 < _len; _key2++) {
args[_key2] = arguments[_key2];
}
var tree;
return _regenerator2.default.wrap(function _callee4$(_context4) {
while (1) {
switch (_context4.prev = _context4.next) {
case 0:
tree = _this5.tree;
_context4.next = 3;
return _helpers.arrayDiff.apply(undefined, args.concat([function (newItems) {
return newItems.forEach(function (item) {
var instance = tree[item];
var link = undefined;
var object = undefined;
// Observe changes to it
_this5.observe(function (state) {
return state.tree[item];
}, function (instance) {
// Links should be reactive as well
if (instance.link !== link) {
if (object) {
object.destroy();
delete instances[instance.id];
}
object = instances[item] = _this5._observeLink(instance.link, container, item);
object.matrixAutoUpdate = false;
link = instance.link;
}
var csys = instance.coordinateSystem;
object.userData.name = instance.name;
object.name = instance.name;
object.visible = typeof instance.visible !== 'undefined' ? instance.visible : true;
object.matrix = new THREE.Matrix4().makeBasis(new (Function.prototype.bind.apply(THREE.Vector3, [null].concat((0, _toConsumableArray3.default)(csys[1]))))(), new (Function.prototype.bind.apply(THREE.Vector3, [null].concat((0, _toConsumableArray3.default)(csys[2]))))(), new (Function.prototype.bind.apply(THREE.Vector3, [null].concat((0, _toConsumableArray3.default)(csys[3]))))()).setPosition(new (Function.prototype.bind.apply(THREE.Vector3, [null].concat((0, _toConsumableArray3.default)(csys[0]))))());
_this5.updateView();
//console.log(` moving instance ${instance.name} to ${JSON.stringify(csys[0])}`);
}, { fireOnStart: true, unsubscribeOnUndefined: true });
});
}, function (deletedItems) {
return deletedItems.forEach(function (item) {
var instance = instances[item];
//console.log(` removing instance ${instance.name}`);
delete instances[item];
return instance.destroy();
});
}]));
case 3:
_this5.updateView();
case 4:
case 'end':
return _context4.stop();
}
}
}, _callee4, _this5);
}));
return function () {
return _ref5.apply(this, arguments);
};
}(),
// options
{
onRemove: function onRemove() {
console.log('assembly is gone', container.name);
(0, _values2.default)(instances).forEach(function (item) {
return item.destroy();
});
instances = {};
container.destroy();
parent === _this5.pool && _this5.removePrimitives();
},
fireOnStart: true,
unsubscribeOnUndefined: true
});
return container;
}
}, {
key: '_observePart',
value: function _observePart(root) {
var _this6 = this;
var parent = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.pool;
var instance = arguments[2];
var clones = {};
var container = new this.session.options.objectPrototype({ session: this.session });
container.name = 'Part';
container.temporary = new THREE.Group();
container.temporary.name = 'Part.temporaray';
container.temporary.updateParentMaterials = false;
container.userData = { id: instance };
container.add(container.temporary);
parent.add(container);
this.observe(
// selector
function (state) {
return (state.tree[root] || {}).solids;
},
// onChange
function () {
var _ref6 = (0, _asyncToGenerator3.default)(_regenerator2.default.mark(function _callee5() {
for (var _len2 = arguments.length, args = Array(_len2), _key3 = 0; _key3 < _len2; _key3++) {
args[_key3] = arguments[_key3];
}
var part;
return _regenerator2.default.wrap(function _callee5$(_context5) {
while (1) {
switch (_context5.prev = _context5.next) {
case 0:
part = _this6.tree[root];
_context5.next = 3;
return _helpers.arrayDiff.apply(undefined, args.concat([function (newItems) {
newItems.map(function (item) {
var primitive = _this6.primitives[item];
if (!primitive) {
// primitive is not yet known
// Create bounds representation
var mesh = void 0;
if (part.min && part.max) {
var min = part.min;
var max = part.max;
mesh = new THREE.Mesh(new THREE.BoxBufferGeometry(max[0] - min[0], max[1] - min[1], max[2] - min[2]), new _this6.session.options.meshShader((0, _extends3.default)({
color: new THREE.Color('rgb(' + (part.color ? part.color.join(',') : '190, 190, 190') + ')')
}, _this6.session.options.meshShaderOptions)));
if (_this6.session.options.materials.shadows) {
mesh.castShadow = true;
mesh.receiveShadow = true;
}
mesh.position.set((max[0] + min[0]) / 2, (max[1] + min[1]) / 2, (max[2] + min[2]) / 2);
container.reset(mesh).add(mesh);
}
// If none exists, create empty waiting list entry from item
if (!_this6.waiting[item]) _this6.waiting[item] = [];
// Register item on the waiting-list
_this6.waiting[item].push(function (primitive) {
// Delete bounds
mesh && mesh.destroyAsync();
// Create real clone, finally
createClone({ root: root, parent: parent, clones: clones, container: container, primitive: primitive, item: item });
});
} else createClone({ root: root, parent: parent, clones: clones, container: container, primitive: primitive, item: item });
});
_this6.updateView();
}, function (deletedItems) {
return deletedItems.map(function (item) {
var clone = clones[item];
// Remove clone from primitives
var primitive = _this6.primitives[item];
if (primitive) primitive.references.splice(primitive.references.indexOf(clone), 1);
delete clones[item];
return clone.destroyAsync();
});
}]));
case 3:
case 'end':
return _context5.stop();
}
}
}, _callee5, _this6);
}));
return function () {
return _ref6.apply(this, arguments);
};
}(),
// options
{
onRemove: function onRemove() {
console.log('part is gone', container.name);
(0, _values2.default)(clones).forEach(function (item) {
return item.destroy();
});
clones = {};
container.destroy();
parent === _this6.pool && _this6.removePrimitives();
},
fireOnStart: true,
unsubscribeOnUndefined: true
});
return container;
}
}, {
key: '_instanciateFeature',
value: function _instanciateFeature(id, props) {
var _featurePlugins$id = this.featurePlugins[id],
parent = _featurePlugins$id.parent,
feature = _featurePlugins$id.feature,
persistent = _featurePlugins$id.persistent,
pluginPrototype = _featurePlugins$id.pluginPrototype;
// If activeSelection is on we must reset it
!persistent && this.session.globals.activeSelection && this.store.dispatch(_globals.actions.setActiveSelection());
// Each plugin gets a distinct pool to draw into
var pool = new THREE.Group();
pool.name = 'Instance';
pool.updateParentMaterials = false;
pool.measurable = pluginPrototype.measurable;
pool.name = feature.name;
parent.add(pool);
// Intanciate and link new plugin
var plugin = new pluginPrototype(this.session, (0, _extends3.default)({
name: feature.name,
feature: feature,
pool: pool,
connection: this
}, props));
// Link plugins
this.featurePlugins[id].plugin = plugin;
this.store.dispatch(_connections.actions.linkPlugins(this.id, plugin.id));
return plugin;
}
}, {
key: '_mapFeatures',
value: function _mapFeatures(parent) {
for (var _len3 = arguments.length, features = Array(_len3 > 1 ? _len3 - 1 : 0), _key4 = 1; _key4 < _len3; _key4++) {
features[_key4 - 1] = arguments[_key4];
}
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = (0, _getIterator3.default)(features), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var id = _step.value;
var feature = this.tree[id];
var type = feature.class;
var pluginPrototype = this.session.featurePlugins[type];
if (!pluginPrototype && this.session.defaultFeaturePlugin) pluginPrototype = this.session.defaultFeaturePlugin;
if (pluginPrototype) {
// Map feature plugin
this.featurePlugins[id] = {
feature: feature,
parent: parent.temporary,
pluginPrototype: pluginPrototype,
persistent: pluginPrototype.persistent
};
if (pluginPrototype.persistent) {
// Return persistent plugins
this._instanciateFeature(id);
}
}
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
}
}, {
key: '_unmapFeatures',
value: function _unmapFeatures() {
var _this7 = this;
for (var _len4 = arguments.length, features = Array(_len4), _key5 = 0; _key5 < _len4; _key5++) {
features[_key5] = arguments[_key5];
}
this._destroyFeatures(features);
features.forEach(function (id) {
return delete _this7.featurePlugins[id];
});
}
}, {
key: '_destroyFeatures',
value: function _destroyFeatures() {
var _this8 = this;
for (var _len5 = arguments.length, features = Array(_len5), _key6 = 0; _key6 < _len5; _key6++) {
features[_key6] = arguments[_key6];
}
var plugins = features.map(function (id) {
return _this8.featurePlugins[id];
}).filter(function (data) {
return data && data.plugin;
}).map(function (data) {
return data.plugin.id;
});
if (plugins.length > 0) {
this.store.dispatch(_connections.actions.unlinkPlugins(this.id, plugins));
}
features.forEach(function (id) {
// Find real plugin class
var _ref7 = _this8.featurePlugins[id] || {},
plugin = _ref7.plugin,
parent = _ref7.parent,
persistent = _ref7.persistent;
if (plugin) {
if (!persistent) {
delete _this8.featurePlugins[id].plugin;
}
parent.remove(plugin.pool);
_this8.defer(function () {
return _this8.store.dispatch(_plugins.actions.unregister(plugin.id));
});
}
});
}
}, {
key: '_observeFeatures',
value: function _observeFeatures(root) {
var _this9 = this;
var parent = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.pool;
//console.log("observeFeatures...")
return this.observe(
// selector
function (state) {
return (state.tree[root] || {}).features;
},
// onChange
function () {
for (var _len6 = arguments.length, args = Array(_len6), _key7 = 0; _key7 < _len6; _key7++) {
args[_key7] = arguments[_key7];
}
_helpers.arrayDiff.apply(undefined, args.concat([function (newItems) {
return _this9._mapFeatures.apply(_this9, [parent].concat((0, _toConsumableArray3.default)(newItems)));
}, function (deletedItems) {
return _this9._unmapFeatures.apply(_this9, (0, _toConsumableArray3.default)(deletedItems));
}]));
},
// options
{ fireOnStart: true, unsubscribeOnUndefined: true });
}
}, {
key: '_resolveArray',
value: function _resolveArray(array, state) {
var _iteratorNormalCompletion2 = true;
var _didIteratorError2 = false;
var _iteratorError2 = undefined;
try {
for (var _iterator2 = (0, _getIterator3.default)(array), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
var member = _step2.value;
if (member.type === 'id') {
array[array.indexOf(member)] = this._get(member.value, state);
} else if (member.type === 'array') {
this._resolveArray(member, state);
}
}
} catch (err) {
_didIteratorError2 = true;
_iteratorError2 = err;
} finally {
try {
if (!_iteratorNormalCompletion2 && _iterator2.return) {
_iterator2.return();
}
} finally {
if (_didIteratorError2) {
throw _iteratorError2;
}
}
}
}
}, {
key: '__onDestroyed',
value: function __onDestroyed() {
var _this10 = this;
(0, _values2.default)(this.primitives).forEach(function (item) {
return item.destroy();
});
this.primitives = {};
(0, _values2.default)(this.session.plugins).forEach(function (plugin) {
return plugin.connection === _this10.id && _this10.store.dispatch(_plugins.actions.unregister(plugin.id));
});
if (this.session.globals.activeConnection === this.id) {
this.session.dispatch(_globals.actions.setActiveConnection());
}
this.socket && this.socket.disconnect();
}
}]);
return Connection;
}((0, _lifecycle2.default)(_base2.default, false));
exports.default = Connection;
function createClone(_ref8) {
var root = _ref8.root,
parent = _ref8.parent,
clones = _ref8.clones,
container = _ref8.container,
primitive = _ref8.primitive,
item = _ref8.item;
var clone = clones[item] = primitive.clone();
primitive.references.push(clone);
// Calculate new deep ID
var array = [root];
parent = container;
while (parent && parent.userData && parent.userData.id) {
array.push(parent.userData.id);
parent = parent.parent;
}
array = array.reverse();
// deep clone materials;
var _iteratorNormalCompletion3 = true;
var _didIteratorError3 = false;
var _iteratorError3 = undefined;
try {
for (var _iterator3 = (0, _getIterator3.default)(clone.children.keys()), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {
var child = _step3.value;
var c = clone.children[child];
var p = primitive.children[child];
if (c.material) {
var isMultiMaterial = Array.isArray(c.material);
if (isMultiMaterial) {
for (var i = 0, l = c.material.length; i < l; i++) {
var pMaterial = p.material[i];
var cMaterial = c.material[i] = pMaterial.clone(true);
cMaterial.meta = (0, _extends3.default)({}, pMaterial.meta, { originalId: pMaterial.meta.id, id: [].concat((0, _toConsumableArray3.default)(array), [pMaterial.meta.id]).join(',') });
}
} else {
c.material = p.material.clone(true);
c.material.meta = (0, _extends3.default)({}, p.material.meta);
}
}
}
} catch (err) {
_didIteratorError3 = true;
_iteratorError3 = err;
} finally {
try {
if (!_iteratorNormalCompletion3 && _iterator3.return) {
_iterator3.return();
}
} finally {
if (_didIteratorError3) {
throw _iteratorError3;
}
}
}
return container.reset(clone).add(clone);
}