(function (global, factory) { if (typeof define === "function" && define.amd) { define(["exports", "three"], factory); } else if (typeof exports !== "undefined") { factory(exports, require("three")); } else { var mod = { exports: {} }; factory(mod.exports, global.three); global.DMLoader = mod.exports; } })(typeof globalThis !== "undefined" ? globalThis : typeof self !== "undefined" ? self : this, function (_exports, _three) { "use strict"; Object.defineProperty(_exports, "__esModule", { value: true }); _exports.Rhino3dmLoader = void 0; function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); } function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } Object.defineProperty(subClass, "prototype", { value: Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }), writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); } function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } function _possibleConstructorReturn(self, call) { if (call && (typeof call === "object" || typeof call === "function")) { return call; } else if (call !== void 0) { throw new TypeError("Derived constructors may only return object or undefined"); } return _assertThisInitialized(self); } function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } } function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } var _taskCache = new WeakMap(); var Rhino3dmLoader = /*#__PURE__*/function (_Loader) { _inherits(Rhino3dmLoader, _Loader); var _super = _createSuper(Rhino3dmLoader); function Rhino3dmLoader(manager) { var _this; _classCallCheck(this, Rhino3dmLoader); _this = _super.call(this, manager); _this.libraryPath = ''; _this.libraryPending = null; _this.libraryBinary = null; _this.libraryConfig = {}; _this.url = ''; _this.workerLimit = 4; _this.workerPool = []; _this.workerNextTaskID = 1; _this.workerSourceURL = ''; _this.workerConfig = {}; _this.materials = []; _this.warnings = []; return _this; } _createClass(Rhino3dmLoader, [{ key: "setLibraryPath", value: function setLibraryPath(path) { this.libraryPath = path; return this; } }, { key: "setWorkerLimit", value: function setWorkerLimit(workerLimit) { this.workerLimit = workerLimit; return this; } }, { key: "load", value: function load(url, onLoad, onProgress, onError) { var _this2 = this; var loader = new _three.FileLoader(this.manager); loader.setPath(this.path); loader.setResponseType('arraybuffer'); loader.setRequestHeader(this.requestHeader); this.url = url; loader.load(url, function (buffer) { // Check for an existing task using this buffer. A transferred buffer cannot be transferred // again from this thread. if (_taskCache.has(buffer)) { var cachedTask = _taskCache.get(buffer); return cachedTask.promise.then(onLoad).catch(onError); } _this2.decodeObjects(buffer, url).then(function (result) { result.userData.warnings = _this2.warnings; onLoad(result); }).catch(function (e) { return onError(e); }); }, onProgress, onError); } }, { key: "debug", value: function debug() { console.log('Task load: ', this.workerPool.map(function (worker) { return worker._taskLoad; })); } }, { key: "decodeObjects", value: function decodeObjects(buffer, url) { var _this3 = this; var worker; var taskID; var taskCost = buffer.byteLength; var objectPending = this._getWorker(taskCost).then(function (_worker) { worker = _worker; taskID = _this3.workerNextTaskID++; return new Promise(function (resolve, reject) { worker._callbacks[taskID] = { resolve: resolve, reject: reject }; worker.postMessage({ type: 'decode', id: taskID, buffer: buffer }, [buffer]); // this.debug(); }); }).then(function (message) { return _this3._createGeometry(message.data); }).catch(function (e) { throw e; }); // Remove task from the task list. // Note: replaced '.finally()' with '.catch().then()' block - iOS 11 support (#19416) objectPending.catch(function () { return true; }).then(function () { if (worker && taskID) { _this3._releaseTask(worker, taskID); //this.debug(); } }); // Cache the task result. _taskCache.set(buffer, { url: url, promise: objectPending }); return objectPending; } }, { key: "parse", value: function parse(data, onLoad, onError) { var _this4 = this; this.decodeObjects(data, '').then(function (result) { result.userData.warnings = _this4.warnings; onLoad(result); }).catch(function (e) { return onError(e); }); } }, { key: "_compareMaterials", value: function _compareMaterials(material) { var mat = {}; mat.name = material.name; mat.color = {}; mat.color.r = material.color.r; mat.color.g = material.color.g; mat.color.b = material.color.b; mat.type = material.type; for (var i = 0; i < this.materials.length; i++) { var m = this.materials[i]; var _mat = {}; _mat.name = m.name; _mat.color = {}; _mat.color.r = m.color.r; _mat.color.g = m.color.g; _mat.color.b = m.color.b; _mat.type = m.type; if (JSON.stringify(mat) === JSON.stringify(_mat)) { return m; } } this.materials.push(material); return material; } }, { key: "_createMaterial", value: function _createMaterial(material) { if (material === undefined) { return new _three.MeshStandardMaterial({ color: new _three.Color(1, 1, 1), metalness: 0.8, name: 'default', side: 2 }); } var _diffuseColor = material.diffuseColor; var diffusecolor = new _three.Color(_diffuseColor.r / 255.0, _diffuseColor.g / 255.0, _diffuseColor.b / 255.0); if (_diffuseColor.r === 0 && _diffuseColor.g === 0 && _diffuseColor.b === 0) { diffusecolor.r = 1; diffusecolor.g = 1; diffusecolor.b = 1; } // console.log( material ); var mat = new _three.MeshStandardMaterial({ color: diffusecolor, name: material.name, side: 2, transparent: material.transparency > 0 ? true : false, opacity: 1.0 - material.transparency }); var textureLoader = new _three.TextureLoader(); for (var i = 0; i < material.textures.length; i++) { var texture = material.textures[i]; if (texture.image !== null) { var map = textureLoader.load(texture.image); switch (texture.type) { case 'Diffuse': mat.map = map; break; case 'Bump': mat.bumpMap = map; break; case 'Transparency': mat.alphaMap = map; mat.transparent = true; break; case 'Emap': mat.envMap = map; break; } map.wrapS = texture.wrapU === 0 ? THREE.RepeatWrapping : THREE.ClampToEdgeWrapping; map.wrapT = texture.wrapV === 0 ? THREE.RepeatWrapping : THREE.ClampToEdgeWrapping; map.repeat.set(texture.repeat[0], texture.repeat[1]); } } return mat; } }, { key: "_createGeometry", value: function _createGeometry(data) { // console.log(data); var object = new _three.Object3D(); var instanceDefinitionObjects = []; var instanceDefinitions = []; var instanceReferences = []; object.userData['layers'] = data.layers; object.userData['groups'] = data.groups; object.userData['settings'] = data.settings; object.userData['objectType'] = 'File3dm'; object.userData['materials'] = null; object.name = this.url; var objects = data.objects; var materials = data.materials; for (var i = 0; i < objects.length; i++) { var obj = objects[i]; var attributes = obj.attributes; switch (obj.objectType) { case 'InstanceDefinition': instanceDefinitions.push(obj); break; case 'InstanceReference': instanceReferences.push(obj); break; default: var _object = void 0; if (attributes.materialIndex >= 0) { var rMaterial = materials[attributes.materialIndex]; var material = this._createMaterial(rMaterial); material = this._compareMaterials(material); _object = this._createObject(obj, material); } else { var _material2 = this._createMaterial(); _object = this._createObject(obj, _material2); } if (_object === undefined) { continue; } var layer = data.layers[attributes.layerIndex]; _object.visible = layer ? data.layers[attributes.layerIndex].visible : true; if (attributes.isInstanceDefinitionObject) { instanceDefinitionObjects.push(_object); } else { object.add(_object); } break; } } for (var _i = 0; _i < instanceDefinitions.length; _i++) { var iDef = instanceDefinitions[_i]; objects = []; for (var j = 0; j < iDef.attributes.objectIds.length; j++) { var objId = iDef.attributes.objectIds[j]; for (var p = 0; p < instanceDefinitionObjects.length; p++) { var idoId = instanceDefinitionObjects[p].userData.attributes.id; if (objId === idoId) { objects.push(instanceDefinitionObjects[p]); } } } // Currently clones geometry and does not take advantage of instancing for (var _j = 0; _j < instanceReferences.length; _j++) { var iRef = instanceReferences[_j]; if (iRef.geometry.parentIdefId === iDef.attributes.id) { var iRefObject = new _three.Object3D(); var xf = iRef.geometry.xform.array; var matrix = new _three.Matrix4(); matrix.set(xf[0], xf[1], xf[2], xf[3], xf[4], xf[5], xf[6], xf[7], xf[8], xf[9], xf[10], xf[11], xf[12], xf[13], xf[14], xf[15]); iRefObject.applyMatrix4(matrix); for (var _p = 0; _p < objects.length; _p++) { iRefObject.add(objects[_p].clone(true)); } object.add(iRefObject); } } } object.userData['materials'] = this.materials; return object; } }, { key: "_createObject", value: function _createObject(obj, mat) { var loader = new _three.BufferGeometryLoader(); var attributes = obj.attributes; var geometry, material, _color, color; switch (obj.objectType) { case 'Point': case 'PointSet': geometry = loader.parse(obj.geometry); if (geometry.attributes.hasOwnProperty('color')) { material = new _three.PointsMaterial({ vertexColors: true, sizeAttenuation: false, size: 2 }); } else { _color = attributes.drawColor; color = new _three.Color(_color.r / 255.0, _color.g / 255.0, _color.b / 255.0); material = new _three.PointsMaterial({ color: color, sizeAttenuation: false, size: 2 }); } material = this._compareMaterials(material); var points = new _three.Points(geometry, material); points.userData['attributes'] = attributes; points.userData['objectType'] = obj.objectType; if (attributes.name) { points.name = attributes.name; } return points; case 'Mesh': case 'Extrusion': case 'SubD': case 'Brep': if (obj.geometry === null) return; geometry = loader.parse(obj.geometry); if (geometry.attributes.hasOwnProperty('color')) { mat.vertexColors = true; } if (mat === null) { mat = this._createMaterial(); mat = this._compareMaterials(mat); } var mesh = new _three.Mesh(geometry, mat); mesh.castShadow = attributes.castsShadows; mesh.receiveShadow = attributes.receivesShadows; mesh.userData['attributes'] = attributes; mesh.userData['objectType'] = obj.objectType; if (attributes.name) { mesh.name = attributes.name; } return mesh; case 'Curve': geometry = loader.parse(obj.geometry); _color = attributes.drawColor; color = new _three.Color(_color.r / 255.0, _color.g / 255.0, _color.b / 255.0); material = new _three.LineBasicMaterial({ color: color }); material = this._compareMaterials(material); var lines = new _three.Line(geometry, material); lines.userData['attributes'] = attributes; lines.userData['objectType'] = obj.objectType; if (attributes.name) { lines.name = attributes.name; } return lines; case 'TextDot': geometry = obj.geometry; var ctx = document.createElement('canvas').getContext('2d'); var font = "".concat(geometry.fontHeight, "px ").concat(geometry.fontFace); ctx.font = font; var width = ctx.measureText(geometry.text).width + 10; var height = geometry.fontHeight + 10; var r = window.devicePixelRatio; ctx.canvas.width = width * r; ctx.canvas.height = height * r; ctx.canvas.style.width = width + 'px'; ctx.canvas.style.height = height + 'px'; ctx.setTransform(r, 0, 0, r, 0, 0); ctx.font = font; ctx.textBaseline = 'middle'; ctx.textAlign = 'center'; color = attributes.drawColor; ctx.fillStyle = "rgba(".concat(color.r, ",").concat(color.g, ",").concat(color.b, ",").concat(color.a, ")"); ctx.fillRect(0, 0, width, height); ctx.fillStyle = 'white'; ctx.fillText(geometry.text, width / 2, height / 2); var texture = new _three.CanvasTexture(ctx.canvas); texture.minFilter = _three.LinearFilter; texture.wrapS = _three.ClampToEdgeWrapping; texture.wrapT = _three.ClampToEdgeWrapping; material = new _three.SpriteMaterial({ map: texture, depthTest: false }); var sprite = new _three.Sprite(material); sprite.position.set(geometry.point[0], geometry.point[1], geometry.point[2]); sprite.scale.set(width / 10, height / 10, 1.0); sprite.userData['attributes'] = attributes; sprite.userData['objectType'] = obj.objectType; if (attributes.name) { sprite.name = attributes.name; } return sprite; case 'Light': geometry = obj.geometry; var light; switch (geometry.lightStyle.name) { case 'LightStyle_WorldPoint': light = new _three.PointLight(); light.castShadow = attributes.castsShadows; light.position.set(geometry.location[0], geometry.location[1], geometry.location[2]); light.shadow.normalBias = 0.1; break; case 'LightStyle_WorldSpot': light = new _three.SpotLight(); light.castShadow = attributes.castsShadows; light.position.set(geometry.location[0], geometry.location[1], geometry.location[2]); light.target.position.set(geometry.direction[0], geometry.direction[1], geometry.direction[2]); light.angle = geometry.spotAngleRadians; light.shadow.normalBias = 0.1; break; case 'LightStyle_WorldRectangular': light = new _three.RectAreaLight(); var _width = Math.abs(geometry.width[2]); var _height = Math.abs(geometry.length[0]); light.position.set(geometry.location[0] - _height / 2, geometry.location[1], geometry.location[2] - _width / 2); light.height = _height; light.width = _width; light.lookAt(new _three.Vector3(geometry.direction[0], geometry.direction[1], geometry.direction[2])); break; case 'LightStyle_WorldDirectional': light = new _three.DirectionalLight(); light.castShadow = attributes.castsShadows; light.position.set(geometry.location[0], geometry.location[1], geometry.location[2]); light.target.position.set(geometry.direction[0], geometry.direction[1], geometry.direction[2]); light.shadow.normalBias = 0.1; break; case 'LightStyle_WorldLinear': // not conversion exists, warning has already been printed to the console break; default: break; } if (light) { light.intensity = geometry.intensity; _color = geometry.diffuse; color = new _three.Color(_color.r / 255.0, _color.g / 255.0, _color.b / 255.0); light.color = color; light.userData['attributes'] = attributes; light.userData['objectType'] = obj.objectType; } return light; } } }, { key: "_initLibrary", value: function _initLibrary() { var _this5 = this; if (!this.libraryPending) { // Load rhino3dm wrapper. var jsLoader = new _three.FileLoader(this.manager); jsLoader.setPath(this.libraryPath); var jsContent = new Promise(function (resolve, reject) { jsLoader.load('rhino3dm.js', resolve, undefined, reject); }); // Load rhino3dm WASM binary. var binaryLoader = new _three.FileLoader(this.manager); binaryLoader.setPath(this.libraryPath); binaryLoader.setResponseType('arraybuffer'); var binaryContent = new Promise(function (resolve, reject) { binaryLoader.load('rhino3dm.wasm', resolve, undefined, reject); }); this.libraryPending = Promise.all([jsContent, binaryContent]).then(function (_ref) { var _ref2 = _slicedToArray(_ref, 2), jsContent = _ref2[0], binaryContent = _ref2[1]; //this.libraryBinary = binaryContent; _this5.libraryConfig.wasmBinary = binaryContent; var fn = Rhino3dmWorker.toString(); var body = ['/* rhino3dm.js */', jsContent, '/* worker */', fn.substring(fn.indexOf('{') + 1, fn.lastIndexOf('}'))].join('\n'); _this5.workerSourceURL = URL.createObjectURL(new Blob([body])); }); } return this.libraryPending; } }, { key: "_getWorker", value: function _getWorker(taskCost) { var _this6 = this; return this._initLibrary().then(function () { if (_this6.workerPool.length < _this6.workerLimit) { var _worker2 = new Worker(_this6.workerSourceURL); _worker2._callbacks = {}; _worker2._taskCosts = {}; _worker2._taskLoad = 0; _worker2.postMessage({ type: 'init', libraryConfig: _this6.libraryConfig }); _worker2.onmessage = function (e) { var message = e.data; switch (message.type) { case 'warning': _this6.warnings.push(message.data); console.warn(message.data); break; case 'decode': _worker2._callbacks[message.id].resolve(message); break; case 'error': _worker2._callbacks[message.id].reject(message); break; default: console.error('THREE.Rhino3dmLoader: Unexpected message, "' + message.type + '"'); } }; _this6.workerPool.push(_worker2); } else { _this6.workerPool.sort(function (a, b) { return a._taskLoad > b._taskLoad ? -1 : 1; }); } var worker = _this6.workerPool[_this6.workerPool.length - 1]; worker._taskLoad += taskCost; return worker; }); } }, { key: "_releaseTask", value: function _releaseTask(worker, taskID) { worker._taskLoad -= worker._taskCosts[taskID]; delete worker._callbacks[taskID]; delete worker._taskCosts[taskID]; } }, { key: "dispose", value: function dispose() { for (var i = 0; i < this.workerPool.length; ++i) { this.workerPool[i].terminate(); } this.workerPool.length = 0; return this; } }]); return Rhino3dmLoader; }(_three.Loader); /* WEB WORKER */ _exports.Rhino3dmLoader = Rhino3dmLoader; function Rhino3dmWorker() { var libraryPending; var libraryConfig; var rhino; var taskID; onmessage = function onmessage(e) { var message = e.data; switch (message.type) { case 'init': // console.log(message) libraryConfig = message.libraryConfig; var wasmBinary = libraryConfig.wasmBinary; var RhinoModule; libraryPending = new Promise(function (resolve) { /* Like Basis Loader */ RhinoModule = { wasmBinary: wasmBinary, onRuntimeInitialized: resolve }; rhino3dm(RhinoModule); // eslint-disable-line no-undef }).then(function () { rhino = RhinoModule; }); break; case 'decode': taskID = message.id; var buffer = message.buffer; libraryPending.then(function () { try { var data = decodeObjects(rhino, buffer); self.postMessage({ type: 'decode', id: message.id, data: data }); } catch (error) { self.postMessage({ type: 'error', id: message.id, error: error }); } }); break; } }; function decodeObjects(rhino, buffer) { var arr = new Uint8Array(buffer); var doc = rhino.File3dm.fromByteArray(arr); var objects = []; var materials = []; var layers = []; var views = []; var namedViews = []; var groups = []; var strings = []; //Handle objects var objs = doc.objects(); var cnt = objs.count; for (var i = 0; i < cnt; i++) { var _object = objs.get(i); var object = extractObjectData(_object, doc); _object.delete(); if (object) { objects.push(object); } } // Handle instance definitions // console.log( `Instance Definitions Count: ${doc.instanceDefinitions().count()}` ); for (var _i2 = 0; _i2 < doc.instanceDefinitions().count(); _i2++) { var idef = doc.instanceDefinitions().get(_i2); var idefAttributes = extractProperties(idef); idefAttributes.objectIds = idef.getObjectIds(); objects.push({ geometry: null, attributes: idefAttributes, objectType: 'InstanceDefinition' }); } // Handle materials var textureTypes = [// rhino.TextureType.Bitmap, rhino.TextureType.Diffuse, rhino.TextureType.Bump, rhino.TextureType.Transparency, rhino.TextureType.Opacity, rhino.TextureType.Emap]; var pbrTextureTypes = [rhino.TextureType.PBR_BaseColor, rhino.TextureType.PBR_Subsurface, rhino.TextureType.PBR_SubsurfaceScattering, rhino.TextureType.PBR_SubsurfaceScatteringRadius, rhino.TextureType.PBR_Metallic, rhino.TextureType.PBR_Specular, rhino.TextureType.PBR_SpecularTint, rhino.TextureType.PBR_Roughness, rhino.TextureType.PBR_Anisotropic, rhino.TextureType.PBR_Anisotropic_Rotation, rhino.TextureType.PBR_Sheen, rhino.TextureType.PBR_SheenTint, rhino.TextureType.PBR_Clearcoat, rhino.TextureType.PBR_ClearcoatBump, rhino.TextureType.PBR_ClearcoatRoughness, rhino.TextureType.PBR_OpacityIor, rhino.TextureType.PBR_OpacityRoughness, rhino.TextureType.PBR_Emission, rhino.TextureType.PBR_AmbientOcclusion, rhino.TextureType.PBR_Displacement]; for (var _i3 = 0; _i3 < doc.materials().count(); _i3++) { var _material = doc.materials().get(_i3); var _pbrMaterial = _material.physicallyBased(); var material = extractProperties(_material); var textures = []; for (var j = 0; j < textureTypes.length; j++) { var _texture = _material.getTexture(textureTypes[j]); if (_texture) { var textureType = textureTypes[j].constructor.name; textureType = textureType.substring(12, textureType.length); var texture = { type: textureType }; var image = doc.getEmbeddedFileAsBase64(_texture.fileName); texture.wrapU = _texture.wrapU; texture.wrapV = _texture.wrapV; texture.wrapW = _texture.wrapW; var uvw = _texture.uvwTransform.toFloatArray(true); texture.repeat = [uvw[0], uvw[5]]; if (image) { texture.image = 'data:image/png;base64,' + image; } else { self.postMessage({ type: 'warning', id: taskID, data: { message: "THREE.3DMLoader: Image for ".concat(textureType, " texture not embedded in file."), type: 'missing resource' } }); texture.image = null; } textures.push(texture); _texture.delete(); } } material.textures = textures; if (_pbrMaterial.supported) { for (var _j2 = 0; _j2 < pbrTextureTypes.length; _j2++) { var _texture2 = _material.getTexture(pbrTextureTypes[_j2]); if (_texture2) { var _image = doc.getEmbeddedFileAsBase64(_texture2.fileName); var _textureType = pbrTextureTypes[_j2].constructor.name; _textureType = _textureType.substring(12, _textureType.length); var _texture3 = { type: _textureType, image: 'data:image/png;base64,' + _image }; textures.push(_texture3); _texture2.delete(); } } var pbMaterialProperties = extractProperties(_material.physicallyBased()); material = Object.assign(pbMaterialProperties, material); } materials.push(material); _material.delete(); _pbrMaterial.delete(); } // Handle layers for (var _i4 = 0; _i4 < doc.layers().count(); _i4++) { var _layer = doc.layers().get(_i4); var layer = extractProperties(_layer); layers.push(layer); _layer.delete(); } // Handle views for (var _i5 = 0; _i5 < doc.views().count(); _i5++) { var _view = doc.views().get(_i5); var view = extractProperties(_view); views.push(view); _view.delete(); } // Handle named views for (var _i6 = 0; _i6 < doc.namedViews().count(); _i6++) { var _namedView = doc.namedViews().get(_i6); var namedView = extractProperties(_namedView); namedViews.push(namedView); _namedView.delete(); } // Handle groups for (var _i7 = 0; _i7 < doc.groups().count(); _i7++) { var _group = doc.groups().get(_i7); var group = extractProperties(_group); groups.push(group); _group.delete(); } // Handle settings var settings = extractProperties(doc.settings()); //TODO: Handle other document stuff like dimstyles, instance definitions, bitmaps etc. // Handle dimstyles // console.log( `Dimstyle Count: ${doc.dimstyles().count()}` ); // Handle bitmaps // console.log( `Bitmap Count: ${doc.bitmaps().count()}` ); // Handle strings // console.log( `Document Strings Count: ${doc.strings().count()}` ); // Note: doc.strings().documentUserTextCount() counts any doc.strings defined in a section //console.log( `Document User Text Count: ${doc.strings().documentUserTextCount()}` ); var strings_count = doc.strings().count(); for (var _i8 = 0; _i8 < strings_count; _i8++) { strings.push(doc.strings().get(_i8)); } doc.delete(); return { objects: objects, materials: materials, layers: layers, views: views, namedViews: namedViews, groups: groups, strings: strings, settings: settings }; } function extractObjectData(object, doc) { var _geometry = object.geometry(); var _attributes = object.attributes(); var objectType = _geometry.objectType; var geometry, attributes, position, data, mesh; // skip instance definition objects //if( _attributes.isInstanceDefinitionObject ) { continue; } // TODO: handle other geometry types switch (objectType) { case rhino.ObjectType.Curve: var pts = curveToPoints(_geometry, 100); position = {}; attributes = {}; data = {}; position.itemSize = 3; position.type = 'Float32Array'; position.array = []; for (var j = 0; j < pts.length; j++) { position.array.push(pts[j][0]); position.array.push(pts[j][1]); position.array.push(pts[j][2]); } attributes.position = position; data.attributes = attributes; geometry = { data: data }; break; case rhino.ObjectType.Point: var pt = _geometry.location; position = {}; var color = {}; attributes = {}; data = {}; position.itemSize = 3; position.type = 'Float32Array'; position.array = [pt[0], pt[1], pt[2]]; var _color = _attributes.drawColor(doc); color.itemSize = 3; color.type = 'Float32Array'; color.array = [_color.r / 255.0, _color.g / 255.0, _color.b / 255.0]; attributes.position = position; attributes.color = color; data.attributes = attributes; geometry = { data: data }; break; case rhino.ObjectType.PointSet: case rhino.ObjectType.Mesh: geometry = _geometry.toThreejsJSON(); break; case rhino.ObjectType.Brep: var faces = _geometry.faces(); mesh = new rhino.Mesh(); for (var faceIndex = 0; faceIndex < faces.count; faceIndex++) { var face = faces.get(faceIndex); var _mesh = face.getMesh(rhino.MeshType.Any); if (_mesh) { mesh.append(_mesh); _mesh.delete(); } face.delete(); } if (mesh.faces().count > 0) { mesh.compact(); geometry = mesh.toThreejsJSON(); faces.delete(); } mesh.delete(); break; case rhino.ObjectType.Extrusion: mesh = _geometry.getMesh(rhino.MeshType.Any); if (mesh) { geometry = mesh.toThreejsJSON(); mesh.delete(); } break; case rhino.ObjectType.TextDot: geometry = extractProperties(_geometry); break; case rhino.ObjectType.Light: geometry = extractProperties(_geometry); if (geometry.lightStyle.name === 'LightStyle_WorldLinear') { self.postMessage({ type: 'warning', id: taskID, data: { message: "THREE.3DMLoader: No conversion exists for ".concat(objectType.constructor.name, " ").concat(geometry.lightStyle.name), type: 'no conversion', guid: _attributes.id } }); } break; case rhino.ObjectType.InstanceReference: geometry = extractProperties(_geometry); geometry.xform = extractProperties(_geometry.xform); geometry.xform.array = _geometry.xform.toFloatArray(true); break; case rhino.ObjectType.SubD: // TODO: precalculate resulting vertices and faces and warn on excessive results _geometry.subdivide(3); mesh = rhino.Mesh.createFromSubDControlNet(_geometry); if (mesh) { geometry = mesh.toThreejsJSON(); mesh.delete(); } break; /* case rhino.ObjectType.Annotation: case rhino.ObjectType.Hatch: case rhino.ObjectType.ClipPlane: */ default: self.postMessage({ type: 'warning', id: taskID, data: { message: "THREE.3DMLoader: Conversion not implemented for ".concat(objectType.constructor.name), type: 'not implemented', guid: _attributes.id } }); break; } if (geometry) { attributes = extractProperties(_attributes); attributes.geometry = extractProperties(_geometry); if (_attributes.groupCount > 0) { attributes.groupIds = _attributes.getGroupList(); } if (_attributes.userStringCount > 0) { attributes.userStrings = _attributes.getUserStrings(); } if (_geometry.userStringCount > 0) { attributes.geometry.userStrings = _geometry.getUserStrings(); } attributes.drawColor = _attributes.drawColor(doc); objectType = objectType.constructor.name; objectType = objectType.substring(11, objectType.length); return { geometry: geometry, attributes: attributes, objectType: objectType }; } else { self.postMessage({ type: 'warning', id: taskID, data: { message: "THREE.3DMLoader: ".concat(objectType.constructor.name, " has no associated mesh geometry."), type: 'missing mesh', guid: _attributes.id } }); } } function extractProperties(object) { var result = {}; for (var property in object) { var value = object[property]; if (typeof value !== 'function') { if (typeof value === 'object' && value !== null && value.hasOwnProperty('constructor')) { result[property] = { name: value.constructor.name, value: value.value }; } else { result[property] = value; } } else {// these are functions that could be called to extract more data. //console.log( `${property}: ${object[ property ].constructor.name}` ); } } return result; } function curveToPoints(curve, pointLimit) { var pointCount = pointLimit; var rc = []; var ts = []; if (curve instanceof rhino.LineCurve) { return [curve.pointAtStart, curve.pointAtEnd]; } if (curve instanceof rhino.PolylineCurve) { pointCount = curve.pointCount; for (var i = 0; i < pointCount; i++) { rc.push(curve.point(i)); } return rc; } if (curve instanceof rhino.PolyCurve) { var segmentCount = curve.segmentCount; for (var _i9 = 0; _i9 < segmentCount; _i9++) { var segment = curve.segmentCurve(_i9); var segmentArray = curveToPoints(segment, pointCount); rc = rc.concat(segmentArray); segment.delete(); } return rc; } if (curve instanceof rhino.ArcCurve) { pointCount = Math.floor(curve.angleDegrees / 5); pointCount = pointCount < 2 ? 2 : pointCount; // alternative to this hardcoded version: https://stackoverflow.com/a/18499923/2179399 } if (curve instanceof rhino.NurbsCurve && curve.degree === 1) { var pLine = curve.tryGetPolyline(); for (var _i10 = 0; _i10 < pLine.count; _i10++) { rc.push(pLine.get(_i10)); } pLine.delete(); return rc; } var domain = curve.domain; var divisions = pointCount - 1.0; for (var j = 0; j < pointCount; j++) { var t = domain[0] + j / divisions * (domain[1] - domain[0]); if (t === domain[0] || t === domain[1]) { ts.push(t); continue; } var tan = curve.tangentAt(t); var prevTan = curve.tangentAt(ts.slice(-1)[0]); // Duplicated from THREE.Vector3 // How to pass imports to worker? var tS = tan[0] * tan[0] + tan[1] * tan[1] + tan[2] * tan[2]; var ptS = prevTan[0] * prevTan[0] + prevTan[1] * prevTan[1] + prevTan[2] * prevTan[2]; var denominator = Math.sqrt(tS * ptS); var angle = void 0; if (denominator === 0) { angle = Math.PI / 2; } else { var theta = (tan.x * prevTan.x + tan.y * prevTan.y + tan.z * prevTan.z) / denominator; angle = Math.acos(Math.max(-1, Math.min(1, theta))); } if (angle < 0.1) continue; ts.push(t); } rc = ts.map(function (t) { return curve.pointAt(t); }); return rc; } } });