{"version":3,"sources":["jsdelivr-header.js","/npm/online-3d-viewer@0.18.0/build/engine/o3dv.module.js"],"names":[],"mappings":"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","file":"/npm/online-3d-viewer@0.18.0/build/engine/o3dv.module.js","sourceRoot":"","sourcesContent":["/**\n * Minified by jsDelivr using Terser v5.39.0.\n * Original file: /npm/online-3d-viewer@0.18.0/build/engine/o3dv.module.js\n *\n * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files\n */\n","import * as THREE from 'three';\nimport { TGALoader } from 'three/examples/jsm/loaders/TGALoader.js';\nimport { FBXLoader } from 'three/examples/jsm/loaders/FBXLoader.js';\nimport { ColladaLoader } from 'three/examples/jsm/loaders/ColladaLoader.js';\nimport { VRMLLoader } from 'three/examples/jsm/loaders/VRMLLoader.js';\nimport { ThreeMFLoader } from 'three/examples/jsm/loaders/3MFLoader.js';\nimport { AMFLoader } from 'three/examples/jsm/loaders/AMFLoader.js';\nimport * as fflate from 'fflate';\nimport { SVGLoader } from 'three/examples/jsm/loaders/SVGLoader.js';\n\nfunction IsDefined (val)\r\n{\r\n    return val !== undefined && val !== null;\r\n}\r\n\r\nfunction ValueOrDefault (val, def)\r\n{\r\n    if (val === undefined || val === null) {\r\n        return def;\r\n    }\r\n    return val;\r\n}\r\n\r\nfunction CopyObjectAttributes (src, dest)\r\n{\r\n    if (!IsDefined (src)) {\r\n        return;\r\n    }\r\n    for (let attribute of Object.keys (src)) {\r\n        if (IsDefined (src[attribute])) {\r\n            dest[attribute] = src[attribute];\r\n        }\r\n    }\r\n}\r\n\r\nfunction IsObjectEmpty (obj)\r\n{\r\n    return Object.keys (obj).length === 0;\r\n}\r\n\r\nfunction FormatString (template, ...args)\r\n{\r\n    return template.replace (/{([0-9]+)}/g, (match, index) => {\r\n        return args[index] === undefined ? match : args[index];\r\n    });\r\n}\r\n\r\nfunction EscapeHtmlChars (str)\r\n{\r\n    return str.replace (/</g, '&lt;').replace (/>/g, '&gt;');\r\n}\n\nclass EventNotifier\r\n{\r\n    constructor ()\r\n    {\r\n        this.eventListeners = new Map ();\r\n    }\r\n\r\n    AddEventListener (eventId, listener)\r\n    {\r\n        if (!this.eventListeners.has (eventId)) {\r\n            this.eventListeners.set (eventId, []);\r\n        }\r\n        let listeners = this.eventListeners.get (eventId);\r\n        listeners.push (listener);\r\n    }\r\n\r\n    HasEventListener (eventId)\r\n    {\r\n        return this.eventListeners.has (eventId);\r\n    }\r\n\r\n    GetEventNotifier (eventId)\r\n    {\r\n        return () => {\r\n            this.NotifyEventListeners (eventId);\r\n        };\r\n    }\r\n\r\n    NotifyEventListeners (eventId, ...args)\r\n    {\r\n        if (!this.eventListeners.has (eventId)) {\r\n            return;\r\n        }\r\n        let listeners = this.eventListeners.get (eventId);\r\n        for (let listener of listeners) {\r\n            listener (...args);\r\n        }\r\n    }\r\n}\n\nlet gLocalizedStrings = null;\r\nlet gLanguageCode = null;\r\n\r\nfunction SetLocalizedStrings (localizedStrings)\r\n{\r\n    gLocalizedStrings = localizedStrings;\r\n}\r\n\r\nfunction SetLanguageCode (languageCode)\r\n{\r\n    gLanguageCode = languageCode;\r\n}\r\n\r\nfunction Loc (str)\r\n{\r\n    if (gLocalizedStrings === null || gLanguageCode === null) {\r\n        return str;\r\n    }\r\n    if (!gLocalizedStrings[str] || !gLocalizedStrings[str][gLanguageCode]) {\r\n        return str;\r\n    }\r\n    return gLocalizedStrings[str][gLanguageCode];\r\n}\r\n\r\nfunction FLoc (str, ...args)\r\n{\r\n    return FormatString (Loc (str), ...args);\r\n}\n\nclass TaskRunner\r\n{\r\n    constructor ()\r\n    {\r\n        this.count = null;\r\n        this.current = null;\r\n        this.callbacks = null;\r\n    }\r\n\r\n    Run (count, callbacks)\r\n    {\r\n        this.count = count;\r\n        this.current = 0;\r\n        this.callbacks = callbacks;\r\n        if (count === 0) {\r\n            this.TaskReady ();\r\n        } else {\r\n            this.RunOnce ();\r\n        }\r\n    }\r\n\r\n    RunBatch (count, batchCount, callbacks)\r\n    {\r\n        let stepCount = 0;\r\n        if (count > 0) {\r\n            stepCount = parseInt ((count - 1) / batchCount, 10) + 1;\r\n        }\r\n        this.Run (stepCount, {\r\n            runTask : (index, ready) => {\r\n                const firstIndex = index * batchCount;\r\n                const lastIndex = Math.min ((index + 1) * batchCount, count) - 1;\r\n                callbacks.runTask (firstIndex, lastIndex, ready);\r\n            },\r\n            onReady : callbacks.onReady\r\n        });\r\n    }\r\n\r\n    RunOnce ()\r\n    {\r\n        setTimeout (() => {\r\n            this.callbacks.runTask (this.current, this.TaskReady.bind (this));\r\n        }, 0);\r\n    }\r\n\r\n    TaskReady ()\r\n    {\r\n        this.current += 1;\r\n        if (this.current < this.count) {\r\n            this.RunOnce ();\r\n        } else {\r\n            if (this.callbacks.onReady) {\r\n                this.callbacks.onReady ();\r\n            }\r\n        }\r\n    }\r\n}\r\n\r\nfunction RunTaskAsync (task)\r\n{\r\n    setTimeout (() => {\r\n        task ();\r\n    }, 10);\r\n}\r\n\r\nfunction RunTasks (count, callbacks)\r\n{\r\n    let taskRunner = new TaskRunner ();\r\n    taskRunner.Run (count, callbacks);\r\n}\r\n\r\nfunction RunTasksBatch (count, batchCount, callbacks)\r\n{\r\n    let taskRunner = new TaskRunner ();\r\n    taskRunner.RunBatch (count, batchCount, callbacks);\r\n}\r\n\r\nfunction WaitWhile (expression)\r\n{\r\n    function Waiter (expression)\r\n    {\r\n        if (expression ()) {\r\n            setTimeout (() => {\r\n                Waiter (expression);\r\n            }, 10);\r\n        }\r\n    }\r\n    Waiter (expression);\r\n}\n\nconst Eps = 0.00000001;\r\nconst BigEps = 0.0001;\r\nconst RadDeg = 57.29577951308232;\r\nconst DegRad = 0.017453292519943;\r\n\r\nfunction IsZero (a)\r\n{\r\n\treturn Math.abs (a) < Eps;\r\n}\r\n\r\nfunction IsLower (a, b)\r\n{\r\n\treturn b - a > Eps;\r\n}\r\n\r\nfunction IsGreater (a, b)\r\n{\r\n\treturn a - b > Eps;\r\n}\r\n\r\nfunction IsLowerOrEqual (a, b)\r\n{\r\n\treturn b - a > -1e-8;\r\n}\r\n\r\nfunction IsGreaterOrEqual (a, b)\r\n{\r\n\treturn a - b > -1e-8;\r\n}\r\n\r\nfunction IsEqual (a, b)\r\n{\r\n\treturn Math.abs (b - a) < Eps;\r\n}\r\n\r\nfunction IsEqualEps (a, b, eps)\r\n{\r\n\treturn Math.abs (b - a) < eps;\r\n}\r\n\r\nfunction IsPositive (a)\r\n{\r\n\treturn a > Eps;\r\n}\r\n\r\nfunction IsNegative (a)\r\n{\r\n\treturn a < -1e-8;\r\n}\r\n\r\nconst Direction =\r\n{\r\n\tX : 1,\r\n\tY : 2,\r\n\tZ : 3\r\n};\n\nclass Coord2D\r\n{\r\n\tconstructor (x, y)\r\n\t{\r\n\t\tthis.x = x;\r\n\t\tthis.y = y;\r\n\t}\r\n\r\n\tClone ()\r\n\t{\r\n\t\treturn new Coord2D (this.x, this.y);\r\n\t}\r\n}\r\n\r\nfunction CoordIsEqual2D (a, b)\r\n{\r\n\treturn IsEqual (a.x, b.x) && IsEqual (a.y, b.y);\r\n}\r\n\r\nfunction AddCoord2D (a, b)\r\n{\r\n\treturn new Coord2D (a.x + b.x, a.y + b.y);\r\n}\r\n\r\nfunction SubCoord2D (a, b)\r\n{\r\n\treturn new Coord2D (a.x - b.x, a.y - b.y);\r\n}\r\n\r\nfunction CoordDistance2D (a, b)\r\n{\r\n\treturn Math.sqrt ((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));\r\n}\r\n\r\nfunction DotVector2D (a, b)\r\n{\r\n\treturn a.x * b.x + a.y * b.y;\r\n}\n\n/**\r\n * RGB color object. Components are numbers in the range of 0..255.\r\n */\r\nclass RGBColor\r\n{\r\n    /**\r\n     * @param {number} r Red component.\r\n     * @param {number} g Green component.\r\n     * @param {number} b Blue component.\r\n     */\r\n    constructor (r, g, b)\r\n    {\r\n        this.r = r;\r\n        this.g = g;\r\n        this.b = b;\r\n    }\r\n\r\n    /**\r\n     * Sets the value of all components.\r\n     * @param {number} r Red component.\r\n     * @param {number} g Green component.\r\n     * @param {number} b Blue component.\r\n     */\r\n    Set (r, g, b)\r\n    {\r\n        this.r = r;\r\n        this.g = g;\r\n        this.b = b;\r\n    }\r\n\r\n    /**\r\n     * Creates a clone of the object.\r\n     * @returns {RGBColor}\r\n     */\r\n    Clone ()\r\n    {\r\n        return new RGBColor (this.r, this.g, this.b);\r\n    }\r\n}\r\n\r\n/**\r\n * RGBA color object. Components are numbers in the range of 0..255.\r\n */\r\nclass RGBAColor\r\n{\r\n    /**\r\n     * @param {number} r Red component.\r\n     * @param {number} g Green component.\r\n     * @param {number} b Blue component.\r\n     * @param {number} a Alpha component.\r\n     */\r\n    constructor (r, g, b, a)\r\n    {\r\n        this.r = r;\r\n        this.g = g;\r\n        this.b = b;\r\n        this.a = a;\r\n    }\r\n\r\n    /**\r\n     * Sets the value of all components.\r\n     * @param {number} r Red component.\r\n     * @param {number} g Green component.\r\n     * @param {number} b Blue component.\r\n     * @param {number} a Alpha component.\r\n     */\r\n    Set (r, g, b, a)\r\n    {\r\n        this.r = r;\r\n        this.g = g;\r\n        this.b = b;\r\n        this.a = a;\r\n    }\r\n\r\n    /**\r\n     * Creates a clone of the object.\r\n     * @returns {RGBAColor}\r\n     */\r\n    Clone ()\r\n    {\r\n        return new RGBAColor (this.r, this.g, this.b, this.a);\r\n    }\r\n}\r\n\r\nfunction ColorComponentFromFloat (component)\r\n{\r\n    return parseInt (Math.round (component * 255.0), 10);\r\n}\r\n\r\nfunction ColorComponentToFloat (component)\r\n{\r\n    return component / 255.0;\r\n}\r\n\r\nfunction RGBColorFromFloatComponents (r, g, b)\r\n{\r\n    return new RGBColor (\r\n        ColorComponentFromFloat (r),\r\n        ColorComponentFromFloat (g),\r\n        ColorComponentFromFloat (b)\r\n    );\r\n}\r\n\r\nfunction SRGBToLinear (component)\r\n{\r\n    if (component < 0.04045) {\r\n        return component * 0.0773993808;\r\n    } else {\r\n        return Math.pow (component * 0.9478672986 + 0.0521327014, 2.4);\r\n    }\r\n}\r\n\r\nfunction LinearToSRGB (component)\r\n{\r\n    if (component < 0.0031308) {\r\n        return component * 12.92;\r\n    } else {\r\n        return 1.055 * (Math.pow (component, 0.41666)) - 0.055;\r\n    }\r\n}\r\n\r\nfunction IntegerToHexString (intVal)\r\n{\r\n    let result = parseInt (intVal, 10).toString (16);\r\n    while (result.length < 2) {\r\n        result = '0' + result;\r\n    }\r\n    return result;\r\n}\r\n\r\nfunction RGBColorToHexString (color)\r\n{\r\n    let r = IntegerToHexString (color.r);\r\n    let g = IntegerToHexString (color.g);\r\n    let b = IntegerToHexString (color.b);\r\n    return r + g + b;\r\n}\r\n\r\nfunction RGBAColorToHexString (color)\r\n{\r\n    let r = IntegerToHexString (color.r);\r\n    let g = IntegerToHexString (color.g);\r\n    let b = IntegerToHexString (color.b);\r\n    let a = IntegerToHexString (color.a);\r\n    return r + g + b + a;\r\n}\r\n\r\nfunction HexStringToRGBColor (hexString)\r\n{\r\n    if (hexString.length !== 6) {\r\n        return null;\r\n    }\r\n\r\n    let r = parseInt (hexString.substring (0, 2), 16);\r\n    let g = parseInt (hexString.substring (2, 4), 16);\r\n    let b = parseInt (hexString.substring (4, 6), 16);\r\n    return new RGBColor (r, g, b);\r\n}\r\n\r\nfunction HexStringToRGBAColor (hexString)\r\n{\r\n    if (hexString.length !== 6 && hexString.length !== 8) {\r\n        return null;\r\n    }\r\n\r\n    let r = parseInt (hexString.substring (0, 2), 16);\r\n    let g = parseInt (hexString.substring (2, 4), 16);\r\n    let b = parseInt (hexString.substring (4, 6), 16);\r\n    let a = 255;\r\n    if (hexString.length === 8) {\r\n        a = parseInt (hexString.substring (6, 8), 16);\r\n    }\r\n    return new RGBAColor (r, g, b, a);\r\n}\r\n\r\nfunction ArrayToRGBColor (arr)\r\n{\r\n\treturn new RGBColor (arr[0], arr[1], arr[2]);\r\n}\r\n\r\nfunction RGBColorIsEqual (a, b)\r\n{\r\n\treturn a.r === b.r && a.g === b.g && a.b === b.b;\r\n}\n\nclass TextureMap\r\n{\r\n    constructor ()\r\n    {\r\n        this.name = null;\r\n        this.mimeType = null;\r\n        this.buffer = null;\r\n        this.offset = new Coord2D (0.0, 0.0);\r\n        this.scale = new Coord2D (1.0, 1.0);\r\n        this.rotation = 0.0; // radians\r\n    }\r\n\r\n    IsValid ()\r\n    {\r\n        return this.name !== null && this.buffer !== null;\r\n    }\r\n\r\n    HasTransformation ()\r\n    {\r\n        if (!CoordIsEqual2D (this.offset, new Coord2D (0.0, 0.0))) {\r\n            return true;\r\n        }\r\n        if (!CoordIsEqual2D (this.scale, new Coord2D (1.0, 1.0))) {\r\n            return true;\r\n        }\r\n        if (!IsEqual (this.rotation, 0.0)) {\r\n            return true;\r\n        }\r\n        return false;\r\n    }\r\n\r\n    IsEqual (rhs)\r\n    {\r\n        if (this.name !== rhs.name) {\r\n            return false;\r\n        }\r\n        if (this.mimeType !== rhs.mimeType) {\r\n            return false;\r\n        }\r\n        if (!CoordIsEqual2D (this.offset, rhs.offset)) {\r\n            return false;\r\n        }\r\n        if (!CoordIsEqual2D (this.scale, rhs.scale)) {\r\n            return false;\r\n        }\r\n        if (!IsEqual (this.rotation, rhs.rotation)) {\r\n            return false;\r\n        }\r\n        return true;\r\n    }\r\n}\r\n\r\nfunction TextureMapIsEqual (aTex, bTex)\r\n{\r\n    if (aTex === null && bTex === null) {\r\n        return true;\r\n    } else if (aTex === null || bTex === null) {\r\n        return false;\r\n    }\r\n    return aTex.IsEqual (bTex);\r\n}\r\n\r\nconst MaterialType =\r\n{\r\n    Phong : 1,\r\n    Physical : 2\r\n};\r\n\r\nconst MaterialSource =\r\n{\r\n    Model : 1,\r\n    DefaultFace : 2,\r\n    DefaultLine : 3\r\n};\r\n\r\nclass MaterialBase\r\n{\r\n    constructor (type)\r\n    {\r\n        this.type = type;\r\n        this.source = MaterialSource.Model;\r\n\r\n        this.name = '';\r\n        this.color = new RGBColor (0, 0, 0);\r\n\r\n        this.vertexColors = false;\r\n    }\r\n\r\n    IsEqual (rhs)\r\n    {\r\n        if (this.type !== rhs.type) {\r\n            return false;\r\n        }\r\n        if (this.source !== rhs.source) {\r\n            return false;\r\n        }\r\n        if (this.name !== rhs.name) {\r\n            return false;\r\n        }\r\n        if (!RGBColorIsEqual (this.color, rhs.color)) {\r\n            return false;\r\n        }\r\n        if (this.vertexColors !== rhs.vertexColors) {\r\n            return false;\r\n        }\r\n        return true;\r\n    }\r\n}\r\n\r\nclass FaceMaterial extends MaterialBase\r\n{\r\n    constructor (type)\r\n    {\r\n        super (type);\r\n\r\n        this.emissive = new RGBColor (0, 0, 0);\r\n\r\n        this.opacity = 1.0; // 0.0 .. 1.0\r\n        this.transparent = false;\r\n\r\n        this.diffuseMap = null;\r\n        this.bumpMap = null;\r\n        this.normalMap = null;\r\n        this.emissiveMap = null;\r\n\r\n        this.alphaTest = 0.0; // 0.0 .. 1.0\r\n        this.multiplyDiffuseMap = false;\r\n    }\r\n\r\n    IsEqual (rhs)\r\n    {\r\n        if (!super.IsEqual (rhs)) {\r\n            return false;\r\n        }\r\n        if (!RGBColorIsEqual (this.emissive, rhs.emissive)) {\r\n            return false;\r\n        }\r\n        if (!IsEqual (this.opacity, rhs.opacity)) {\r\n            return false;\r\n        }\r\n        if (this.transparent !== rhs.transparent) {\r\n            return false;\r\n        }\r\n        if (!TextureMapIsEqual (this.diffuseMap, rhs.diffuseMap)) {\r\n            return false;\r\n        }\r\n        if (!TextureMapIsEqual (this.bumpMap, rhs.bumpMap)) {\r\n            return false;\r\n        }\r\n        if (!TextureMapIsEqual (this.normalMap, rhs.normalMap)) {\r\n            return false;\r\n        }\r\n        if (!TextureMapIsEqual (this.emissiveMap, rhs.emissiveMap)) {\r\n            return false;\r\n        }\r\n        if (!IsEqual (this.alphaTest, rhs.alphaTest)) {\r\n            return false;\r\n        }\r\n        if (this.multiplyDiffuseMap !== rhs.multiplyDiffuseMap) {\r\n            return false;\r\n        }\r\n        return true;\r\n    }\r\n}\r\n\r\nclass PhongMaterial extends FaceMaterial\r\n{\r\n    constructor ()\r\n    {\r\n        super (MaterialType.Phong);\r\n\r\n        this.ambient = new RGBColor (0, 0, 0);\r\n        this.specular = new RGBColor (0, 0, 0);\r\n        this.shininess = 0.0; // 0.0 .. 1.0\r\n        this.specularMap = null;\r\n    }\r\n\r\n    IsEqual (rhs)\r\n    {\r\n        if (!super.IsEqual (rhs)) {\r\n            return false;\r\n        }\r\n        if (!RGBColorIsEqual (this.ambient, rhs.ambient)) {\r\n            return false;\r\n        }\r\n        if (!RGBColorIsEqual (this.specular, rhs.specular)) {\r\n            return false;\r\n        }\r\n        if (!IsEqual (this.shininess, rhs.shininess)) {\r\n            return false;\r\n        }\r\n        if (!TextureMapIsEqual (this.specularMap, rhs.specularMap)) {\r\n            return false;\r\n        }\r\n        return true;\r\n    }\r\n}\r\n\r\nclass PhysicalMaterial extends FaceMaterial\r\n{\r\n    constructor ()\r\n    {\r\n        super (MaterialType.Physical);\r\n\r\n        this.metalness = 0.0; // 0.0 .. 1.0\r\n        this.roughness = 1.0; // 0.0 .. 1.0\r\n        this.metalnessMap = null;\r\n    }\r\n\r\n    IsEqual (rhs)\r\n    {\r\n        if (!super.IsEqual (rhs)) {\r\n            return false;\r\n        }\r\n        if (!IsEqual (this.metalness, rhs.metalness)) {\r\n            return false;\r\n        }\r\n        if (!IsEqual (this.roughness, rhs.roughness)) {\r\n            return false;\r\n        }\r\n        if (!TextureMapIsEqual (this.metalnessMap, rhs.metalnessMap)) {\r\n            return false;\r\n        }\r\n        return true;\r\n    }\r\n}\r\n\r\nfunction TextureIsEqual (a, b)\r\n{\r\n    if (a.name !== b.name) {\r\n        return false;\r\n    }\r\n    if (a.mimeType !== b.mimeType) {\r\n        return false;\r\n    }\r\n    if (!CoordIsEqual2D (a.offset, b.offset)) {\r\n        return false;\r\n    }\r\n    if (!CoordIsEqual2D (a.scale, b.scale)) {\r\n        return false;\r\n    }\r\n    if (!IsEqual (a.rotation, b.rotation)) {\r\n        return false;\r\n    }\r\n    return true;\r\n}\n\nlet loadedExternalLibUrls = new Set ();\r\n\r\nfunction LoadExternalLibraryFromUrl (libraryUrl)\r\n{\r\n    return new Promise ((resolve, reject) => {\r\n        if (loadedExternalLibUrls.has (libraryUrl)) {\r\n            resolve ();\r\n            return;\r\n        }\r\n\r\n        let scriptElement = document.createElement ('script');\r\n        scriptElement.type = 'text/javascript';\r\n        scriptElement.src = libraryUrl;\r\n        scriptElement.onload = () => {\r\n            loadedExternalLibUrls.add (libraryUrl);\r\n            resolve ();\r\n        };\r\n        scriptElement.onerror = () => {\r\n            reject ();\r\n        };\r\n        document.head.appendChild (scriptElement);\r\n    });\r\n}\n\nfunction NameFromLine (line, startIndex, commentChar)\r\n{\r\n\tlet name = line.substring (startIndex);\r\n\tlet commentStart = name.indexOf (commentChar);\r\n\tif (commentStart !== -1) {\r\n\t\tname = name.substring (0, commentStart);\r\n\t}\r\n\treturn name.trim ();\r\n}\r\n\r\nfunction ParametersFromLine (line, commentChar)\r\n{\r\n\tif (commentChar !== null) {\r\n\t\tlet commentStart = line.indexOf (commentChar);\r\n\t\tif (commentStart !== -1) {\r\n\t\t\tline = line.substring (0, commentStart).trim ();\r\n\t\t}\r\n\t}\r\n\treturn line.split (/\\s+/u);\r\n}\r\n\r\nfunction ReadLines (str, onLine)\r\n{\r\n\tfunction LineFound (line, onLine)\r\n\t{\r\n\t\tlet trimmed = line.trim ();\r\n\t\tif (trimmed.length > 0) {\r\n\t\t\tonLine (trimmed);\r\n\t\t}\r\n\t}\r\n\r\n\tlet cursor = 0;\r\n\tlet next = str.indexOf ('\\n', cursor);\r\n\twhile (next !== -1) {\r\n\t\tLineFound (str.substring (cursor, next), onLine);\r\n\t\tcursor = next + 1;\r\n\t\tnext = str.indexOf ('\\n', cursor);\r\n\t}\r\n\tLineFound (str.substring (cursor), onLine);\r\n}\r\n\r\nfunction IsPowerOfTwo (x)\r\n{\r\n\treturn (x & (x - 1)) === 0;\r\n}\r\n\r\nfunction NextPowerOfTwo (x)\r\n{\r\n\tif (IsPowerOfTwo (x)) {\r\n\t\treturn x;\r\n\t}\r\n\tlet npot = Math.pow (2, Math.ceil (Math.log (x) / Math.log (2)));\r\n\treturn parseInt (npot, 10);\r\n}\r\n\r\nfunction UpdateMaterialTransparency (material)\r\n{\r\n\tmaterial.transparent = false;\r\n\tif (IsLower (material.opacity, 1.0)) {\r\n\t\tmaterial.transparent = true;\r\n\t}\r\n}\r\n\r\nclass ColorToMaterialConverter\r\n{\r\n\tconstructor (model)\r\n\t{\r\n\t\tthis.model = model;\r\n\t\tthis.colorToMaterialIndex = new Map ();\r\n\t}\r\n\r\n\tGetMaterialIndex (r, g, b, a)\r\n\t{\r\n\t\tlet colorKey =\r\n\t\t\tIntegerToHexString (r) +\r\n\t\t\tIntegerToHexString (g) +\r\n\t\t\tIntegerToHexString (b);\r\n\t\tlet hasAlpha = (a !== undefined && a !== null);\r\n\t\tif (hasAlpha) {\r\n\t\t\tcolorKey += IntegerToHexString (a);\r\n\t\t}\r\n\r\n\t\tif (this.colorToMaterialIndex.has (colorKey)) {\r\n\t\t\treturn this.colorToMaterialIndex.get (colorKey);\r\n\t\t} else {\r\n            let material = new PhongMaterial ();\r\n            material.name = colorKey.toUpperCase ();\r\n            material.color = new RGBColor (r, g, b);\r\n            if (hasAlpha && a < 255) {\r\n                material.opacity = a / 255.0;\r\n                UpdateMaterialTransparency (material);\r\n            }\r\n            let materialIndex = this.model.AddMaterial (material);\r\n            this.colorToMaterialIndex.set (colorKey, materialIndex);\r\n            return materialIndex;\r\n\t\t}\r\n\t}\r\n}\r\n\r\nlet occtWorkerUrl = null;\r\n\r\nfunction CreateOcctWorker (worker)\r\n{\r\n\treturn new Promise ((resolve, reject) => {\r\n\t\tif (occtWorkerUrl !== null) {\r\n\t\t\tresolve (new Worker (occtWorkerUrl));\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tlet baseUrl = 'https://cdn.jsdelivr.net/npm/occt-import-js@0.0.22/dist/';\r\n\t\tfetch (baseUrl + 'occt-import-js-worker.js')\r\n\t\t\t.then ((response) => {\r\n\t\t\t\tif (!response.ok) {\r\n\t\t\t\t\treturn reject ();\r\n\t\t\t\t}\r\n\t\t\t\treturn response.text ();\r\n\t\t\t})\r\n\t\t\t.then ((workerScript) => {\r\n\t\t\t\tworkerScript = workerScript.replace ('occt-import-js.js', baseUrl + 'occt-import-js.js');\r\n\t\t\t\tworkerScript = workerScript.replace ('return path', 'return \\'' + baseUrl + 'occt-import-js.wasm\\'');\r\n\t\t\t\tlet blob = new Blob ([workerScript], { type : 'text/javascript' });\r\n\t\t\t\tocctWorkerUrl = URL.createObjectURL (blob);\r\n\t\t\t\treturn resolve (new Worker (occtWorkerUrl));\r\n\t\t\t})\r\n\t\t\t.catch (reject);\r\n\t});\r\n}\r\n\r\nfunction LoadExternalLibrary (libraryName)\r\n{\r\n\tif (libraryName === 'rhino3dm') {\r\n\t\treturn LoadExternalLibraryFromUrl ('https://cdn.jsdelivr.net/npm/rhino3dm@8.17.0/rhino3dm.min.js');\r\n\t} else if (libraryName === 'webifc') {\r\n\t\treturn LoadExternalLibraryFromUrl ('https://cdn.jsdelivr.net/npm/web-ifc@0.0.68/web-ifc-api-iife.js');\r\n\t} else if (libraryName === 'draco3d') {\r\n\t\treturn LoadExternalLibraryFromUrl ('https://cdn.jsdelivr.net/npm/draco3d@1.5.7/draco_decoder_nodejs.min.js');\r\n\t} else {\r\n\t\treturn null;\r\n\t}\r\n}\n\n/**\r\n * File source identifier for import.\r\n * @enum\r\n */\r\nconst FileSource =\r\n{\r\n\t/** The file is provided by a URL. */\r\n    Url : 1,\r\n\t/** The file is provided by a {@link File} object. */\r\n    File : 2,\r\n\t/** Used internally if a file is originated by a compressed archive. */\r\n\tDecompressed : 3\r\n};\r\n\r\nconst FileFormat =\r\n{\r\n    Text : 1,\r\n    Binary : 2\r\n};\r\n\r\nfunction GetFileName (filePath)\r\n{\r\n\tlet fileName = filePath;\r\n\r\n\tlet firstParamIndex = fileName.indexOf ('?');\r\n\tif (firstParamIndex !== -1) {\r\n\t\tfileName = fileName.substring (0, firstParamIndex);\r\n\t}\r\n\r\n\tlet firstSeparator = fileName.lastIndexOf ('/');\r\n\tif (firstSeparator === -1) {\r\n\t\tfirstSeparator = fileName.lastIndexOf ('\\\\');\r\n\t}\r\n\tif (firstSeparator !== -1) {\r\n\t\tfileName = fileName.substring (firstSeparator + 1);\r\n\t}\r\n\r\n\treturn decodeURI (fileName);\r\n}\r\n\r\nfunction GetFileExtension (filePath)\r\n{\r\n\tlet fileName = GetFileName (filePath);\r\n\tlet firstPoint = fileName.lastIndexOf ('.');\r\n\tif (firstPoint === -1) {\r\n\t\treturn '';\r\n\t}\r\n\tlet extension = fileName.substring (firstPoint + 1);\r\n\treturn extension.toLowerCase ();\r\n}\r\n\r\nfunction RequestUrl (url, onProgress)\r\n{\r\n\treturn new Promise ((resolve, reject) => {\r\n\t\tlet request = new XMLHttpRequest ();\r\n\t\trequest.open ('GET', url, true);\r\n\r\n\t\trequest.onprogress = (event) => {\r\n\t\t\tonProgress (event.loaded, event.total);\r\n\t\t};\r\n\r\n\t\trequest.onload = () => {\r\n\t\t\tif (request.status === 200) {\r\n\t\t\t\tresolve (request.response);\r\n\t\t\t} else {\r\n\t\t\t\treject ();\r\n\t\t\t}\r\n\t\t};\r\n\r\n\t\trequest.onerror = () => {\r\n\t\t\treject ();\r\n\t\t};\r\n\r\n\t\trequest.responseType = 'arraybuffer';\r\n\t\trequest.send (null);\r\n\t});\r\n}\r\n\r\nfunction ReadFile (file, onProgress)\r\n{\r\n\treturn new Promise ((resolve, reject) => {\r\n\t\tlet reader = new FileReader ();\r\n\r\n\t\treader.onprogress = (event) => {\r\n\t\t\tonProgress (event.loaded, event.total);\r\n\t\t};\r\n\r\n\t\treader.onloadend = (event) => {\r\n\t\t\tif (event.target.readyState === FileReader.DONE) {\r\n\t\t\t\tresolve (event.target.result);\r\n\t\t\t}\r\n\t\t};\r\n\r\n\t\treader.onerror = () => {\r\n\t\t\treject ();\r\n\t\t};\r\n\r\n\t\treader.readAsArrayBuffer (file);\r\n\t});\r\n}\r\n\r\nfunction TransformFileHostUrls (urls)\r\n{\r\n    for (let i = 0; i < urls.length; i++) {\r\n        let url = urls[i];\r\n        if (url.indexOf ('www.dropbox.com') !== -1) {\r\n            url = url.replace ('www.dropbox.com', 'dl.dropbox.com');\r\n            urls[i] = url;\r\n        } else if (url.indexOf ('github.com') !== -1) {\r\n            url = url.replace ('github.com', 'raw.githubusercontent.com');\r\n            url = url.replace ('/blob', '');\r\n            urls[i] = url;\r\n        }\r\n    }\r\n}\r\n\r\nfunction IsUrl (str)\r\n{\r\n\tconst regex = /^https?:\\/\\/\\S+$/g;\r\n\tconst match = str.match (regex);\r\n\treturn match !== null;\r\n}\n\nclass Coord3D\r\n{\r\n\tconstructor (x, y, z)\r\n\t{\r\n\t\tthis.x = x;\r\n\t\tthis.y = y;\r\n\t\tthis.z = z;\r\n\t}\r\n\r\n\tLength ()\r\n\t{\r\n\t\treturn Math.sqrt (this.x * this.x + this.y * this.y + this.z * this.z);\r\n\t}\r\n\r\n\tMultiplyScalar (scalar)\r\n\t{\r\n\t\tthis.x *= scalar;\r\n\t\tthis.y *= scalar;\r\n\t\tthis.z *= scalar;\r\n\t\treturn this;\r\n\t}\r\n\r\n\tNormalize ()\r\n\t{\r\n\t\tlet length = this.Length ();\r\n\t\tif (length > 0.0) {\r\n\t\t\tthis.MultiplyScalar (1.0 / length);\r\n\t\t}\r\n\t\treturn this;\r\n\t}\r\n\r\n\tOffset (direction, distance)\r\n\t{\r\n\t\tlet normal = direction.Clone ().Normalize ();\r\n\t\tthis.x += normal.x * distance;\r\n\t\tthis.y += normal.y * distance;\r\n\t\tthis.z += normal.z * distance;\r\n\t\treturn this;\r\n\t}\r\n\r\n\tRotate (axis, angle, origo)\r\n\t{\r\n\t\tlet normal = axis.Clone ().Normalize ();\r\n\r\n\t\tlet u = normal.x;\r\n\t\tlet v = normal.y;\r\n\t\tlet w = normal.z;\r\n\r\n\t\tlet x = this.x - origo.x;\r\n\t\tlet y = this.y - origo.y;\r\n\t\tlet z = this.z - origo.z;\r\n\r\n\t\tlet si = Math.sin (angle);\r\n\t\tlet co = Math.cos (angle);\r\n\t\tthis.x = - u * (- u * x - v * y - w * z) * (1.0 - co) + x * co + (- w * y + v * z) * si;\r\n\t\tthis.y = - v * (- u * x - v * y - w * z) * (1.0 - co) + y * co + (w * x - u * z) * si;\r\n\t\tthis.z = - w * (- u * x - v * y - w * z) * (1.0 - co) + z * co + (- v * x + u * y) * si;\r\n\r\n\t\tthis.x += origo.x;\r\n\t\tthis.y += origo.y;\r\n\t\tthis.z += origo.z;\r\n\t\treturn this;\r\n\t}\r\n\r\n\tClone ()\r\n\t{\r\n\t\treturn new Coord3D (this.x, this.y, this.z);\r\n\t}\r\n}\r\n\r\nfunction CoordIsEqual3D (a, b)\r\n{\r\n\treturn IsEqual (a.x, b.x) && IsEqual (a.y, b.y) && IsEqual (a.z, b.z);\r\n}\r\n\r\nfunction AddCoord3D (a, b)\r\n{\r\n\treturn new Coord3D (a.x + b.x, a.y + b.y, a.z + b.z);\r\n}\r\n\r\nfunction SubCoord3D (a, b)\r\n{\r\n\treturn new Coord3D (a.x - b.x, a.y - b.y, a.z - b.z);\r\n}\r\n\r\nfunction CoordDistance3D (a, b)\r\n{\r\n\treturn Math.sqrt ((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y) + (a.z - b.z) * (a.z - b.z));\r\n}\r\n\r\nfunction DotVector3D (a, b)\r\n{\r\n\treturn a.x * b.x + a.y * b.y + a.z * b.z;\r\n}\r\n\r\nfunction VectorAngle3D (a, b)\r\n{\r\n\tlet aDirection = a.Clone ().Normalize ();\r\n\tlet bDirection = b.Clone ().Normalize ();\r\n\tif (CoordIsEqual3D (aDirection, bDirection)) {\r\n\t\treturn 0.0;\r\n\t}\r\n\tlet product = DotVector3D (aDirection, bDirection);\r\n\treturn Math.acos (product);\r\n}\r\n\r\nfunction CrossVector3D (a, b)\r\n{\r\n\tlet result = new Coord3D (0.0, 0.0, 0.0);\r\n\tresult.x = a.y * b.z - a.z * b.y;\r\n\tresult.y = a.z * b.x - a.x * b.z;\r\n\tresult.z = a.x * b.y - a.y * b.x;\r\n\treturn result;\r\n}\r\n\r\nfunction VectorLength3D (x, y, z)\r\n{\r\n\treturn Math.sqrt (x * x + y * y + z * z);\r\n}\r\n\r\nfunction ArrayToCoord3D (arr)\r\n{\r\n\treturn new Coord3D (arr[0], arr[1], arr[2]);\r\n}\n\nclass MeshPrimitiveBuffer\r\n{\r\n    constructor ()\r\n    {\r\n        this.indices = [];\r\n        this.vertices = [];\r\n        this.colors = [];\r\n        this.normals = [];\r\n        this.uvs = [];\r\n        this.material = null;\r\n    }\r\n\r\n    GetBounds ()\r\n    {\r\n        let min = [Infinity, Infinity, Infinity];\r\n        let max = [-Infinity, -Infinity, -Infinity];\r\n        for (let i = 0; i < this.vertices.length / 3; i++) {\r\n            for (let j = 0; j < 3; j++) {\r\n                min[j] = Math.min (min[j], this.vertices[i * 3 + j]);\r\n                max[j] = Math.max (max[j], this.vertices[i * 3 + j]);\r\n            }\r\n        }\r\n        return {\r\n            min : min,\r\n            max : max\r\n        };\r\n    }\r\n\r\n    GetByteLength (indexTypeSize, numberTypeSize)\r\n    {\r\n        let indexCount = this.indices.length;\r\n        let numberCount = this.vertices.length + this.colors.length + this.normals.length + this.uvs.length;\r\n        return indexCount * indexTypeSize + numberCount * numberTypeSize;\r\n    }\r\n}\r\n\r\nclass MeshBuffer\r\n{\r\n    constructor ()\r\n    {\r\n        this.primitives = [];\r\n    }\r\n\r\n    PrimitiveCount ()\r\n    {\r\n        return this.primitives.length;\r\n    }\r\n\r\n    GetPrimitive (index)\r\n    {\r\n        return this.primitives[index];\r\n    }\r\n\r\n    GetByteLength (indexTypeSize, numberTypeSize)\r\n    {\r\n        let byteLength = 0;\r\n        for (let i = 0; i < this.primitives.length; i++) {\r\n            let primitive = this.primitives[i];\r\n            byteLength += primitive.GetByteLength (indexTypeSize, numberTypeSize);\r\n        }\r\n        return byteLength;\r\n    }\r\n}\r\n\r\nfunction ConvertMeshToMeshBuffer (mesh)\r\n{\r\n    function AddVertexToPrimitiveBuffer (mesh, indices, primitiveBuffer, meshVertexToPrimitiveVertices)\r\n    {\r\n        function GetColorOrDefault (mesh, colorIndex, forceColors)\r\n        {\r\n            if (colorIndex !== null) {\r\n                return mesh.GetVertexColor (colorIndex);\r\n            } else if (forceColors) {\r\n                return new RGBColor (0, 0, 0);\r\n            } else {\r\n                return null;\r\n            }\r\n        }\r\n\r\n        function GetUVOrDefault (mesh, uvIndex, forceUVs)\r\n        {\r\n            if (uvIndex !== null) {\r\n                return mesh.GetTextureUV (uvIndex);\r\n            } else if (forceUVs) {\r\n                return new Coord2D (0.0, 0.0);\r\n            } else {\r\n                return null;\r\n            }\r\n        }\r\n\r\n        function AddVertex (mesh, indices, primitiveBuffer)\r\n        {\r\n            let forceColors = mesh.VertexColorCount () > 0;\r\n            let forceUVs = mesh.TextureUVCount () > 0;\r\n\r\n            let vertex = mesh.GetVertex (indices.vertex);\r\n            let normal = mesh.GetNormal (indices.normal);\r\n\r\n            let primitiveVertexIndex = primitiveBuffer.vertices.length / 3;\r\n            primitiveBuffer.indices.push (primitiveVertexIndex);\r\n            primitiveBuffer.vertices.push (vertex.x, vertex.y, vertex.z);\r\n\r\n            let color = GetColorOrDefault (mesh, indices.color, forceColors);\r\n            if (color !== null) {\r\n                primitiveBuffer.colors.push (color.r / 255.0, color.g / 255.0, color.b / 255.0);\r\n            }\r\n\r\n            primitiveBuffer.normals.push (normal.x, normal.y, normal.z);\r\n\r\n            let uv = GetUVOrDefault (mesh, indices.uv, forceUVs);\r\n            if (uv !== null) {\r\n                primitiveBuffer.uvs.push (uv.x, uv.y);\r\n            }\r\n\r\n            return {\r\n                index : primitiveVertexIndex,\r\n                color : color,\r\n                normal : normal,\r\n                uv : uv\r\n            };\r\n        }\r\n\r\n        function FindMatchingPrimitiveVertex (mesh, primitiveVertices, indices)\r\n        {\r\n            function IsEqualColor (mesh, colorIndex, existingColor)\r\n            {\r\n                if (existingColor === null && colorIndex === null) {\r\n                    return true;\r\n                }\r\n                let color = GetColorOrDefault (mesh, colorIndex, true);\r\n                return RGBColorIsEqual (existingColor, color);\r\n            }\r\n\r\n            function IsEqualNormal (mesh, normalIndex, existingNormal)\r\n            {\r\n                let normal = mesh.GetNormal (normalIndex);\r\n                return CoordIsEqual3D (existingNormal, normal);\r\n            }\r\n\r\n            function IsEqualUV (mesh, uvIndex, existingUv)\r\n            {\r\n                if (existingUv === null && uvIndex === null) {\r\n                    return true;\r\n                }\r\n                let uv = GetUVOrDefault (mesh, uvIndex, true);\r\n                return CoordIsEqual2D (existingUv, uv);\r\n            }\r\n\r\n            for (let i = 0; i < primitiveVertices.length; i++) {\r\n                let primitiveVertex = primitiveVertices[i];\r\n                let equalColor = IsEqualColor (mesh, indices.color, primitiveVertex.color);\r\n                let equalNormal = IsEqualNormal (mesh, indices.normal, primitiveVertex.normal);\r\n                let equalUv = IsEqualUV (mesh, indices.uv, primitiveVertex.uv);\r\n                if (equalColor && equalNormal && equalUv) {\r\n                    return primitiveVertex;\r\n                }\r\n            }\r\n            return null;\r\n        }\r\n\r\n        if (meshVertexToPrimitiveVertices.has (indices.vertex)) {\r\n            let primitiveVertices = meshVertexToPrimitiveVertices.get (indices.vertex);\r\n            let existingPrimitiveVertex = FindMatchingPrimitiveVertex (mesh, primitiveVertices, indices);\r\n            if (existingPrimitiveVertex !== null) {\r\n                primitiveBuffer.indices.push (existingPrimitiveVertex.index);\r\n            } else {\r\n                let primitiveVertex = AddVertex (mesh, indices, primitiveBuffer);\r\n                primitiveVertices.push (primitiveVertex);\r\n            }\r\n        } else {\r\n            let primitiveVertex = AddVertex (mesh, indices, primitiveBuffer);\r\n            meshVertexToPrimitiveVertices.set (indices.vertex, [primitiveVertex]);\r\n        }\r\n    }\r\n\r\n    let meshBuffer = new MeshBuffer ();\r\n\r\n    let triangleCount = mesh.TriangleCount ();\r\n    if (triangleCount === 0) {\r\n        return null;\r\n    }\r\n\r\n    let triangleIndices = [];\r\n    for (let i = 0; i < triangleCount; i++) {\r\n        triangleIndices.push (i);\r\n    }\r\n    triangleIndices.sort ((a, b) => {\r\n        let aTriangle = mesh.GetTriangle (a);\r\n        let bTriangle = mesh.GetTriangle (b);\r\n        return aTriangle.mat - bTriangle.mat;\r\n    });\r\n\r\n    let primitiveBuffer = null;\r\n    let meshVertexToPrimitiveVertices = null;\r\n    for (let i = 0; i < triangleIndices.length; i++) {\r\n        let triangleIndex = triangleIndices[i];\r\n        let triangle = mesh.GetTriangle (triangleIndex);\r\n        if (primitiveBuffer === null || primitiveBuffer.material !== triangle.mat) {\r\n            primitiveBuffer = new MeshPrimitiveBuffer ();\r\n            primitiveBuffer.material = triangle.mat;\r\n            meshVertexToPrimitiveVertices = new Map ();\r\n            meshBuffer.primitives.push (primitiveBuffer);\r\n        }\r\n        let v0Indices = {\r\n            vertex : triangle.v0,\r\n            color : triangle.c0,\r\n            normal : triangle.n0,\r\n            uv : triangle.u0\r\n        };\r\n        let v1Indices = {\r\n            vertex : triangle.v1,\r\n            color : triangle.c1,\r\n            normal : triangle.n1,\r\n            uv : triangle.u1\r\n        };\r\n        let v2Indices = {\r\n            vertex : triangle.v2,\r\n            color : triangle.c2,\r\n            normal : triangle.n2,\r\n            uv : triangle.u2\r\n        };\r\n\r\n        AddVertexToPrimitiveBuffer (mesh, v0Indices, primitiveBuffer, meshVertexToPrimitiveVertices);\r\n        AddVertexToPrimitiveBuffer (mesh, v1Indices, primitiveBuffer, meshVertexToPrimitiveVertices);\r\n        AddVertexToPrimitiveBuffer (mesh, v2Indices, primitiveBuffer, meshVertexToPrimitiveVertices);\r\n    }\r\n\r\n    return meshBuffer;\r\n}\n\nfunction ArrayBufferToUtf8String (buffer)\r\n{\r\n\tlet decoder = new TextDecoder ('utf-8');\r\n\treturn decoder.decode (buffer);\r\n}\r\n\r\nfunction ArrayBufferToAsciiString (buffer)\r\n{\r\n\tlet text = '';\r\n\tlet bufferView = new Uint8Array (buffer);\r\n\tfor (let i = 0; i < bufferView.byteLength; i++) {\r\n\t\ttext += String.fromCharCode (bufferView[i]);\r\n\t}\r\n\treturn text;\r\n}\r\n\r\nfunction AsciiStringToArrayBuffer (str)\r\n{\r\n\tlet buffer = new ArrayBuffer (str.length);\r\n\tlet bufferView = new Uint8Array (buffer);\r\n\tfor (let i = 0; i < str.length; i++) {\r\n\t\tbufferView[i] = str.charCodeAt (i);\r\n\t}\r\n\treturn buffer;\r\n}\r\n\r\nfunction Utf8StringToArrayBuffer (str)\r\n{\r\n\tlet encoder = new TextEncoder ();\r\n\tlet uint8Array = encoder.encode (str);\r\n\treturn uint8Array.buffer;\r\n}\r\n\r\nfunction Base64DataURIToArrayBuffer (uri)\r\n{\r\n\tlet dataPrefix = 'data:';\r\n\tif (!uri.startsWith (dataPrefix)) {\r\n\t\treturn null;\r\n\t}\r\n\r\n\tlet mimeSeparator = uri.indexOf (';');\r\n\tif (mimeSeparator === -1) {\r\n\t\treturn null;\r\n\t}\r\n\r\n\tlet bufferSeparator = uri.indexOf (',');\r\n\tif (bufferSeparator === -1) {\r\n\t\treturn null;\r\n\t}\r\n\r\n\tlet mimeType = uri.substring (dataPrefix.length, dataPrefix.length + mimeSeparator - 5);\r\n\tlet base64String = atob (uri.substring (bufferSeparator + 1));\r\n\tlet buffer = new ArrayBuffer (base64String.length);\r\n\tlet bufferView = new Uint8Array (buffer);\r\n\tfor (let i = 0; i < base64String.length; i++) {\r\n\t\tbufferView[i] = base64String.charCodeAt (i);\r\n\t}\r\n\r\n\treturn {\r\n\t\tmimeType : mimeType,\r\n\t\tbuffer : buffer\r\n\t};\r\n}\r\n\r\nfunction GetFileExtensionFromMimeType (mimeType)\r\n{\r\n\tif (mimeType === undefined || mimeType === null) {\r\n\t\treturn '';\r\n\t}\r\n\tlet mimeParts = mimeType.split ('/');\r\n\tif (mimeParts.length === 0) {\r\n\t\treturn '';\r\n\t}\r\n\treturn mimeParts[mimeParts.length - 1];\r\n}\r\n\r\nfunction CreateObjectUrl (content)\r\n{\r\n\tlet blob = new Blob ([content]);\r\n\tlet url = URL.createObjectURL (blob);\r\n\treturn url;\r\n}\r\n\r\nfunction CreateObjectUrlWithMimeType (content, mimeType)\r\n{\r\n\tlet blob = new Blob ([content], { type : mimeType });\r\n\tlet url = URL.createObjectURL (blob);\r\n\treturn url;\r\n}\r\n\r\nfunction RevokeObjectUrl (url)\r\n{\r\n\tURL.revokeObjectURL (url);\r\n}\n\nclass ExportedFile\r\n{\r\n\tconstructor (name)\r\n\t{\r\n\t\tthis.name = name;\r\n\t\tthis.content = null;\r\n\t}\r\n\r\n\tGetName ()\r\n\t{\r\n\t\treturn this.name;\r\n\t}\r\n\r\n\tSetName (name)\r\n\t{\r\n\t\tthis.name = name;\r\n\t}\r\n\r\n\tGetTextContent ()\r\n\t{\r\n\t\tlet text = ArrayBufferToUtf8String (this.content);\r\n\t\treturn text;\r\n\t}\r\n\r\n\tGetBufferContent ()\r\n\t{\r\n\t\treturn this.content;\r\n\t}\r\n\r\n\tSetTextContent (content)\r\n\t{\r\n\t\tlet buffer = Utf8StringToArrayBuffer (content);\r\n\t\tthis.content = buffer;\r\n\t}\r\n\r\n\tSetBufferContent (content)\r\n\t{\r\n\t\tthis.content = content;\r\n\t}\r\n}\r\n\r\nclass ExporterBase\r\n{\r\n    constructor ()\r\n    {\r\n\r\n    }\r\n\r\n    CanExport (format, extension)\r\n    {\r\n        return false;\r\n    }\r\n\r\n\tExport (exporterModel, format, onFinish)\r\n\t{\r\n\t\tlet files = [];\r\n\t\tthis.ExportContent (exporterModel, format, files, () => {\r\n\t\t\tonFinish (files);\r\n\t\t});\r\n\t}\r\n\r\n\tExportContent (exporterModel, format, files, onFinish)\r\n\t{\r\n\r\n\t}\r\n\r\n\tGetExportedMaterialName (originalName)\r\n\t{\r\n\t\treturn this.GetExportedName (originalName, Loc ('Material'));\r\n\t}\r\n\r\n\tGetExportedMeshName (originalName)\r\n\t{\r\n\t\treturn this.GetExportedName (originalName, Loc ('Mesh'));\r\n\t}\r\n\r\n\tGetExportedName (originalName, defaultName)\r\n\t{\r\n\t\tif (originalName.length === 0) {\r\n\t\t\treturn defaultName;\r\n\t\t}\r\n\t\treturn originalName;\r\n\t}\r\n}\n\nclass Exporter3dm extends ExporterBase\r\n{\r\n\tconstructor ()\r\n\t{\r\n\t\tsuper ();\r\n        this.rhino = null;\r\n\t}\r\n\r\n    CanExport (format, extension)\r\n    {\r\n        return format === FileFormat.Binary && extension === '3dm';\r\n    }\r\n\r\n\tExportContent (exporterModel, format, files, onFinish)\r\n\t{\r\n\t\tif (this.rhino === null) {\r\n\t\t\tLoadExternalLibrary ('rhino3dm').then (() => {\r\n                rhino3dm ().then ((rhino) => {\r\n                    this.rhino = rhino;\r\n                    this.ExportRhinoContent (exporterModel, files, onFinish);\r\n                });\r\n            }).catch (() => {\r\n                onFinish ();\r\n            });\r\n\t\t} else {\r\n\t\t\tthis.ExportRhinoContent (exporterModel, files, onFinish);\r\n\t\t}\r\n\t}\r\n\r\n    ExportRhinoContent (exporterModel, files, onFinish)\r\n    {\r\n        function ColorToRhinoColor (color)\r\n        {\r\n            return {\r\n                r : color.r,\r\n                g : color.g,\r\n                b : color.b,\r\n                a : 255\r\n            };\r\n        }\r\n\r\n\t\tlet rhinoFile = new ExportedFile ('model.3dm');\r\n\t\tfiles.push (rhinoFile);\r\n\r\n        let rhinoDoc = new this.rhino.File3dm ();\r\n        exporterModel.EnumerateTransformedMeshInstances ((mesh) => {\r\n            let meshBuffer = ConvertMeshToMeshBuffer (mesh);\r\n            for (let primitiveIndex = 0; primitiveIndex < meshBuffer.PrimitiveCount (); primitiveIndex++) {\r\n                let primitive = meshBuffer.GetPrimitive (primitiveIndex);\r\n                let threeJson = {\r\n                    data : {\r\n                        attributes : {\r\n                            position : {\r\n                                itemSize : 3,\r\n                                type : 'Float32Array',\r\n                                array : primitive.vertices\r\n                            },\r\n                            normal : {\r\n                                itemSize : 3,\r\n                                type : 'Float32Array',\r\n                                array : primitive.normals\r\n                            }\r\n                        },\r\n                        index : {\r\n                            type : 'Uint16Array',\r\n                            array : primitive.indices\r\n                        }\r\n                    }\r\n                };\r\n\r\n                let material = exporterModel.GetMaterial (primitive.material);\r\n                let rhinoMaterial = new this.rhino.Material ();\r\n                rhinoMaterial.name = this.GetExportedMaterialName (material.name);\r\n                if (material.type === MaterialType.Phong) {\r\n                    rhinoMaterial.ambientColor = ColorToRhinoColor (material.ambient);\r\n                    rhinoMaterial.specularColor = ColorToRhinoColor (material.specular);\r\n                }\r\n                rhinoMaterial.diffuseColor = ColorToRhinoColor (material.color);\r\n                rhinoMaterial.transparency = 1.0 - material.opacity;\r\n\r\n                let rhinoMaterialIndex = rhinoDoc.materials ().count;\r\n                rhinoDoc.materials ().add (rhinoMaterial);\r\n\r\n                let rhinoMesh = new this.rhino.Mesh.createFromThreejsJSON (threeJson);\r\n                let rhinoAttributes = new this.rhino.ObjectAttributes ();\r\n                rhinoAttributes.name = this.GetExportedMeshName (mesh.GetName ());\r\n                rhinoAttributes.materialSource = this.rhino.ObjectMaterialSource.MaterialFromObject;\r\n                rhinoAttributes.materialIndex = rhinoMaterialIndex;\r\n                rhinoDoc.objects ().add (rhinoMesh, rhinoAttributes);\r\n            }\r\n        });\r\n\r\n        let writeOptions = new this.rhino.File3dmWriteOptions ();\r\n        writeOptions.version = 6;\r\n        let rhinoDocBuffer = rhinoDoc.toByteArrayOptions (writeOptions);\r\n        rhinoFile.SetBufferContent (rhinoDocBuffer);\r\n\t\tonFinish ();\r\n    }\r\n}\n\nconst PropertyType =\r\n{\r\n    Text : 1,\r\n    Integer : 2,\r\n    Number : 3,\r\n    Boolean : 4,\r\n    Percent : 5,\r\n    Color : 6\r\n};\r\n\r\nclass Property\r\n{\r\n    constructor (type, name, value)\r\n    {\r\n        this.type = type;\r\n        this.name = name;\r\n        this.value = value;\r\n    }\r\n\r\n    Clone ()\r\n    {\r\n        const clonable = (this.type === PropertyType.Color);\r\n        if (clonable) {\r\n            return new Property (this.type, this.name, this.value.Clone ());\r\n        } else {\r\n            return new Property (this.type, this.name, this.value);\r\n        }\r\n    }\r\n}\r\n\r\nclass PropertyGroup\r\n{\r\n    constructor (name)\r\n    {\r\n        this.name = name;\r\n        this.properties = [];\r\n    }\r\n\r\n    PropertyCount ()\r\n    {\r\n        return this.properties.length;\r\n    }\r\n\r\n    AddProperty (property)\r\n    {\r\n        this.properties.push (property);\r\n    }\r\n\r\n    GetProperty (index)\r\n    {\r\n        return this.properties[index];\r\n    }\r\n\r\n    Clone ()\r\n    {\r\n        let cloned = new PropertyGroup (this.name);\r\n        for (let property of this.properties) {\r\n            cloned.AddProperty (property.Clone ());\r\n        }\r\n        return cloned;\r\n    }\r\n}\r\n\r\nfunction PropertyToString (property)\r\n{\r\n    if (property.type === PropertyType.Text) {\r\n        return EscapeHtmlChars (property.value);\r\n    } else if (property.type === PropertyType.Integer) {\r\n        return property.value.toLocaleString ();\r\n    } else if (property.type === PropertyType.Number) {\r\n        return property.value.toLocaleString (undefined, {\r\n            minimumFractionDigits: 2,\r\n            maximumFractionDigits: 2\r\n        });\r\n    } else if (property.type === PropertyType.Boolean) {\r\n        return property.value ? Loc ('True') : Loc ('False');\r\n    } else if (property.type === PropertyType.Percent) {\r\n        return parseInt (property.value * 100, 10).toString () + '%';\r\n    } else if (property.type === PropertyType.Color) {\r\n        return '#' + RGBColorToHexString (property.value);\r\n    }\r\n    return null;\r\n}\n\nfunction GenerateGuid ()\r\n{\r\n    // https://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid\r\n    let template = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx';\r\n    return template.replace (/[xy]/g, (c) => {\r\n        let r = Math.random () * 16 | 0;\r\n        let v = (c === 'x') ? r : (r & 0x3 | 0x8);\r\n        return v.toString (16);\r\n    });\r\n}\r\n\r\nclass ExporterBim extends ExporterBase\r\n{\r\n    constructor ()\r\n    {\r\n        super ();\r\n    }\r\n\r\n    CanExport (format, extension)\r\n    {\r\n        return format === FileFormat.Text && extension === 'bim';\r\n    }\r\n\r\n    ExportContent (exporterModel, format, files, onFinish)\r\n    {\r\n        let bimContent = {\r\n            schema_version : '1.1.0',\r\n            meshes : [],\r\n            elements : [],\r\n            info : {}\r\n        };\r\n\r\n        this.ExportProperties (exporterModel.GetModel (), bimContent.info);\r\n\r\n        let meshId = 0;\r\n        exporterModel.EnumerateTransformedMeshInstances ((mesh) => {\r\n            let bimMesh = {\r\n                mesh_id : meshId,\r\n                coordinates : [],\r\n                indices : []\r\n            };\r\n\r\n            mesh.EnumerateVertices ((vertex) => {\r\n                bimMesh.coordinates.push (vertex.x, vertex.y, vertex.z);\r\n            });\r\n            mesh.EnumerateTriangleVertexIndices ((v0, v1, v2) => {\r\n                bimMesh.indices.push (v0, v1, v2);\r\n            });\r\n\r\n            let bimElement = {\r\n                mesh_id : meshId,\r\n                type : 'Other',\r\n                color : {\r\n                    r : 200,\r\n                    g : 200,\r\n                    b : 200,\r\n                    a : 255\r\n                },\r\n                vector : {\r\n                    x : 0.0,\r\n                    y : 0.0,\r\n                    z : 0.0\r\n                },\r\n                rotation : {\r\n                    qx: 0.0,\r\n                    qy: 0.0,\r\n                    qz: 0.0,\r\n                    qw: 1.0\r\n                },\r\n                guid : GenerateGuid (),\r\n                info : {}\r\n            };\r\n\r\n            let defaultColor = null;\r\n            let hasOnlyOneColor = true;\r\n            let faceColors = [];\r\n            for (let i = 0; i < mesh.TriangleCount (); i++) {\r\n                let triangle = mesh.GetTriangle (i);\r\n                let material = exporterModel.GetMaterial (triangle.mat);\r\n                let faceColor = {\r\n                    r : Math.round (material.color.r),\r\n                    g : Math.round (material.color.g),\r\n                    b : Math.round (material.color.b),\r\n                    a : ColorComponentFromFloat (material.opacity),\r\n                };\r\n                faceColors.push (faceColor.r, faceColor.g, faceColor.b, faceColor.a);\r\n                if (hasOnlyOneColor) {\r\n                    if (defaultColor === null) {\r\n                        defaultColor = faceColor;\r\n                    } else {\r\n                        if (defaultColor.r !== faceColor.r || defaultColor.g !== faceColor.g || defaultColor.b !== faceColor.b || defaultColor.a !== faceColor.a) {\r\n                            hasOnlyOneColor = false;\r\n                            defaultColor = null;\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n\r\n            if (hasOnlyOneColor) {\r\n                bimElement.color = defaultColor;\r\n            } else {\r\n                bimElement.face_colors = faceColors;\r\n            }\r\n\r\n            bimElement.info['Name'] = mesh.GetName ();\r\n            this.ExportProperties (mesh, bimElement.info);\r\n\r\n            bimContent.meshes.push (bimMesh);\r\n            bimContent.elements.push (bimElement);\r\n            meshId += 1;\r\n        });\r\n\r\n        let bimFile = new ExportedFile ('model.bim');\r\n        bimFile.SetTextContent (JSON.stringify (bimContent, null, 4));\r\n        files.push (bimFile);\r\n        onFinish ();\r\n    }\r\n\r\n    ExportProperties (element, targetObject)\r\n    {\r\n        for (let groupIndex = 0; groupIndex < element.PropertyGroupCount (); groupIndex++) {\r\n            let group = element.GetPropertyGroup (groupIndex);\r\n            for (let propertyIndex = 0; propertyIndex < group.PropertyCount (); propertyIndex++) {\r\n                let property = group.GetProperty (propertyIndex);\r\n                targetObject[property.name] = PropertyToString (property);\r\n            }\r\n        }\r\n    }\r\n}\n\nclass BinaryWriter\r\n{\r\n    constructor (byteLength, isLittleEndian)\r\n    {\r\n        this.arrayBuffer = new ArrayBuffer (byteLength);\r\n        this.dataView = new DataView (this.arrayBuffer);\r\n        this.isLittleEndian = isLittleEndian;\r\n        this.position = 0;\r\n    }\r\n\r\n    GetPosition ()\r\n    {\r\n        return this.position;\r\n    }\r\n\r\n    SetPosition (position)\r\n    {\r\n        this.position = position;\r\n    }\r\n\r\n    End ()\r\n    {\r\n        return this.position >= this.arrayBuffer.byteLength;\r\n    }\r\n\r\n    GetBuffer ()\r\n    {\r\n        return this.arrayBuffer;\r\n    }\r\n\r\n    WriteArrayBuffer (arrayBuffer)\r\n    {\r\n        let bufferView = new Uint8Array (arrayBuffer);\r\n        let thisBufferView = new Uint8Array (this.arrayBuffer);\r\n        thisBufferView.set (bufferView, this.position);\r\n        this.position += arrayBuffer.byteLength;\r\n    }\r\n\r\n    WriteBoolean8 (val)\r\n    {\r\n        this.dataView.setInt8 (this.position, val ? 1 : 0);\r\n        this.position = this.position + 1;\r\n    }\r\n\r\n    WriteCharacter8 (val)\r\n    {\r\n        this.dataView.setInt8 (this.position, val);\r\n        this.position = this.position + 1;\r\n    }\r\n\r\n    WriteUnsignedCharacter8 (val)\r\n    {\r\n        this.dataView.setUint8 (this.position, val);\r\n        this.position = this.position + 1;\r\n    }\r\n\r\n    WriteInteger16 (val)\r\n    {\r\n        this.dataView.setInt16 (this.position, val, this.isLittleEndian);\r\n        this.position = this.position + 2;\r\n    }\r\n\r\n    WriteUnsignedInteger16 (val)\r\n    {\r\n        this.dataView.setUint16 (this.position, val, this.isLittleEndian);\r\n        this.position = this.position + 2;\r\n    }\r\n\r\n    WriteInteger32 (val)\r\n    {\r\n        this.dataView.setInt32 (this.position, val, this.isLittleEndian);\r\n        this.position = this.position + 4;\r\n    }\r\n\r\n    WriteUnsignedInteger32 (val)\r\n    {\r\n        this.dataView.setUint32 (this.position, val, this.isLittleEndian);\r\n        this.position = this.position + 4;\r\n    }\r\n\r\n    WriteFloat32 (val)\r\n    {\r\n        this.dataView.setFloat32 (this.position, val, this.isLittleEndian);\r\n        this.position = this.position + 4;\r\n    }\r\n\r\n    WriteDouble64 (val)\r\n    {\r\n        this.dataView.setFloat64 (this.position, val, this.isLittleEndian);\r\n        this.position = this.position + 8;\r\n    }\r\n}\n\nclass Coord4D\r\n{\r\n\tconstructor (x, y, z, w)\r\n\t{\r\n\t\tthis.x = x;\r\n\t\tthis.y = y;\r\n\t\tthis.z = z;\r\n        this.w = w;\r\n\t}\r\n\r\n\tClone ()\r\n\t{\r\n\t\treturn new Coord4D (this.x, this.y, this.z, this.w);\r\n\t}\r\n}\n\nclass Quaternion\r\n{\r\n\tconstructor (x, y, z, w)\r\n\t{\r\n\t\tthis.x = x;\r\n\t\tthis.y = y;\r\n\t\tthis.z = z;\r\n        this.w = w;\r\n\t}\r\n}\r\n\r\nfunction QuaternionIsEqual (a, b)\r\n{\r\n\treturn IsEqual (a.x, b.x) && IsEqual (a.y, b.y) && IsEqual (a.z, b.z) && IsEqual (a.w, b.w);\r\n}\r\n\r\nfunction ArrayToQuaternion (arr)\r\n{\r\n\treturn new Quaternion (arr[0], arr[1], arr[2], arr[3]);\r\n}\r\n\r\nfunction QuaternionFromAxisAngle (axis, angle)\r\n{\r\n\tconst a = angle / 2.0;\r\n\tconst s = Math.sin (a);\r\n\r\n\treturn new Quaternion (\r\n\t\taxis.x * s,\r\n\t\taxis.y * s,\r\n\t\taxis.z * s,\r\n\t\tMath.cos (a)\r\n\t);\r\n}\r\n\r\nfunction QuaternionFromXYZ (x, y, z, mode) {\r\n\r\n\tconst c1 = Math.cos (x / 2.0);\r\n\tconst c2 = Math.cos (y / 2.0);\r\n\tconst c3 = Math.cos (z / 2.0);\r\n\r\n\tconst s1 = Math.sin (x / 2.0);\r\n\tconst s2 = Math.sin (y / 2.0);\r\n\tconst s3 = Math.sin (z / 2.0);\r\n\r\n\tlet quaternion = new Quaternion (0.0, 0.0, 0.0, 1.0);\r\n\tif (mode === 'XYZ') {\r\n\t\tquaternion.x = s1 * c2 * c3 + c1 * s2 * s3;\r\n\t\tquaternion.y = c1 * s2 * c3 - s1 * c2 * s3;\r\n\t\tquaternion.z = c1 * c2 * s3 + s1 * s2 * c3;\r\n\t\tquaternion.w = c1 * c2 * c3 - s1 * s2 * s3;\r\n\t} else if (mode === 'YXZ') {\r\n\t\tquaternion.x = s1 * c2 * c3 + c1 * s2 * s3;\r\n\t\tquaternion.y = c1 * s2 * c3 - s1 * c2 * s3;\r\n\t\tquaternion.z = c1 * c2 * s3 - s1 * s2 * c3;\r\n\t\tquaternion.w = c1 * c2 * c3 + s1 * s2 * s3;\r\n\t} else if (mode === 'ZXY') {\r\n\t\tquaternion.x = s1 * c2 * c3 - c1 * s2 * s3;\r\n\t\tquaternion.y = c1 * s2 * c3 + s1 * c2 * s3;\r\n\t\tquaternion.z = c1 * c2 * s3 + s1 * s2 * c3;\r\n\t\tquaternion.w = c1 * c2 * c3 - s1 * s2 * s3;\r\n\t} else if (mode === 'ZYX') {\r\n\t\tquaternion.x = s1 * c2 * c3 - c1 * s2 * s3;\r\n\t\tquaternion.y = c1 * s2 * c3 + s1 * c2 * s3;\r\n\t\tquaternion.z = c1 * c2 * s3 - s1 * s2 * c3;\r\n\t\tquaternion.w = c1 * c2 * c3 + s1 * s2 * s3;\r\n\t} else if (mode === 'YZX') {\r\n\t\tquaternion.x = s1 * c2 * c3 + c1 * s2 * s3;\r\n\t\tquaternion.y = c1 * s2 * c3 + s1 * c2 * s3;\r\n\t\tquaternion.z = c1 * c2 * s3 - s1 * s2 * c3;\r\n\t\tquaternion.w = c1 * c2 * c3 - s1 * s2 * s3;\r\n\t} else if (mode === 'XZY') {\r\n\t\tquaternion.x = s1 * c2 * c3 - c1 * s2 * s3;\r\n\t\tquaternion.y = c1 * s2 * c3 - s1 * c2 * s3;\r\n\t\tquaternion.z = c1 * c2 * s3 + s1 * s2 * c3;\r\n\t\tquaternion.w = c1 * c2 * c3 + s1 * s2 * s3;\r\n\t} else {\r\n\t\treturn null;\r\n\t}\r\n\r\n\treturn quaternion;\r\n}\n\nclass Matrix\r\n{\r\n    constructor (matrix)\r\n    {\r\n        this.matrix = null;\r\n        if (matrix !== undefined && matrix !== null) {\r\n            this.matrix = matrix;\r\n        }\r\n    }\r\n\r\n    IsValid ()\r\n    {\r\n        return this.matrix !== null;\r\n    }\r\n\r\n    Set (matrix)\r\n    {\r\n        this.matrix = matrix;\r\n        return this;\r\n    }\r\n\r\n    Get ()\r\n    {\r\n        return this.matrix;\r\n    }\r\n\r\n    Clone ()\r\n    {\r\n        let result = [\r\n            this.matrix[0], this.matrix[1], this.matrix[2], this.matrix[3],\r\n            this.matrix[4], this.matrix[5], this.matrix[6], this.matrix[7],\r\n            this.matrix[8], this.matrix[9], this.matrix[10], this.matrix[11],\r\n            this.matrix[12], this.matrix[13], this.matrix[14], this.matrix[15]\r\n        ];\r\n        return new Matrix (result);\r\n    }\r\n\r\n    CreateIdentity ()\r\n    {\r\n        this.matrix = [\r\n            1.0, 0.0, 0.0, 0.0,\r\n            0.0, 1.0, 0.0, 0.0,\r\n            0.0, 0.0, 1.0, 0.0,\r\n            0.0, 0.0, 0.0, 1.0\r\n        ];\r\n        return this;\r\n    }\r\n\r\n    IsIdentity ()\r\n    {\r\n        let identity = new Matrix ().CreateIdentity ().Get ();\r\n        for (let i = 0; i < 16; i++) {\r\n            if (!IsEqual (this.matrix[i], identity[i])) {\r\n                return false;\r\n            }\r\n        }\r\n        return true;\r\n    }\r\n\r\n    CreateTranslation (x, y, z)\r\n    {\r\n        this.matrix = [\r\n            1.0, 0.0, 0.0, 0.0,\r\n            0.0, 1.0, 0.0, 0.0,\r\n            0.0, 0.0, 1.0, 0.0,\r\n            x, y, z, 1.0\r\n        ];\r\n        return this;\r\n    }\r\n\r\n    CreateRotation (x, y, z, w)\r\n    {\r\n        let x2 = x + x;\r\n        let y2 = y + y;\r\n        let z2 = z + z;\r\n        let xx = x * x2;\r\n        let xy = x * y2;\r\n        let xz = x * z2;\r\n        let yy = y * y2;\r\n        let yz = y * z2;\r\n        let zz = z * z2;\r\n        let wx = w * x2;\r\n        let wy = w * y2;\r\n        let wz = w * z2;\r\n        this.matrix = [\r\n            1.0 - (yy + zz), xy + wz, xz - wy, 0.0,\r\n            xy - wz, 1.0 - (xx + zz), yz + wx, 0.0,\r\n            xz + wy, yz - wx, 1.0 - (xx + yy), 0.0,\r\n            0.0, 0.0, 0.0, 1.0\r\n        ];\r\n        return this;\r\n    }\r\n\r\n    CreateRotationAxisAngle (axis, angle)\r\n    {\r\n        let quaternion = QuaternionFromAxisAngle (axis, angle);\r\n        return this.CreateRotation (quaternion.x, quaternion.y, quaternion.z, quaternion.w);\r\n    }\r\n\r\n    CreateScale (x, y, z)\r\n    {\r\n        this.matrix = [\r\n            x, 0.0, 0.0, 0.0,\r\n            0.0, y, 0.0, 0.0,\r\n            0.0, 0.0, z, 0.0,\r\n            0.0, 0.0, 0.0, 1.0\r\n        ];\r\n        return this;\r\n    }\r\n\r\n    ComposeTRS (translation, rotation, scale)\r\n    {\r\n        let tx = translation.x;\r\n        let ty = translation.y;\r\n        let tz = translation.z;\r\n        let qx = rotation.x;\r\n        let qy = rotation.y;\r\n        let qz = rotation.z;\r\n        let qw = rotation.w;\r\n        let sx = scale.x;\r\n        let sy = scale.y;\r\n        let sz = scale.z;\r\n\r\n        let x2 = qx + qx;\r\n        let y2 = qy + qy;\r\n        let z2 = qz + qz;\r\n        let xx = qx * x2;\r\n        let xy = qx * y2;\r\n        let xz = qx * z2;\r\n        let yy = qy * y2;\r\n        let yz = qy * z2;\r\n        let zz = qz * z2;\r\n        let wx = qw * x2;\r\n        let wy = qw * y2;\r\n        let wz = qw * z2;\r\n\r\n        this.matrix = [\r\n            (1.0 - (yy + zz)) * sx, (xy + wz) * sx, (xz - wy) * sx, 0.0,\r\n            (xy - wz) * sy, (1.0 - (xx + zz)) * sy, (yz + wx) * sy, 0.0,\r\n            (xz + wy) * sz, (yz - wx) * sz, (1.0 - (xx + yy)) * sz, 0.0,\r\n            tx, ty, tz, 1.0\r\n        ];\r\n        return this;\r\n    }\r\n\r\n    DecomposeTRS ()\r\n    {\r\n        let translation = new Coord3D (\r\n            this.matrix[12],\r\n            this.matrix[13],\r\n            this.matrix[14]\r\n        );\r\n\r\n        let sx = VectorLength3D (this.matrix[0], this.matrix[1], this.matrix[2]);\r\n        let sy = VectorLength3D (this.matrix[4], this.matrix[5], this.matrix[6]);\r\n        let sz = VectorLength3D (this.matrix[8], this.matrix[9], this.matrix[10]);\r\n        let determinant = this.Determinant ();\r\n        if (IsNegative (determinant)) {\r\n            sx *= -1;\r\n        }\r\n        let scale = new Coord3D (sx, sy, sz);\r\n\r\n        let m00 = this.matrix[0] / sx;\r\n        let m01 = this.matrix[4] / sy;\r\n        let m02 = this.matrix[8] / sz;\r\n        let m10 = this.matrix[1] / sx;\r\n        let m11 = this.matrix[5] / sy;\r\n        let m12 = this.matrix[9] / sz;\r\n        let m20 = this.matrix[2] / sx;\r\n        let m21 = this.matrix[6] / sy;\r\n        let m22 = this.matrix[10] / sz;\r\n\r\n        // http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm\r\n        let rotation = null;\r\n        let tr = m00 + m11 + m22;\r\n        if (tr > 0.0) {\r\n            let s = Math.sqrt (tr + 1.0) * 2.0;\r\n            rotation = new Quaternion (\r\n                (m21 - m12) / s,\r\n                (m02 - m20) / s,\r\n                (m10 - m01) / s,\r\n                0.25 * s\r\n            );\r\n        } else if ((m00 > m11) && (m00 > m22)) {\r\n            let s = Math.sqrt (1.0 + m00 - m11 - m22) * 2.0;\r\n            rotation = new Quaternion (\r\n                0.25 * s,\r\n                (m01 + m10) / s,\r\n                (m02 + m20) / s,\r\n                (m21 - m12) / s\r\n            );\r\n        } else if (m11 > m22) {\r\n            let s = Math.sqrt (1.0 + m11 - m00 - m22) * 2.0;\r\n            rotation = new Quaternion (\r\n                (m01 + m10) / s,\r\n                0.25 * s,\r\n                (m12 + m21) / s,\r\n                (m02 - m20) / s\r\n            );\r\n        } else {\r\n            let s = Math.sqrt (1.0 + m22 - m00 - m11) * 2.0;\r\n            rotation = new Quaternion (\r\n                (m02 + m20) / s,\r\n                (m12 + m21) / s,\r\n                0.25 * s,\r\n                (m10 - m01) / s\r\n            );\r\n        }\r\n\r\n        return {\r\n            translation : translation,\r\n            rotation : rotation,\r\n            scale : scale\r\n        };\r\n    }\r\n\r\n    Determinant ()\r\n    {\r\n        let a00 = this.matrix[0];\r\n        let a01 = this.matrix[1];\r\n        let a02 = this.matrix[2];\r\n        let a03 = this.matrix[3];\r\n        let a10 = this.matrix[4];\r\n        let a11 = this.matrix[5];\r\n        let a12 = this.matrix[6];\r\n        let a13 = this.matrix[7];\r\n        let a20 = this.matrix[8];\r\n        let a21 = this.matrix[9];\r\n        let a22 = this.matrix[10];\r\n        let a23 = this.matrix[11];\r\n        let a30 = this.matrix[12];\r\n        let a31 = this.matrix[13];\r\n        let a32 = this.matrix[14];\r\n        let a33 = this.matrix[15];\r\n\r\n        let b00 = a00 * a11 - a01 * a10;\r\n        let b01 = a00 * a12 - a02 * a10;\r\n        let b02 = a00 * a13 - a03 * a10;\r\n        let b03 = a01 * a12 - a02 * a11;\r\n        let b04 = a01 * a13 - a03 * a11;\r\n        let b05 = a02 * a13 - a03 * a12;\r\n        let b06 = a20 * a31 - a21 * a30;\r\n        let b07 = a20 * a32 - a22 * a30;\r\n        let b08 = a20 * a33 - a23 * a30;\r\n        let b09 = a21 * a32 - a22 * a31;\r\n        let b10 = a21 * a33 - a23 * a31;\r\n        let b11 = a22 * a33 - a23 * a32;\r\n\r\n        let determinant = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;\r\n        return determinant;\r\n    }\r\n\r\n    Invert ()\r\n    {\r\n        let a00 = this.matrix[0];\r\n        let a01 = this.matrix[1];\r\n        let a02 = this.matrix[2];\r\n        let a03 = this.matrix[3];\r\n        let a10 = this.matrix[4];\r\n        let a11 = this.matrix[5];\r\n        let a12 = this.matrix[6];\r\n        let a13 = this.matrix[7];\r\n        let a20 = this.matrix[8];\r\n        let a21 = this.matrix[9];\r\n        let a22 = this.matrix[10];\r\n        let a23 = this.matrix[11];\r\n        let a30 = this.matrix[12];\r\n        let a31 = this.matrix[13];\r\n        let a32 = this.matrix[14];\r\n        let a33 = this.matrix[15];\r\n\r\n        let b00 = a00 * a11 - a01 * a10;\r\n        let b01 = a00 * a12 - a02 * a10;\r\n        let b02 = a00 * a13 - a03 * a10;\r\n        let b03 = a01 * a12 - a02 * a11;\r\n        let b04 = a01 * a13 - a03 * a11;\r\n        let b05 = a02 * a13 - a03 * a12;\r\n        let b06 = a20 * a31 - a21 * a30;\r\n        let b07 = a20 * a32 - a22 * a30;\r\n        let b08 = a20 * a33 - a23 * a30;\r\n        let b09 = a21 * a32 - a22 * a31;\r\n        let b10 = a21 * a33 - a23 * a31;\r\n        let b11 = a22 * a33 - a23 * a32;\r\n\r\n        let determinant = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;\r\n        if (IsEqual (determinant, 0.0)) {\r\n            return null;\r\n        }\r\n\r\n        let result = [\r\n            (a11 * b11 - a12 * b10 + a13 * b09) / determinant,\r\n            (a02 * b10 - a01 * b11 - a03 * b09) / determinant,\r\n            (a31 * b05 - a32 * b04 + a33 * b03) / determinant,\r\n            (a22 * b04 - a21 * b05 - a23 * b03) / determinant,\r\n            (a12 * b08 - a10 * b11 - a13 * b07) / determinant,\r\n            (a00 * b11 - a02 * b08 + a03 * b07) / determinant,\r\n            (a32 * b02 - a30 * b05 - a33 * b01) / determinant,\r\n            (a20 * b05 - a22 * b02 + a23 * b01) / determinant,\r\n            (a10 * b10 - a11 * b08 + a13 * b06) / determinant,\r\n            (a01 * b08 - a00 * b10 - a03 * b06) / determinant,\r\n            (a30 * b04 - a31 * b02 + a33 * b00) / determinant,\r\n            (a21 * b02 - a20 * b04 - a23 * b00) / determinant,\r\n            (a11 * b07 - a10 * b09 - a12 * b06) / determinant,\r\n            (a00 * b09 - a01 * b07 + a02 * b06) / determinant,\r\n            (a31 * b01 - a30 * b03 - a32 * b00) / determinant,\r\n            (a20 * b03 - a21 * b01 + a22 * b00) / determinant\r\n        ];\r\n\r\n        return new Matrix (result);\r\n    }\r\n\r\n    Transpose ()\r\n    {\r\n        let result = [\r\n            this.matrix[0], this.matrix[4], this.matrix[8], this.matrix[12],\r\n            this.matrix[1], this.matrix[5], this.matrix[9], this.matrix[13],\r\n            this.matrix[2], this.matrix[6], this.matrix[10], this.matrix[14],\r\n            this.matrix[3], this.matrix[7], this.matrix[11], this.matrix[15]\r\n        ];\r\n        return new Matrix (result);\r\n    }\r\n\r\n    InvertTranspose ()\r\n    {\r\n        let result = this.Invert ();\r\n        if (result === null) {\r\n            return null;\r\n        }\r\n        return result.Transpose ();\r\n    }\r\n\r\n    MultiplyVector (vector)\r\n    {\r\n        let a00 = vector.x;\r\n        let a01 = vector.y;\r\n        let a02 = vector.z;\r\n        let a03 = vector.w;\r\n\r\n        let b00 = this.matrix[0];\r\n        let b01 = this.matrix[1];\r\n        let b02 = this.matrix[2];\r\n        let b03 = this.matrix[3];\r\n        let b10 = this.matrix[4];\r\n        let b11 = this.matrix[5];\r\n        let b12 = this.matrix[6];\r\n        let b13 = this.matrix[7];\r\n        let b20 = this.matrix[8];\r\n        let b21 = this.matrix[9];\r\n        let b22 = this.matrix[10];\r\n        let b23 = this.matrix[11];\r\n        let b30 = this.matrix[12];\r\n        let b31 = this.matrix[13];\r\n        let b32 = this.matrix[14];\r\n        let b33 = this.matrix[15];\r\n\r\n        let result = new Coord4D (\r\n            a00 * b00 + a01 * b10 + a02 * b20 + a03 * b30,\r\n            a00 * b01 + a01 * b11 + a02 * b21 + a03 * b31,\r\n            a00 * b02 + a01 * b12 + a02 * b22 + a03 * b32,\r\n            a00 * b03 + a01 * b13 + a02 * b23 + a03 * b33\r\n        );\r\n        return result;\r\n    }\r\n\r\n    MultiplyMatrix (matrix)\r\n    {\r\n        let a00 = this.matrix[0];\r\n        let a01 = this.matrix[1];\r\n        let a02 = this.matrix[2];\r\n        let a03 = this.matrix[3];\r\n        let a10 = this.matrix[4];\r\n        let a11 = this.matrix[5];\r\n        let a12 = this.matrix[6];\r\n        let a13 = this.matrix[7];\r\n        let a20 = this.matrix[8];\r\n        let a21 = this.matrix[9];\r\n        let a22 = this.matrix[10];\r\n        let a23 = this.matrix[11];\r\n        let a30 = this.matrix[12];\r\n        let a31 = this.matrix[13];\r\n        let a32 = this.matrix[14];\r\n        let a33 = this.matrix[15];\r\n\r\n        let b00 = matrix.matrix[0];\r\n        let b01 = matrix.matrix[1];\r\n        let b02 = matrix.matrix[2];\r\n        let b03 = matrix.matrix[3];\r\n        let b10 = matrix.matrix[4];\r\n        let b11 = matrix.matrix[5];\r\n        let b12 = matrix.matrix[6];\r\n        let b13 = matrix.matrix[7];\r\n        let b20 = matrix.matrix[8];\r\n        let b21 = matrix.matrix[9];\r\n        let b22 = matrix.matrix[10];\r\n        let b23 = matrix.matrix[11];\r\n        let b30 = matrix.matrix[12];\r\n        let b31 = matrix.matrix[13];\r\n        let b32 = matrix.matrix[14];\r\n        let b33 = matrix.matrix[15];\r\n\r\n        let result = [\r\n            a00 * b00 + a01 * b10 + a02 * b20 + a03 * b30,\r\n            a00 * b01 + a01 * b11 + a02 * b21 + a03 * b31,\r\n            a00 * b02 + a01 * b12 + a02 * b22 + a03 * b32,\r\n            a00 * b03 + a01 * b13 + a02 * b23 + a03 * b33,\r\n            a10 * b00 + a11 * b10 + a12 * b20 + a13 * b30,\r\n            a10 * b01 + a11 * b11 + a12 * b21 + a13 * b31,\r\n            a10 * b02 + a11 * b12 + a12 * b22 + a13 * b32,\r\n            a10 * b03 + a11 * b13 + a12 * b23 + a13 * b33,\r\n            a20 * b00 + a21 * b10 + a22 * b20 + a23 * b30,\r\n            a20 * b01 + a21 * b11 + a22 * b21 + a23 * b31,\r\n            a20 * b02 + a21 * b12 + a22 * b22 + a23 * b32,\r\n            a20 * b03 + a21 * b13 + a22 * b23 + a23 * b33,\r\n            a30 * b00 + a31 * b10 + a32 * b20 + a33 * b30,\r\n            a30 * b01 + a31 * b11 + a32 * b21 + a33 * b31,\r\n            a30 * b02 + a31 * b12 + a32 * b22 + a33 * b32,\r\n            a30 * b03 + a31 * b13 + a32 * b23 + a33 * b33\r\n        ];\r\n\r\n        return new Matrix (result);\r\n    }\r\n}\r\n\r\nfunction MatrixIsEqual (a, b)\r\n{\r\n    const aMatrix = a.Get ();\r\n    const bMatrix = b.Get ();\r\n\tfor (let i = 0; i < 16; i++) {\r\n        if (!IsEqual (aMatrix[i], bMatrix[i])) {\r\n            return false;\r\n        }\r\n    }\r\n    return true;\r\n}\n\nclass Transformation\r\n{\r\n    constructor (matrix)\r\n    {\r\n        if (matrix !== undefined && matrix !== null) {\r\n            this.matrix = matrix;\r\n        } else {\r\n            this.matrix = new Matrix ();\r\n            this.matrix.CreateIdentity ();\r\n        }\r\n    }\r\n\r\n    SetMatrix (matrix)\r\n    {\r\n        this.matrix = matrix;\r\n        return this;\r\n    }\r\n\r\n    GetMatrix ()\r\n    {\r\n        return this.matrix;\r\n    }\r\n\r\n    IsIdentity ()\r\n    {\r\n        return this.matrix.IsIdentity ();\r\n    }\r\n\r\n    AppendMatrix (matrix)\r\n    {\r\n        this.matrix = this.matrix.MultiplyMatrix (matrix);\r\n        return this;\r\n    }\r\n\r\n    Append (transformation)\r\n    {\r\n        this.AppendMatrix (transformation.GetMatrix ());\r\n        return this;\r\n    }\r\n\r\n    TransformCoord3D (coord)\r\n    {\r\n        let coord4D = new Coord4D (coord.x, coord.y, coord.z, 1.0);\r\n        let resultCoord4D = this.matrix.MultiplyVector (coord4D);\r\n        let result = new Coord3D (resultCoord4D.x, resultCoord4D.y, resultCoord4D.z);\r\n        return result;\r\n    }\r\n\r\n    Clone ()\r\n    {\r\n        const clonedMatrix = this.matrix.Clone ();\r\n        return new Transformation (clonedMatrix);\r\n    }\r\n}\r\n\r\nfunction TransformationIsEqual (a, b)\r\n{\r\n    return MatrixIsEqual (a.GetMatrix (), b.GetMatrix ());\r\n}\n\nfunction IsEmptyMesh (mesh)\r\n{\r\n    return mesh.LineCount () === 0 && mesh.TriangleCount () === 0;\r\n}\r\n\r\nfunction CalculateTriangleNormal (v0, v1, v2)\r\n{\r\n    let v = SubCoord3D (v1, v0);\r\n    let w = SubCoord3D (v2, v0);\r\n    let normal = CrossVector3D (v, w);\r\n    normal.Normalize ();\r\n    return normal;\r\n}\r\n\r\nfunction TransformMesh (mesh, transformation)\r\n{\r\n    if (transformation.IsIdentity ()) {\r\n        return;\r\n    }\r\n\r\n    for (let i = 0; i < mesh.VertexCount (); i++) {\r\n        let vertex = mesh.GetVertex (i);\r\n        let transformed = transformation.TransformCoord3D (vertex);\r\n        vertex.x = transformed.x;\r\n        vertex.y = transformed.y;\r\n        vertex.z = transformed.z;\r\n    }\r\n\r\n    if (mesh.NormalCount () > 0) {\r\n        let normalMatrix = transformation.GetMatrix ().InvertTranspose ();\r\n        if (normalMatrix !== null) {\r\n            let normalTransformation = new Transformation (normalMatrix);\r\n            for (let i = 0; i < mesh.NormalCount (); i++) {\r\n                let normal = mesh.GetNormal (i);\r\n                let transformed = normalTransformation.TransformCoord3D (normal);\r\n                normal.x = transformed.x;\r\n                normal.y = transformed.y;\r\n                normal.z = transformed.z;\r\n            }\r\n        }\r\n    }\r\n}\r\n\r\nfunction FlipMeshTrianglesOrientation (mesh)\r\n{\r\n    for (let i = 0; i < mesh.TriangleCount (); i++) {\r\n        let triangle = mesh.GetTriangle (i);\r\n        let tmp = triangle.v1;\r\n        triangle.v1 = triangle.v2;\r\n        triangle.v2 = tmp;\r\n    }\r\n}\n\nclass Object3D\r\n{\r\n    constructor ()\r\n    {\r\n\r\n    }\r\n\r\n    VertexCount ()\r\n    {\r\n        return 0;\r\n    }\r\n\r\n    VertexColorCount ()\r\n    {\r\n        return 0;\r\n    }\r\n\r\n    NormalCount ()\r\n    {\r\n        return 0;\r\n    }\r\n\r\n    TextureUVCount ()\r\n    {\r\n        return 0;\r\n    }\r\n\r\n    LineCount ()\r\n    {\r\n        return 0;\r\n    }\r\n\r\n    LineSegmentCount ()\r\n    {\r\n        return 0;\r\n    }\r\n\r\n    TriangleCount ()\r\n    {\r\n        return 0;\r\n    }\r\n\r\n    EnumerateVertices (onVertex)\r\n    {\r\n\r\n    }\r\n\r\n    EnumerateTriangleVertexIndices (onTriangleVertexIndices)\r\n    {\r\n\r\n    }\r\n\r\n    EnumerateTriangleVertices (onTriangleVertices)\r\n    {\r\n\r\n    }\r\n}\r\n\r\nclass ModelObject3D extends Object3D\r\n{\r\n    constructor ()\r\n    {\r\n        super ();\r\n        this.name = '';\r\n        this.propertyGroups = [];\r\n    }\r\n\r\n    GetName ()\r\n    {\r\n        return this.name;\r\n    }\r\n\r\n    SetName (name)\r\n    {\r\n        this.name = name;\r\n    }\r\n\r\n    PropertyGroupCount ()\r\n    {\r\n        return this.propertyGroups.length;\r\n    }\r\n\r\n    AddPropertyGroup (propertyGroup)\r\n    {\r\n        this.propertyGroups.push (propertyGroup);\r\n        return this.propertyGroups.length - 1;\r\n    }\r\n\r\n    GetPropertyGroup (index)\r\n    {\r\n        return this.propertyGroups[index];\r\n    }\r\n\r\n    CloneProperties (target)\r\n    {\r\n        for (let propertyGroup of this.propertyGroups) {\r\n            target.AddPropertyGroup (propertyGroup.Clone ());\r\n        }\r\n    }\r\n}\n\nclass MeshInstanceId\r\n{\r\n    constructor (nodeId, meshIndex)\r\n    {\r\n        this.nodeId = nodeId;\r\n        this.meshIndex = meshIndex;\r\n    }\r\n\r\n    IsEqual (rhs)\r\n    {\r\n        return this.nodeId === rhs.nodeId && this.meshIndex === rhs.meshIndex;\r\n    }\r\n\r\n    GetKey ()\r\n    {\r\n        return this.nodeId.toString () + ':' + this.meshIndex.toString ();\r\n    }\r\n}\r\n\r\nclass MeshInstance extends ModelObject3D\r\n{\r\n    constructor (id, node, mesh)\r\n    {\r\n        super ();\r\n        this.id = id;\r\n        this.node = node;\r\n        this.mesh = mesh;\r\n    }\r\n\r\n    GetId ()\r\n    {\r\n        return this.id;\r\n    }\r\n\r\n    GetTransformation ()\r\n    {\r\n        return this.node.GetWorldTransformation ();\r\n    }\r\n\r\n    GetMesh ()\r\n    {\r\n        return this.mesh;\r\n    }\r\n\r\n    VertexCount ()\r\n    {\r\n        return this.mesh.VertexCount ();\r\n    }\r\n\r\n    VertexColorCount ()\r\n    {\r\n        return this.mesh.VertexColorCount ();\r\n    }\r\n\r\n    NormalCount ()\r\n    {\r\n        return this.mesh.NormalCount ();\r\n    }\r\n\r\n    TextureUVCount ()\r\n    {\r\n        return this.mesh.TextureUVCount ();\r\n    }\r\n\r\n    LineCount ()\r\n    {\r\n        return this.mesh.LineCount ();\r\n    }\r\n\r\n    LineSegmentCount ()\r\n    {\r\n        return this.mesh.LineSegmentCount ();\r\n    }\r\n\r\n    TriangleCount ()\r\n    {\r\n        return this.mesh.TriangleCount ();\r\n    }\r\n\r\n    EnumerateVertices (onVertex)\r\n    {\r\n        let transformation = this.node.GetWorldTransformation ();\r\n        if (transformation.IsIdentity ()) {\r\n            this.mesh.EnumerateVertices (onVertex);\r\n        } else {\r\n            this.mesh.EnumerateVertices ((vertex) => {\r\n                const transformed = transformation.TransformCoord3D (vertex);\r\n                onVertex (transformed);\r\n            });\r\n        }\r\n    }\r\n\r\n    EnumerateTriangleVertexIndices (onTriangleVertexIndices)\r\n    {\r\n        this.mesh.EnumerateTriangleVertexIndices (onTriangleVertexIndices);\r\n    }\r\n\r\n    EnumerateTriangleVertices (onTriangleVertices)\r\n    {\r\n        let transformation = this.node.GetWorldTransformation ();\r\n        if (transformation.IsIdentity ()) {\r\n            this.mesh.EnumerateTriangleVertices (onTriangleVertices);\r\n        } else {\r\n            this.mesh.EnumerateTriangleVertices ((v0, v1, v2) => {\r\n                const v0Transformed = transformation.TransformCoord3D (v0);\r\n                const v1Transformed = transformation.TransformCoord3D (v1);\r\n                const v2Transformed = transformation.TransformCoord3D (v2);\r\n                onTriangleVertices (v0Transformed, v1Transformed, v2Transformed);\r\n            });\r\n        }\r\n    }\r\n\r\n    PropertyGroupCount ()\r\n    {\r\n        return this.mesh.PropertyGroupCount ();\r\n    }\r\n\r\n    AddPropertyGroup (propertyGroup)\r\n    {\r\n        return this.mesh.AddPropertyGroup (propertyGroup);\r\n    }\r\n\r\n    GetPropertyGroup (index)\r\n    {\r\n        return this.mesh.GetPropertyGroup (index);\r\n    }\r\n\r\n    GetTransformedMesh ()\r\n    {\r\n        let transformation = this.node.GetWorldTransformation ();\r\n        let transformed = this.mesh.Clone ();\r\n        TransformMesh (transformed, transformation);\r\n        return transformed;\r\n    }\r\n}\n\nconst GltfComponentType$1 =\r\n{\r\n    UNSIGNED_INT : 5125,\r\n    FLOAT : 5126\r\n};\r\n\r\nconst GltfBufferType =\r\n{\r\n    ARRAY_BUFFER : 34962,\r\n    ELEMENT_ARRAY_BUFFER : 34963\r\n};\r\n\r\nclass ExporterGltf extends ExporterBase\r\n{\r\n\tconstructor ()\r\n\t{\r\n\t\tsuper ();\r\n        this.components = {\r\n            index : {\r\n                type : GltfComponentType$1.UNSIGNED_INT,\r\n                size : 4\r\n            },\r\n            number : {\r\n                type : GltfComponentType$1.FLOAT,\r\n                size : 4\r\n            }\r\n        };\r\n\t}\r\n\r\n    CanExport (format, extension)\r\n    {\r\n        return (format === FileFormat.Text && extension === 'gltf') || (format === FileFormat.Binary && extension === 'glb');\r\n    }\r\n\r\n\tExportContent (exporterModel, format, files, onFinish)\r\n\t{\r\n        if (format === FileFormat.Text) {\r\n            this.ExportAsciiContent (exporterModel, files);\r\n        } else if (format === FileFormat.Binary) {\r\n            this.ExportBinaryContent (exporterModel, files);\r\n        }\r\n        onFinish ();\r\n\t}\r\n\r\n\tExportAsciiContent (exporterModel, files)\r\n\t{\r\n        let gltfFile = new ExportedFile ('model.gltf');\r\n        let binFile = new ExportedFile ('model.bin');\r\n        files.push (gltfFile);\r\n        files.push (binFile);\r\n\r\n        let meshDataArr = this.GetMeshData (exporterModel);\r\n        let mainBuffer = this.GetMainBuffer (meshDataArr);\r\n        let mainJson = this.GetMainJson (exporterModel, meshDataArr);\r\n        mainJson.buffers.push ({\r\n            uri : binFile.GetName (),\r\n            byteLength : mainBuffer.byteLength\r\n        });\r\n\r\n        let fileNameToIndex = new Map ();\r\n        this.ExportMaterials (exporterModel, mainJson, (texture) => {\r\n            let fileName = GetFileName (texture.name);\r\n            if (fileNameToIndex.has (fileName)) {\r\n                return fileNameToIndex.get (fileName);\r\n            } else {\r\n                let textureFile = new ExportedFile (fileName);\r\n                textureFile.SetBufferContent (texture.buffer);\r\n                files.push (textureFile);\r\n\r\n                let textureIndex = mainJson.textures.length;\r\n                fileNameToIndex.set (fileName, textureIndex);\r\n\r\n                mainJson.images.push ({\r\n                    uri : fileName\r\n                });\r\n\r\n                mainJson.textures.push ({\r\n                    source : textureIndex\r\n                });\r\n\r\n                return textureIndex;\r\n            }\r\n        });\r\n\r\n        gltfFile.SetTextContent (JSON.stringify (mainJson, null, 4));\r\n        binFile.SetBufferContent (mainBuffer);\r\n    }\r\n\r\n    ExportBinaryContent (exporterModel, files)\r\n    {\r\n        function AlignToBoundary (size)\r\n        {\r\n            let remainder = size % 4;\r\n            if (remainder === 0) {\r\n                return size;\r\n            }\r\n            return size + (4 - remainder);\r\n        }\r\n\r\n        function WriteCharacters (writer, char, count)\r\n        {\r\n            for (let i = 0; i < count; i++) {\r\n                writer.WriteUnsignedCharacter8 (char);\r\n            }\r\n        }\r\n\r\n        let glbFile = new ExportedFile ('model.glb');\r\n        files.push (glbFile);\r\n\r\n        let meshDataArr = this.GetMeshData (exporterModel);\r\n        let mainBuffer = this.GetMainBuffer (meshDataArr);\r\n        let mainJson = this.GetMainJson (exporterModel, meshDataArr);\r\n\r\n        let textureBuffers = [];\r\n        let textureOffset = mainBuffer.byteLength;\r\n\r\n        let fileNameToIndex = new Map ();\r\n        this.ExportMaterials (exporterModel, mainJson, (texture) => {\r\n            let fileName = GetFileName (texture.name);\r\n            let extension = GetFileExtension (texture.name);\r\n            if (fileNameToIndex.has (fileName)) {\r\n                return fileNameToIndex.get (fileName);\r\n            } else {\r\n                let bufferViewIndex = mainJson.bufferViews.length;\r\n                let textureIndex = mainJson.textures.length;\r\n                fileNameToIndex.set (fileName, textureIndex);\r\n                let textureBuffer = texture.buffer;\r\n                textureBuffers.push (textureBuffer);\r\n                mainJson.bufferViews.push ({\r\n                    buffer : 0,\r\n                    byteOffset : textureOffset,\r\n                    byteLength : textureBuffer.byteLength\r\n                });\r\n                textureOffset += textureBuffer.byteLength;\r\n                mainJson.images.push ({\r\n                    bufferView : bufferViewIndex,\r\n                    mimeType : 'image/' + extension\r\n                });\r\n                mainJson.textures.push ({\r\n                    source : textureIndex\r\n                });\r\n\r\n                return textureIndex;\r\n            }\r\n        });\r\n\r\n        let mainBinaryBufferLength = mainBuffer.byteLength;\r\n        for (let i = 0; i < textureBuffers.length; i++) {\r\n            let textureBuffer = textureBuffers[i];\r\n            mainBinaryBufferLength += textureBuffer.byteLength;\r\n        }\r\n        let mainBinaryBufferAlignedLength = AlignToBoundary (mainBinaryBufferLength);\r\n        mainJson.buffers.push ({\r\n            byteLength : mainBinaryBufferAlignedLength\r\n        });\r\n\r\n        let mainJsonString = JSON.stringify (mainJson);\r\n        let mainJsonBuffer = Utf8StringToArrayBuffer (mainJsonString);\r\n        let mainJsonBufferLength = mainJsonBuffer.byteLength;\r\n        let mainJsonBufferAlignedLength = AlignToBoundary (mainJsonBufferLength);\r\n\r\n        let glbSize = 12 + 8 + mainJsonBufferAlignedLength + 8 + mainBinaryBufferAlignedLength;\r\n        let glbWriter = new BinaryWriter (glbSize, true);\r\n\r\n        glbWriter.WriteUnsignedInteger32 (0x46546C67);\r\n        glbWriter.WriteUnsignedInteger32 (2);\r\n        glbWriter.WriteUnsignedInteger32 (glbSize);\r\n\r\n        glbWriter.WriteUnsignedInteger32 (mainJsonBufferAlignedLength);\r\n        glbWriter.WriteUnsignedInteger32 (0x4E4F534A);\r\n        glbWriter.WriteArrayBuffer (mainJsonBuffer);\r\n        WriteCharacters (glbWriter, 32, mainJsonBufferAlignedLength - mainJsonBufferLength);\r\n\r\n        glbWriter.WriteUnsignedInteger32 (mainBinaryBufferAlignedLength);\r\n        glbWriter.WriteUnsignedInteger32 (0x004E4942);\r\n        glbWriter.WriteArrayBuffer (mainBuffer);\r\n\r\n        for (let i = 0; i < textureBuffers.length; i++) {\r\n            let textureBuffer = textureBuffers[i];\r\n            glbWriter.WriteArrayBuffer (textureBuffer);\r\n        }\r\n        WriteCharacters (glbWriter, 0, mainBinaryBufferAlignedLength - mainBinaryBufferLength);\r\n\r\n        glbFile.SetBufferContent (glbWriter.GetBuffer ());\r\n    }\r\n\r\n    GetMeshData (exporterModel)\r\n    {\r\n        let meshDataArr = [];\r\n\r\n        exporterModel.EnumerateMeshes ((mesh) => {\r\n            let buffer = ConvertMeshToMeshBuffer (mesh);\r\n            meshDataArr.push ({\r\n                name : mesh.GetName (),\r\n                buffer : buffer,\r\n                offsets : [],\r\n                sizes : []\r\n            });\r\n        });\r\n\r\n        return meshDataArr;\r\n    }\r\n\r\n    GetMainBuffer (meshDataArr)\r\n    {\r\n        let mainBufferSize = 0;\r\n        for (let meshData of meshDataArr) {\r\n            mainBufferSize += meshData.buffer.GetByteLength (this.components.index.size, this.components.number.size);\r\n        }\r\n\r\n        let writer = new BinaryWriter (mainBufferSize, true);\r\n        for (let meshData of meshDataArr) {\r\n            for (let primitiveIndex = 0; primitiveIndex < meshData.buffer.PrimitiveCount (); primitiveIndex++) {\r\n                let primitive = meshData.buffer.GetPrimitive (primitiveIndex);\r\n                let offset = writer.GetPosition ();\r\n                for (let i = 0; i < primitive.indices.length; i++) {\r\n                    writer.WriteUnsignedInteger32 (primitive.indices[i]);\r\n                }\r\n                for (let i = 0; i < primitive.vertices.length; i++) {\r\n                    writer.WriteFloat32 (primitive.vertices[i]);\r\n                }\r\n                for (let i = 0; i < primitive.colors.length; i++) {\r\n                    writer.WriteFloat32 (SRGBToLinear (primitive.colors[i]));\r\n                }\r\n                for (let i = 0; i < primitive.normals.length; i++) {\r\n                    writer.WriteFloat32 (primitive.normals[i]);\r\n                }\r\n                for (let i = 0; i < primitive.uvs.length; i++) {\r\n                    let texCoord = primitive.uvs[i];\r\n                    if (i % 2 === 1) {\r\n                        texCoord *= -1;\r\n                    }\r\n                    writer.WriteFloat32 (texCoord);\r\n                }\r\n                meshData.offsets.push (offset);\r\n                meshData.sizes.push (writer.GetPosition () - offset);\r\n            }\r\n        }\r\n\r\n        return writer.GetBuffer ();\r\n    }\r\n\r\n    GetMainJson (exporterModel, meshDataArr)\r\n    {\r\n        class BufferViewCreator\r\n        {\r\n            constructor (mainJson, byteOffset)\r\n            {\r\n                this.mainJson = mainJson;\r\n                this.byteOffset = byteOffset;\r\n            }\r\n\r\n            AddBufferView (byteLength, target)\r\n            {\r\n                let bufferView = {\r\n                    buffer : 0,\r\n                    byteOffset : this.byteOffset,\r\n                    byteLength : byteLength,\r\n                    target : target\r\n                };\r\n                this.mainJson.bufferViews.push (bufferView);\r\n                this.byteOffset += byteLength;\r\n                return this.mainJson.bufferViews.length - 1;\r\n            }\r\n        }\r\n\r\n        function NodeHasVisibleChildren (model, node)\r\n        {\r\n            for (let meshIndex of node.GetMeshIndices ()) {\r\n                let meshInstanceId = new MeshInstanceId (node.GetId (), meshIndex);\r\n                if (model.IsMeshInstanceVisible (meshInstanceId)) {\r\n                    return true;\r\n                }\r\n            }\r\n            for (let childNode of node.GetChildNodes ()) {\r\n                if (NodeHasVisibleChildren (model, childNode)) {\r\n                    return true;\r\n                }\r\n            }\r\n            return false;\r\n        }\r\n\r\n        function AddNode (model, jsonParent, jsonNodes, node)\r\n        {\r\n            if (node.IsMeshNode ()) {\r\n                for (let meshIndex of node.GetMeshIndices ()) {\r\n                    AddMeshNode (model, jsonParent, jsonNodes, node, meshIndex, true);\r\n                }\r\n            } else if (NodeHasVisibleChildren (model, node)) {\r\n                let nodeJson = {};\r\n\r\n                let nodeName = node.GetName ();\r\n                if (nodeName.length > 0) {\r\n                    nodeJson.name = nodeName;\r\n                }\r\n\r\n                let transformation = node.GetTransformation ();\r\n                if (!transformation.IsIdentity ()) {\r\n                    nodeJson.matrix = node.GetTransformation ().GetMatrix ().Get ();\r\n                }\r\n\r\n                jsonNodes.push (nodeJson);\r\n                jsonParent.push (jsonNodes.length - 1);\r\n\r\n                nodeJson.children = [];\r\n                AddChildNodes (model, nodeJson.children, jsonNodes, node);\r\n            }\r\n        }\r\n\r\n        function AddMeshNode (model, jsonParent, jsonNodes, node, meshIndex, isStandaloneNode)\r\n        {\r\n            let meshInstanceId = new MeshInstanceId (node.GetId (), meshIndex);\r\n            if (!model.IsMeshInstanceVisible (meshInstanceId)) {\r\n                return;\r\n            }\r\n\r\n            let nodeJson = {\r\n                mesh : model.MapMeshIndex (meshIndex)\r\n            };\r\n            if (isStandaloneNode) {\r\n                let transformation = node.GetTransformation ();\r\n                if (!transformation.IsIdentity ()) {\r\n                    nodeJson.matrix = node.GetTransformation ().GetMatrix ().Get ();\r\n                }\r\n            }\r\n\r\n            jsonNodes.push (nodeJson);\r\n            jsonParent.push (jsonNodes.length - 1);\r\n        }\r\n\r\n        function AddChildNodes (model, jsonParent, jsonNodes, node)\r\n        {\r\n            for (let childNode of node.GetChildNodes ()) {\r\n                AddNode (model, jsonParent, jsonNodes, childNode);\r\n            }\r\n            for (let meshIndex of node.GetMeshIndices ()) {\r\n                AddMeshNode (model, jsonParent, jsonNodes, node, meshIndex, false);\r\n            }\r\n        }\r\n\r\n        let mainJson = {\r\n            asset : {\r\n                generator : 'https://3dviewer.net',\r\n                version : '2.0'\r\n            },\r\n            scene : 0,\r\n            scenes : [\r\n                {\r\n                    nodes : []\r\n                }\r\n            ],\r\n            nodes : [],\r\n            materials : [],\r\n            meshes : [],\r\n            buffers : [],\r\n            bufferViews : [],\r\n            accessors : []\r\n        };\r\n\r\n        let rootNode = exporterModel.GetModel ().GetRootNode ();\r\n        AddChildNodes (exporterModel, mainJson.scenes[0].nodes, mainJson.nodes, rootNode);\r\n\r\n        for (let meshData of meshDataArr) {\r\n            let jsonMesh = {\r\n                name : this.GetExportedMeshName (meshData.name),\r\n                primitives : []\r\n            };\r\n\r\n            let primitives = meshData.buffer.primitives;\r\n            for (let primitiveIndex = 0; primitiveIndex < primitives.length; primitiveIndex++) {\r\n                let primitive = primitives[primitiveIndex];\r\n\r\n                let bufferViewCreator = new BufferViewCreator (mainJson, meshData.offsets[primitiveIndex]);\r\n                let indicesBufferView = bufferViewCreator.AddBufferView (primitive.indices.length * this.components.index.size, GltfBufferType.ELEMENT_ARRAY_BUFFER);\r\n                let verticesBufferView = bufferViewCreator.AddBufferView (primitive.vertices.length * this.components.number.size, GltfBufferType.ARRAY_BUFFER);\r\n                let colorsBufferView = null;\r\n                if (primitive.colors.length > 0) {\r\n                    colorsBufferView = bufferViewCreator.AddBufferView (primitive.colors.length * this.components.number.size, GltfBufferType.ARRAY_BUFFER);\r\n                }\r\n                let normalsBufferView = bufferViewCreator.AddBufferView (primitive.normals.length * this.components.number.size, GltfBufferType.ARRAY_BUFFER);\r\n                let uvsBufferView = null;\r\n                if (primitive.uvs.length > 0) {\r\n                    uvsBufferView = bufferViewCreator.AddBufferView (primitive.uvs.length * this.components.number.size, GltfBufferType.ARRAY_BUFFER);\r\n                }\r\n\r\n                let jsonPrimitive = {\r\n                    attributes : {},\r\n                    mode : 4,\r\n                    material : primitive.material\r\n                };\r\n\r\n                let bounds = primitive.GetBounds ();\r\n\r\n                mainJson.accessors.push ({\r\n                    bufferView : indicesBufferView,\r\n                    byteOffset : 0,\r\n                    componentType : this.components.index.type,\r\n                    count : primitive.indices.length,\r\n                    type : 'SCALAR'\r\n                });\r\n                jsonPrimitive.indices = mainJson.accessors.length - 1;\r\n\r\n                mainJson.accessors.push ({\r\n                    bufferView : verticesBufferView,\r\n                    byteOffset : 0,\r\n                    componentType : this.components.number.type,\r\n                    count : primitive.vertices.length / 3,\r\n                    min : bounds.min,\r\n                    max : bounds.max,\r\n                    type : 'VEC3'\r\n                });\r\n                jsonPrimitive.attributes.POSITION = mainJson.accessors.length - 1;\r\n\r\n                if (colorsBufferView !== null) {\r\n                    mainJson.accessors.push ({\r\n                        bufferView : colorsBufferView,\r\n                        byteOffset : 0,\r\n                        componentType : this.components.number.type,\r\n                        count : primitive.colors.length / 3,\r\n                        type : 'VEC3'\r\n                    });\r\n                    jsonPrimitive.attributes.COLOR_0 = mainJson.accessors.length - 1;\r\n                }\r\n\r\n                mainJson.accessors.push ({\r\n                    bufferView : normalsBufferView,\r\n                    byteOffset : 0,\r\n                    componentType : this.components.number.type,\r\n                    count : primitive.normals.length / 3,\r\n                    type : 'VEC3'\r\n                });\r\n                jsonPrimitive.attributes.NORMAL = mainJson.accessors.length - 1;\r\n\r\n                if (uvsBufferView !== null) {\r\n                    mainJson.accessors.push ({\r\n                        bufferView : uvsBufferView,\r\n                        byteOffset : 0,\r\n                        componentType : this.components.number.type,\r\n                        count : primitive.uvs.length / 2,\r\n                        type : 'VEC2'\r\n                    });\r\n                    jsonPrimitive.attributes.TEXCOORD_0 = mainJson.accessors.length - 1;\r\n                }\r\n\r\n                jsonMesh.primitives.push (jsonPrimitive);\r\n            }\r\n\r\n            mainJson.meshes.push (jsonMesh);\r\n        }\r\n\r\n        return mainJson;\r\n    }\r\n\r\n    ExportMaterials (exporterModel, mainJson, addTexture)\r\n    {\r\n        function ExportMaterial (obj, mainJson, material, addTexture)\r\n        {\r\n            function ColorToRGBA (color, opacity)\r\n            {\r\n                return [\r\n                    SRGBToLinear (color.r / 255.0),\r\n                    SRGBToLinear (color.g / 255.0),\r\n                    SRGBToLinear (color.b / 255.0),\r\n                    opacity\r\n                ];\r\n            }\r\n\r\n            function ColorToRGB (color)\r\n            {\r\n                return [\r\n                    SRGBToLinear (color.r / 255.0),\r\n                    SRGBToLinear (color.g / 255.0),\r\n                    SRGBToLinear (color.b / 255.0)\r\n                ];\r\n            }\r\n\r\n            function GetTextureParams (mainJson, texture, addTexture)\r\n            {\r\n                if (texture === null || !texture.IsValid ()) {\r\n                    return null;\r\n                }\r\n\r\n                if (mainJson.images === undefined) {\r\n                    mainJson.images = [];\r\n                }\r\n                if (mainJson.textures === undefined) {\r\n                    mainJson.textures = [];\r\n                }\r\n\r\n                let textureIndex = addTexture (texture);\r\n                let textureParams = {\r\n                    index : textureIndex\r\n                };\r\n\r\n                if (texture.HasTransformation ()) {\r\n                    let extensionName = 'KHR_texture_transform';\r\n                    if (mainJson.extensionsUsed === undefined) {\r\n                        mainJson.extensionsUsed = [];\r\n                    }\r\n                    if (mainJson.extensionsUsed.indexOf (extensionName) === -1) {\r\n                        mainJson.extensionsUsed.push (extensionName);\r\n                    }\r\n                    textureParams.extensions = {\r\n                        KHR_texture_transform : {\r\n                            offset : [texture.offset.x, -texture.offset.y],\r\n                            scale : [texture.scale.x, texture.scale.y],\r\n                            rotation : -texture.rotation\r\n                        }\r\n                    };\r\n                }\r\n\r\n                return textureParams;\r\n            }\r\n\r\n            let jsonMaterial = {\r\n                name : obj.GetExportedMaterialName (material.name),\r\n                pbrMetallicRoughness : {\r\n                    baseColorFactor : ColorToRGBA (material.color, material.opacity)\r\n                },\r\n                emissiveFactor : ColorToRGB (material.emissive),\r\n                doubleSided : true,\r\n                alphaMode : 'OPAQUE'\r\n            };\r\n\r\n            if (material.transparent) {\r\n                // TODO: mask, alphaCutoff?\r\n                jsonMaterial.alphaMode = 'BLEND';\r\n            }\r\n\r\n            let baseColorTexture = GetTextureParams (mainJson, material.diffuseMap, addTexture);\r\n            if (baseColorTexture !== null) {\r\n                if (!material.multiplyDiffuseMap) {\r\n                    jsonMaterial.pbrMetallicRoughness.baseColorFactor = ColorToRGBA (new RGBColor (255, 255, 255), material.opacity);\r\n                }\r\n                jsonMaterial.pbrMetallicRoughness.baseColorTexture = baseColorTexture;\r\n            }\r\n            if (material.type === MaterialType.Physical) {\r\n                let metallicTexture = GetTextureParams (mainJson, material.metalnessMap, addTexture);\r\n                if (metallicTexture !== null) {\r\n                    jsonMaterial.pbrMetallicRoughness.metallicRoughnessTexture = metallicTexture;\r\n                } else {\r\n                    jsonMaterial.pbrMetallicRoughness.metallicFactor = material.metalness;\r\n                    jsonMaterial.pbrMetallicRoughness.roughnessFactor = material.roughness;\r\n                }\r\n            }\r\n            let normalTexture = GetTextureParams (mainJson, material.normalMap, addTexture);\r\n            if (normalTexture !== null) {\r\n                jsonMaterial.normalTexture = normalTexture;\r\n            }\r\n            let emissiveTexture = GetTextureParams (mainJson, material.emissiveMap, addTexture);\r\n            if (emissiveTexture !== null) {\r\n                jsonMaterial.emissiveTexture = emissiveTexture;\r\n            }\r\n\r\n            mainJson.materials.push (jsonMaterial);\r\n        }\r\n\r\n        for (let materialIndex = 0; materialIndex < exporterModel.MaterialCount (); materialIndex++) {\r\n            let material = exporterModel.GetMaterial (materialIndex);\r\n            ExportMaterial (this, mainJson, material, addTexture);\r\n        }\r\n    }\r\n}\n\nclass ExporterSettings\r\n{\r\n    constructor (settings)\r\n    {\r\n        this.transformation = new Transformation ();\r\n        this.isMeshVisible = (meshInstanceId) => {\r\n            return true;\r\n        };\r\n\r\n        CopyObjectAttributes (settings, this);\r\n    }\r\n}\r\n\r\nclass ExporterModel\r\n{\r\n    constructor (model, settings)\r\n    {\r\n        this.model = model;\r\n        this.settings = settings || new ExporterSettings ();\r\n        this.visibleMeshes = null;\r\n        this.meshToVisibleMeshIndex = null;\r\n    }\r\n\r\n    GetModel ()\r\n    {\r\n        return this.model;\r\n    }\r\n\r\n    MaterialCount ()\r\n    {\r\n        return this.model.MaterialCount ();\r\n    }\r\n\r\n    GetMaterial (index)\r\n    {\r\n        return this.model.GetMaterial (index);\r\n    }\r\n\r\n    VertexCount ()\r\n    {\r\n        let vertexCount = 0;\r\n        this.EnumerateMeshInstances ((meshInstance) => {\r\n            vertexCount += meshInstance.VertexCount ();\r\n        });\r\n        return vertexCount;\r\n    }\r\n\r\n    TriangleCount ()\r\n    {\r\n        let triangleCount = 0;\r\n        this.EnumerateMeshInstances ((meshInstance) => {\r\n            triangleCount += meshInstance.TriangleCount ();\r\n        });\r\n        return triangleCount;\r\n    }\r\n\r\n    MeshCount ()\r\n    {\r\n        let meshCount = 0;\r\n        this.EnumerateMeshes ((mesh) => {\r\n            meshCount += 1;\r\n        });\r\n        return meshCount;\r\n    }\r\n\r\n    EnumerateMeshes (onMesh)\r\n    {\r\n        this.FillVisibleMeshCache ();\r\n        for (let meshIndex = 0; meshIndex < this.model.MeshCount (); meshIndex++) {\r\n            if (this.visibleMeshes.has (meshIndex)) {\r\n                let mesh = this.model.GetMesh (meshIndex);\r\n                onMesh (mesh);\r\n            }\r\n        }\r\n    }\r\n\r\n    MapMeshIndex (meshIndex)\r\n    {\r\n        this.FillVisibleMeshCache ();\r\n        return this.meshToVisibleMeshIndex.get (meshIndex);\r\n    }\r\n\r\n    IsMeshInstanceVisible (meshInstanceId)\r\n    {\r\n        return this.settings.isMeshVisible (meshInstanceId);\r\n    }\r\n\r\n    MeshInstanceCount ()\r\n    {\r\n        let meshInstanceCount = 0;\r\n        this.EnumerateMeshInstances ((meshInstance) => {\r\n            meshInstanceCount += 1;\r\n        });\r\n        return meshInstanceCount;\r\n    }\r\n\r\n    EnumerateMeshInstances (onMeshInstance)\r\n    {\r\n        this.model.EnumerateMeshInstances ((meshInstance) => {\r\n            if (this.settings.isMeshVisible (meshInstance.GetId ())) {\r\n                onMeshInstance (meshInstance);\r\n            }\r\n        });\r\n    }\r\n\r\n    EnumerateTransformedMeshInstances (onMesh)\r\n    {\r\n        this.EnumerateMeshInstances ((meshInstance) => {\r\n            let transformation = meshInstance.GetTransformation ();\r\n            if (!this.settings.transformation.IsIdentity ()) {\r\n                transformation.Append (this.settings.transformation);\r\n            }\r\n\r\n            let mesh = meshInstance.GetMesh ();\r\n            let transformed = mesh.Clone ();\r\n            if (!transformation.IsIdentity ()) {\r\n                TransformMesh (transformed, transformation);\r\n            }\r\n\r\n            onMesh (transformed);\r\n        });\r\n    }\r\n\r\n    EnumerateVerticesAndTriangles (callbacks)\r\n    {\r\n        let transformedMeshes = [];\r\n        this.EnumerateTransformedMeshInstances ((mesh) => {\r\n            transformedMeshes.push (mesh);\r\n        });\r\n\r\n        for (let mesh of transformedMeshes) {\r\n            mesh.EnumerateVertices ((vertex) => {\r\n                callbacks.onVertex (vertex.x, vertex.y, vertex.z);\r\n            });\r\n        }\r\n\r\n        let vertexOffset = 0;\r\n        for (let mesh of transformedMeshes) {\r\n            mesh.EnumerateTriangleVertexIndices ((v0, v1, v2) => {\r\n                callbacks.onTriangle (v0 + vertexOffset, v1 + vertexOffset, v2 + vertexOffset);\r\n            });\r\n            vertexOffset += mesh.VertexCount ();\r\n        }\r\n    }\r\n\r\n    EnumerateTrianglesWithNormals (onTriangle)\r\n    {\r\n        this.EnumerateTransformedMeshInstances ((mesh) => {\r\n            mesh.EnumerateTriangleVertices ((v0, v1, v2) => {\r\n                let normal = CalculateTriangleNormal (v0, v1, v2);\r\n                onTriangle (v0, v1, v2, normal);\r\n            });\r\n        });\r\n    }\r\n\r\n    FillVisibleMeshCache ()\r\n    {\r\n        if (this.visibleMeshes !== null && this.meshToVisibleMeshIndex !== null) {\r\n            return;\r\n        }\r\n\r\n        this.visibleMeshes = new Set ();\r\n        this.model.EnumerateMeshInstances ((meshInstance) => {\r\n            let meshInstanceId = meshInstance.GetId ();\r\n            if (this.settings.isMeshVisible (meshInstanceId)) {\r\n                this.visibleMeshes.add (meshInstanceId.meshIndex);\r\n            }\r\n        });\r\n\r\n        this.meshToVisibleMeshIndex = new Map ();\r\n        let visibleMeshIndex = 0;\r\n        for (let meshIndex = 0; meshIndex < this.model.MeshCount (); meshIndex++) {\r\n            if (this.visibleMeshes.has (meshIndex)) {\r\n                this.meshToVisibleMeshIndex.set (meshIndex, visibleMeshIndex);\r\n                visibleMeshIndex += 1;\r\n            }\r\n        }\r\n    }\r\n}\n\nclass TextWriter\r\n{\r\n\tconstructor ()\r\n\t{\r\n\t\tthis.text = '';\r\n\t\tthis.indentation = 0;\r\n\t}\r\n\r\n\tGetText ()\r\n\t{\r\n\t\treturn this.text;\r\n\t}\r\n\r\n\tIndent (diff)\r\n\t{\r\n\t\tthis.indentation += diff;\r\n\t}\r\n\r\n\tWriteArrayLine (arr)\r\n\t{\r\n\t\tthis.WriteLine (arr.join (' '));\r\n\t}\r\n\r\n\tWriteLine (str)\r\n\t{\r\n\t\tthis.WriteIndentation ();\r\n\t\tthis.Write (str + '\\n');\r\n\t}\r\n\r\n\tWriteIndentation ()\r\n\t{\r\n\t\tfor (let i = 0; i < this.indentation; i++) {\r\n\t\t\tthis.Write ('  ');\r\n\t\t}\r\n\t}\r\n\r\n\tWrite (str)\r\n\t{\r\n\t\tthis.text += str;\r\n\t}\r\n}\n\nclass ExporterObj extends ExporterBase\r\n{\r\n    constructor ()\r\n    {\r\n        super ();\r\n    }\r\n\r\n    CanExport (format, extension)\r\n    {\r\n        return format === FileFormat.Text && extension === 'obj';\r\n    }\r\n\r\n    ExportContent (exporterModel, format, files, onFinish)\r\n    {\r\n        function WriteTexture (mtlWriter, keyword, texture, files)\r\n        {\r\n            if (texture === null || !texture.IsValid ()) {\r\n                return;\r\n            }\r\n            let fileName = GetFileName (texture.name);\r\n            mtlWriter.WriteArrayLine ([keyword, fileName]);\r\n\r\n            let fileIndex = files.findIndex ((file) => {\r\n                return file.GetName () === fileName;\r\n            });\r\n            if (fileIndex === -1) {\r\n                let textureFile = new ExportedFile (fileName);\r\n                textureFile.SetBufferContent (texture.buffer);\r\n                files.push (textureFile);\r\n            }\r\n        }\r\n\r\n        let mtlFile = new ExportedFile ('model.mtl');\r\n        let objFile = new ExportedFile ('model.obj');\r\n\r\n        files.push (mtlFile);\r\n        files.push (objFile);\r\n\r\n        let mtlWriter = new TextWriter ();\r\n        mtlWriter.WriteLine (this.GetHeaderText ());\r\n        for (let materialIndex = 0; materialIndex < exporterModel.MaterialCount (); materialIndex++) {\r\n            let material = exporterModel.GetMaterial (materialIndex);\r\n            mtlWriter.WriteArrayLine (['newmtl', this.GetExportedMaterialName (material.name)]);\r\n            mtlWriter.WriteArrayLine (['Kd', material.color.r / 255.0, material.color.g / 255.0, material.color.b / 255.0]);\r\n            mtlWriter.WriteArrayLine (['d', material.opacity]);\r\n            if (material.type === MaterialType.Phong) {\r\n                mtlWriter.WriteArrayLine (['Ka', material.ambient.r / 255.0, material.ambient.g / 255.0, material.ambient.b / 255.0]);\r\n                mtlWriter.WriteArrayLine (['Ks', material.specular.r / 255.0, material.specular.g / 255.0, material.specular.b / 255.0]);\r\n                mtlWriter.WriteArrayLine (['Ns', material.shininess * 1000.0]);\r\n            }\r\n            WriteTexture (mtlWriter, 'map_Kd', material.diffuseMap, files);\r\n            if (material.type === MaterialType.Phong) {\r\n                WriteTexture (mtlWriter, 'map_Ks', material.specularMap, files);\r\n            }\r\n            WriteTexture (mtlWriter, 'bump', material.bumpMap, files);\r\n        }\r\n        mtlFile.SetTextContent (mtlWriter.GetText ());\r\n\r\n        let objWriter = new TextWriter ();\r\n        objWriter.WriteLine (this.GetHeaderText ());\r\n        objWriter.WriteArrayLine (['mtllib', mtlFile.GetName ()]);\r\n        let vertexOffset = 0;\r\n        let normalOffset = 0;\r\n        let uvOffset = 0;\r\n        let usedMaterialName = null;\r\n        exporterModel.EnumerateTransformedMeshInstances ((mesh) => {\r\n            objWriter.WriteArrayLine (['g', this.GetExportedMeshName (mesh.GetName ())]);\r\n            for (let vertexIndex = 0; vertexIndex < mesh.VertexCount (); vertexIndex++) {\r\n                let vertex = mesh.GetVertex (vertexIndex);\r\n                objWriter.WriteArrayLine (['v', vertex.x, vertex.y, vertex.z]);\r\n            }\r\n            for (let normalIndex = 0; normalIndex < mesh.NormalCount (); normalIndex++) {\r\n                let normal = mesh.GetNormal (normalIndex);\r\n                objWriter.WriteArrayLine (['vn', normal.x, normal.y, normal.z]);\r\n            }\r\n            for (let textureUVIndex = 0; textureUVIndex < mesh.TextureUVCount (); textureUVIndex++) {\r\n                let uv = mesh.GetTextureUV (textureUVIndex);\r\n                objWriter.WriteArrayLine (['vt', uv.x, uv.y]);\r\n            }\r\n            for (let triangleIndex = 0; triangleIndex < mesh.TriangleCount (); triangleIndex++) {\r\n                let triangle = mesh.GetTriangle (triangleIndex);\r\n                let v0 = triangle.v0 + vertexOffset + 1;\r\n                let v1 = triangle.v1 + vertexOffset + 1;\r\n                let v2 = triangle.v2 + vertexOffset + 1;\r\n                let n0 = triangle.n0 + normalOffset + 1;\r\n                let n1 = triangle.n1 + normalOffset + 1;\r\n                let n2 = triangle.n2 + normalOffset + 1;\r\n                let u0 = '';\r\n                let u1 = '';\r\n                let u2 = '';\r\n                if (triangle.HasTextureUVs ()) {\r\n                    u0 = triangle.u0 + uvOffset + 1;\r\n                    u1 = triangle.u1 + uvOffset + 1;\r\n                    u2 = triangle.u2 + uvOffset + 1;\r\n                }\r\n                if (triangle.mat !== null) {\r\n                    let material = exporterModel.GetMaterial (triangle.mat);\r\n                    let materialName = this.GetExportedMaterialName (material.name);\r\n                    if (materialName !== usedMaterialName) {\r\n                        objWriter.WriteArrayLine (['usemtl', materialName]);\r\n                        usedMaterialName = materialName;\r\n                    }\r\n                }\r\n                objWriter.WriteArrayLine (['f', [v0, u0, n0].join ('/'), [v1, u1, n1].join ('/'), [v2, u2, n2].join ('/')]);\r\n            }\r\n            for (let lineIndex = 0; lineIndex < mesh.LineCount (); lineIndex++) {\r\n                let line = mesh.GetLine (lineIndex);\r\n                let vertexIndices = [];\r\n                for (let vertexIndex = 0; vertexIndex < line.vertices.length; vertexIndex++) {\r\n                    vertexIndices.push (line.vertices[vertexIndex] + vertexOffset + 1);\r\n                }\r\n                if (line.mat !== null) {\r\n                    let material = exporterModel.GetMaterial (line.mat);\r\n                    let materialName = this.GetExportedMaterialName (material.name);\r\n                    if (materialName !== usedMaterialName) {\r\n                        objWriter.WriteArrayLine (['usemtl', materialName]);\r\n                        usedMaterialName = materialName;\r\n                    }\r\n                }\r\n                objWriter.WriteArrayLine (['l', vertexIndices.join (' ')]);\r\n            }\r\n            vertexOffset += mesh.VertexCount ();\r\n            normalOffset += mesh.NormalCount ();\r\n            uvOffset += mesh.TextureUVCount ();\r\n        });\r\n\r\n        objFile.SetTextContent (objWriter.GetText ());\r\n        onFinish ();\r\n    }\r\n\r\n    GetHeaderText ()\r\n    {\r\n        return '# exported by https://3dviewer.net';\r\n    }\r\n}\n\nclass ExporterOff extends ExporterBase\r\n{\r\n\tconstructor ()\r\n\t{\r\n\t\tsuper ();\r\n\t}\r\n\r\n    CanExport (format, extension)\r\n    {\r\n        return format === FileFormat.Text && extension === 'off';\r\n    }\r\n\r\n\tExportContent (exporterModel, format, files, onFinish)\r\n\t{\r\n\t\tlet offFile = new ExportedFile ('model.off');\r\n\t\tfiles.push (offFile);\r\n\r\n\t\tlet offWriter = new TextWriter ();\r\n\t\toffWriter.WriteLine ('OFF');\r\n\t\toffWriter.WriteArrayLine ([exporterModel.VertexCount (), exporterModel.TriangleCount (), 0]);\r\n\r\n\t\texporterModel.EnumerateVerticesAndTriangles ({\r\n\t\t\tonVertex : function (x, y, z) {\r\n\t\t\t\toffWriter.WriteArrayLine ([x, y, z]);\r\n\t\t\t},\r\n\t\t\tonTriangle : function (v0, v1, v2) {\r\n\t\t\t\toffWriter.WriteArrayLine ([3, v0, v1, v2]);\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\toffFile.SetTextContent (offWriter.GetText ());\r\n\t\tonFinish ();\r\n\t}\r\n}\n\nclass ExporterPly extends ExporterBase\r\n{\r\n\tconstructor ()\r\n\t{\r\n\t\tsuper ();\r\n\t}\r\n\r\n    CanExport (format, extension)\r\n    {\r\n        return (format === FileFormat.Text || format === FileFormat.Binary) && extension === 'ply';\r\n    }\r\n\r\n\tExportContent (exporterModel, format, files, onFinish)\r\n\t{\r\n\t\tif (format === FileFormat.Text) {\r\n\t\t\tthis.ExportText (exporterModel, files);\r\n\t\t} else {\r\n\t\t\tthis.ExportBinary (exporterModel, files);\r\n\t\t}\r\n\t\tonFinish ();\r\n\t}\r\n\r\n\tExportText (exporterModel, files)\r\n\t{\r\n\t\tlet plyFile = new ExportedFile ('model.ply');\r\n\t\tfiles.push (plyFile);\r\n\r\n\t\tlet plyWriter = new TextWriter ();\r\n\r\n\t\tlet vertexCount = exporterModel.VertexCount ();\r\n\t\tlet triangleCount = exporterModel.TriangleCount ();\r\n\t\tlet headerText = this.GetHeaderText ('ascii', vertexCount, triangleCount);\r\n\t\tplyWriter.Write (headerText);\r\n\r\n\t\texporterModel.EnumerateVerticesAndTriangles ({\r\n\t\t\tonVertex : function (x, y, z) {\r\n\t\t\t\tplyWriter.WriteArrayLine ([x, y, z]);\r\n\t\t\t},\r\n\t\t\tonTriangle : function (v0, v1, v2) {\r\n\t\t\t\tplyWriter.WriteArrayLine ([3, v0, v1, v2]);\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\tplyFile.SetTextContent (plyWriter.GetText ());\r\n\t}\r\n\r\n\tExportBinary (exporterModel, files)\r\n\t{\r\n\t\tlet plyFile = new ExportedFile ('model.ply');\r\n\t\tfiles.push (plyFile);\r\n\r\n\t\tlet vertexCount = exporterModel.VertexCount ();\r\n\t\tlet triangleCount = exporterModel.TriangleCount ();\r\n\t\tlet headerText = this.GetHeaderText ('binary_little_endian', vertexCount, triangleCount);\r\n\r\n\t\tlet fullByteLength = headerText.length + vertexCount * 3 * 4 + triangleCount * (1 + 3 * 4);\r\n\t\tlet plyWriter = new BinaryWriter (fullByteLength, true);\r\n\r\n\t\tfor (let i = 0; i < headerText.length; i++) {\r\n\t\t\tplyWriter.WriteUnsignedCharacter8 (headerText.charCodeAt (i));\r\n\t\t}\r\n\r\n\t\texporterModel.EnumerateVerticesAndTriangles ({\r\n\t\t\tonVertex : function (x, y, z) {\r\n\t\t\t\tplyWriter.WriteFloat32 (x);\r\n\t\t\t\tplyWriter.WriteFloat32 (y);\r\n\t\t\t\tplyWriter.WriteFloat32 (z);\r\n\t\t\t},\r\n\t\t\tonTriangle : function (v0, v1, v2) {\r\n\t\t\t\tplyWriter.WriteUnsignedCharacter8 (3);\r\n\t\t\t\tplyWriter.WriteInteger32 (v0);\r\n\t\t\t\tplyWriter.WriteInteger32 (v1);\r\n\t\t\t\tplyWriter.WriteInteger32 (v2);\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\tplyFile.SetBufferContent (plyWriter.GetBuffer ());\r\n\t}\r\n\r\n\tGetHeaderText (format, vertexCount, triangleCount)\r\n\t{\r\n\t\tlet headerWriter = new TextWriter ();\r\n\t\theaderWriter.WriteLine ('ply');\r\n\t\theaderWriter.WriteLine ('format ' + format + ' 1.0');\r\n\t\theaderWriter.WriteLine ('element vertex ' + vertexCount);\r\n\t\theaderWriter.WriteLine ('property float x');\r\n\t\theaderWriter.WriteLine ('property float y');\r\n\t\theaderWriter.WriteLine ('property float z');\r\n\t\theaderWriter.WriteLine ('element face ' + triangleCount);\r\n\t\theaderWriter.WriteLine ('property list uchar int vertex_index');\r\n\t\theaderWriter.WriteLine ('end_header');\r\n\t\treturn headerWriter.GetText ();\r\n\t}\r\n}\n\nclass ExporterStl extends ExporterBase\r\n{\r\n\tconstructor ()\r\n\t{\r\n\t\tsuper ();\r\n\t}\r\n\r\n    CanExport (format, extension)\r\n    {\r\n        return (format === FileFormat.Text || format === FileFormat.Binary) && extension === 'stl';\r\n    }\r\n\r\n\tExportContent (exporterModel, format, files, onFinish)\r\n\t{\r\n\t\tif (format === FileFormat.Text) {\r\n\t\t\tthis.ExportText (exporterModel, files);\r\n\t\t} else {\r\n\t\t\tthis.ExportBinary (exporterModel, files);\r\n\t\t}\r\n\t\tonFinish ();\r\n\t}\r\n\r\n\tExportText (exporterModel, files)\r\n\t{\r\n\t\tlet stlFile = new ExportedFile ('model.stl');\r\n\t\tfiles.push (stlFile);\r\n\r\n\t\tlet stlWriter = new TextWriter ();\r\n\t\tstlWriter.WriteLine ('solid Model');\r\n\t\texporterModel.EnumerateTrianglesWithNormals ((v0, v1, v2, normal) => {\r\n\t\t\tstlWriter.WriteArrayLine (['facet', 'normal', normal.x, normal.y, normal.z]);\r\n\t\t\tstlWriter.Indent (1);\r\n\t\t\tstlWriter.WriteLine ('outer loop');\r\n\t\t\tstlWriter.Indent (1);\r\n\t\t\tstlWriter.WriteArrayLine (['vertex', v0.x, v0.y, v0.z]);\r\n\t\t\tstlWriter.WriteArrayLine (['vertex', v1.x, v1.y, v1.z]);\r\n\t\t\tstlWriter.WriteArrayLine (['vertex', v2.x, v2.y, v2.z]);\r\n\t\t\tstlWriter.Indent (-1);\r\n\t\t\tstlWriter.WriteLine ('endloop');\r\n\t\t\tstlWriter.Indent (-1);\r\n\t\t\tstlWriter.WriteLine ('endfacet');\r\n\t\t});\r\n\t\tstlWriter.WriteLine ('endsolid Model');\r\n\r\n\t\tstlFile.SetTextContent (stlWriter.GetText ());\r\n\t}\r\n\r\n\tExportBinary (exporterModel, files)\r\n\t{\r\n\t\tlet stlFile = new ExportedFile ('model.stl');\r\n\t\tfiles.push (stlFile);\r\n\r\n\t\tlet triangleCount = exporterModel.TriangleCount ();\r\n\t\tlet headerSize = 80;\r\n\t\tlet fullByteLength = headerSize + 4 + triangleCount * 50;\r\n\t\tlet stlWriter = new BinaryWriter (fullByteLength, true);\r\n\r\n\t\tfor (let i = 0; i < headerSize; i++) {\r\n\t\t\tstlWriter.WriteUnsignedCharacter8 (0);\r\n\t\t}\r\n\r\n\t\tstlWriter.WriteUnsignedInteger32 (triangleCount);\r\n\t\texporterModel.EnumerateTrianglesWithNormals ((v0, v1, v2, normal) => {\r\n\t\t\tstlWriter.WriteFloat32 (normal.x);\r\n\t\t\tstlWriter.WriteFloat32 (normal.y);\r\n\t\t\tstlWriter.WriteFloat32 (normal.z);\r\n\r\n\t\t\tstlWriter.WriteFloat32 (v0.x);\r\n\t\t\tstlWriter.WriteFloat32 (v0.y);\r\n\t\t\tstlWriter.WriteFloat32 (v0.z);\r\n\r\n\t\t\tstlWriter.WriteFloat32 (v1.x);\r\n\t\t\tstlWriter.WriteFloat32 (v1.y);\r\n\t\t\tstlWriter.WriteFloat32 (v1.z);\r\n\r\n\t\t\tstlWriter.WriteFloat32 (v2.x);\r\n\t\t\tstlWriter.WriteFloat32 (v2.y);\r\n\t\t\tstlWriter.WriteFloat32 (v2.z);\r\n\r\n\t\t\tstlWriter.WriteUnsignedInteger16 (0);\r\n\t\t});\r\n\r\n\t\tstlFile.SetBufferContent (stlWriter.GetBuffer ());\r\n\t}\r\n}\n\nclass Exporter\r\n{\r\n    constructor ()\r\n    {\r\n        this.exporters = [\r\n            new ExporterObj (),\r\n            new ExporterStl (),\r\n            new ExporterPly (),\r\n            new ExporterOff (),\r\n            new ExporterGltf (),\r\n            new Exporter3dm (),\r\n            new ExporterBim ()\r\n        ];\r\n    }\r\n\r\n    AddExporter (exporter)\r\n    {\r\n        this.exporters.push (exporter);\r\n    }\r\n\r\n    Export (model, settings, format, extension, callbacks)\r\n    {\r\n        let exporter = null;\r\n        for (let i = 0; i < this.exporters.length; i++) {\r\n            let currentExporter = this.exporters[i];\r\n            if (currentExporter.CanExport (format, extension)) {\r\n                exporter = currentExporter;\r\n                break;\r\n            }\r\n        }\r\n        if (exporter === null) {\r\n            callbacks.onError ();\r\n            return;\r\n        }\r\n\r\n        let exporterModel = new ExporterModel (model, settings);\r\n        exporter.Export (exporterModel, format, (files) => {\r\n            if (files.length === 0) {\r\n                callbacks.onError ();\r\n            } else {\r\n                callbacks.onSuccess (files);\r\n            }\r\n        });\r\n    }\r\n}\n\nclass Box3D\r\n{\r\n    constructor (min, max)\r\n    {\r\n        this.min = min;\r\n        this.max = max;\r\n    }\r\n\r\n    GetMin ()\r\n    {\r\n        return this.min;\r\n    }\r\n\r\n    GetMax ()\r\n    {\r\n        return this.max;\r\n    }\r\n\r\n    GetCenter ()\r\n    {\r\n        return new Coord3D (\r\n            (this.min.x + this.max.x) / 2.0,\r\n            (this.min.y + this.max.y) / 2.0,\r\n            (this.min.z + this.max.z) / 2.0\r\n        );\r\n    }\r\n}\r\n\r\nclass BoundingBoxCalculator3D\r\n{\r\n    constructor ()\r\n    {\r\n        this.box = new Box3D (\r\n            new Coord3D (Infinity, Infinity, Infinity),\r\n            new Coord3D (-Infinity, -Infinity, -Infinity)\r\n        );\r\n        this.isValid = false;\r\n    }\r\n\r\n    GetBox ()\r\n    {\r\n        if (!this.isValid) {\r\n            return null;\r\n        }\r\n        return this.box;\r\n    }\r\n\r\n    AddPoint (point)\r\n    {\r\n        this.box.min.x = Math.min (this.box.min.x, point.x);\r\n        this.box.min.y = Math.min (this.box.min.y, point.y);\r\n        this.box.min.z = Math.min (this.box.min.z, point.z);\r\n        this.box.max.x = Math.max (this.box.max.x, point.x);\r\n        this.box.max.y = Math.max (this.box.max.y, point.y);\r\n        this.box.max.z = Math.max (this.box.max.z, point.z);\r\n        this.isValid = true;\r\n    }\r\n}\n\nclass Segment2D\r\n{\r\n\tconstructor (beg, end)\r\n\t{\r\n\t\tthis.beg = beg;\r\n\t\tthis.end = end;\r\n\t}\r\n\r\n\tClone ()\r\n\t{\r\n\t\treturn new Segment2D (this.beg, this.end);\r\n\t}\r\n}\r\n\r\nfunction ProjectPointToSegment2D (segment, point)\r\n{\r\n    let begToEndVec = SubCoord2D (segment.end, segment.beg);\r\n    let begToPointVec = SubCoord2D (point, segment.beg);\r\n    let nom = DotVector2D (begToEndVec, begToPointVec);\r\n    let denom = DotVector2D (begToEndVec, begToEndVec);\r\n    if (IsZero (denom)) {\r\n        return segment.beg.Clone ();\r\n    }\r\n    let t = nom / denom;\r\n    t = Math.max (0.0, Math.min (1.0, t));\r\n    return new Coord2D (\r\n        segment.beg.x + t * begToEndVec.x,\r\n        segment.beg.y + t * begToEndVec.y\r\n    );\r\n}\r\n\r\nfunction SegmentPointDistance2D (segment, point)\r\n{\r\n    let projected = ProjectPointToSegment2D (segment, point);\r\n    return CoordDistance2D (projected, point);\r\n}\n\nclass OctreeNode\r\n{\r\n    constructor (boundingBox, level)\r\n    {\r\n        this.boundingBox = boundingBox;\r\n        this.level = level;\r\n        this.pointItems = [];\r\n        this.childNodes = [];\r\n    }\r\n\r\n    AddPoint (point, data, options)\r\n    {\r\n        let node = this.FindNodeForPoint (point);\r\n        if (node === null) {\r\n            return false;\r\n        }\r\n\r\n        if (node.FindPointDirectly (point) !== null) {\r\n            return false;\r\n        }\r\n\r\n        if (node.pointItems.length < options.maxPointsPerNode || node.level >= options.maxTreeDepth) {\r\n            node.AddPointDirectly (point, data);\r\n            return true;\r\n        } else {\r\n            node.CreateChildNodes ();\r\n            let oldPointItems = node.pointItems;\r\n            node.pointItems = [];\r\n            for (let i = 0; i < oldPointItems.length; i++) {\r\n                let pointItem = oldPointItems[i];\r\n                if (!node.AddPoint (pointItem.point, pointItem.data, options)) {\r\n                    return false;\r\n                }\r\n            }\r\n            return node.AddPoint (point, data, options);\r\n        }\r\n    }\r\n\r\n    FindPoint (point)\r\n    {\r\n        let node = this.FindNodeForPoint (point);\r\n        if (node === null) {\r\n            return null;\r\n        }\r\n        return node.FindPointDirectly (point);\r\n    }\r\n\r\n    AddPointDirectly (point, data)\r\n    {\r\n        this.pointItems.push ({\r\n            point : point,\r\n            data : data\r\n        });\r\n    }\r\n\r\n    FindPointDirectly (point)\r\n    {\r\n        for (let i = 0; i < this.pointItems.length; i++) {\r\n            let pointItem = this.pointItems[i];\r\n            if (CoordIsEqual3D (point, pointItem.point)) {\r\n                return pointItem.data;\r\n            }\r\n        }\r\n        return null;\r\n    }\r\n\r\n    FindNodeForPoint (point)\r\n    {\r\n        if (!this.IsPointInBounds (point)) {\r\n            return null;\r\n        }\r\n\r\n        if (this.childNodes.length === 0) {\r\n            return this;\r\n        }\r\n\r\n        for (let i = 0; i < this.childNodes.length; i++) {\r\n            let childNode = this.childNodes[i];\r\n            let foundNode = childNode.FindNodeForPoint (point);\r\n            if (foundNode !== null) {\r\n                return foundNode;\r\n            }\r\n        }\r\n\r\n        return null;\r\n    }\r\n\r\n    CreateChildNodes ()\r\n    {\r\n        function AddChildNode (node, minX, minY, minZ, sizeX, sizeY, sizeZ)\r\n        {\r\n            let box = new Box3D (\r\n                new Coord3D (minX, minY, minZ),\r\n                new Coord3D (minX + sizeX, minY + sizeY, minZ + sizeZ)\r\n            );\r\n            node.childNodes.push (new OctreeNode (box, node.level + 1));\r\n        }\r\n\r\n        let min = this.boundingBox.min;\r\n        let center = this.boundingBox.GetCenter ();\r\n        let sizeX = (this.boundingBox.max.x - this.boundingBox.min.x) / 2.0;\r\n        let sizeY = (this.boundingBox.max.y - this.boundingBox.min.y) / 2.0;\r\n        let sizeZ = (this.boundingBox.max.z - this.boundingBox.min.z) / 2.0;\r\n\r\n        AddChildNode (this, min.x, min.y, min.z, sizeX, sizeY, sizeZ);\r\n        AddChildNode (this, center.x, min.y, min.z, sizeX, sizeY, sizeZ);\r\n        AddChildNode (this, min.x, center.y, min.z, sizeX, sizeY, sizeZ);\r\n        AddChildNode (this, center.x, center.y, min.z, sizeX, sizeY, sizeZ);\r\n        AddChildNode (this, min.x, min.y, center.z, sizeX, sizeY, sizeZ);\r\n        AddChildNode (this, center.x, min.y, center.z, sizeX, sizeY, sizeZ);\r\n        AddChildNode (this, min.x, center.y, center.z, sizeX, sizeY, sizeZ);\r\n        AddChildNode (this, center.x, center.y, center.z, sizeX, sizeY, sizeZ);\r\n    }\r\n\r\n    IsPointInBounds (point)\r\n    {\r\n        let isEqual =\r\n            IsGreaterOrEqual (point.x, this.boundingBox.min.x) &&\r\n            IsGreaterOrEqual (point.y, this.boundingBox.min.y) &&\r\n            IsGreaterOrEqual (point.z, this.boundingBox.min.z) &&\r\n            IsLowerOrEqual (point.x, this.boundingBox.max.x) &&\r\n            IsLowerOrEqual (point.y, this.boundingBox.max.y) &&\r\n            IsLowerOrEqual (point.z, this.boundingBox.max.z);\r\n        return isEqual;\r\n    }\r\n}\r\n\r\nclass Octree\r\n{\r\n    constructor (boundingBox, options)\r\n    {\r\n        this.options = {\r\n            maxPointsPerNode : 10,\r\n            maxTreeDepth : 10\r\n        };\r\n        if (options !== undefined) {\r\n            if (options.maxPointsPerNode !== undefined) {\r\n                this.options.maxPointsPerNode = options.maxPointsPerNode;\r\n            }\r\n            if (options.maxTreeDepth !== undefined) {\r\n                this.options.maxTreeDepth = options.maxTreeDepth;\r\n            }\r\n        }\r\n        this.rootNode = new OctreeNode (boundingBox, 0);\r\n    }\r\n\r\n    AddPoint (point, data)\r\n    {\r\n        return this.rootNode.AddPoint (point, data, this.options);\r\n    }\r\n\r\n    FindPoint (point)\r\n    {\r\n        return this.rootNode.FindPoint (point);\r\n    }\r\n}\n\nfunction BezierTweenFunction (distance, index, count)\r\n{\r\n    let t = index / count;\r\n\treturn distance * (t * t * (3.0 - 2.0 * t));\r\n}\r\n\r\nfunction LinearTweenFunction (distance, index, count)\r\n{\r\n    return index * distance / count;\r\n}\r\n\r\nfunction ParabolicTweenFunction (distance, index, count)\r\n{\r\n    let t = index / count;\r\n    let t2 = t * t;\r\n    return distance * (t2 / (2.0 * (t2 - t) + 1.0));\r\n}\r\n\r\nfunction TweenCoord3D (a, b, count, tweenFunc)\r\n{\r\n\tlet dir = SubCoord3D (b, a).Normalize ();\r\n\tlet distance = CoordDistance3D (a, b);\r\n\tlet result = [];\r\n\tfor (let i = 0; i < count; i++) {\r\n        let step = tweenFunc (distance, i, count - 1);\r\n\t\tresult.push (a.Clone ().Offset (dir, step));\r\n\t}\r\n\treturn result;\r\n}\n\n/**\r\n * File representation class for importers.\r\n */\r\nclass InputFile\r\n{\r\n    /**\r\n     * @param {string} name Name of the file.\r\n     * @param {FileSource} source Source of the file.\r\n     * @param {string|File} data If the file source is url, this must be the url string. If the file source\r\n     * is file, this must be a {@link File} object.\r\n     */\r\n    constructor (name, source, data)\r\n    {\r\n        this.name = name;\r\n        this.source = source;\r\n        this.data = data;\r\n    }\r\n}\r\n\r\nfunction InputFilesFromUrls (urls)\r\n{\r\n    let inputFiles = [];\r\n    for (let url of urls) {\r\n        let fileName = GetFileName (url);\r\n        inputFiles.push (new InputFile (fileName, FileSource.Url, url));\r\n    }\r\n    return inputFiles;\r\n}\r\n\r\nfunction InputFilesFromFileObjects (fileObjects)\r\n{\r\n    let inputFiles = [];\r\n    for (let fileObject of fileObjects) {\r\n        let fileName = GetFileName (fileObject.name);\r\n        inputFiles.push (new InputFile (fileName, FileSource.File, fileObject));\r\n    }\r\n    return inputFiles;\r\n}\r\n\r\nclass ImporterFile\r\n{\r\n    constructor (name, source, data)\r\n    {\r\n        this.name = GetFileName (name);\r\n        this.extension = GetFileExtension (name);\r\n        this.source = source;\r\n        this.data = data;\r\n        this.content = null;\r\n    }\r\n\r\n    SetContent (content)\r\n    {\r\n        this.content = content;\r\n    }\r\n}\r\n\r\nclass ImporterFileList\r\n{\r\n    constructor ()\r\n    {\r\n        this.files = [];\r\n    }\r\n\r\n    FillFromInputFiles (inputFiles)\r\n    {\r\n        this.files = [];\r\n        for (let inputFile of inputFiles) {\r\n            let file = new ImporterFile (inputFile.name, inputFile.source, inputFile.data);\r\n            this.files.push (file);\r\n        }\r\n    }\r\n\r\n    ExtendFromFileList (fileList)\r\n    {\r\n        let files = fileList.GetFiles ();\r\n        for (let i = 0; i < files.length; i++) {\r\n            let file = files[i];\r\n            if (!this.ContainsFileByPath (file.name)) {\r\n                this.files.push (file);\r\n            }\r\n        }\r\n    }\r\n\r\n    GetFiles ()\r\n    {\r\n        return this.files;\r\n    }\r\n\r\n    GetContent (callbacks)\r\n    {\r\n        RunTasks (this.files.length, {\r\n            runTask : (index, onTaskComplete) => {\r\n                callbacks.onFileListProgress (index, this.files.length);\r\n                this.GetFileContent (this.files[index], {\r\n                    onReady : onTaskComplete,\r\n                    onProgress : callbacks.onFileLoadProgress\r\n                });\r\n            },\r\n            onReady : callbacks.onReady\r\n        });\r\n    }\r\n\r\n    ContainsFileByPath (filePath)\r\n    {\r\n        return this.FindFileByPath (filePath) !== null;\r\n    }\r\n\r\n    FindFileByPath (filePath)\r\n    {\r\n        let fileName = GetFileName (filePath).toLowerCase ();\r\n        for (let fileIndex = 0; fileIndex < this.files.length; fileIndex++) {\r\n            let file = this.files[fileIndex];\r\n            if (file.name.toLowerCase () === fileName) {\r\n                return file;\r\n            }\r\n        }\r\n        return null;\r\n    }\r\n\r\n    IsOnlyUrlSource ()\r\n    {\r\n        if (this.files.length === 0) {\r\n            return false;\r\n        }\r\n        for (let i = 0; i < this.files.length; i++) {\r\n            let file = this.files[i];\r\n            if (file.source !== FileSource.Url && file.source !== FileSource.Decompressed) {\r\n                return false;\r\n            }\r\n        }\r\n        return true;\r\n    }\r\n\r\n    AddFile (file)\r\n    {\r\n        this.files.push (file);\r\n    }\r\n\r\n    GetFileContent (file, callbacks)\r\n    {\r\n        if (file.content !== null) {\r\n            callbacks.onReady ();\r\n            return;\r\n        }\r\n        let loaderPromise = null;\r\n        if (file.source === FileSource.Url) {\r\n            loaderPromise = RequestUrl (file.data, callbacks.onProgress);\r\n        } else if (file.source === FileSource.File) {\r\n            loaderPromise = ReadFile (file.data, callbacks.onProgress);\r\n        } else {\r\n            callbacks.onReady ();\r\n            return;\r\n        }\r\n        loaderPromise.then ((content) => {\r\n            file.SetContent (content);\r\n        }).catch (() => {\r\n        }).finally (() => {\r\n            callbacks.onReady ();\r\n        });\r\n    }\r\n}\n\nclass NodeIdGenerator\r\n{\r\n    constructor ()\r\n    {\r\n        this.nextId = 0;\r\n    }\r\n\r\n    GenerateId ()\r\n    {\r\n        const id = this.nextId;\r\n        this.nextId += 1;\r\n        return id;\r\n    }\r\n}\r\n\r\nclass Node\r\n{\r\n    constructor ()\r\n    {\r\n        this.name = '';\r\n        this.parent = null;\r\n        this.transformation = new Transformation ();\r\n\r\n        this.childNodes = [];\r\n        this.meshIndices = [];\r\n\r\n        this.idGenerator = new NodeIdGenerator ();\r\n        this.id = this.idGenerator.GenerateId ();\r\n    }\r\n\r\n    IsEmpty ()\r\n    {\r\n        return this.childNodes.length === 0 && this.meshIndices.length === 0;\r\n    }\r\n\r\n    IsMeshNode ()\r\n    {\r\n        return this.childNodes.length === 0 && this.meshIndices.length === 1;\r\n    }\r\n\r\n    GetId ()\r\n    {\r\n        return this.id;\r\n    }\r\n\r\n    GetName ()\r\n    {\r\n        return this.name;\r\n    }\r\n\r\n    SetName (name)\r\n    {\r\n        this.name = name;\r\n    }\r\n\r\n    HasParent ()\r\n    {\r\n        return this.parent !== null;\r\n    }\r\n\r\n    GetParent ()\r\n    {\r\n        return this.parent;\r\n    }\r\n\r\n    GetTransformation ()\r\n    {\r\n        return this.transformation;\r\n    }\r\n\r\n    GetWorldTransformation ()\r\n    {\r\n        let transformation = this.transformation.Clone ();\r\n        let parent = this.parent;\r\n        while (parent !== null) {\r\n            transformation.Append (parent.transformation);\r\n            parent = parent.parent;\r\n        }\r\n        return transformation;\r\n    }\r\n\r\n    SetTransformation (transformation)\r\n    {\r\n        this.transformation = transformation;\r\n    }\r\n\r\n    AddChildNode (node)\r\n    {\r\n        node.parent = this;\r\n        node.idGenerator = this.idGenerator;\r\n        node.id = node.idGenerator.GenerateId ();\r\n        this.childNodes.push (node);\r\n        return this.childNodes.length - 1;\r\n    }\r\n\r\n    RemoveChildNode (node)\r\n    {\r\n        node.parent = null;\r\n        let index = this.childNodes.indexOf (node);\r\n        this.childNodes.splice (index, 1);\r\n    }\r\n\r\n    GetChildNodes ()\r\n    {\r\n        return this.childNodes;\r\n    }\r\n\r\n    ChildNodeCount ()\r\n    {\r\n        return this.childNodes.length;\r\n    }\r\n\r\n    GetChildNode (index)\r\n    {\r\n        return this.childNodes[index];\r\n    }\r\n\r\n    AddMeshIndex (index)\r\n    {\r\n        this.meshIndices.push (index);\r\n        return this.meshIndices.length - 1;\r\n    }\r\n\r\n    MeshIndexCount ()\r\n    {\r\n        return this.meshIndices.length;\r\n    }\r\n\r\n    GetMeshIndex (index)\r\n    {\r\n        return this.meshIndices[index];\r\n    }\r\n\r\n    GetMeshIndices ()\r\n    {\r\n        return this.meshIndices;\r\n    }\r\n\r\n    Enumerate (processor)\r\n    {\r\n        processor (this);\r\n        for (const childNode of this.childNodes) {\r\n            childNode.Enumerate (processor);\r\n        }\r\n    }\r\n\r\n    EnumerateChildren (processor)\r\n    {\r\n        for (const childNode of this.childNodes) {\r\n            processor (childNode);\r\n            childNode.EnumerateChildren (processor);\r\n        }\r\n    }\r\n\r\n    EnumerateMeshIndices (processor)\r\n    {\r\n        for (const meshIndex of this.meshIndices) {\r\n            processor (meshIndex);\r\n        }\r\n        for (const childNode of this.childNodes) {\r\n            childNode.EnumerateMeshIndices (processor);\r\n        }\r\n    }\r\n}\n\nconst Unit =\r\n{\r\n    Unknown : 0,\r\n    Millimeter : 1,\r\n    Centimeter : 2,\r\n    Meter : 3,\r\n    Inch : 4,\r\n    Foot : 5\r\n};\n\nclass Model extends ModelObject3D\r\n{\r\n    constructor ()\r\n    {\r\n        super ();\r\n        this.unit = Unit.Unknown;\r\n        this.root = new Node ();\r\n        this.materials = [];\r\n        this.meshes = [];\r\n    }\r\n\r\n    GetUnit ()\r\n    {\r\n        return this.unit;\r\n    }\r\n\r\n    SetUnit (unit)\r\n    {\r\n        this.unit = unit;\r\n    }\r\n\r\n    GetRootNode ()\r\n    {\r\n        return this.root;\r\n    }\r\n\r\n    NodeCount ()\r\n    {\r\n        let count = 0;\r\n        this.root.Enumerate ((node) => {\r\n            count += 1;\r\n        });\r\n        return count - 1;\r\n    }\r\n\r\n    MaterialCount ()\r\n    {\r\n        return this.materials.length;\r\n    }\r\n\r\n    MeshCount ()\r\n    {\r\n        return this.meshes.length;\r\n    }\r\n\r\n    MeshInstanceCount ()\r\n    {\r\n        let count = 0;\r\n        this.root.Enumerate ((node) => {\r\n            count += node.MeshIndexCount ();\r\n        });\r\n        return count;\r\n    }\r\n\r\n    VertexCount ()\r\n    {\r\n        let count = 0;\r\n        this.EnumerateMeshInstances ((meshInstance) => {\r\n            count += meshInstance.VertexCount ();\r\n        });\r\n        return count;\r\n    }\r\n\r\n    VertexColorCount ()\r\n    {\r\n        let count = 0;\r\n        this.EnumerateMeshInstances ((meshInstance) => {\r\n            count += meshInstance.VertexColorCount ();\r\n        });\r\n        return count;\r\n    }\r\n\r\n    NormalCount ()\r\n    {\r\n        let count = 0;\r\n        this.EnumerateMeshInstances ((meshInstance) => {\r\n            count += meshInstance.NormalCount ();\r\n        });\r\n        return count;\r\n    }\r\n\r\n    TextureUVCount ()\r\n    {\r\n        let count = 0;\r\n        this.EnumerateMeshInstances ((meshInstance) => {\r\n            count += meshInstance.TextureUVCount ();\r\n        });\r\n        return count;\r\n    }\r\n\r\n    LineCount ()\r\n    {\r\n        let count = 0;\r\n        this.EnumerateMeshInstances ((meshInstance) => {\r\n            count += meshInstance.LineCount ();\r\n        });\r\n        return count;\r\n    }\r\n\r\n    LineSegmentCount ()\r\n    {\r\n        let count = 0;\r\n        this.EnumerateMeshInstances ((meshInstance) => {\r\n            count += meshInstance.LineSegmentCount ();\r\n        });\r\n        return count;\r\n    }\r\n\r\n    TriangleCount ()\r\n    {\r\n        let count = 0;\r\n        this.EnumerateMeshInstances ((meshInstance) => {\r\n            count += meshInstance.TriangleCount ();\r\n        });\r\n        return count;\r\n    }\r\n\r\n    AddMaterial (material)\r\n    {\r\n        this.materials.push (material);\r\n        return this.materials.length - 1;\r\n    }\r\n\r\n    GetMaterial (index)\r\n    {\r\n        return this.materials[index];\r\n    }\r\n\r\n    AddMesh (mesh)\r\n    {\r\n        this.meshes.push (mesh);\r\n        return this.meshes.length - 1;\r\n    }\r\n\r\n    AddMeshToRootNode (mesh)\r\n    {\r\n        const meshIndex = this.AddMesh (mesh);\r\n        this.root.AddMeshIndex (meshIndex);\r\n        return meshIndex;\r\n    }\r\n\r\n    RemoveMesh (index)\r\n    {\r\n        this.meshes.splice (index, 1);\r\n        this.root.Enumerate ((node) => {\r\n            for (let i = 0; i < node.meshIndices.length; i++) {\r\n                if (node.meshIndices[i] === index) {\r\n                    node.meshIndices.splice (i, 1);\r\n                    i -= 1;\r\n                } else if (node.meshIndices[i] > index) {\r\n                    node.meshIndices[i] -= 1;\r\n                }\r\n            }\r\n        });\r\n    }\r\n\r\n    GetMesh (index)\r\n    {\r\n        return this.meshes[index];\r\n    }\r\n\r\n    GetMeshInstance (instanceId)\r\n    {\r\n        let foundNode = null;\r\n        this.root.Enumerate ((node) => {\r\n            if (node.GetId () === instanceId.nodeId) {\r\n                foundNode = node;\r\n            }\r\n        });\r\n        if (foundNode === null) {\r\n            return null;\r\n        }\r\n        const nodeMeshIndices = foundNode.GetMeshIndices ();\r\n        if (nodeMeshIndices.indexOf (instanceId.meshIndex) === -1) {\r\n            return null;\r\n        }\r\n        let foundMesh = this.GetMesh (instanceId.meshIndex);\r\n        let id = new MeshInstanceId (foundNode.GetId (), instanceId.meshIndex);\r\n        return new MeshInstance (id, foundNode, foundMesh);\r\n    }\r\n\r\n    EnumerateMeshes (onMesh)\r\n    {\r\n        for (const mesh of this.meshes) {\r\n            onMesh (mesh);\r\n        }\r\n    }\r\n\r\n    EnumerateMeshInstances (onMeshInstance)\r\n    {\r\n        this.root.Enumerate ((node) => {\r\n            for (let meshIndex of node.GetMeshIndices ()) {\r\n                let id = new MeshInstanceId (node.GetId (), meshIndex);\r\n                let mesh = this.GetMesh (meshIndex);\r\n                let meshInstance = new MeshInstance (id, node, mesh);\r\n                onMeshInstance (meshInstance);\r\n            }\r\n        });\r\n    }\r\n\r\n    EnumerateTransformedMeshInstances (onMesh)\r\n    {\r\n        this.EnumerateMeshInstances ((meshInstance) => {\r\n            const transformed = meshInstance.GetTransformedMesh ();\r\n            onMesh (transformed);\r\n        });\r\n    }\r\n\r\n    EnumerateVertices (onVertex)\r\n    {\r\n        this.EnumerateMeshInstances ((meshInstance) => {\r\n            meshInstance.EnumerateVertices (onVertex);\r\n        });\r\n    }\r\n\r\n    EnumerateTriangleVertexIndices (onTriangleVertexIndices)\r\n    {\r\n        this.EnumerateMeshInstances ((meshInstance) => {\r\n            meshInstance.EnumerateTriangleVertexIndices (onTriangleVertexIndices);\r\n        });\r\n    }\r\n\r\n    EnumerateTriangleVertices (onTriangleVertices)\r\n    {\r\n        this.EnumerateMeshInstances ((meshInstance) => {\r\n            meshInstance.EnumerateTriangleVertices (onTriangleVertices);\r\n        });\r\n    }\r\n}\n\nclass TopologyVertex\r\n{\r\n    constructor ()\r\n    {\r\n        this.edges = [];\r\n        this.triangles = [];\r\n    }\r\n}\r\n\r\nclass TopologyEdge\r\n{\r\n    constructor (vertex1, vertex2)\r\n    {\r\n        this.vertex1 = vertex1;\r\n        this.vertex2 = vertex2;\r\n        this.triangles = [];\r\n    }\r\n}\r\n\r\nclass TopologyTriangleEdge\r\n{\r\n    constructor (edge, reversed)\r\n    {\r\n        this.edge = edge;\r\n        this.reversed = reversed;\r\n    }\r\n}\r\n\r\nclass TopologyTriangle\r\n{\r\n    constructor ()\r\n    {\r\n        this.triEdge1 = null;\r\n        this.triEdge2 = null;\r\n        this.triEdge3 = null;\r\n    }\r\n}\r\n\r\nclass Topology\r\n{\r\n    constructor ()\r\n    {\r\n        this.vertices = [];\r\n        this.edges = [];\r\n        this.triangleEdges = [];\r\n        this.triangles = [];\r\n        this.edgeStartToEndVertexMap = new Map ();\r\n    }\r\n\r\n    AddVertex ()\r\n    {\r\n        this.vertices.push (new TopologyVertex ());\r\n        return this.vertices.length - 1;\r\n    }\r\n\r\n    AddTriangle (vertex1, vertex2, vertex3)\r\n    {\r\n        function AddTriangleToVertex (vertices, vertexIndex, triangleIndex)\r\n        {\r\n            let vertex = vertices[vertexIndex];\r\n            vertex.triangles.push (triangleIndex);\r\n        }\r\n\r\n        function AddEdgeToVertex (vertices, triangleEdges, vertexIndex, triangleEdgeIndex)\r\n        {\r\n            let vertex = vertices[vertexIndex];\r\n            let triangleEdge = triangleEdges[triangleEdgeIndex];\r\n            vertex.edges.push (triangleEdge.edge);\r\n        }\r\n\r\n        function AddTriangleToEdge (edges, triangleEdges, triangleEdgeIndex, triangleIndex)\r\n        {\r\n            let triangleEdge = triangleEdges[triangleEdgeIndex];\r\n            let edge = edges[triangleEdge.edge];\r\n            edge.triangles.push (triangleIndex);\r\n        }\r\n\r\n        let triangleIndex = this.triangles.length;\r\n\r\n        let triangle = new TopologyTriangle ();\r\n        triangle.triEdge1 = this.AddTriangleEdge (vertex1, vertex2);\r\n        triangle.triEdge2 = this.AddTriangleEdge (vertex2, vertex3);\r\n        triangle.triEdge3 = this.AddTriangleEdge (vertex3, vertex1);\r\n\r\n        AddTriangleToVertex (this.vertices, vertex1, triangleIndex);\r\n        AddTriangleToVertex (this.vertices, vertex2, triangleIndex);\r\n        AddTriangleToVertex (this.vertices, vertex3, triangleIndex);\r\n\r\n        AddEdgeToVertex (this.vertices, this.triangleEdges, vertex1, triangle.triEdge1);\r\n        AddEdgeToVertex (this.vertices, this.triangleEdges, vertex2, triangle.triEdge2);\r\n        AddEdgeToVertex (this.vertices, this.triangleEdges, vertex3, triangle.triEdge3);\r\n\r\n        AddTriangleToEdge (this.edges, this.triangleEdges, triangle.triEdge1, triangleIndex);\r\n        AddTriangleToEdge (this.edges, this.triangleEdges, triangle.triEdge2, triangleIndex);\r\n        AddTriangleToEdge (this.edges, this.triangleEdges, triangle.triEdge3, triangleIndex);\r\n\r\n        this.triangles.push (triangle);\r\n    }\r\n\r\n    AddTriangleEdge (vertex1, vertex2)\r\n    {\r\n        let startVertex = vertex1;\r\n        let endVertex = vertex2;\r\n        let reversed = false;\r\n        if (vertex2 < vertex1) {\r\n            startVertex = vertex2;\r\n            endVertex = vertex1;\r\n            reversed = true;\r\n        }\r\n\r\n        let edgeIndex = this.AddEdge (startVertex, endVertex);\r\n        this.triangleEdges.push (new TopologyTriangleEdge (edgeIndex, reversed));\r\n        return this.triangleEdges.length - 1;\r\n    }\r\n\r\n    AddEdge (startVertex, endVertex)\r\n    {\r\n        if (!this.edgeStartToEndVertexMap.has (startVertex)) {\r\n            this.edgeStartToEndVertexMap.set (startVertex, []);\r\n        }\r\n\r\n        let endVertices = this.edgeStartToEndVertexMap.get (startVertex);\r\n        for (let i = 0; i < endVertices.length; i++) {\r\n            let endVertexItem = endVertices[i];\r\n            if (endVertexItem.endVertex === endVertex) {\r\n                return endVertexItem.edgeIndex;\r\n            }\r\n        }\r\n\r\n        let edgeIndex = this.edges.length;\r\n        endVertices.push ({\r\n            endVertex : endVertex,\r\n            edgeIndex : edgeIndex\r\n        });\r\n\r\n        this.edges.push (new TopologyEdge (startVertex, endVertex));\r\n        return edgeIndex;\r\n    }\r\n}\n\nfunction IsModelEmpty (model)\r\n{\r\n    let isEmpty = true;\r\n    model.EnumerateMeshInstances ((meshInstance) => {\r\n        if (!IsEmptyMesh (meshInstance)) {\r\n            isEmpty = false;\r\n        }\r\n    });\r\n    return isEmpty;\r\n}\r\n\r\nfunction GetBoundingBox (object3D)\r\n{\r\n    let calculator = new BoundingBoxCalculator3D ();\r\n    object3D.EnumerateVertices ((vertex) => {\r\n        calculator.AddPoint (vertex);\r\n    });\r\n    return calculator.GetBox ();\r\n}\r\n\r\nfunction GetTopology (object3D)\r\n{\r\n    function GetVertexIndex (vertex, octree, topology)\r\n    {\r\n        let index = octree.FindPoint (vertex);\r\n        if (index === null) {\r\n            index = topology.AddVertex ();\r\n            octree.AddPoint (vertex, index);\r\n        }\r\n        return index;\r\n    }\r\n\r\n    let boundingBox = GetBoundingBox (object3D);\r\n    let octree = new Octree (boundingBox);\r\n    let topology = new Topology ();\r\n\r\n    object3D.EnumerateTriangleVertices ((v0, v1, v2) => {\r\n        let v0Index = GetVertexIndex (v0, octree, topology);\r\n        let v1Index = GetVertexIndex (v1, octree, topology);\r\n        let v2Index = GetVertexIndex (v2, octree, topology);\r\n        topology.AddTriangle (v0Index, v1Index, v2Index);\r\n    });\r\n    return topology;\r\n}\r\n\r\nfunction IsTwoManifold (object3D)\r\n{\r\n    function GetEdgeOrientationInTriangle (topology, triangleIndex, edgeIndex)\r\n    {\r\n        const triangle = topology.triangles[triangleIndex];\r\n        const triEdge1 = topology.triangleEdges[triangle.triEdge1];\r\n        const triEdge2 = topology.triangleEdges[triangle.triEdge2];\r\n        const triEdge3 = topology.triangleEdges[triangle.triEdge3];\r\n        if (triEdge1.edge === edgeIndex) {\r\n            return triEdge1.reversed;\r\n        }\r\n        if (triEdge2.edge === edgeIndex) {\r\n            return triEdge2.reversed;\r\n        }\r\n        if (triEdge3.edge === edgeIndex) {\r\n            return triEdge3.reversed;\r\n        }\r\n        return null;\r\n    }\r\n\r\n    if (object3D instanceof Model) {\r\n        let isTwoManifold = true;\r\n        object3D.EnumerateMeshInstances ((meshInstance) => {\r\n            if (isTwoManifold) {\r\n                isTwoManifold = IsTwoManifold (meshInstance);\r\n            }\r\n        });\r\n        return isTwoManifold;\r\n    } else {\r\n        const topology = GetTopology (object3D);\r\n        for (let edgeIndex = 0; edgeIndex < topology.edges.length; edgeIndex++) {\r\n            const edge = topology.edges[edgeIndex];\r\n            if (edge.triangles.length !== 2) {\r\n                return false;\r\n            }\r\n\r\n            let edgeOrientation1 = GetEdgeOrientationInTriangle (topology, edge.triangles[0], edgeIndex);\r\n            let edgeOrientation2 = GetEdgeOrientationInTriangle (topology, edge.triangles[1], edgeIndex);\r\n            if (edgeOrientation1 === null || edgeOrientation2 === null || edgeOrientation1 === edgeOrientation2) {\r\n                return false;\r\n            }\r\n        }\r\n        return true;\r\n    }\r\n}\r\n\r\nfunction GetDefaultMaterials (model)\r\n{\r\n    let defaultMaterials = [];\r\n    for (let i = 0; i < model.MaterialCount (); i++) {\r\n        let material = model.GetMaterial (i);\r\n        if (material.source !== MaterialSource.Model && !material.vertexColors) {\r\n            defaultMaterials.push (material);\r\n        }\r\n    }\r\n    return defaultMaterials;\r\n}\r\n\r\nfunction ReplaceDefaultMaterialsColor (model, color, lineColor)\r\n{\r\n    for (let i = 0; i < model.MaterialCount (); i++) {\r\n        let material = model.GetMaterial (i);\r\n        if (material.source === MaterialSource.DefaultFace) {\r\n            material.color = color;\r\n        } else if (material.source === MaterialSource.DefaultLine) {\r\n            material.color = lineColor;\r\n        }\r\n    }\r\n}\n\nclass Mesh extends ModelObject3D\r\n{\r\n    constructor ()\r\n    {\r\n        super ();\r\n        this.vertices = [];\r\n        this.vertexColors = [];\r\n        this.normals = [];\r\n        this.uvs = [];\r\n        this.lines = [];\r\n        this.triangles = [];\r\n    }\r\n\r\n    VertexCount ()\r\n    {\r\n        return this.vertices.length;\r\n    }\r\n\r\n    VertexColorCount ()\r\n    {\r\n        return this.vertexColors.length;\r\n    }\r\n\r\n    NormalCount ()\r\n    {\r\n        return this.normals.length;\r\n    }\r\n\r\n    TextureUVCount ()\r\n    {\r\n        return this.uvs.length;\r\n    }\r\n\r\n    LineCount ()\r\n    {\r\n        return this.lines.length;\r\n    }\r\n\r\n    LineSegmentCount ()\r\n    {\r\n        let lineSegmentCount = 0;\r\n        for (let line of this.lines) {\r\n            lineSegmentCount += line.SegmentCount ();\r\n        }\r\n        return lineSegmentCount;\r\n    }\r\n\r\n    TriangleCount ()\r\n    {\r\n        return this.triangles.length;\r\n    }\r\n\r\n    AddVertex (vertex)\r\n    {\r\n        this.vertices.push (vertex);\r\n        return this.vertices.length - 1;\r\n    }\r\n\r\n    SetVertex (index, vertex)\r\n    {\r\n        this.vertices[index] = vertex;\r\n    }\r\n\r\n    GetVertex (index)\r\n    {\r\n        return this.vertices[index];\r\n    }\r\n\r\n    AddVertexColor (color)\r\n    {\r\n        this.vertexColors.push (color);\r\n        return this.vertexColors.length - 1;\r\n    }\r\n\r\n    SetVertexColor (index, color)\r\n    {\r\n        this.vertexColors[index] = color;\r\n    }\r\n\r\n    GetVertexColor (index)\r\n    {\r\n        return this.vertexColors[index];\r\n    }\r\n\r\n    AddNormal (normal)\r\n    {\r\n        this.normals.push (normal);\r\n        return this.normals.length - 1;\r\n    }\r\n\r\nSetNormal (index, normal)\r\n    {\r\n        this.normals[index] = normal;\r\n    }\r\n\r\n    GetNormal (index)\r\n    {\r\n        return this.normals[index];\r\n    }\r\n\r\n    AddTextureUV (uv)\r\n    {\r\n        this.uvs.push (uv);\r\n        return this.uvs.length - 1;\r\n    }\r\n\r\n    SetTextureUV (index, uv)\r\n    {\r\n        this.uvs[index] = uv;\r\n    }\r\n\r\n    GetTextureUV (index)\r\n    {\r\n        return this.uvs[index];\r\n    }\r\n\r\n    AddLine (line)\r\n    {\r\n        this.lines.push (line);\r\n        return this.lines.length - 1;\r\n    }\r\n\r\n    GetLine (index)\r\n    {\r\n        return this.lines[index];\r\n    }\r\n\r\n    AddTriangle (triangle)\r\n    {\r\n        this.triangles.push (triangle);\r\n        return this.triangles.length - 1;\r\n    }\r\n\r\n    GetTriangle (index)\r\n    {\r\n        return this.triangles[index];\r\n    }\r\n\r\n    EnumerateVertices (onVertex)\r\n    {\r\n        for (const vertex of this.vertices) {\r\n            onVertex (vertex);\r\n        }\r\n    }\r\n\r\n    EnumerateTriangleVertexIndices (onTriangleVertexIndices)\r\n    {\r\n        for (const triangle of this.triangles) {\r\n            onTriangleVertexIndices (triangle.v0, triangle.v1, triangle.v2);\r\n        }\r\n    }\r\n\r\n    EnumerateTriangleVertices (onTriangleVertices)\r\n    {\r\n        for (const triangle of this.triangles) {\r\n            let v0 = this.vertices[triangle.v0];\r\n            let v1 = this.vertices[triangle.v1];\r\n            let v2 = this.vertices[triangle.v2];\r\n            onTriangleVertices (v0, v1, v2);\r\n        }\r\n    }\r\n\r\n    Clone ()\r\n    {\r\n        let cloned = new Mesh ();\r\n\r\n        cloned.SetName (this.GetName ());\r\n        this.CloneProperties (cloned);\r\n\r\n        for (let i = 0; i < this.VertexCount (); i++) {\r\n            let vertex = this.GetVertex (i);\r\n            cloned.AddVertex (vertex.Clone ());\r\n        }\r\n\r\n        for (let i = 0; i < this.VertexColorCount (); i++) {\r\n            let color = this.GetVertexColor (i);\r\n            cloned.AddVertexColor (color.Clone ());\r\n        }\r\n\r\n        for (let i = 0; i < this.NormalCount (); i++) {\r\n            let normal = this.GetNormal (i);\r\n            cloned.AddNormal (normal.Clone ());\r\n        }\r\n\r\n        for (let i = 0; i < this.TextureUVCount (); i++) {\r\n            let uv = this.GetTextureUV (i);\r\n            cloned.AddTextureUV (uv.Clone ());\r\n        }\r\n\r\n        for (let i = 0; i < this.LineCount (); i++) {\r\n            let line = this.GetLine (i);\r\n            cloned.AddLine (line.Clone ());\r\n        }\r\n\r\n        for (let i = 0; i < this.TriangleCount (); i++) {\r\n            let triangle = this.GetTriangle (i);\r\n            cloned.AddTriangle (triangle.Clone ());\r\n        }\r\n\r\n        return cloned;\r\n    }\r\n}\n\nclass Triangle\r\n{\r\n    constructor (v0, v1, v2)\r\n    {\r\n        this.v0 = v0;\r\n        this.v1 = v1;\r\n        this.v2 = v2;\r\n\r\n        this.c0 = null;\r\n        this.c1 = null;\r\n        this.c2 = null;\r\n\r\n        this.n0 = null;\r\n        this.n1 = null;\r\n        this.n2 = null;\r\n\r\n        this.u0 = null;\r\n        this.u1 = null;\r\n        this.u2 = null;\r\n\r\n        this.mat = null;\r\n        this.curve = null;\r\n    }\r\n\r\n    HasVertices ()\r\n    {\r\n        return this.v0 !== null && this.v1 !== null && this.v2 !== null;\r\n    }\r\n\r\n    HasVertexColors ()\r\n    {\r\n        return this.c0 !== null && this.c1 !== null && this.c2 !== null;\r\n    }\r\n\r\n    HasNormals ()\r\n    {\r\n        return this.n0 !== null && this.n1 !== null && this.n2 !== null;\r\n    }\r\n\r\n    HasTextureUVs ()\r\n    {\r\n        return this.u0 !== null && this.u1 !== null && this.u2 !== null;\r\n    }\r\n\r\n    SetVertices (v0, v1, v2)\r\n    {\r\n        this.v0 = v0;\r\n        this.v1 = v1;\r\n        this.v2 = v2;\r\n        return this;\r\n    }\r\n\r\n    SetVertexColors (c0, c1, c2)\r\n    {\r\n        this.c0 = c0;\r\n        this.c1 = c1;\r\n        this.c2 = c2;\r\n        return this;\r\n    }\r\n\r\n    SetNormals (n0, n1, n2)\r\n    {\r\n        this.n0 = n0;\r\n        this.n1 = n1;\r\n        this.n2 = n2;\r\n        return this;\r\n    }\r\n\r\n    SetTextureUVs (u0, u1, u2)\r\n    {\r\n        this.u0 = u0;\r\n        this.u1 = u1;\r\n        this.u2 = u2;\r\n        return this;\r\n    }\r\n\r\n    SetMaterial (mat)\r\n    {\r\n        this.mat = mat;\r\n        return this;\r\n    }\r\n\r\n    SetCurve (curve)\r\n    {\r\n        this.curve = curve;\r\n        return this;\r\n    }\r\n\r\n    Clone ()\r\n    {\r\n        let cloned = new Triangle (this.v0, this.v1, this.v2);\r\n        cloned.SetVertexColors (this.c0, this.c1, this.c2);\r\n        cloned.SetNormals (this.n0, this.n1, this.n2);\r\n        cloned.SetTextureUVs (this.u0, this.u1, this.u2);\r\n        cloned.SetMaterial (this.mat);\r\n        cloned.SetCurve (this.curve);\r\n        return cloned;\r\n    }\r\n}\n\n// Some mobile devices say that they support mediump, but in reality they don't. At the end\r\n// all materials rendered as black. This hack renders a single plane with red material and\r\n// it checks if it's really red. If it's not, then probably there is a driver issue.\r\n// https://github.com/kovacsv/Online3DViewer/issues/69\r\nfunction HasHighpDriverIssue ()\r\n{\r\n    let canvas = document.createElement ('canvas');\r\n    document.body.appendChild (canvas);\r\n    let parameters = {\r\n        canvas : canvas,\r\n        antialias : true\r\n    };\r\n\r\n    let renderer = new THREE.WebGLRenderer (parameters);\r\n    renderer.outputColorSpace = THREE.LinearSRGBColorSpace;\r\n    renderer.setClearColor ('#ffffff', 1);\r\n    renderer.setSize (10, 10);\r\n\r\n    let scene = new THREE.Scene ();\r\n\r\n    let ambientLight = new THREE.AmbientLight (0x888888);\r\n    scene.add (ambientLight);\r\n\r\n    let light = new THREE.DirectionalLight (0x888888);\r\n    light.position.set (0.0, 0.0, 1.0);\r\n    scene.add (light);\r\n\r\n    let camera = new THREE.PerspectiveCamera (45.0, 1.0, 0.1, 1000.0);\r\n    camera.position.set (0.0, 0.0, 1.0);\r\n    camera.up.set (0.0, 1.0, 0.0);\r\n    camera.lookAt (new THREE.Vector3 (0.0, 0.0, 0.0));\r\n    scene.add (camera);\r\n\r\n    let plane = new THREE.PlaneGeometry (1.0, 1.0);\r\n    let mesh = new THREE.Mesh (plane, new THREE.MeshPhongMaterial ({\r\n        color : 0xcc0000\r\n    }));\r\n    scene.add (mesh);\r\n    renderer.render (scene, camera);\r\n\r\n    let context = renderer.getContext ();\r\n    let pixels = new Uint8Array (4);\r\n    context.readPixels(\r\n        5, 5, 1, 1,\r\n        context.RGBA,\r\n        context.UNSIGNED_BYTE,\r\n        pixels\r\n    );\r\n\r\n    document.body.removeChild (canvas);\r\n\r\n    let blackThreshold = 50;\r\n    if (pixels[0] < blackThreshold && pixels[1] < blackThreshold && pixels[2] < blackThreshold) {\r\n        return true;\r\n    }\r\n    return false;\r\n}\r\n\r\nconst ShadingType =\r\n{\r\n    Phong : 1,\r\n    Physical : 2\r\n};\r\n\r\nfunction GetShadingType (model)\r\n{\r\n    let phongCount = 0;\r\n    let physicalCount = 0;\r\n    for (let i = 0; i < model.MaterialCount (); i++) {\r\n        let material = model.GetMaterial (i);\r\n        if (material.type === MaterialType.Phong) {\r\n            phongCount += 1;\r\n        } else if (material.type === MaterialType.Physical) {\r\n            physicalCount += 1;\r\n        }\r\n    }\r\n    if (phongCount >= physicalCount) {\r\n        return ShadingType.Phong;\r\n    } else {\r\n        return ShadingType.Physical;\r\n    }\r\n}\r\n\r\nclass ThreeColorConverter\r\n{\r\n    Convert (color)\r\n    {\r\n        return null;\r\n    }\r\n}\r\n\r\nclass ThreeLinearToSRGBColorConverter extends ThreeColorConverter\r\n{\r\n    Convert (color)\r\n    {\r\n        return new THREE.Color ().copyLinearToSRGB (color);\r\n    }\r\n}\r\n\r\nclass ThreeSRGBToLinearColorConverter extends ThreeColorConverter\r\n{\r\n    Convert (color)\r\n    {\r\n        return new THREE.Color ().copySRGBToLinear (color);\r\n    }\r\n}\r\n\r\nfunction ConvertThreeColorToColor (threeColor)\r\n{\r\n    return RGBColorFromFloatComponents (threeColor.r, threeColor.g, threeColor.b);\r\n}\r\n\r\nfunction ConvertColorToThreeColor (color)\r\n{\r\n    return new THREE.Color (\r\n        color.r / 255.0,\r\n        color.g / 255.0,\r\n        color.b / 255.0\r\n    );\r\n}\r\n\r\nfunction ConvertThreeGeometryToMesh (threeGeometry, materialIndex, colorConverter)\r\n{\r\n    let mesh = new Mesh ();\r\n\r\n    let vertices = threeGeometry.attributes.position.array;\r\n    let vertexItemSize = threeGeometry.attributes.position.itemSize || 3;\r\n    for (let i = 0; i < vertices.length; i += vertexItemSize) {\r\n        let x = vertices[i];\r\n        let y = vertices[i + 1];\r\n        let z = vertices[i + 2];\r\n        mesh.AddVertex (new Coord3D (x, y, z));\r\n    }\r\n\r\n    let hasVertexColors = (threeGeometry.attributes.color !== undefined);\r\n    if (hasVertexColors) {\r\n        let colors = threeGeometry.attributes.color.array;\r\n        let colorItemSize = threeGeometry.attributes.color.itemSize || 3;\r\n        for (let i = 0; i < colors.length; i += colorItemSize) {\r\n            let threeColor = new THREE.Color (colors[i], colors[i + 1], colors[i + 2]);\r\n            if (colorConverter !== null) {\r\n                threeColor = colorConverter.Convert (threeColor);\r\n            }\r\n            mesh.AddVertexColor (ConvertThreeColorToColor (threeColor));\r\n        }\r\n    }\r\n\r\n    let hasNormals = (threeGeometry.attributes.normal !== undefined);\r\n    if (hasNormals) {\r\n        let normals = threeGeometry.attributes.normal.array;\r\n        let normalItemSize = threeGeometry.attributes.normal.itemSize || 3;\r\n        for (let i = 0; i < normals.length; i += normalItemSize) {\r\n            let x = normals[i];\r\n            let y = normals[i + 1];\r\n            let z = normals[i + 2];\r\n            mesh.AddNormal (new Coord3D (x, y, z));\r\n        }\r\n    }\r\n\r\n    let hasUVs = (threeGeometry.attributes.uv !== undefined);\r\n    if (hasUVs) {\r\n        let uvs = threeGeometry.attributes.uv.array;\r\n        let uvItemSize = threeGeometry.attributes.uv.itemSize || 2;\r\n        for (let i = 0; i < uvs.length; i += uvItemSize) {\r\n            let x = uvs[i];\r\n            let y = uvs[i + 1];\r\n            mesh.AddTextureUV (new Coord2D (x, y));\r\n        }\r\n    }\r\n\r\n    let indices = null;\r\n    if (threeGeometry.index !== null) {\r\n        indices = threeGeometry.index.array;\r\n    } else {\r\n        indices = [];\r\n        for (let i = 0; i < vertices.length / 3; i++) {\r\n            indices.push (i);\r\n        }\r\n    }\r\n\r\n    for (let i = 0; i < indices.length; i += 3) {\r\n        let v0 = indices[i];\r\n        let v1 = indices[i + 1];\r\n        let v2 = indices[i + 2];\r\n        let triangle = new Triangle (v0, v1, v2);\r\n        if (hasVertexColors) {\r\n            triangle.SetVertexColors (v0, v1, v2);\r\n        }\r\n        if (hasNormals) {\r\n            triangle.SetNormals (v0, v1, v2);\r\n        }\r\n        if (hasUVs) {\r\n            triangle.SetTextureUVs (v0, v1, v2);\r\n        }\r\n        if (materialIndex !== null) {\r\n            triangle.SetMaterial (materialIndex);\r\n        }\r\n        mesh.AddTriangle (triangle);\r\n    }\r\n\r\n    return mesh;\r\n}\r\n\r\nfunction CreateHighlightMaterial (originalMaterial, highlightColor, withPolygonOffset)\r\n{\r\n    let material = null;\r\n    if (originalMaterial.type === 'MeshPhongMaterial') {\r\n        material = new THREE.MeshPhongMaterial ({\r\n            color : ConvertColorToThreeColor (highlightColor),\r\n            side : THREE.DoubleSide\r\n        });\r\n    } else if (originalMaterial.type === 'MeshStandardMaterial') {\r\n        material = new THREE.MeshStandardMaterial ({\r\n            color : ConvertColorToThreeColor (highlightColor),\r\n            side : THREE.DoubleSide\r\n        });\r\n    } else if (originalMaterial.type === 'LineBasicMaterial') {\r\n        material = new THREE.LineBasicMaterial ({\r\n            color : ConvertColorToThreeColor (highlightColor)\r\n        });\r\n    }\r\n    if (material !== null && withPolygonOffset) {\r\n        material.polygonOffset = true;\r\n        material.polygonOffsetUnit = 1;\r\n        material.polygonOffsetFactor = 1;\r\n    }\r\n    return material;\r\n}\r\n\r\nfunction CreateHighlightMaterials (originalMaterials, highlightColor, withPolygonOffset)\r\n{\r\n    let typeToHighlightMaterial = new Map ();\r\n    let highlightMaterials = [];\r\n    for (let originalMaterial of originalMaterials) {\r\n        if (typeToHighlightMaterial.has (originalMaterial.type)) {\r\n            highlightMaterials.push (typeToHighlightMaterial.get (originalMaterial.type));\r\n            continue;\r\n        }\r\n        let highlightMaterial = CreateHighlightMaterial (originalMaterial, highlightColor, withPolygonOffset);\r\n        typeToHighlightMaterial.set (originalMaterial.type, highlightMaterial);\r\n        highlightMaterials.push (highlightMaterial);\r\n    }\r\n    return highlightMaterials;\r\n}\r\n\r\nfunction DisposeThreeObjects (mainObject)\r\n{\r\n    if (mainObject === null) {\r\n        return;\r\n    }\r\n\r\n    mainObject.traverse ((obj) => {\r\n        if (obj.isMesh || obj.isLineSegments) {\r\n            if (Array.isArray (obj.material)) {\r\n                for (let material of obj.material) {\r\n                    material.dispose ();\r\n                }\r\n            } else {\r\n                obj.material.dispose ();\r\n            }\r\n            obj.userData = null;\r\n            obj.geometry.dispose ();\r\n        }\r\n    });\r\n}\r\n\r\nfunction GetLineSegmentsProjectedDistance (camera, canvasWidth, canvasHeight, lineSegments, screenPoint)\r\n{\r\n    function GetProjectedVertex (camera, canvasWidth, canvasHeight, lineSegments, vertices, index)\r\n    {\r\n        let vertex = new THREE.Vector3 (\r\n            vertices[3 * index],\r\n            vertices[3 * index + 1],\r\n            vertices[3 * index + 2]\r\n        );\r\n        vertex.applyMatrix4 (lineSegments.matrixWorld);\r\n        let projected = vertex.project (camera);\r\n        return new Coord2D (\r\n            (projected.x + 1.0) * canvasWidth / 2.0,\r\n            -(projected.y - 1.0) * canvasHeight / 2.0\r\n        );\r\n    }\r\n\r\n    let vertices = lineSegments.geometry.attributes.position.array;\r\n    let segmentCount = vertices.length / 6;\r\n    let distance = Infinity;\r\n    for (let segmentIndex = 0; segmentIndex < segmentCount; segmentIndex++) {\r\n        let segment = new Segment2D (\r\n            GetProjectedVertex (camera, canvasWidth, canvasHeight, lineSegments, vertices, 2 * segmentIndex),\r\n            GetProjectedVertex (camera, canvasWidth, canvasHeight, lineSegments, vertices, 2 * segmentIndex + 1)\r\n        );\r\n        distance = Math.min (distance, SegmentPointDistance2D (segment, screenPoint));\r\n    }\r\n    return distance;\r\n}\n\nclass ModelFinalizer\r\n{\r\n    constructor (params)\r\n    {\r\n        this.params = {\r\n            defaultLineMaterialColor : new RGBColor (0, 0, 0),\r\n            defaultMaterialColor : new RGBColor (0, 0, 0)\r\n        };\r\n        CopyObjectAttributes (params, this.params);\r\n\r\n        this.defaultLineMaterialIndex = null;\r\n        this.defaultMaterialIndex = null;\r\n    }\r\n\r\n    Finalize (model)\r\n    {\r\n        this.Reset ();\r\n\r\n        this.FinalizeMeshes (model);\r\n        this.FinalizeMaterials (model);\r\n        this.FinalizeNodes (model);\r\n    }\r\n\r\n    FinalizeMaterials (model)\r\n    {\r\n        if (model.VertexColorCount () === 0) {\r\n            return;\r\n        }\r\n\r\n        let materialHasVertexColors = new Map ();\r\n        for (let meshIndex = 0; meshIndex < model.MeshCount (); meshIndex++) {\r\n            let mesh = model.GetMesh (meshIndex);\r\n            for (let triangleIndex = 0; triangleIndex < mesh.TriangleCount (); triangleIndex++) {\r\n                let triangle = mesh.GetTriangle (triangleIndex);\r\n                let hasVertexColors = triangle.HasVertexColors ();\r\n                if (!materialHasVertexColors.has (triangle.mat)) {\r\n                    materialHasVertexColors.set (triangle.mat, hasVertexColors);\r\n                } else if (!hasVertexColors) {\r\n                    materialHasVertexColors.set (triangle.mat, false);\r\n                }\r\n            }\r\n        }\r\n\r\n        for (let [materialIndex, hasVertexColors] of materialHasVertexColors) {\r\n            let material = model.GetMaterial (materialIndex);\r\n            material.vertexColors = hasVertexColors;\r\n        }\r\n    }\r\n\r\n    FinalizeMeshes (model)\r\n    {\r\n        for (let meshIndex = 0; meshIndex < model.MeshCount (); meshIndex++) {\r\n            let mesh = model.GetMesh (meshIndex);\r\n            if (IsEmptyMesh (mesh)) {\r\n                model.RemoveMesh (meshIndex);\r\n                meshIndex = meshIndex - 1;\r\n                continue;\r\n            }\r\n            this.FinalizeMesh (model, mesh);\r\n        }\r\n    }\r\n\r\n    FinalizeMesh (model, mesh)\r\n    {\r\n        function CalculateCurveNormals (mesh)\r\n        {\r\n            function AddAverageNormal (mesh, triangle, vertexIndex, triangleNormals, vertexToTriangles)\r\n            {\r\n                function IsNormalInArray (array, normal)\r\n                {\r\n                    for (let i = 0; i < array.length; i++) {\r\n                        let current = array[i];\r\n                        if (CoordIsEqual3D (current, normal)) {\r\n                            return true;\r\n                        }\r\n                    }\r\n                    return false;\r\n                }\r\n\r\n                let averageNormals = [];\r\n                let neigTriangles = vertexToTriangles.get (vertexIndex);\r\n                for (let i = 0; i < neigTriangles.length; i++) {\r\n                    let neigIndex = neigTriangles[i];\r\n                    let neigTriangle = mesh.GetTriangle (neigIndex);\r\n                    if (triangle.curve === neigTriangle.curve) {\r\n                        let triangleNormal = triangleNormals[neigIndex];\r\n                        if (!IsNormalInArray (averageNormals, triangleNormal)) {\r\n                            averageNormals.push (triangleNormal);\r\n                        }\r\n                    }\r\n                }\r\n\r\n                let averageNormal = new Coord3D (0.0, 0.0, 0.0);\r\n                for (let i = 0; i < averageNormals.length; i++) {\r\n                    averageNormal = AddCoord3D (averageNormal, averageNormals[i]);\r\n                }\r\n                averageNormal.MultiplyScalar (1.0 / averageNormals.length);\r\n                averageNormal.Normalize ();\r\n                return mesh.AddNormal (averageNormal);\r\n            }\r\n\r\n            let triangleNormals = [];\r\n            let vertexToTriangles = new Map ();\r\n\r\n            for (let vertexIndex = 0; vertexIndex < mesh.VertexCount (); vertexIndex++) {\r\n                vertexToTriangles.set (vertexIndex, []);\r\n            }\r\n\r\n            for (let triangleIndex = 0; triangleIndex < mesh.TriangleCount (); triangleIndex++) {\r\n                let triangle = mesh.GetTriangle (triangleIndex);\r\n                let v0 = mesh.GetVertex (triangle.v0);\r\n                let v1 = mesh.GetVertex (triangle.v1);\r\n                let v2 = mesh.GetVertex (triangle.v2);\r\n                let normal = CalculateTriangleNormal (v0, v1, v2);\r\n                triangleNormals.push (normal);\r\n                vertexToTriangles.get (triangle.v0).push (triangleIndex);\r\n                vertexToTriangles.get (triangle.v1).push (triangleIndex);\r\n                vertexToTriangles.get (triangle.v2).push (triangleIndex);\r\n            }\r\n\r\n            for (let triangleIndex = 0; triangleIndex < mesh.TriangleCount (); triangleIndex++) {\r\n                let triangle = mesh.GetTriangle (triangleIndex);\r\n                if (!triangle.HasNormals ()) {\r\n                    let n0 = AddAverageNormal (mesh, triangle, triangle.v0, triangleNormals, vertexToTriangles);\r\n                    let n1 = AddAverageNormal (mesh, triangle, triangle.v1, triangleNormals, vertexToTriangles);\r\n                    let n2 = AddAverageNormal (mesh, triangle, triangle.v2, triangleNormals, vertexToTriangles);\r\n                    triangle.SetNormals (n0, n1, n2);\r\n                }\r\n            }\r\n        }\r\n\r\n        let meshStatus = {\r\n            calculateCurveNormals : false\r\n        };\r\n\r\n        for (let i = 0; i < mesh.LineCount (); i++) {\r\n            let line = mesh.GetLine (i);\r\n            if (line.mat === null) {\r\n                line.mat = this.GetDefaultMaterialIndex (model, MaterialSource.DefaultLine);\r\n            }\r\n        }\r\n\r\n        for (let i = 0; i < mesh.TriangleCount (); i++) {\r\n            let triangle = mesh.GetTriangle (i);\r\n            this.FinalizeTriangle (mesh, triangle, meshStatus);\r\n            if (triangle.mat === null) {\r\n                triangle.mat = this.GetDefaultMaterialIndex (model, MaterialSource.DefaultFace);\r\n            }\r\n        }\r\n\r\n        if (meshStatus.calculateCurveNormals) {\r\n            CalculateCurveNormals (mesh);\r\n        }\r\n    }\r\n\r\n    FinalizeTriangle (mesh, triangle, meshStatus)\r\n    {\r\n        if (!triangle.HasNormals ()) {\r\n            if (triangle.curve === null || triangle.curve === 0) {\r\n                let v0 = mesh.GetVertex (triangle.v0);\r\n                let v1 = mesh.GetVertex (triangle.v1);\r\n                let v2 = mesh.GetVertex (triangle.v2);\r\n                let normal = CalculateTriangleNormal (v0, v1, v2);\r\n                let normalIndex = mesh.AddNormal (normal);\r\n                triangle.SetNormals (normalIndex, normalIndex, normalIndex);\r\n            } else {\r\n                meshStatus.calculateCurveNormals = true;\r\n            }\r\n        }\r\n\r\n        if (triangle.curve === null) {\r\n            triangle.curve = 0;\r\n        }\r\n    }\r\n\r\n    FinalizeNodes (model)\r\n    {\r\n        let rootNode = model.GetRootNode ();\r\n\r\n        let emptyNodes = [];\r\n        rootNode.EnumerateChildren ((node) => {\r\n            if (node.IsEmpty ()) {\r\n                emptyNodes.push (node);\r\n            }\r\n        });\r\n\r\n        for (let nodeIndex = 0; nodeIndex < emptyNodes.length; nodeIndex++) {\r\n            let node = emptyNodes[nodeIndex];\r\n            let parentNode = node.GetParent ();\r\n            if (parentNode === null) {\r\n                continue;\r\n            }\r\n            parentNode.RemoveChildNode (node);\r\n            if (parentNode.IsEmpty ()) {\r\n                emptyNodes.push (parentNode);\r\n            }\r\n        }\r\n    }\r\n\r\n    GetDefaultMaterialIndex (model, source)\r\n    {\r\n        function GetIndex (model, index, source, color)\r\n        {\r\n            if (index !== null) {\r\n                return index;\r\n            }\r\n            let defaultMaterial = new PhongMaterial ();\r\n            defaultMaterial.color = color;\r\n            defaultMaterial.source = source;\r\n            return model.AddMaterial (defaultMaterial);\r\n        }\r\n\r\n        if (source === MaterialSource.DefaultLine) {\r\n            this.defaultLineMaterialIndex = GetIndex (model, this.defaultLineMaterialIndex, MaterialSource.DefaultLine, this.params.defaultLineMaterialColor);\r\n            return this.defaultLineMaterialIndex;\r\n        } else if (source === MaterialSource.DefaultFace) {\r\n            this.defaultMaterialIndex = GetIndex (model, this.defaultMaterialIndex, MaterialSource.DefaultFace, this.params.defaultMaterialColor);\r\n            return this.defaultMaterialIndex;\r\n        } else {\r\n            return null;\r\n        }\r\n    }\r\n\r\n    Reset ()\r\n    {\r\n        this.defaultLineMaterialIndex = null;\r\n        this.defaultMaterialIndex = null;\r\n    }\r\n}\r\n\r\nfunction FinalizeModel (model, params)\r\n{\r\n    let finalizer = new ModelFinalizer (params);\r\n    finalizer.Finalize (model);\r\n}\r\n\r\nfunction CheckModel (model)\r\n{\r\n    function IsCorrectValue (val)\r\n    {\r\n        if (val === undefined || val === null) {\r\n            return false;\r\n        }\r\n        return true;\r\n    }\r\n\r\n    function IsCorrectNumber (val)\r\n    {\r\n        if (!IsCorrectValue (val)) {\r\n            return false;\r\n        }\r\n        if (isNaN (val)) {\r\n            return false;\r\n        }\r\n        return true;\r\n    }\r\n\r\n    function IsCorrectIndex (val, count)\r\n    {\r\n        if (!IsCorrectNumber (val)) {\r\n            return false;\r\n        }\r\n        if (val < 0 || val >= count) {\r\n            return false;\r\n        }\r\n        return true;\r\n    }\r\n\r\n    function CheckMesh (model, mesh)\r\n    {\r\n        function CheckTriangle (model, mesh, triangle)\r\n        {\r\n            if (!IsCorrectIndex (triangle.v0, mesh.VertexCount ())) {\r\n                return false;\r\n            }\r\n            if (!IsCorrectIndex (triangle.v1, mesh.VertexCount ())) {\r\n                return false;\r\n            }\r\n            if (!IsCorrectIndex (triangle.v2, mesh.VertexCount ())) {\r\n                return false;\r\n            }\r\n            if (triangle.HasVertexColors ()) {\r\n                if (!IsCorrectIndex (triangle.c0, mesh.VertexColorCount ())) {\r\n                    return false;\r\n                }\r\n                if (!IsCorrectIndex (triangle.c1, mesh.VertexColorCount ())) {\r\n                    return false;\r\n                }\r\n                if (!IsCorrectIndex (triangle.c2, mesh.VertexColorCount ())) {\r\n                    return false;\r\n                }\r\n            }\r\n            if (!IsCorrectIndex (triangle.n0, mesh.NormalCount ())) {\r\n                return false;\r\n            }\r\n            if (!IsCorrectIndex (triangle.n1, mesh.NormalCount ())) {\r\n                return false;\r\n            }\r\n            if (!IsCorrectIndex (triangle.n2, mesh.NormalCount ())) {\r\n                return false;\r\n            }\r\n            if (triangle.HasTextureUVs ()) {\r\n                if (!IsCorrectIndex (triangle.u0, mesh.TextureUVCount ())) {\r\n                    return false;\r\n                }\r\n                    if (!IsCorrectIndex (triangle.u1, mesh.TextureUVCount ())) {\r\n                    return false;\r\n                }\r\n                if (!IsCorrectIndex (triangle.u2, mesh.TextureUVCount ())) {\r\n                    return false;\r\n                }\r\n            }\r\n            if (!IsCorrectIndex (triangle.mat, model.MaterialCount ())) {\r\n                return false;\r\n            }\r\n            if (!IsCorrectNumber (triangle.curve)) {\r\n                return false;\r\n            }\r\n\r\n            return true;\r\n        }\r\n\r\n        for (let i = 0; i < mesh.VertexCount (); i++) {\r\n            let vertex = mesh.GetVertex (i);\r\n            if (!IsCorrectNumber (vertex.x)) {\r\n                return false;\r\n            }\r\n            if (!IsCorrectNumber (vertex.y)) {\r\n                return false;\r\n            }\r\n            if (!IsCorrectNumber (vertex.z)) {\r\n                return false;\r\n            }\r\n        }\r\n\r\n        for (let i = 0; i < mesh.VertexColorCount (); i++) {\r\n            let color = mesh.GetVertexColor (i);\r\n            if (!IsCorrectNumber (color.r)) {\r\n                return false;\r\n            }\r\n            if (!IsCorrectNumber (color.g)) {\r\n                return false;\r\n            }\r\n            if (!IsCorrectNumber (color.b)) {\r\n                return false;\r\n            }\r\n        }\r\n\r\n        for (let i = 0; i < mesh.NormalCount (); i++) {\r\n            let normal = mesh.GetNormal (i);\r\n            if (!IsCorrectNumber (normal.x)) {\r\n                return false;\r\n            }\r\n            if (!IsCorrectNumber (normal.y)) {\r\n                return false;\r\n            }\r\n            if (!IsCorrectNumber (normal.z)) {\r\n                return false;\r\n            }\r\n        }\r\n\r\n        for (let i = 0; i < mesh.TextureUVCount (); i++) {\r\n            let uv = mesh.GetTextureUV (i);\r\n            if (!IsCorrectNumber (uv.x)) {\r\n                return false;\r\n            }\r\n            if (!IsCorrectNumber (uv.y)) {\r\n                return false;\r\n            }\r\n        }\r\n\r\n        for (let i = 0; i < mesh.TriangleCount (); i++) {\r\n            let triangle = mesh.GetTriangle (i);\r\n            if (!CheckTriangle (model, mesh, triangle)) {\r\n                return false;\r\n            }\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    for (let i = 0; i < model.MeshCount (); i++) {\r\n        let mesh = model.GetMesh (i);\r\n        if (!CheckMesh (model, mesh)) {\r\n            return false;\r\n        }\r\n    }\r\n\r\n    return true;\r\n}\n\nclass ImporterBase\r\n{\r\n    constructor ()\r\n    {\r\n        this.name = null;\r\n        this.extension = null;\r\n        this.callbacks = null;\r\n        this.model = null;\r\n        this.error = null;\r\n        this.message = null;\r\n    }\r\n\r\n    Import (name, extension, content, callbacks)\r\n    {\r\n        this.Clear ();\r\n\r\n        this.name = name;\r\n        this.extension = extension;\r\n        this.callbacks = callbacks;\r\n        this.model = new Model ();\r\n        this.error = false;\r\n        this.message = null;\r\n        this.ResetContent ();\r\n        this.ImportContent (content, () => {\r\n            this.CreateResult (callbacks);\r\n        });\r\n    }\r\n\r\n    Clear ()\r\n    {\r\n        this.name = null;\r\n        this.extension = null;\r\n        this.callbacks = null;\r\n        this.model = null;\r\n        this.error = null;\r\n        this.message = null;\r\n        this.ClearContent ();\r\n    }\r\n\r\n    CreateResult (callbacks)\r\n    {\r\n        if (this.error) {\r\n            callbacks.onError ();\r\n            callbacks.onComplete ();\r\n            return;\r\n        }\r\n\r\n        if (IsModelEmpty (this.model)) {\r\n            this.SetError (Loc ('The model doesn\\'t contain any meshes.'));\r\n            callbacks.onError ();\r\n            callbacks.onComplete ();\r\n            return;\r\n        }\r\n\r\n        FinalizeModel (this.model, {\r\n            defaultLineMaterialColor : this.callbacks.getDefaultLineMaterialColor (),\r\n            defaultMaterialColor : this.callbacks.getDefaultMaterialColor ()\r\n        });\r\n\r\n        callbacks.onSuccess ();\r\n        callbacks.onComplete ();\r\n    }\r\n\r\n    CanImportExtension (extension)\r\n    {\r\n        return false;\r\n    }\r\n\r\n    GetUpDirection ()\r\n    {\r\n        return Direction.Z;\r\n    }\r\n\r\n    ClearContent ()\r\n    {\r\n\r\n    }\r\n\r\n    ResetContent ()\r\n    {\r\n\r\n    }\r\n\r\n    ImportContent (fileContent, onFinish)\r\n    {\r\n\r\n    }\r\n\r\n    GetModel ()\r\n    {\r\n        return this.model;\r\n    }\r\n\r\n    SetError (message)\r\n    {\r\n        this.error = true;\r\n        if (message !== undefined && message !== null) {\r\n            this.message = message;\r\n        }\r\n    }\r\n\r\n    WasError ()\r\n    {\r\n        return this.error;\r\n    }\r\n\r\n    GetErrorMessage ()\r\n    {\r\n        return this.message;\r\n    }\r\n}\n\nclass Line\r\n{\r\n    constructor (vertices)\r\n    {\r\n        this.vertices = vertices;\r\n        this.mat = null;\r\n    }\r\n\r\n    HasVertices ()\r\n    {\r\n        return this.vertices !== null && this.vertices.length >= 2;\r\n    }\r\n\r\n    GetVertices ()\r\n    {\r\n        return this.vertices;\r\n    }\r\n\r\n    SetMaterial (mat)\r\n    {\r\n        this.mat = mat;\r\n        return this;\r\n    }\r\n\r\n    SegmentCount ()\r\n    {\r\n        if (this.vertices === null) {\r\n            return 0;\r\n        }\r\n        return this.vertices.length - 1;\r\n    }\r\n\r\n    Clone ()\r\n    {\r\n        let cloned = new Line ([...this.vertices]);\r\n        cloned.SetMaterial (this.mat);\r\n        return cloned;\r\n    }\r\n}\n\nclass Importer3dm extends ImporterBase\r\n{\r\n    constructor ()\r\n    {\r\n        super ();\r\n        this.rhino = null;\r\n    }\r\n\r\n    CanImportExtension (extension)\r\n    {\r\n        return extension === '3dm';\r\n    }\r\n\r\n    GetUpDirection ()\r\n    {\r\n        return Direction.Z;\r\n    }\r\n\r\n    ClearContent ()\r\n    {\r\n        this.instanceIdToObject = null;\r\n        this.instanceIdToDefinition = null;\r\n    }\r\n\r\n    ResetContent ()\r\n    {\r\n        this.instanceIdToObject = new Map ();\r\n        this.instanceIdToDefinition = new Map ();\r\n    }\r\n\r\n    ImportContent (fileContent, onFinish)\r\n    {\r\n        if (this.rhino === null) {\r\n            LoadExternalLibrary ('rhino3dm').then (() => {\r\n                rhino3dm ().then ((rhino) => {\r\n                    this.rhino = rhino;\r\n                    this.ImportRhinoContent (fileContent);\r\n                    onFinish ();\r\n                });\r\n            }).catch (() => {\r\n                this.SetError (Loc ('Failed to load rhino3dm.'));\r\n                onFinish ();\r\n            });\r\n        } else {\r\n            this.ImportRhinoContent (fileContent);\r\n            onFinish ();\r\n        }\r\n    }\r\n\r\n    ImportRhinoContent (fileContent)\r\n    {\r\n        let rhinoDoc = this.rhino.File3dm.fromByteArray (fileContent);\r\n        if (rhinoDoc === null) {\r\n            this.SetError (Loc ('Failed to read Rhino file.'));\r\n            return;\r\n        }\r\n        this.ImportRhinoDocument (rhinoDoc);\r\n        if (IsModelEmpty (this.model)) {\r\n            this.SetError (Loc ('The model doesn\\'t contain any 3D meshes. Try to save the model while you are in shaded view in Rhino.'));\r\n        }\r\n    }\r\n\r\n    ImportRhinoDocument (rhinoDoc)\r\n    {\r\n        this.InitRhinoInstances (rhinoDoc);\r\n        this.ImportRhinoUserStrings (rhinoDoc);\r\n        this.ImportRhinoGeometry (rhinoDoc);\r\n    }\r\n\r\n    InitRhinoInstances (rhinoDoc)\r\n    {\r\n        let rhinoObjects = rhinoDoc.objects ();\r\n        for (let i = 0; i < rhinoObjects.count; i++) {\r\n            let rhinoObject = rhinoObjects.get (i);\r\n            let rhinoAttributes = rhinoObject.attributes ();\r\n            if (rhinoAttributes.isInstanceDefinitionObject) {\r\n                this.instanceIdToObject.set (rhinoAttributes.id, rhinoObject);\r\n            }\r\n        }\r\n        let rhinoInstanceDefinitions = rhinoDoc.instanceDefinitions ();\r\n        for (let i = 0; i < rhinoInstanceDefinitions.count; i++) {\r\n            let rhinoInstanceDefinition = rhinoInstanceDefinitions.get (i);\r\n            this.instanceIdToDefinition.set (rhinoInstanceDefinition.id, rhinoInstanceDefinition);\r\n        }\r\n    }\r\n\r\n    ImportRhinoUserStrings (rhinoDoc)\r\n    {\r\n        let docStrings = rhinoDoc.strings ();\r\n        if (docStrings.count > 0) {\r\n            let propertyGroup = new PropertyGroup (Loc ('Document user texts'));\r\n            for (let i = 0; i < docStrings.count; i++) {\r\n                let docString = docStrings.get (i);\r\n                propertyGroup.AddProperty (new Property (PropertyType.Text, docString[0], docString[1]));\r\n            }\r\n            this.model.AddPropertyGroup (propertyGroup);\r\n        }\r\n    }\r\n\r\n    ImportRhinoGeometry (rhinoDoc)\r\n    {\r\n        let rhinoObjects = rhinoDoc.objects ();\r\n        for (let i = 0; i < rhinoObjects.count; i++) {\r\n            let rhinoObject = rhinoObjects.get (i);\r\n            this.ImportRhinoGeometryObject (rhinoDoc, rhinoObject, []);\r\n        }\r\n    }\r\n\r\n    ImportRhinoGeometryObject (rhinoDoc, rhinoObject, rhinoInstanceReferences)\r\n    {\r\n        let rhinoGeometry = rhinoObject.geometry ();\r\n        let rhinoAttributes = rhinoObject.attributes ();\r\n\r\n        let objectType = rhinoGeometry.objectType;\r\n        if (rhinoAttributes.isInstanceDefinitionObject && rhinoInstanceReferences.length === 0) {\r\n            return;\r\n        }\r\n\r\n        if (objectType === this.rhino.ObjectType.Mesh) {\r\n            this.ImportRhinoGeometryAsMesh (rhinoDoc, rhinoGeometry, rhinoObject, rhinoInstanceReferences);\r\n        } else if (objectType === this.rhino.ObjectType.Extrusion) {\r\n            let rhinoMesh = rhinoGeometry.getMesh (this.rhino.MeshType.Any);\r\n            if (rhinoMesh !== null) {\r\n                this.ImportRhinoGeometryAsMesh (rhinoDoc, rhinoMesh, rhinoObject, rhinoInstanceReferences);\r\n                rhinoMesh.delete ();\r\n            }\r\n        } else if (objectType === this.rhino.ObjectType.Brep) {\r\n            let rhinoMesh = new this.rhino.Mesh ();\r\n            let faces = rhinoGeometry.faces ();\r\n            for (let i = 0; i < faces.count; i++) {\r\n                let face = faces.get (i);\r\n                let mesh = face.getMesh (this.rhino.MeshType.Any);\r\n                if (mesh) {\r\n                    rhinoMesh.append (mesh);\r\n                    mesh.delete ();\r\n                }\r\n                face.delete ();\r\n            }\r\n            faces.delete ();\r\n            rhinoMesh.compact ();\r\n            this.ImportRhinoGeometryAsMesh (rhinoDoc, rhinoMesh, rhinoObject, rhinoInstanceReferences);\r\n            rhinoMesh.delete ();\r\n        } else if (objectType === this.rhino.ObjectType.SubD) {\r\n            rhinoGeometry.subdivide (3);\r\n            let rhinoMesh = this.rhino.Mesh.createFromSubDControlNet (rhinoGeometry, true);\r\n            if (rhinoMesh !== null) {\r\n                this.ImportRhinoGeometryAsMesh (rhinoDoc, rhinoMesh, rhinoObject, rhinoInstanceReferences);\r\n                rhinoMesh.delete ();\r\n            }\r\n        } else if (objectType === this.rhino.ObjectType.Curve) {\r\n            this.ImportRhinoGeometryAsMesh (rhinoDoc, rhinoGeometry, rhinoObject, rhinoInstanceReferences);\r\n        } else if (objectType === this.rhino.ObjectType.InstanceReference) {\r\n            let parentDefinitionId = rhinoGeometry.parentIdefId;\r\n            if (this.instanceIdToDefinition.has (parentDefinitionId)) {\r\n                let instanceDefinition = this.instanceIdToDefinition.get (parentDefinitionId);\r\n                let instanceObjectIds = instanceDefinition.getObjectIds ();\r\n                for (let i = 0; i < instanceObjectIds.length; i++) {\r\n                    let instanceObjectId = instanceObjectIds[i];\r\n                    if (this.instanceIdToObject.has (instanceObjectId)) {\r\n                        let instanceObject = this.instanceIdToObject.get (instanceObjectId);\r\n                        rhinoInstanceReferences.push (rhinoObject);\r\n                        this.ImportRhinoGeometryObject (rhinoDoc, instanceObject, rhinoInstanceReferences);\r\n                        rhinoInstanceReferences.pop ();\r\n                    }\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    ImportRhinoGeometryAsMesh (rhinoDoc, rhinoGeometry, rhinoObject, rhinoInstanceReferences)\r\n    {\r\n        function GetSegmentedCurveLine (curveGeometry)\r\n        {\r\n            let domainLength = curveGeometry.domain[1] - curveGeometry.domain[0];\r\n            let segmentCount = Math.max (parseInt (domainLength / 0.2, 10), 1);\r\n            let segmentLength = domainLength / segmentCount;\r\n            let vertices = [];\r\n            for (let i = 0; i <= segmentCount; i++) {\r\n                if (i === segmentCount && curveGeometry.isClosed) {\r\n                    vertices.push (vertices[0]);\r\n                } else {\r\n                    let position = rhinoGeometry.pointAt (curveGeometry.domain[0] + i * segmentLength);\r\n                    vertices.push (mesh.AddVertex (ArrayToCoord3D (position)));\r\n                }\r\n            }\r\n            return new Line (vertices);\r\n        }\r\n\r\n        let materialIndex = this.GetMaterialIndex (rhinoDoc, rhinoObject, rhinoInstanceReferences);\r\n        let mesh = null;\r\n        if (rhinoGeometry.objectType === this.rhino.ObjectType.Mesh) {\r\n            let threeJson = rhinoGeometry.toThreejsJSON ();\r\n            mesh = ConvertThreeGeometryToMesh (threeJson.data, materialIndex, null);\r\n        } else if (rhinoGeometry.objectType === this.rhino.ObjectType.Curve) {\r\n            mesh = new Mesh ();\r\n            if (rhinoGeometry instanceof this.rhino.LineCurve) {\r\n                let fromVertex = mesh.AddVertex (ArrayToCoord3D (rhinoGeometry.line.from));\r\n                let toVertex = mesh.AddVertex (ArrayToCoord3D (rhinoGeometry.line.to));\r\n                let line = new Line ([fromVertex, toVertex]);\r\n                line.SetMaterial (materialIndex);\r\n                mesh.AddLine (line);\r\n            } else if (rhinoGeometry instanceof this.rhino.NurbsCurve) {\r\n                let line = GetSegmentedCurveLine (rhinoGeometry);\r\n                line.SetMaterial (materialIndex);\r\n                mesh.AddLine (line);\r\n            } else if (rhinoGeometry instanceof this.rhino.ArcCurve) {\r\n                let line = GetSegmentedCurveLine (rhinoGeometry);\r\n                line.SetMaterial (materialIndex);\r\n                mesh.AddLine (line);\r\n            }\r\n        }\r\n\r\n        // TODO: BezierCurve, PolyCurve\r\n\r\n        if (mesh === null) {\r\n            return null;\r\n        }\r\n\r\n        let rhinoAttributes = rhinoObject.attributes ();\r\n        mesh.SetName (rhinoAttributes.name);\r\n\r\n        let userStrings = rhinoAttributes.getUserStrings ();\r\n        if (userStrings.length > 0) {\r\n            let propertyGroup = new PropertyGroup (Loc ('User texts'));\r\n            for (let i = 0; i < userStrings.length; i++) {\r\n                let userString = userStrings[i];\r\n                propertyGroup.AddProperty (new Property (PropertyType.Text, userString[0], userString[1]));\r\n            }\r\n            mesh.AddPropertyGroup (propertyGroup);\r\n        }\r\n\r\n        if (rhinoInstanceReferences.length !== 0) {\r\n            let matrix = new Matrix ().CreateIdentity ();\r\n            for (let i = rhinoInstanceReferences.length - 1; i >= 0; i--) {\r\n                let rhinoInstanceReference = rhinoInstanceReferences[i];\r\n                let rhinoInstanceReferenceGeometry = rhinoInstanceReference.geometry ();\r\n                let rhinoInstanceReferenceMatrix = rhinoInstanceReferenceGeometry.xform.toFloatArray (false);\r\n                let transformationMatrix = new Matrix (rhinoInstanceReferenceMatrix);\r\n                matrix = matrix.MultiplyMatrix (transformationMatrix);\r\n            }\r\n            let transformation = new Transformation (matrix);\r\n            TransformMesh (mesh, transformation);\r\n        }\r\n        this.model.AddMeshToRootNode (mesh);\r\n    }\r\n\r\n    GetMaterialIndex (rhinoDoc, rhinoObject, rhinoInstanceReferences)\r\n    {\r\n        function GetRhinoMaterial (rhino, rhinoObject, rhinoInstanceReferences)\r\n        {\r\n            let rhinoAttributes = rhinoObject.attributes ();\r\n            if (rhinoAttributes.materialSource === rhino.ObjectMaterialSource.MaterialFromObject) {\r\n                let materialIndex = rhinoAttributes.materialIndex;\r\n                if (materialIndex > -1) {\r\n                    return rhinoDoc.materials ().get (materialIndex);\r\n                }\r\n            } else if (rhinoAttributes.materialSource === rhino.ObjectMaterialSource.MaterialFromLayer) {\r\n                let layerIndex = rhinoAttributes.layerIndex;\r\n                if (layerIndex > -1) {\r\n                    let layer = rhinoDoc.layers ().get (layerIndex);\r\n                    let layerMaterialIndex = layer.renderMaterialIndex;\r\n                    if (layerMaterialIndex > -1) {\r\n                        return rhinoDoc.materials ().get (layerMaterialIndex);\r\n                    } else {\r\n                        // use layer color only in case of curves\r\n                        let rhinoGeometry = rhinoObject.geometry ();\r\n                        if (rhinoGeometry.objectType === rhino.ObjectType.Curve) {\r\n                            let material = new rhino.Material ();\r\n                            material.name = layer.name;\r\n                            material.diffuseColor = layer.color;\r\n                            return material;\r\n                        }\r\n                    }\r\n                }\r\n            } else if (rhinoAttributes.materialSource === rhino.ObjectMaterialSource.MaterialFromParent) {\r\n                if (rhinoInstanceReferences.length !== 0) {\r\n                    return GetRhinoMaterial (rhino, rhinoInstanceReferences[0], []);\r\n                }\r\n            }\r\n            return null;\r\n        }\r\n\r\n        function ConvertRhinoMaterial (rhinoMaterial, callbacks)\r\n        {\r\n            function SetColor (color, rhinoColor)\r\n            {\r\n                color.Set (rhinoColor.r, rhinoColor.g, rhinoColor.b);\r\n            }\r\n\r\n            function IsBlack (rhinoColor)\r\n            {\r\n                return rhinoColor.r === 0 && rhinoColor.g === 0 && rhinoColor.b === 0;\r\n            }\r\n\r\n            function IsWhite (rhinoColor)\r\n            {\r\n                return rhinoColor.r === 255 && rhinoColor.g === 255 && rhinoColor.b === 255;\r\n            }\r\n\r\n            let material = null;\r\n            let physicallyBased = rhinoMaterial.physicallyBased ();\r\n            if (physicallyBased.supported) {\r\n                material = new PhysicalMaterial ();\r\n                material.metalness = physicallyBased.metallic ? 1.0 : 0.0;\r\n                material.roughness = physicallyBased.roughness;\r\n            } else {\r\n                material = new PhongMaterial ();\r\n                SetColor (material.ambient, rhinoMaterial.ambientColor);\r\n                SetColor (material.specular, rhinoMaterial.specularColor);\r\n            }\r\n\r\n            material.name = rhinoMaterial.name;\r\n\r\n            SetColor (material.color, rhinoMaterial.diffuseColor);\r\n            material.opacity = 1.0 - rhinoMaterial.transparency;\r\n            UpdateMaterialTransparency (material);\r\n\r\n            if (IsBlack (material.color) && !IsWhite (rhinoMaterial.reflectionColor)) {\r\n                SetColor (material.color, rhinoMaterial.reflectionColor);\r\n            }\r\n            if (IsBlack (material.color) && !IsWhite (rhinoMaterial.transparentColor)) {\r\n                SetColor (material.color, rhinoMaterial.transparentColor);\r\n            }\r\n\r\n            let rhinoTexture = rhinoMaterial.getBitmapTexture ();\r\n            if (rhinoTexture) {\r\n                let texture = new TextureMap ();\r\n                let textureName = GetFileName (rhinoTexture.fileName);\r\n                let textureBuffer = callbacks.getFileBuffer (textureName);\r\n                texture.name = textureName;\r\n                texture.buffer = textureBuffer;\r\n                material.diffuseMap = texture;\r\n            }\r\n\r\n            return material;\r\n        }\r\n\r\n        function FindMatchingMaterial (model, rhinoMaterial, callbacks)\r\n        {\r\n            let material = ConvertRhinoMaterial (rhinoMaterial, callbacks);\r\n            for (let i = 0; i < model.MaterialCount (); i++) {\r\n                let current = model.GetMaterial (i);\r\n                if (current.IsEqual (material)) {\r\n                    return i;\r\n                }\r\n            }\r\n            return model.AddMaterial (material);\r\n        }\r\n\r\n        let rhinoMaterial = GetRhinoMaterial (this.rhino, rhinoObject, rhinoInstanceReferences);\r\n        if (rhinoMaterial === null) {\r\n            return null;\r\n        }\r\n        return FindMatchingMaterial (this.model, rhinoMaterial, this.callbacks);\r\n    }\r\n}\n\nclass BinaryReader\r\n{\r\n    constructor (arrayBuffer, isLittleEndian)\r\n    {\r\n        this.arrayBuffer = arrayBuffer;\r\n        this.dataView = new DataView (arrayBuffer);\r\n        this.isLittleEndian = isLittleEndian;\r\n        this.position = 0;\r\n    }\r\n\r\n    GetPosition ()\r\n    {\r\n        return this.position;\r\n    }\r\n\r\n    SetPosition (position)\r\n    {\r\n        this.position = position;\r\n    }\r\n\r\n    GetByteLength ()\r\n    {\r\n        return this.arrayBuffer.byteLength;\r\n    }\r\n\r\n    Skip (bytes)\r\n    {\r\n        this.position = this.position + bytes;\r\n    }\r\n\r\n    End ()\r\n    {\r\n        return this.position >= this.arrayBuffer.byteLength;\r\n    }\r\n\r\n    ReadArrayBuffer (byteLength)\r\n    {\r\n        let originalBufferView = new Uint8Array (this.arrayBuffer);\r\n        let arrayBuffer = new ArrayBuffer (byteLength);\r\n        let bufferView = new Uint8Array (arrayBuffer);\r\n        let subArray = originalBufferView.subarray (this.position, this.position + byteLength);\r\n        bufferView.set (subArray, 0);\r\n        this.position += byteLength;\r\n        return arrayBuffer;\r\n    }\r\n\r\n    ReadBoolean8 ()\r\n    {\r\n        let result = this.dataView.getInt8 (this.position);\r\n        this.position = this.position + 1;\r\n        return result ? true : false;\r\n    }\r\n\r\n    ReadCharacter8 ()\r\n    {\r\n        let result = this.dataView.getInt8 (this.position);\r\n        this.position = this.position + 1;\r\n        return result;\r\n    }\r\n\r\n    ReadUnsignedCharacter8 ()\r\n    {\r\n        let result = this.dataView.getUint8 (this.position);\r\n        this.position = this.position + 1;\r\n        return result;\r\n    }\r\n\r\n    ReadInteger16 ()\r\n    {\r\n        let result = this.dataView.getInt16 (this.position, this.isLittleEndian);\r\n        this.position = this.position + 2;\r\n        return result;\r\n    }\r\n\r\n    ReadUnsignedInteger16 ()\r\n    {\r\n        let result = this.dataView.getUint16 (this.position, this.isLittleEndian);\r\n        this.position = this.position + 2;\r\n        return result;\r\n    }\r\n\r\n    ReadInteger32 ()\r\n    {\r\n        let result = this.dataView.getInt32 (this.position, this.isLittleEndian);\r\n        this.position = this.position + 4;\r\n        return result;\r\n    }\r\n\r\n    ReadUnsignedInteger32 ()\r\n    {\r\n        let result = this.dataView.getUint32 (this.position, this.isLittleEndian);\r\n        this.position = this.position + 4;\r\n        return result;\r\n    }\r\n\r\n    ReadFloat32 ()\r\n    {\r\n        let result = this.dataView.getFloat32 (this.position, this.isLittleEndian);\r\n        this.position = this.position + 4;\r\n        return result;\r\n    }\r\n\r\n    ReadDouble64 ()\r\n    {\r\n        let result = this.dataView.getFloat64 (this.position, this.isLittleEndian);\r\n        this.position = this.position + 8;\r\n        return result;\r\n    }\r\n}\n\nconst CHUNK3DS =\r\n{\r\n    MAIN3DS : 0x4D4D,\r\n    EDIT3DS : 0x3D3D,\r\n    EDIT_MATERIAL : 0xAFFF,\r\n    MAT_NAME : 0xA000,\r\n    MAT_AMBIENT : 0xA010,\r\n    MAT_DIFFUSE : 0xA020,\r\n    MAT_SPECULAR : 0xA030,\r\n    MAT_SHININESS : 0xA040,\r\n    MAT_SHININESS_STRENGTH : 0xA041,\r\n    MAT_TRANSPARENCY : 0xA050,\r\n    MAT_COLOR_F : 0x0010,\r\n    MAT_COLOR : 0x0011,\r\n    MAT_LIN_COLOR : 0x0012,\r\n    MAT_LIN_COLOR_F : 0x0013,\r\n    MAT_TEXMAP : 0xA200,\r\n    MAT_TEXMAP_NAME : 0xA300,\r\n    MAT_TEXMAP_UOFFSET : 0xA358,\r\n    MAT_TEXMAP_VOFFSET : 0xA35A,\r\n    MAT_TEXMAP_USCALE : 0xA354,\r\n    MAT_TEXMAP_VSCALE : 0xA356,\r\n    MAT_TEXMAP_ROTATION : 0xA35C,\r\n    PERCENTAGE : 0x0030,\r\n    PERCENTAGE_F : 0x0031,\r\n    EDIT_OBJECT : 0x4000,\r\n    OBJ_TRIMESH : 0x4100,\r\n    TRI_VERTEX : 0x4110,\r\n    TRI_TEXVERTEX : 0x4140,\r\n    TRI_FACE : 0x4120,\r\n    TRI_TRANSFORMATION : 0x4160,\r\n    TRI_MATERIAL : 0x4130,\r\n    TRI_SMOOTH : 0x4150,\r\n    KF3DS : 0xB000,\r\n    OBJECT_NODE : 0xB002,\r\n    OBJECT_HIERARCHY : 0xB010,\r\n    OBJECT_INSTANCE_NAME : 0xB011,\r\n    OBJECT_PIVOT : 0xB013,\r\n    OBJECT_POSITION : 0xB020,\r\n    OBJECT_ROTATION : 0xB021,\r\n    OBJECT_SCALE : 0xB022,\r\n    OBJECT_ID : 0xB030\r\n};\r\n\r\nclass Importer3dsNode\r\n{\r\n    constructor ()\r\n    {\r\n        this.id = -1;\r\n        this.name = '';\r\n        this.flags = -1;\r\n        this.parentId = -1;\r\n        this.instanceName = '';\r\n        this.pivot = [0.0, 0.0, 0.0];\r\n        this.positions = [];\r\n        this.rotations = [];\r\n        this.scales = [];\r\n    }\r\n}\r\n\r\nclass Importer3dsNodeList\r\n{\r\n    constructor ()\r\n    {\r\n        this.nodes = [];\r\n        this.nodeIdToNode = new Map ();\r\n    }\r\n\r\n    IsEmpty ()\r\n    {\r\n        return this.nodes.length === 0;\r\n    }\r\n\r\n    AddNode (node)\r\n    {\r\n        this.nodes.push (node);\r\n        this.nodeIdToNode.set (node.nodeId, node);\r\n    }\r\n\r\n    GetNodes ()\r\n    {\r\n        return this.nodes;\r\n    }\r\n}\r\n\r\nclass Importer3ds extends ImporterBase\r\n{\r\n    constructor ()\r\n    {\r\n        super ();\r\n    }\r\n\r\n    CanImportExtension (extension)\r\n    {\r\n        return extension === '3ds';\r\n    }\r\n\r\n    GetUpDirection ()\r\n    {\r\n        return Direction.Z;\r\n    }\r\n\r\n    ClearContent ()\r\n    {\r\n        this.materialNameToIndex = null;\r\n        this.meshNameToIndex = null;\r\n        this.nodeList = null;\r\n    }\r\n\r\n    ResetContent ()\r\n    {\r\n        this.materialNameToIndex = new Map ();\r\n        this.meshNameToIndex = new Map ();\r\n        this.nodeList = new Importer3dsNodeList ();\r\n    }\r\n\r\n    ImportContent (fileContent, onFinish)\r\n    {\r\n        this.ProcessBinary (fileContent);\r\n        onFinish ();\r\n    }\r\n\r\n    ProcessBinary (fileContent)\r\n    {\r\n        let reader = new BinaryReader (fileContent, true);\r\n        let endByte = reader.GetByteLength ();\r\n        this.ReadChunks (reader, endByte, (chunkId, chunkLength) => {\r\n            if (chunkId === CHUNK3DS.MAIN3DS) {\r\n                this.ReadMainChunk (reader, chunkLength);\r\n            } else {\r\n                this.SkipChunk (reader, chunkLength);\r\n            }\r\n        });\r\n    }\r\n\r\n    ReadMainChunk (reader, length)\r\n    {\r\n        let endByte = this.GetChunkEnd (reader, length);\r\n        this.ReadChunks (reader, endByte, (chunkId, chunkLength) => {\r\n            if (chunkId === CHUNK3DS.EDIT3DS) {\r\n                this.ReadEditorChunk (reader, chunkLength);\r\n            } else if (chunkId === CHUNK3DS.KF3DS) {\r\n                this.ReadKeyFrameChunk (reader, chunkLength);\r\n            } else {\r\n                this.SkipChunk (reader, chunkLength);\r\n            }\r\n        });\r\n        this.BuildNodeHierarchy ();\r\n    }\r\n\r\n    ReadEditorChunk (reader, length)\r\n    {\r\n        let endByte = this.GetChunkEnd (reader, length);\r\n        this.ReadChunks (reader, endByte, (chunkId, chunkLength) => {\r\n            if (chunkId === CHUNK3DS.EDIT_MATERIAL) {\r\n                this.ReadMaterialChunk (reader, chunkLength);\r\n            } else if (chunkId === CHUNK3DS.EDIT_OBJECT) {\r\n                this.ReadObjectChunk (reader, chunkLength);\r\n            } else {\r\n                this.SkipChunk (reader, chunkLength);\r\n            }\r\n        });\r\n    }\r\n\r\n    ReadMaterialChunk (reader, length)\r\n    {\r\n        let material = new PhongMaterial ();\r\n        let endByte = this.GetChunkEnd (reader, length);\r\n        let shininess = null;\r\n        let shininessStrength = null;\r\n        this.ReadChunks (reader, endByte, (chunkId, chunkLength) => {\r\n            if (chunkId === CHUNK3DS.MAT_NAME) {\r\n                material.name = this.ReadName (reader);\r\n            } else if (chunkId === CHUNK3DS.MAT_AMBIENT) {\r\n                material.ambient = this.ReadColorChunk (reader, chunkLength);\r\n            } else if (chunkId === CHUNK3DS.MAT_DIFFUSE) {\r\n                material.color = this.ReadColorChunk (reader, chunkLength);\r\n            } else if (chunkId === CHUNK3DS.MAT_SPECULAR) {\r\n                material.specular = this.ReadColorChunk (reader, chunkLength);\r\n            } else if (chunkId === CHUNK3DS.MAT_SHININESS) {\r\n                shininess = this.ReadPercentageChunk (reader, chunkLength);\r\n            } else if (chunkId === CHUNK3DS.MAT_SHININESS_STRENGTH) {\r\n                shininessStrength = this.ReadPercentageChunk (reader, chunkLength);\r\n            } else if (chunkId === CHUNK3DS.MAT_TRANSPARENCY) {\r\n                material.opacity = 1.0 - this.ReadPercentageChunk (reader, chunkLength);\r\n                UpdateMaterialTransparency (material);\r\n            } else if (chunkId === CHUNK3DS.MAT_TEXMAP) {\r\n                material.diffuseMap = this.ReadTextureMapChunk (reader, chunkLength);\r\n                UpdateMaterialTransparency (material);\r\n            } else {\r\n                this.SkipChunk (reader, chunkLength);\r\n            }\r\n        });\r\n\r\n        if (shininess !== null && shininessStrength !== null) {\r\n            material.shininess = shininess * shininessStrength / 10.0;\r\n        }\r\n        let materialIndex = this.model.AddMaterial (material);\r\n        this.materialNameToIndex.set (material.name, materialIndex);\r\n    }\r\n\r\n    ReadTextureMapChunk (reader, length)\r\n    {\r\n        let texture = new TextureMap ();\r\n        let endByte = this.GetChunkEnd (reader, length);\r\n        this.ReadChunks (reader, endByte, (chunkId, chunkLength) => {\r\n            if (chunkId === CHUNK3DS.MAT_TEXMAP_NAME) {\r\n                let textureName = this.ReadName (reader);\r\n                let textureBuffer = this.callbacks.getFileBuffer (textureName);\r\n                texture.name = textureName;\r\n                texture.buffer = textureBuffer;\r\n            } else if (chunkId === CHUNK3DS.MAT_TEXMAP_UOFFSET) {\r\n                texture.offset.x = reader.ReadFloat32 ();\r\n            } else if (chunkId === CHUNK3DS.MAT_TEXMAP_VOFFSET) {\r\n                texture.offset.y = reader.ReadFloat32 ();\r\n            } else if (chunkId === CHUNK3DS.MAT_TEXMAP_USCALE) {\r\n                texture.scale.x = reader.ReadFloat32 ();\r\n            } else if (chunkId === CHUNK3DS.MAT_TEXMAP_VSCALE) {\r\n                texture.scale.y = reader.ReadFloat32 ();\r\n            } else if (chunkId === CHUNK3DS.MAT_TEXMAP_ROTATION) {\r\n                texture.rotation = reader.ReadFloat32 () * DegRad;\r\n            } else {\r\n                this.SkipChunk (reader, chunkLength);\r\n            }\r\n        });\r\n        return texture;\r\n    }\r\n\r\n    ReadColorChunk (reader, length)\r\n    {\r\n        let color = new RGBColor (0, 0, 0);\r\n        let endByte = this.GetChunkEnd (reader, length);\r\n        let hasLinColor = false;\r\n        this.ReadChunks (reader, endByte, (chunkId, chunkLength) => {\r\n            if (chunkId === CHUNK3DS.MAT_COLOR) {\r\n                if (!hasLinColor) {\r\n                    color.r = reader.ReadUnsignedCharacter8 ();\r\n                    color.g = reader.ReadUnsignedCharacter8 ();\r\n                    color.b = reader.ReadUnsignedCharacter8 ();\r\n                }\r\n            } else if (chunkId === CHUNK3DS.MAT_LIN_COLOR) {\r\n                color.r = reader.ReadUnsignedCharacter8 ();\r\n                color.g = reader.ReadUnsignedCharacter8 ();\r\n                color.b = reader.ReadUnsignedCharacter8 ();\r\n                hasLinColor = true;\r\n            } else if (chunkId === CHUNK3DS.MAT_COLOR_F) {\r\n                if (!hasLinColor) {\r\n                    color.r = ColorComponentFromFloat (reader.ReadFloat32 ());\r\n                    color.g = ColorComponentFromFloat (reader.ReadFloat32 ());\r\n                    color.b = ColorComponentFromFloat (reader.ReadFloat32 ());\r\n                }\r\n            } else if (chunkId === CHUNK3DS.MAT_LIN_COLOR_F) {\r\n                color.r = ColorComponentFromFloat (reader.ReadFloat32 ());\r\n                color.g = ColorComponentFromFloat (reader.ReadFloat32 ());\r\n                color.b = ColorComponentFromFloat (reader.ReadFloat32 ());\r\n                hasLinColor = true;\r\n            } else {\r\n                this.SkipChunk (reader, chunkLength);\r\n            }\r\n        });\r\n        return color;\r\n    }\r\n\r\n    ReadPercentageChunk (reader, length)\r\n    {\r\n        let percentage = 0.0;\r\n        let endByte = this.GetChunkEnd (reader, length);\r\n        this.ReadChunks (reader, endByte, (chunkId, chunkLength) => {\r\n            if (chunkId === CHUNK3DS.PERCENTAGE) {\r\n                percentage = reader.ReadUnsignedInteger16 () / 100.0;\r\n            } else if (chunkId === CHUNK3DS.PERCENTAGE_F) {\r\n                percentage = reader.ReadFloat32 ();\r\n            } else {\r\n                this.SkipChunk (reader, chunkLength);\r\n            }\r\n        });\r\n        return percentage;\r\n    }\r\n\r\n    ReadObjectChunk (reader, length)\r\n    {\r\n        let endByte = this.GetChunkEnd (reader, length);\r\n        let objectName = this.ReadName (reader);\r\n        this.ReadChunks (reader, endByte, (chunkId, chunkLength) => {\r\n            if (chunkId === CHUNK3DS.OBJ_TRIMESH) {\r\n                this.ReadMeshChunk (reader, chunkLength, objectName);\r\n            } else {\r\n                this.SkipChunk (reader, chunkLength);\r\n            }\r\n        });\r\n    }\r\n\r\n    ReadMeshChunk (reader, length, objectName)\r\n    {\r\n        function ApplyMeshTransformation (mesh, meshMatrix)\r\n        {\r\n            if (!meshMatrix.IsValid ()) {\r\n                return;\r\n            }\r\n\r\n            let determinant = meshMatrix.Determinant ();\r\n            let mirrorByX = IsNegative (determinant);\r\n            if (mirrorByX) {\r\n                let scaleMatrix = new Matrix ().CreateScale (-1, 1.0, 1.0);\r\n                meshMatrix = scaleMatrix.MultiplyMatrix (meshMatrix);\r\n            }\r\n\r\n            let invMeshMatrix = meshMatrix.Invert ();\r\n            if (invMeshMatrix === null) {\r\n                return;\r\n            }\r\n\r\n            let transformation = new Transformation (invMeshMatrix);\r\n            TransformMesh (mesh, transformation);\r\n            if (mirrorByX) {\r\n                FlipMeshTrianglesOrientation (mesh);\r\n            }\r\n        }\r\n\r\n        let mesh = new Mesh ();\r\n        mesh.SetName (objectName);\r\n\r\n        let endByte = this.GetChunkEnd (reader, length);\r\n        let matrixElements = null;\r\n        this.ReadChunks (reader, endByte, (chunkId, chunkLength) => {\r\n            if (chunkId === CHUNK3DS.TRI_VERTEX) {\r\n                this.ReadVerticesChunk (mesh, reader);\r\n            } else if (chunkId === CHUNK3DS.TRI_TEXVERTEX) {\r\n                this.ReadTextureVerticesChunk (mesh, reader);\r\n            } else if (chunkId === CHUNK3DS.TRI_FACE) {\r\n                this.ReadFacesChunk (mesh, reader, chunkLength);\r\n            } else if (chunkId === CHUNK3DS.TRI_TRANSFORMATION) {\r\n                matrixElements = this.ReadTransformationChunk (reader);\r\n            } else {\r\n                this.SkipChunk (reader, chunkLength);\r\n            }\r\n        });\r\n\r\n        if (mesh.VertexCount () === mesh.TextureUVCount ()) {\r\n            for (let i = 0; i < mesh.TriangleCount (); i++) {\r\n                let triangle = mesh.GetTriangle (i);\r\n                triangle.SetTextureUVs (\r\n                    triangle.v0,\r\n                    triangle.v1,\r\n                    triangle.v2\r\n                );\r\n            }\r\n        }\r\n\r\n        let meshMatrix = new Matrix (matrixElements);\r\n        ApplyMeshTransformation (mesh, meshMatrix);\r\n\r\n        let meshIndex = this.model.AddMesh (mesh);\r\n        this.meshNameToIndex.set (mesh.GetName (), meshIndex);\r\n    }\r\n\r\n    ReadVerticesChunk (mesh, reader)\r\n    {\r\n        let vertexCount = reader.ReadUnsignedInteger16 ();\r\n        for (let i = 0; i < vertexCount; i++) {\r\n            let x = reader.ReadFloat32 ();\r\n            let y = reader.ReadFloat32 ();\r\n            let z = reader.ReadFloat32 ();\r\n            mesh.AddVertex (new Coord3D (x, y, z));\r\n        }\r\n    }\r\n\r\n    ReadTextureVerticesChunk (mesh, reader)\r\n    {\r\n        let texVertexCount = reader.ReadUnsignedInteger16 ();\r\n        for (let i = 0; i < texVertexCount; i++) {\r\n            let x = reader.ReadFloat32 ();\r\n            let y = reader.ReadFloat32 ();\r\n            mesh.AddTextureUV (new Coord2D (x, y));\r\n        }\r\n    }\r\n\r\n    ReadFacesChunk (mesh, reader, length)\r\n    {\r\n        let endByte = this.GetChunkEnd (reader, length);\r\n        let faceCount = reader.ReadUnsignedInteger16 ();\r\n        for (let i = 0; i < faceCount; i++) {\r\n            let v0 = reader.ReadUnsignedInteger16 ();\r\n            let v1 = reader.ReadUnsignedInteger16 ();\r\n            let v2 = reader.ReadUnsignedInteger16 ();\r\n            reader.ReadUnsignedInteger16 (); // flags\r\n            mesh.AddTriangle (new Triangle (v0, v1, v2));\r\n        }\r\n\r\n        this.ReadChunks (reader, endByte, (chunkId, chunkLength) => {\r\n            if (chunkId === CHUNK3DS.TRI_MATERIAL) {\r\n                this.ReadFaceMaterialsChunk (mesh, reader);\r\n            } else if (chunkId === CHUNK3DS.TRI_SMOOTH) {\r\n                this.ReadFaceSmoothingGroupsChunk (mesh, faceCount, reader);\r\n            } else {\r\n                this.SkipChunk (reader, chunkLength);\r\n            }\r\n        });\r\n    }\r\n\r\n    ReadFaceMaterialsChunk (mesh, reader)\r\n    {\r\n        let materialName = this.ReadName (reader);\r\n        let materialIndex = this.materialNameToIndex.get (materialName);\r\n        let faceCount = reader.ReadUnsignedInteger16 ();\r\n        for (let i = 0; i < faceCount; i++) {\r\n            let faceIndex = reader.ReadUnsignedInteger16 ();\r\n            let triangle = mesh.GetTriangle (faceIndex);\r\n            if (materialIndex !== undefined) {\r\n                triangle.mat = materialIndex;\r\n            }\r\n        }\r\n    }\r\n\r\n    ReadFaceSmoothingGroupsChunk (mesh, faceCount, reader)\r\n    {\r\n        for (let i = 0; i < faceCount; i++) {\r\n            let smoothingGroup = reader.ReadUnsignedInteger32 ();\r\n            let triangle = mesh.GetTriangle (i);\r\n            triangle.curve = smoothingGroup;\r\n        }\r\n    }\r\n\r\n    ReadTransformationChunk (reader)\r\n    {\r\n        let matrix = [];\r\n        for (let i = 0; i < 4; i++) {\r\n            for (let j = 0; j < 3; j++) {\r\n                matrix.push (reader.ReadFloat32 ());\r\n            }\r\n            if (i < 3) {\r\n                matrix.push (0);\r\n            } else {\r\n                matrix.push (1);\r\n            }\r\n        }\r\n        return matrix;\r\n    }\r\n\r\n    ReadKeyFrameChunk (reader, length)\r\n    {\r\n        let endByte = this.GetChunkEnd (reader, length);\r\n        this.ReadChunks (reader, endByte, (chunkId, chunkLength) => {\r\n            if (chunkId === CHUNK3DS.OBJECT_NODE) {\r\n                this.ReadObjectNodeChunk (reader, chunkLength);\r\n            } else {\r\n                this.SkipChunk (reader, chunkLength);\r\n            }\r\n        });\r\n    }\r\n\r\n    BuildNodeHierarchy ()\r\n    {\r\n        function GetNodeTransformation (node3ds, isMeshNode)\r\n        {\r\n            function GetNodePosition (node3ds)\r\n            {\r\n                if (node3ds.positions.length === 0) {\r\n                    return [0.0, 0.0, 0.0];\r\n                }\r\n                return node3ds.positions[0];\r\n            }\r\n\r\n            function GetNodeRotation (node3ds)\r\n            {\r\n                function GetQuaternionFromAxisAndAngle (axisAngle)\r\n                {\r\n                    let result = [0.0, 0.0, 0.0, 1.0];\r\n                    let length = Math.sqrt (axisAngle[0] * axisAngle[0] + axisAngle[1] * axisAngle[1] + axisAngle[2] * axisAngle[2]);\r\n                    if (length > 0.0) {\r\n                        let omega = axisAngle[3] * -0.5;\r\n                        let si = Math.sin (omega) / length;\r\n                        result = [si * axisAngle[0], si * axisAngle[1], si * axisAngle[2], Math.cos (omega)];\r\n                    }\r\n                    return result;\r\n                }\r\n\r\n                if (node3ds.rotations.length === 0) {\r\n                    return [0.0, 0.0, 0.0, 1.0];\r\n                }\r\n\r\n                let rotation = node3ds.rotations[0];\r\n                return GetQuaternionFromAxisAndAngle (rotation);\r\n            }\r\n\r\n            function GetNodeScale (node3ds)\r\n            {\r\n                if (node3ds.scales.length === 0) {\r\n                    return [1.0, 1.0, 1.0];\r\n                }\r\n                return node3ds.scales[0];\r\n            }\r\n\r\n            let matrix = new Matrix ();\r\n            matrix.ComposeTRS (\r\n                ArrayToCoord3D (GetNodePosition (node3ds)),\r\n                ArrayToQuaternion (GetNodeRotation (node3ds)),\r\n                ArrayToCoord3D (GetNodeScale (node3ds))\r\n            );\r\n\r\n            if (isMeshNode) {\r\n                let pivotPoint = node3ds.pivot;\r\n                let pivotMatrix = new Matrix ().CreateTranslation (-pivotPoint[0], -pivotPoint[1], -pivotPoint[2]);\r\n                matrix = pivotMatrix.MultiplyMatrix (matrix);\r\n            }\r\n\r\n            return new Transformation (matrix);\r\n        }\r\n\r\n        let rootNode = this.model.GetRootNode ();\r\n        if (this.nodeList.IsEmpty ()) {\r\n            for (let meshIndex = 0; meshIndex < this.model.MeshCount (); meshIndex++) {\r\n                rootNode.AddMeshIndex (meshIndex);\r\n            }\r\n        } else {\r\n            let nodeIdToModelNode = new Map ();\r\n            for (let node3ds of this.nodeList.GetNodes ()) {\r\n                let node = new Node ();\r\n                if (node3ds.name.length > 0 && node3ds.name !== '$$$DUMMY') {\r\n                    node.SetName (node3ds.name);\r\n                    if (node3ds.instanceName.length > 0) {\r\n                        node.SetName (node.GetName () + ' ' + node3ds.instanceName);\r\n                    }\r\n                }\r\n                if (node3ds.parentId === 65535 || !nodeIdToModelNode.has (node3ds.parentId)) {\r\n                    rootNode.AddChildNode (node);\r\n                } else {\r\n                    let parentNode = nodeIdToModelNode.get (node3ds.parentId);\r\n                    parentNode.AddChildNode (node);\r\n                }\r\n                nodeIdToModelNode.set (node3ds.id, node);\r\n                let isMeshNode = this.meshNameToIndex.has (node3ds.name);\r\n                node.SetTransformation (GetNodeTransformation (node3ds, isMeshNode));\r\n                if (isMeshNode) {\r\n                    node.AddMeshIndex (this.meshNameToIndex.get (node3ds.name));\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    ReadObjectNodeChunk (reader, length)\r\n    {\r\n        function ReadTrackVector (obj, reader, type)\r\n        {\r\n            let result = [];\r\n            reader.Skip (10);\r\n\r\n            let keyNum = reader.ReadInteger32 ();\r\n            for (let i = 0; i < keyNum; i++) {\r\n                reader.ReadInteger32 ();\r\n                let flags = reader.ReadUnsignedInteger16 ();\r\n                if (flags !== 0) {\r\n                    reader.ReadFloat32 ();\r\n                }\r\n\r\n                let current = null;\r\n                if (type === CHUNK3DS.OBJECT_ROTATION) {\r\n                    let tmp = reader.ReadFloat32 ();\r\n                    current = obj.ReadVector (reader);\r\n                    current[3] = tmp;\r\n                } else {\r\n                    current = obj.ReadVector (reader);\r\n                }\r\n                result.push (current);\r\n            }\r\n\r\n            return result;\r\n        }\r\n\r\n        let node3ds = new Importer3dsNode ();\r\n        let endByte = this.GetChunkEnd (reader, length);\r\n        this.ReadChunks (reader, endByte, (chunkId, chunkLength) => {\r\n            if (chunkId === CHUNK3DS.OBJECT_HIERARCHY) {\r\n                node3ds.name = this.ReadName (reader);\r\n                node3ds.flags = reader.ReadUnsignedInteger32 ();\r\n                node3ds.parentId = reader.ReadUnsignedInteger16 ();\r\n            } else if (chunkId === CHUNK3DS.OBJECT_INSTANCE_NAME) {\r\n                node3ds.instanceName = this.ReadName (reader);\r\n            } else if (chunkId === CHUNK3DS.OBJECT_PIVOT) {\r\n                node3ds.pivot = this.ReadVector (reader);\r\n            } else if (chunkId === CHUNK3DS.OBJECT_POSITION) {\r\n                node3ds.positions = ReadTrackVector (this, reader, CHUNK3DS.OBJECT_POSITION);\r\n            } else if (chunkId === CHUNK3DS.OBJECT_ROTATION) {\r\n                node3ds.rotations = ReadTrackVector (this, reader, CHUNK3DS.OBJECT_ROTATION);\r\n            } else if (chunkId === CHUNK3DS.OBJECT_SCALE) {\r\n                node3ds.scales = ReadTrackVector (this, reader, CHUNK3DS.OBJECT_SCALE);\r\n            } else if (chunkId === CHUNK3DS.OBJECT_ID) {\r\n                node3ds.id = reader.ReadUnsignedInteger16 ();\r\n            } else {\r\n                this.SkipChunk (reader, chunkLength);\r\n            }\r\n        });\r\n\r\n        this.nodeList.AddNode (node3ds);\r\n    }\r\n\r\n    ReadName (reader)\r\n    {\r\n        let name = '';\r\n        let char = 0;\r\n        let count = 0;\r\n        while (count < 64) {\r\n            char = reader.ReadCharacter8 ();\r\n            if (char === 0) {\r\n                break;\r\n            }\r\n            name = name + String.fromCharCode (char);\r\n            count = count + 1;\r\n        }\r\n        return name;\r\n    }\r\n\r\n    ReadVector (reader)\r\n    {\r\n        let result = [\r\n            reader.ReadFloat32 (),\r\n            reader.ReadFloat32 (),\r\n            reader.ReadFloat32 ()\r\n        ];\r\n        return result;\r\n    }\r\n\r\n    ReadChunks (reader, endByte, onChunk)\r\n    {\r\n        while (reader.GetPosition () <= endByte - 6) {\r\n        let chunkId = reader.ReadUnsignedInteger16 ();\r\n            let chunkLength = reader.ReadUnsignedInteger32 ();\r\n            onChunk (chunkId, chunkLength);\r\n        }\r\n    }\r\n\r\n    GetChunkEnd (reader, length)\r\n    {\r\n        return reader.GetPosition () + length - 6;\r\n    }\r\n\r\n    SkipChunk (reader, length)\r\n    {\r\n        reader.Skip (length - 6);\r\n    }\r\n}\n\nconst GltfComponentType =\r\n{\r\n    BYTE : 5120,\r\n    UNSIGNED_BYTE : 5121,\r\n    SHORT : 5122,\r\n    UNSIGNED_SHORT : 5123,\r\n    UNSIGNED_INT : 5125,\r\n    FLOAT : 5126\r\n};\r\n\r\nconst GltfDataType =\r\n{\r\n    SCALAR : 0,\r\n    VEC2 : 1,\r\n    VEC3 : 2,\r\n    VEC4 : 3,\r\n    MAT2 : 4,\r\n    MAT3  : 5,\r\n    MAT4  : 6\r\n};\r\n\r\nconst GltfRenderMode =\r\n{\r\n    TRIANGLES : 4,\r\n    TRIANGLE_STRIP  : 5,\r\n    TRIANGLE_FAN : 6\r\n};\r\n\r\nconst GltfConstants =\r\n{\r\n    GLTF_STRING : 0x46546C67,\r\n    JSON_CHUNK_TYPE : 0x4E4F534A,\r\n    BINARY_CHUNK_TYPE : 0x004E4942\r\n};\r\n\r\nfunction GetGltfColor (color)\r\n{\r\n    return RGBColorFromFloatComponents (\r\n        LinearToSRGB (color[0]),\r\n        LinearToSRGB (color[1]),\r\n        LinearToSRGB (color[2])\r\n    );\r\n}\r\n\r\nfunction GetGltfVertexColor (color, componentType)\r\n{\r\n    function GetColorComponent (component, componentType)\r\n    {\r\n        let normalized = component;\r\n        if (componentType === GltfComponentType.UNSIGNED_BYTE) {\r\n            normalized /= 255.0;\r\n        } else if (componentType === GltfComponentType.UNSIGNED_SHORT) {\r\n            normalized /= 65535.0;\r\n        }\r\n        return ColorComponentFromFloat (LinearToSRGB (normalized));\r\n    }\r\n\r\n    return new RGBColor (\r\n        GetColorComponent (color[0], componentType),\r\n        GetColorComponent (color[1], componentType),\r\n        GetColorComponent (color[2], componentType)\r\n    );\r\n}\r\n\r\nclass GltfBufferReader\r\n{\r\n    constructor (buffer)\r\n    {\r\n        this.reader = new BinaryReader (buffer, true);\r\n        this.componentType = null;\r\n        this.dataType = null;\r\n        this.byteStride = null;\r\n        this.dataCount = null;\r\n        this.sparseReader = null;\r\n    }\r\n\r\n    SetComponentType (componentType)\r\n    {\r\n        this.componentType = componentType;\r\n    }\r\n\r\n    SetDataType (dataType)\r\n    {\r\n        if (dataType === 'SCALAR') {\r\n            this.dataType = GltfDataType.SCALAR;\r\n        } else if (dataType === 'VEC2') {\r\n            this.dataType = GltfDataType.VEC2;\r\n        } else if (dataType === 'VEC3') {\r\n            this.dataType = GltfDataType.VEC3;\r\n        } else if (dataType === 'VEC4') {\r\n            this.dataType = GltfDataType.VEC4;\r\n        } else if (dataType === 'MAT2') {\r\n            this.dataType = GltfDataType.MAT2;\r\n        } else if (dataType === 'MAT3') {\r\n            this.dataType = GltfDataType.MAT3;\r\n        } else if (dataType === 'MAT4') {\r\n            this.dataType = GltfDataType.MAT4;\r\n        }\r\n    }\r\n\r\n    SetByteStride (byteStride)\r\n    {\r\n        this.byteStride = byteStride;\r\n    }\r\n\r\n    SetDataCount (dataCount)\r\n    {\r\n        this.dataCount = dataCount;\r\n    }\r\n\r\n    SetSparseReader (indexReader, valueReader)\r\n    {\r\n        this.sparseReader = {\r\n            indexReader : indexReader,\r\n            valueReader : valueReader\r\n        };\r\n    }\r\n\r\n    ReadArrayBuffer (byteLength)\r\n    {\r\n        return this.reader.ReadArrayBuffer (byteLength);\r\n    }\r\n\r\n    GetDataCount ()\r\n    {\r\n        return this.dataCount;\r\n    }\r\n\r\n    ReadData ()\r\n    {\r\n        if (this.dataType === null) {\r\n            return null;\r\n        }\r\n        if (this.dataType === GltfDataType.SCALAR) {\r\n            let data = this.ReadComponent ();\r\n            this.SkipBytesByStride (1);\r\n            return data;\r\n        } else if (this.dataType === GltfDataType.VEC2) {\r\n            let x = this.ReadComponent ();\r\n            let y = this.ReadComponent ();\r\n            this.SkipBytesByStride (2);\r\n            return new Coord2D (x, y);\r\n        } else if (this.dataType === GltfDataType.VEC3) {\r\n            let x = this.ReadComponent ();\r\n            let y = this.ReadComponent ();\r\n            let z = this.ReadComponent ();\r\n            this.SkipBytesByStride (3);\r\n            return new Coord3D (x, y, z);\r\n        } else if (this.dataType === GltfDataType.VEC4) {\r\n            let x = this.ReadComponent ();\r\n            let y = this.ReadComponent ();\r\n            let z = this.ReadComponent ();\r\n            let w = this.ReadComponent ();\r\n            this.SkipBytesByStride (4);\r\n            return new Coord4D (x, y, z, w);\r\n        }\r\n        return null;\r\n    }\r\n\r\n    EnumerateData (onData)\r\n    {\r\n        if (this.sparseReader === null) {\r\n            for (let i = 0; i < this.dataCount; i++) {\r\n                onData (this.ReadData ());\r\n            }\r\n        } else {\r\n            let sparseData = [];\r\n            for (let i = 0; i < this.sparseReader.indexReader.GetDataCount (); i++) {\r\n                let index = this.sparseReader.indexReader.ReadData ();\r\n                let value = this.sparseReader.valueReader.ReadData ();\r\n                sparseData.push ({\r\n                    index : index,\r\n                    value : value\r\n                });\r\n            }\r\n            let sparseIndex = 0;\r\n            for (let i = 0; i < this.dataCount; i++) {\r\n                let data = this.ReadData ();\r\n                if (sparseIndex < sparseData.length && sparseData[sparseIndex].index === i) {\r\n                    onData (sparseData[sparseIndex].value);\r\n                    sparseIndex += 1;\r\n                } else {\r\n                    onData (data);\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    SkipBytes (bytes)\r\n    {\r\n        this.reader.Skip (bytes);\r\n    }\r\n\r\n    ReadComponent ()\r\n    {\r\n        if (this.componentType === null) {\r\n            return null;\r\n        }\r\n        if (this.componentType === GltfComponentType.BYTE) {\r\n            return this.reader.ReadCharacter8 ();\r\n        } else if (this.componentType === GltfComponentType.UNSIGNED_BYTE) {\r\n            return this.reader.ReadUnsignedCharacter8 ();\r\n        } else if (this.componentType === GltfComponentType.SHORT) {\r\n            return this.reader.ReadInteger16 ();\r\n        } else if (this.componentType === GltfComponentType.UNSIGNED_SHORT) {\r\n            return this.reader.ReadUnsignedInteger16 ();\r\n        } else if (this.componentType === GltfComponentType.UNSIGNED_INT) {\r\n            return this.reader.ReadInteger32 ();\r\n        } else if (this.componentType === GltfComponentType.FLOAT) {\r\n            return this.reader.ReadFloat32 ();\r\n        }\r\n        return null;\r\n    }\r\n\r\n    SkipBytesByStride (componentCount)\r\n    {\r\n        if (this.byteStride === null) {\r\n            return;\r\n        }\r\n        let readBytes = componentCount * this.GetComponentSize ();\r\n        this.reader.Skip (this.byteStride - readBytes);\r\n    }\r\n\r\n    GetComponentSize ()\r\n    {\r\n        if (this.componentType === GltfComponentType.BYTE) {\r\n            return 1;\r\n        } else if (this.componentType === GltfComponentType.UNSIGNED_BYTE) {\r\n            return 1;\r\n        } else if (this.componentType === GltfComponentType.SHORT) {\r\n            return 2;\r\n        } else if (this.componentType === GltfComponentType.UNSIGNED_SHORT) {\r\n            return 2;\r\n        } else if (this.componentType === GltfComponentType.UNSIGNED_INT) {\r\n            return 4;\r\n        } else if (this.componentType === GltfComponentType.FLOAT) {\r\n            return 4;\r\n        }\r\n        return 0;\r\n    }\r\n}\r\n\r\nclass GltfExtensions\r\n{\r\n    constructor ()\r\n    {\r\n        this.supportedExtensions = [\r\n            'KHR_draco_mesh_compression',\r\n            'KHR_materials_pbrSpecularGlossiness',\r\n            'KHR_texture_transform',\r\n        ];\r\n        this.draco = null;\r\n    }\r\n\r\n    LoadLibraries (extensionsRequired, callbacks)\r\n    {\r\n        if (extensionsRequired === undefined) {\r\n            callbacks.onSuccess ();\r\n            return;\r\n        }\r\n        if (this.draco === null && extensionsRequired.indexOf ('KHR_draco_mesh_compression') !== -1) {\r\n\t\t\tLoadExternalLibrary ('draco3d').then (() => {\r\n                DracoDecoderModule ().then ((draco) => {\r\n                    this.draco = draco;\r\n                    callbacks.onSuccess ();\r\n                });\r\n            }).catch (() => {\r\n                callbacks.onError (Loc ('Failed to load draco decoder.'));\r\n            });\r\n        } else {\r\n            callbacks.onSuccess ();\r\n        }\r\n    }\r\n\r\n    GetUnsupportedExtensions (extensionsRequired)\r\n    {\r\n        let unsupportedExtensions = [];\r\n        if (extensionsRequired === undefined) {\r\n            return unsupportedExtensions;\r\n        }\r\n        for (let i = 0; i < extensionsRequired.length; i++) {\r\n            let requiredExtension = extensionsRequired[i];\r\n            if (this.supportedExtensions.indexOf (requiredExtension) === -1) {\r\n                unsupportedExtensions.push (requiredExtension);\r\n            }\r\n        }\r\n        return unsupportedExtensions;\r\n    }\r\n\r\n    ProcessMaterial (gltfMaterial, material, imporTextureFn)\r\n    {\r\n        if (gltfMaterial.extensions === undefined) {\r\n            return null;\r\n        }\r\n\r\n        let khrSpecularGlossiness = gltfMaterial.extensions.KHR_materials_pbrSpecularGlossiness;\r\n        if (khrSpecularGlossiness === undefined) {\r\n            return null;\r\n        }\r\n\r\n        let phongMaterial = new PhongMaterial ();\r\n        let diffuseColor = khrSpecularGlossiness.diffuseFactor;\r\n        if (diffuseColor !== undefined) {\r\n            phongMaterial.color = GetGltfColor (diffuseColor);\r\n            phongMaterial.opacity = diffuseColor[3];\r\n        }\r\n        let diffuseTexture = khrSpecularGlossiness.diffuseTexture;\r\n        if (diffuseTexture !== undefined) {\r\n            phongMaterial.diffuseMap = imporTextureFn (diffuseTexture);\r\n        }\r\n        let specularColor = khrSpecularGlossiness.specularFactor;\r\n        if (specularColor !== undefined) {\r\n            phongMaterial.specular = GetGltfColor (specularColor);\r\n        }\r\n        let specularTexture = khrSpecularGlossiness.specularGlossinessTexture;\r\n        if (specularTexture !== undefined) {\r\n            phongMaterial.specularMap = imporTextureFn (specularTexture);\r\n        }\r\n        let glossiness = khrSpecularGlossiness.glossinessFactor;\r\n        if (glossiness !== undefined) {\r\n            phongMaterial.shininess = glossiness;\r\n        }\r\n\r\n        return phongMaterial;\r\n    }\r\n\r\n    ProcessTexture (gltfTexture, texture)\r\n    {\r\n        if (gltfTexture.extensions === undefined) {\r\n            return;\r\n        }\r\n        let khrTextureTransform = gltfTexture.extensions.KHR_texture_transform;\r\n        if (khrTextureTransform !== undefined) {\r\n            if (khrTextureTransform.offset !== undefined) {\r\n                texture.offset.x = khrTextureTransform.offset[0];\r\n                texture.offset.y = -khrTextureTransform.offset[1];\r\n            }\r\n            if (khrTextureTransform.scale !== undefined) {\r\n                texture.scale.x = khrTextureTransform.scale[0];\r\n                texture.scale.y = khrTextureTransform.scale[1];\r\n            }\r\n            if (khrTextureTransform.rotation !== undefined) {\r\n                texture.rotation = -khrTextureTransform.rotation;\r\n            }\r\n        }\r\n    }\r\n\r\n    ProcessPrimitive (importer, gltf, primitive, mesh)\r\n    {\r\n        function EnumerateComponents (draco, decoder, dracoMesh, attributeId, processor)\r\n        {\r\n            let attribute = decoder.GetAttributeByUniqueId (dracoMesh, attributeId);\r\n            let numComponents = attribute.num_components ();\r\n            let numPoints = dracoMesh.num_points ();\r\n            let numValues = numPoints * numComponents;\r\n            let dataSize = numValues * 4;\r\n            let attributePtr = draco._malloc (dataSize);\r\n            decoder.GetAttributeDataArrayForAllPoints (dracoMesh, attribute, draco.DT_FLOAT32, dataSize, attributePtr);\r\n            let attributeArray = new Float32Array (draco.HEAPF32.buffer, attributePtr, numValues).slice ();\r\n            if (numComponents === 2) {\r\n                for (let i = 0; i < attributeArray.length; i += 2) {\r\n                    processor (new Coord2D (\r\n                        attributeArray[i + 0],\r\n                        attributeArray[i + 1]\r\n                    ));\r\n                }\r\n            } else if (numComponents === 3) {\r\n                for (let i = 0; i < attributeArray.length; i += 3) {\r\n                    processor (new Coord3D (\r\n                        attributeArray[i + 0],\r\n                        attributeArray[i + 1],\r\n                        attributeArray[i + 2]\r\n                    ));\r\n                }\r\n            } else if (numComponents === 4) {\r\n                for (let i = 0; i < attributeArray.length; i += 4) {\r\n                    processor (new Coord4D (\r\n                        attributeArray[i + 0],\r\n                        attributeArray[i + 1],\r\n                        attributeArray[i + 2],\r\n                        attributeArray[i + 3]\r\n                    ));\r\n                }\r\n            }\r\n            draco._free (attributePtr);\r\n        }\r\n\r\n        if (this.draco === null) {\r\n            return false;\r\n        }\r\n\r\n        if (primitive.extensions === undefined || primitive.extensions.KHR_draco_mesh_compression === undefined) {\r\n            return false;\r\n        }\r\n\r\n        let decoder = new this.draco.Decoder ();\r\n        let decoderBuffer = new this.draco.DecoderBuffer ();\r\n\r\n        let extensionParams = primitive.extensions.KHR_draco_mesh_compression;\r\n        let compressedBufferView = gltf.bufferViews[extensionParams.bufferView];\r\n        let compressedReader = importer.GetReaderFromBufferView (compressedBufferView);\r\n        let compressedArrayBuffer = compressedReader.ReadArrayBuffer (compressedBufferView.byteLength);\r\n        decoderBuffer.Init (new Int8Array (compressedArrayBuffer), compressedArrayBuffer.byteLength);\r\n        let geometryType = decoder.GetEncodedGeometryType (decoderBuffer);\r\n        if (geometryType !== this.draco.TRIANGULAR_MESH) {\r\n            return true;\r\n        }\r\n\r\n        let dracoMesh = new this.draco.Mesh ();\r\n        let decodingStatus = decoder.DecodeBufferToMesh (decoderBuffer, dracoMesh);\r\n        if (!decodingStatus.ok ()) {\r\n            return true;\r\n        }\r\n\r\n        let hasVertices = (extensionParams.attributes.POSITION !== undefined);\r\n        let hasVertexColors = false;\r\n        let hasNormals = (extensionParams.attributes.NORMAL !== undefined);\r\n        let hasUVs = (extensionParams.attributes.TEXCOORD_0 !== undefined);\r\n\r\n        if (!hasVertices) {\r\n            return true;\r\n        }\r\n\r\n        let vertexOffset = mesh.VertexCount ();\r\n        let vertexColorOffset = mesh.VertexColorCount ();\r\n        let normalOffset = mesh.NormalCount ();\r\n        let uvOffset = mesh.TextureUVCount ();\r\n\r\n        EnumerateComponents (this.draco, decoder, dracoMesh, extensionParams.attributes.POSITION, (vertex) => {\r\n            mesh.AddVertex (vertex);\r\n        });\r\n\r\n        if (hasNormals) {\r\n            EnumerateComponents (this.draco, decoder, dracoMesh, extensionParams.attributes.NORMAL, (normal) => {\r\n                mesh.AddNormal (normal);\r\n            });\r\n        }\r\n\r\n        if (hasUVs) {\r\n            EnumerateComponents (this.draco, decoder, dracoMesh, extensionParams.attributes.TEXCOORD_0, (uv) => {\r\n                uv.y = -uv.y;\r\n                mesh.AddTextureUV (uv);\r\n            });\r\n        }\r\n\r\n        let faceCount = dracoMesh.num_faces ();\r\n        let indexCount = faceCount * 3;\r\n        let indexDataSize = indexCount * 4;\r\n        let indexDataPtr = this.draco._malloc (indexDataSize);\r\n        decoder.GetTrianglesUInt32Array (dracoMesh, indexDataSize, indexDataPtr);\r\n        let indexArray = new Uint32Array (this.draco.HEAPU32.buffer, indexDataPtr, indexCount).slice ();\r\n        for (let i = 0; i < indexArray.length; i += 3) {\r\n            let v0 = indexArray[i];\r\n            let v1 = indexArray[i + 1];\r\n            let v2 = indexArray[i + 2];\r\n            importer.AddTriangle (primitive, mesh, v0, v1, v2, hasVertexColors, hasNormals, hasUVs, vertexOffset, vertexColorOffset, normalOffset, uvOffset);\r\n        }\r\n        this.draco._free (indexDataPtr);\r\n\r\n        return true;\r\n    }\r\n}\r\n\r\nclass ImporterGltf extends ImporterBase\r\n{\r\n    constructor ()\r\n    {\r\n        super ();\r\n        this.gltfExtensions = new GltfExtensions ();\r\n    }\r\n\r\n    CanImportExtension (extension)\r\n    {\r\n        return extension === 'gltf' || extension === 'glb';\r\n    }\r\n\r\n    GetUpDirection ()\r\n    {\r\n        return Direction.Y;\r\n    }\r\n\r\n    ClearContent ()\r\n    {\r\n        this.bufferContents = null;\r\n        this.imageIndexToTextureParams = null;\r\n    }\r\n\r\n    ResetContent ()\r\n    {\r\n        this.bufferContents = [];\r\n        this.imageIndexToTextureParams = new Map ();\r\n    }\r\n\r\n    ImportContent (fileContent, onFinish)\r\n    {\r\n        if (this.extension === 'gltf') {\r\n            this.ProcessGltf (fileContent, onFinish);\r\n        } else if (this.extension === 'glb') {\r\n            this.ProcessBinaryGltf (fileContent, onFinish);\r\n        }\r\n    }\r\n\r\n    ProcessGltf (fileContent, onFinish)\r\n    {\r\n        let textContent = ArrayBufferToUtf8String (fileContent);\r\n        let gltf = JSON.parse (textContent);\r\n        if (gltf.asset.version !== '2.0') {\r\n            this.SetError (Loc ('Invalid glTF version.'));\r\n            onFinish ();\r\n            return;\r\n        }\r\n\r\n        for (let i = 0; i < gltf.buffers.length; i++) {\r\n            let buffer = null;\r\n            let gltfBuffer = gltf.buffers[i];\r\n            let base64Buffer = Base64DataURIToArrayBuffer (gltfBuffer.uri);\r\n            if (base64Buffer !== null) {\r\n                buffer = base64Buffer.buffer;\r\n            } else {\r\n                let fileBuffer = this.callbacks.getFileBuffer (gltfBuffer.uri);\r\n                if (fileBuffer !== null) {\r\n                    buffer = fileBuffer;\r\n                }\r\n            }\r\n            if (buffer === null) {\r\n                this.SetError (Loc ('One of the requested buffers is missing.'));\r\n                onFinish ();\r\n                return;\r\n            }\r\n            this.bufferContents.push (buffer);\r\n        }\r\n\r\n        this.ProcessMainFile (gltf, onFinish);\r\n    }\r\n\r\n    ProcessBinaryGltf (fileContent, onFinish)\r\n    {\r\n        function ReadChunk (reader)\r\n        {\r\n            let length = reader.ReadUnsignedInteger32 ();\r\n            let type = reader.ReadUnsignedInteger32 ();\r\n            let buffer = reader.ReadArrayBuffer (length);\r\n            return {\r\n                type : type,\r\n                buffer : buffer\r\n            };\r\n        }\r\n\r\n        let reader = new BinaryReader (fileContent, true);\r\n        let magic = reader.ReadUnsignedInteger32 ();\r\n        if (magic !== GltfConstants.GLTF_STRING) {\r\n            this.SetError (Loc ('Invalid glTF file.'));\r\n            onFinish ();\r\n            return;\r\n        }\r\n        let version = reader.ReadUnsignedInteger32 ();\r\n        if (version !== 2) {\r\n            this.SetError (Loc ('Invalid glTF version.'));\r\n            onFinish ();\r\n            return;\r\n        }\r\n        let length = reader.ReadUnsignedInteger32 ();\r\n        if (length !== reader.GetByteLength ()) {\r\n            this.SetError (Loc ('Invalid glTF file.'));\r\n            onFinish ();\r\n            return;\r\n        }\r\n\r\n        let gltfTextContent = null;\r\n        while (!reader.End ()) {\r\n            let chunk = ReadChunk (reader);\r\n            if (chunk.type === GltfConstants.JSON_CHUNK_TYPE) {\r\n                gltfTextContent = ArrayBufferToUtf8String (chunk.buffer);\r\n            } else if (chunk.type === GltfConstants.BINARY_CHUNK_TYPE) {\r\n                this.bufferContents.push (chunk.buffer);\r\n            }\r\n        }\r\n\r\n        if (gltfTextContent !== null) {\r\n            let gltf = JSON.parse (gltfTextContent);\r\n            this.ProcessMainFile (gltf, onFinish);\r\n        }\r\n    }\r\n\r\n    ProcessMainFile (gltf, onFinish)\r\n    {\r\n        let unsupportedExtensions = this.gltfExtensions.GetUnsupportedExtensions (gltf.extensionsRequired);\r\n        if (unsupportedExtensions.length > 0) {\r\n            this.SetError (FLoc ('Unsupported extension: {0}.', unsupportedExtensions.join (', ')));\r\n            onFinish ();\r\n            return;\r\n        }\r\n\r\n        this.gltfExtensions.LoadLibraries (gltf.extensionsRequired, {\r\n            onSuccess : () => {\r\n                this.ImportModel (gltf);\r\n                onFinish ();\r\n            },\r\n            onError : (message) => {\r\n                this.SetError (message);\r\n                onFinish ();\r\n            }\r\n        });\r\n    }\r\n\r\n    ImportModel (gltf)\r\n    {\r\n        let materials = gltf.materials;\r\n        if (materials !== undefined) {\r\n            for (let material of materials) {\r\n                this.ImportMaterial (gltf, material);\r\n            }\r\n        }\r\n\r\n        let meshes = gltf.meshes;\r\n        if (meshes !== undefined) {\r\n            for (let mesh of meshes) {\r\n                this.ImportMesh (gltf, mesh);\r\n            }\r\n        }\r\n\r\n        this.ImportProperties (this.model, gltf.asset, Loc ('Asset properties'));\r\n        this.ImportScene (gltf);\r\n    }\r\n\r\n    ImportProperties (modelObject, gltfObject, propertyGroupName)\r\n    {\r\n        if (gltfObject === undefined || gltfObject === null) {\r\n            return;\r\n        }\r\n\r\n        let propertyGroup = new PropertyGroup (propertyGroupName);\r\n        for (let propertyName in gltfObject) {\r\n            if (Object.prototype.hasOwnProperty.call (gltfObject, propertyName)) {\r\n                let property = null;\r\n                let propertyValue = gltfObject[propertyName];\r\n                if (typeof propertyValue === 'string') {\r\n                    property = new Property (PropertyType.Text, propertyName, propertyValue);\r\n                } else if (typeof propertyValue === 'number') {\r\n                    if (Number.isInteger (propertyValue)) {\r\n                        property = new Property (PropertyType.Integer, propertyName, propertyValue);\r\n                    } else {\r\n                        property = new Property (PropertyType.Number, propertyName, propertyValue);\r\n                    }\r\n                }\r\n                if (property !== null) {\r\n                    propertyGroup.AddProperty (property);\r\n                }\r\n            }\r\n        }\r\n\r\n        if (propertyGroup.PropertyCount () === 0) {\r\n            return;\r\n        }\r\n\r\n        modelObject.AddPropertyGroup (propertyGroup);\r\n    }\r\n\r\n    GetDefaultScene (gltf)\r\n    {\r\n        let defaultSceneIndex = gltf.scene || 0;\r\n        if (defaultSceneIndex >= gltf.scenes.length) {\r\n            return null;\r\n        }\r\n        return gltf.scenes[defaultSceneIndex];\r\n    }\r\n\r\n    ImportMaterial (gltf, gltfMaterial)\r\n    {\r\n        let material = new PhysicalMaterial ();\r\n        if (gltfMaterial.name !== undefined) {\r\n            material.name = gltfMaterial.name;\r\n        }\r\n\r\n        material.color = GetGltfColor ([1.0, 1.0, 1.0]);\r\n        if (gltfMaterial.pbrMetallicRoughness !== undefined) {\r\n            let baseColor = gltfMaterial.pbrMetallicRoughness.baseColorFactor;\r\n            if (baseColor !== undefined) {\r\n                material.color = GetGltfColor (baseColor);\r\n                material.opacity = baseColor[3];\r\n            }\r\n            let metallicFactor = gltfMaterial.pbrMetallicRoughness.metallicFactor;\r\n            if (metallicFactor !== undefined) {\r\n                material.metalness = metallicFactor;\r\n            }\r\n            let roughnessFactor = gltfMaterial.pbrMetallicRoughness.roughnessFactor;\r\n            if (roughnessFactor !== undefined) {\r\n                material.roughness = roughnessFactor;\r\n            }\r\n            let emissiveColor = gltfMaterial.emissiveFactor;\r\n            if (emissiveColor !== undefined) {\r\n                material.emissive = GetGltfColor (emissiveColor);\r\n            }\r\n\r\n            material.diffuseMap = this.ImportTexture (gltf, gltfMaterial.pbrMetallicRoughness.baseColorTexture);\r\n            material.metalnessMap = this.ImportTexture (gltf, gltfMaterial.pbrMetallicRoughness.metallicRoughnessTexture);\r\n            material.normalMap = this.ImportTexture (gltf, gltfMaterial.normalTexture);\r\n            material.emissiveMap = this.ImportTexture (gltf, gltfMaterial.emissiveTexture);\r\n            if (material.diffuseMap !== null) {\r\n                material.multiplyDiffuseMap = true;\r\n            }\r\n\r\n            let alphaMode = gltfMaterial.alphaMode;\r\n            if (alphaMode !== undefined) {\r\n                if (alphaMode === 'BLEND') {\r\n                    material.transparent = true;\r\n                } else if (alphaMode === 'MASK') {\r\n                    material.transparent = true;\r\n                    material.alphaTest = gltfMaterial.alphaCutoff || 0.5;\r\n                }\r\n            }\r\n        }\r\n\r\n        let newMaterial = this.gltfExtensions.ProcessMaterial (gltfMaterial, material, (textureRef) => {\r\n            return this.ImportTexture (gltf, textureRef);\r\n        });\r\n        if (newMaterial !== null) {\r\n            material = newMaterial;\r\n        }\r\n        this.model.AddMaterial (material);\r\n    }\r\n\r\n    ImportTexture (gltf, gltfTextureRef)\r\n    {\r\n        if (gltfTextureRef === undefined || gltfTextureRef === null) {\r\n            return null;\r\n        }\r\n\r\n        let texture = new TextureMap ();\r\n        let gltfTexture = gltf.textures[gltfTextureRef.index];\r\n        let gltfImageIndex = gltfTexture.source;\r\n        let gltfImage = gltf.images[gltfImageIndex];\r\n\r\n        let textureParams = null;\r\n        if (this.imageIndexToTextureParams.has (gltfImageIndex)) {\r\n            textureParams = this.imageIndexToTextureParams.get (gltfImageIndex);\r\n        } else {\r\n            textureParams = {\r\n                name : null,\r\n                mimeType : null,\r\n                buffer : null\r\n            };\r\n            let textureIndexString = gltfImageIndex.toString ();\r\n            if (gltfImage.uri !== undefined) {\r\n                let base64Buffer = Base64DataURIToArrayBuffer (gltfImage.uri);\r\n                if (base64Buffer !== null) {\r\n                    textureParams.name = 'Embedded_' + textureIndexString + '.' + GetFileExtensionFromMimeType (base64Buffer.mimeType);\r\n                    textureParams.mimeType = base64Buffer.mimeType;\r\n                    textureParams.buffer = base64Buffer.buffer;\r\n                } else {\r\n                    let textureBuffer = this.callbacks.getFileBuffer (gltfImage.uri);\r\n                    textureParams.name = gltfImage.uri;\r\n                    textureParams.buffer = textureBuffer;\r\n                }\r\n            } else if (gltfImage.bufferView !== undefined) {\r\n                let bufferView = gltf.bufferViews[gltfImage.bufferView];\r\n                let reader = this.GetReaderFromBufferView (bufferView);\r\n                if (reader !== null) {\r\n                    let buffer = reader.ReadArrayBuffer (bufferView.byteLength);\r\n                    textureParams.name = 'Binary_' + textureIndexString + '.' + GetFileExtensionFromMimeType (gltfImage.mimeType);\r\n                    textureParams.mimeType = gltfImage.mimeType;\r\n                    textureParams.buffer = buffer;\r\n                }\r\n            }\r\n            this.imageIndexToTextureParams.set (gltfImageIndex, textureParams);\r\n        }\r\n\r\n        texture.name = textureParams.name;\r\n        texture.mimeType = textureParams.mimeType;\r\n        texture.buffer = textureParams.buffer;\r\n\r\n        this.gltfExtensions.ProcessTexture (gltfTextureRef, texture);\r\n        return texture;\r\n    }\r\n\r\n    ImportMesh (gltf, gltfMesh)\r\n    {\r\n        let mesh = new Mesh ();\r\n\r\n        this.model.AddMesh (mesh);\r\n        if (gltfMesh.name !== undefined) {\r\n            mesh.SetName (gltfMesh.name);\r\n        }\r\n\r\n        for (let i = 0; i < gltfMesh.primitives.length; i++) {\r\n            let primitive = gltfMesh.primitives[i];\r\n            this.ImportPrimitive (gltf, primitive, mesh);\r\n        }\r\n\r\n        this.ImportProperties (mesh, gltfMesh.extras, Loc ('Mesh properties'));\r\n    }\r\n\r\n    ImportPrimitive (gltf, primitive, mesh)\r\n    {\r\n        function HasAttribute (gltf, primitive, attributeName)\r\n        {\r\n            let accessorIndex = primitive.attributes[attributeName];\r\n            if (accessorIndex === undefined) {\r\n                return false;\r\n            }\r\n            let accessor = gltf.accessors[accessorIndex];\r\n            if (accessor === undefined || accessor.count === 0) {\r\n                return false;\r\n            }\r\n            return true;\r\n        }\r\n\r\n        if (this.gltfExtensions.ProcessPrimitive (this, gltf, primitive, mesh)) {\r\n            return;\r\n        }\r\n\r\n        if (primitive.attributes === undefined) {\r\n            return;\r\n        }\r\n\r\n        let hasVertices = HasAttribute (gltf, primitive, 'POSITION');\r\n        let hasVertexColors = HasAttribute (gltf, primitive, 'COLOR_0');\r\n        let hasNormals = HasAttribute (gltf, primitive, 'NORMAL');\r\n        let hasUVs = HasAttribute (gltf, primitive, 'TEXCOORD_0');\r\n        let hasIndices = (primitive.indices !== undefined);\r\n\r\n        let mode = GltfRenderMode.TRIANGLES;\r\n        if (primitive.mode !== undefined) {\r\n            mode = primitive.mode;\r\n        }\r\n        if (mode !== GltfRenderMode.TRIANGLES && mode !== GltfRenderMode.TRIANGLE_STRIP && mode !== GltfRenderMode.TRIANGLE_FAN) {\r\n            return;\r\n        }\r\n\r\n        let vertexOffset = mesh.VertexCount ();\r\n        let vertexColorOffset = mesh.VertexColorCount ();\r\n        let normalOffset = mesh.NormalCount ();\r\n        let uvOffset = mesh.TextureUVCount ();\r\n\r\n        if (hasVertices) {\r\n            let accessor = gltf.accessors[primitive.attributes.POSITION];\r\n            let reader = this.GetReaderFromAccessor (gltf, accessor);\r\n            if (reader === null) {\r\n                return;\r\n            }\r\n            reader.EnumerateData ((data) => {\r\n                mesh.AddVertex (data);\r\n            });\r\n        } else {\r\n            return;\r\n        }\r\n\r\n        let vertexCount = mesh.VertexCount () - vertexOffset;\r\n\r\n        if (hasVertexColors) {\r\n            let accessor = gltf.accessors[primitive.attributes.COLOR_0];\r\n            let reader = this.GetReaderFromAccessor (gltf, accessor);\r\n            if (reader === null) {\r\n                return;\r\n            }\r\n            reader.EnumerateData ((data) => {\r\n                let color = GetGltfVertexColor ([data.x, data.y, data.z], reader.componentType);\r\n                mesh.AddVertexColor (color);\r\n            });\r\n            if (mesh.VertexColorCount () - vertexColorOffset !== vertexCount) {\r\n                hasVertexColors = false;\r\n            }\r\n        }\r\n\r\n        if (hasNormals) {\r\n            let accessor = gltf.accessors[primitive.attributes.NORMAL];\r\n            let reader = this.GetReaderFromAccessor (gltf, accessor);\r\n            if (reader === null) {\r\n                return;\r\n            }\r\n            reader.EnumerateData ((data) => {\r\n                mesh.AddNormal (data);\r\n            });\r\n            if (mesh.NormalCount () - normalOffset !== vertexCount) {\r\n                hasNormals = false;\r\n            }\r\n        }\r\n\r\n        if (hasUVs) {\r\n            let accessor = gltf.accessors[primitive.attributes.TEXCOORD_0];\r\n            let reader = this.GetReaderFromAccessor (gltf, accessor);\r\n            if (reader === null) {\r\n                return;\r\n            }\r\n            reader.EnumerateData ((data) => {\r\n                data.y = -data.y;\r\n                mesh.AddTextureUV (data);\r\n            });\r\n            if (mesh.TextureUVCount () - uvOffset !== vertexCount) {\r\n                hasUVs = false;\r\n            }\r\n        }\r\n\r\n        let vertexIndices = [];\r\n        if (hasIndices) {\r\n            let accessor = gltf.accessors[primitive.indices];\r\n            let reader = this.GetReaderFromAccessor (gltf, accessor);\r\n            if (reader === null) {\r\n                return;\r\n            }\r\n            reader.EnumerateData ((data) => {\r\n                vertexIndices.push (data);\r\n            });\r\n        } else {\r\n            let primitiveVertexCount = mesh.VertexCount () - vertexOffset;\r\n            for (let i = 0; i < primitiveVertexCount; i++) {\r\n                vertexIndices.push (i);\r\n            }\r\n        }\r\n\r\n        if (mode === GltfRenderMode.TRIANGLES) {\r\n            for (let i = 0; i < vertexIndices.length; i += 3) {\r\n                let v0 = vertexIndices[i];\r\n                let v1 = vertexIndices[i + 1];\r\n                let v2 = vertexIndices[i + 2];\r\n                this.AddTriangle (primitive, mesh, v0, v1, v2, hasVertexColors, hasNormals, hasUVs, vertexOffset, vertexColorOffset, normalOffset, uvOffset);\r\n            }\r\n        } else if (mode === GltfRenderMode.TRIANGLE_STRIP) {\r\n            for (let i = 0; i < vertexIndices.length - 2; i++) {\r\n                let v0 = vertexIndices[i];\r\n                let v1 = vertexIndices[i + 1];\r\n                let v2 = vertexIndices[i + 2];\r\n                if (i % 2 === 1) {\r\n                    let tmp = v1;\r\n                    v1 = v2;\r\n                    v2 = tmp;\r\n                }\r\n                this.AddTriangle (primitive, mesh, v0, v1, v2, hasVertexColors, hasNormals, hasUVs, vertexOffset, vertexColorOffset, normalOffset, uvOffset);\r\n            }\r\n        } else if (mode === GltfRenderMode.TRIANGLE_FAN) {\r\n            for (let i = 1; i < vertexIndices.length - 1; i++) {\r\n                let v0 = vertexIndices[0];\r\n                let v1 = vertexIndices[i];\r\n                let v2 = vertexIndices[i + 1];\r\n                this.AddTriangle (primitive, mesh, v0, v1, v2, hasVertexColors, hasNormals, hasUVs, vertexOffset, vertexColorOffset, normalOffset, uvOffset);\r\n            }\r\n        }\r\n    }\r\n\r\n    AddTriangle (primitive, mesh, v0, v1, v2, hasVertexColors, hasNormals, hasUVs, vertexOffset, vertexColorOffset, normalOffset, uvOffset)\r\n    {\r\n        let triangle = new Triangle (\r\n            vertexOffset + v0,\r\n            vertexOffset + v1,\r\n            vertexOffset + v2\r\n        );\r\n        if (hasVertexColors) {\r\n            triangle.SetVertexColors (\r\n                vertexColorOffset + v0,\r\n                vertexColorOffset + v1,\r\n                vertexColorOffset + v2\r\n            );\r\n        }\r\n        if (hasNormals) {\r\n            triangle.SetNormals (\r\n                normalOffset + v0,\r\n                normalOffset + v1,\r\n                normalOffset + v2\r\n            );\r\n        }\r\n        if (hasUVs) {\r\n            triangle.SetTextureUVs (\r\n                uvOffset + v0,\r\n                uvOffset + v1,\r\n                uvOffset + v2\r\n            );\r\n        }\r\n        if (primitive.material !== undefined) {\r\n            triangle.mat = primitive.material;\r\n        }\r\n        mesh.AddTriangle (triangle);\r\n    }\r\n\r\n    ImportScene (gltf)\r\n    {\r\n        let scene = this.GetDefaultScene (gltf);\r\n        if (scene === null) {\r\n            return;\r\n        }\r\n\r\n        let rootNode = this.model.GetRootNode ();\r\n        for (let nodeIndex of scene.nodes) {\r\n            let gltfNode = gltf.nodes[nodeIndex];\r\n            this.ImportNode (gltf, gltfNode, rootNode);\r\n        }\r\n\r\n        this.ImportProperties (this.model, scene.extras, Loc ('Scene properties'));\r\n    }\r\n\r\n    ImportNode (gltf, gltfNode, parentNode)\r\n    {\r\n        function GetNodeTransformation (gltfNode)\r\n        {\r\n            let matrix = new Matrix ().CreateIdentity ();\r\n            if (gltfNode.matrix !== undefined) {\r\n                matrix.Set (gltfNode.matrix);\r\n            } else {\r\n                let translation = [0.0, 0.0, 0.0];\r\n                let rotation = [0.0, 0.0, 0.0, 1.0];\r\n                let scale = [1.0, 1.0, 1.0];\r\n                if (gltfNode.translation !== undefined) {\r\n                    translation = gltfNode.translation;\r\n                }\r\n                if (gltfNode.rotation !== undefined) {\r\n                    rotation = gltfNode.rotation;\r\n                }\r\n                if (gltfNode.scale !== undefined) {\r\n                    scale = gltfNode.scale;\r\n                }\r\n                matrix.ComposeTRS (\r\n                    ArrayToCoord3D (translation),\r\n                    ArrayToQuaternion (rotation),\r\n                    ArrayToCoord3D (scale)\r\n                );\r\n            }\r\n            return new Transformation (matrix);\r\n        }\r\n\r\n        if (gltfNode.children === undefined && gltfNode.mesh === undefined) {\r\n            return;\r\n        }\r\n\r\n        let node = new Node ();\r\n        if (gltfNode.name !== undefined) {\r\n            node.SetName (gltfNode.name);\r\n        }\r\n        node.SetTransformation (GetNodeTransformation (gltfNode));\r\n        parentNode.AddChildNode (node);\r\n\r\n        if (gltfNode.children !== undefined) {\r\n            for (let childIndex of gltfNode.children) {\r\n                let childGltfNode = gltf.nodes[childIndex];\r\n                this.ImportNode (gltf, childGltfNode, node);\r\n            }\r\n        }\r\n\r\n        if (gltfNode.mesh !== undefined) {\r\n            let mesh = this.model.GetMesh (gltfNode.mesh);\r\n            this.ImportProperties (mesh, gltfNode.extras, Loc ('Node properties'));\r\n            node.AddMeshIndex (gltfNode.mesh);\r\n        }\r\n    }\r\n\r\n    GetReaderFromBufferView (bufferView)\r\n    {\r\n        let bufferIndex = bufferView.buffer || 0;\r\n        let buffer = this.bufferContents[bufferIndex];\r\n        if (buffer === undefined || buffer === null) {\r\n            return null;\r\n        }\r\n\r\n        let reader = new GltfBufferReader (buffer);\r\n        reader.SkipBytes (bufferView.byteOffset || 0);\r\n        let byteStride = bufferView.byteStride;\r\n        if (byteStride !== undefined && byteStride !== 0) {\r\n            reader.SetByteStride (byteStride);\r\n        }\r\n\r\n        return reader;\r\n    }\r\n\r\n    GetReaderFromAccessor (gltf, accessor)\r\n    {\r\n        let bufferViewIndex = accessor.bufferView || 0;\r\n        let bufferView = gltf.bufferViews[bufferViewIndex];\r\n        let reader = this.GetReaderFromBufferView (bufferView);\r\n        if (reader === null) {\r\n            return null;\r\n        }\r\n\r\n        reader.SetComponentType (accessor.componentType);\r\n        reader.SetDataType (accessor.type);\r\n        reader.SetDataCount (accessor.count);\r\n        reader.SkipBytes (accessor.byteOffset || 0);\r\n\r\n        if (accessor.sparse !== undefined) {\r\n            let indexReader = this.GetReaderFromSparseAccessor (gltf, accessor.sparse.indices, accessor.sparse.indices.componentType, 'SCALAR', accessor.sparse.count);\r\n            let valueReader = this.GetReaderFromSparseAccessor (gltf, accessor.sparse.values, accessor.componentType, accessor.type, accessor.sparse.count);\r\n            if (indexReader !== null && valueReader !== null) {\r\n                reader.SetSparseReader (indexReader, valueReader);\r\n            }\r\n        }\r\n        return reader;\r\n    }\r\n\r\n    GetReaderFromSparseAccessor (gltf, sparseAccessor, componentType, type, count)\r\n    {\r\n        if (sparseAccessor.bufferView === undefined) {\r\n            return null;\r\n        }\r\n\r\n        let bufferView = gltf.bufferViews[sparseAccessor.bufferView];\r\n        let reader = this.GetReaderFromBufferView (bufferView);\r\n        if (reader === null) {\r\n            return null;\r\n        }\r\n\r\n        reader.SetComponentType (componentType);\r\n        reader.SetDataType (type);\r\n        reader.SetDataCount (count);\r\n        reader.SkipBytes (sparseAccessor.byteOffset || 0);\r\n        return reader;\r\n    }\r\n}\n\nclass ImporterIfc extends ImporterBase\r\n{\r\n    constructor ()\r\n    {\r\n        super ();\r\n        this.ifc = null;\r\n    }\r\n\r\n    CanImportExtension (extension)\r\n    {\r\n        return extension === 'ifc';\r\n    }\r\n\r\n    GetUpDirection ()\r\n    {\r\n        return Direction.Y;\r\n    }\r\n\r\n    ClearContent ()\r\n    {\r\n        this.expressIDToMesh = null;\r\n        this.colorToMaterial = null;\r\n    }\r\n\r\n    ResetContent ()\r\n    {\r\n        this.expressIDToMesh = new Map ();\r\n        this.colorToMaterial = new ColorToMaterialConverter (this.model);\r\n    }\r\n\r\n    ImportContent (fileContent, onFinish)\r\n    {\r\n        if (this.ifc === null) {\r\n            LoadExternalLibrary ('webifc').then (() => {\r\n                this.ifc = new WebIFC.IfcAPI ();\r\n                this.ifc.Init ().then (() => {\r\n                    this.ImportIfcContent (fileContent);\r\n                    onFinish ();\r\n                });\r\n            }).catch (() => {\r\n                this.SetError (Loc ('Failed to load web-ifc.'));\r\n                onFinish ();\r\n            });\r\n        } else {\r\n            this.ImportIfcContent (fileContent);\r\n            onFinish ();\r\n        }\r\n    }\r\n\r\n    ImportIfcContent (fileContent)\r\n    {\r\n        const fileBuffer = new Uint8Array (fileContent);\r\n        const modelID = this.ifc.OpenModel (fileBuffer, {\r\n            COORDINATE_TO_ORIGIN : true\r\n        });\r\n        const ifcMeshes = this.ifc.LoadAllGeometry (modelID);\r\n        for (let meshIndex = 0; meshIndex < ifcMeshes.size (); meshIndex++) {\r\n            const ifcMesh = ifcMeshes.get (meshIndex);\r\n            if (ifcMesh.geometries.size () > 0) {\r\n                this.ImportIfcMesh (modelID, ifcMesh);\r\n            }\r\n        }\r\n        this.ImportProperties (modelID);\r\n        this.ifc.CloseModel (modelID);\r\n    }\r\n\r\n    ImportIfcMesh (modelID, ifcMesh)\r\n    {\r\n        let mesh = new Mesh ();\r\n        mesh.SetName (FLoc ('Mesh {0}', ifcMesh.expressID.toString ()));\r\n\r\n        let vertexOffset = 0;\r\n        const ifcGeometries = ifcMesh.geometries;\r\n        for (let geometryIndex = 0; geometryIndex < ifcGeometries.size (); geometryIndex++) {\r\n            const ifcGeometry = ifcGeometries.get (geometryIndex);\r\n            const ifcGeometryData = this.ifc.GetGeometry (modelID, ifcGeometry.geometryExpressID);\r\n            const ifcVertices = this.ifc.GetVertexArray (ifcGeometryData.GetVertexData (), ifcGeometryData.GetVertexDataSize ());\r\n            const ifcIndices = this.ifc.GetIndexArray (ifcGeometryData.GetIndexData (), ifcGeometryData.GetIndexDataSize ());\r\n            const materialIndex = this.GetMaterialIndexByColor (ifcGeometry.color);\r\n            const matrix = new Matrix (ifcGeometry.flatTransformation);\r\n            const transformation = new Transformation (matrix);\r\n\r\n            for (let i = 0; i < ifcVertices.length; i += 6) {\r\n                const x = ifcVertices[i];\r\n                const y = ifcVertices[i + 1];\r\n                const z = ifcVertices[i + 2];\r\n                const coord = new Coord3D (x, y, z);\r\n                const transformed = transformation.TransformCoord3D (coord);\r\n                mesh.AddVertex (transformed);\r\n            }\r\n            // TODO: normals\r\n            for (let i = 0; i < ifcIndices.length; i += 3) {\r\n                const v0 = ifcIndices[i];\r\n                const v1 = ifcIndices[i + 1];\r\n                const v2 = ifcIndices[i + 2];\r\n                const triangle = new Triangle (\r\n                    vertexOffset + v0,\r\n                    vertexOffset + v1,\r\n                    vertexOffset + v2\r\n                );\r\n                triangle.SetMaterial (materialIndex);\r\n                mesh.AddTriangle (triangle);\r\n            }\r\n            vertexOffset += ifcVertices.length / 6;\r\n        }\r\n\r\n        this.expressIDToMesh.set (ifcMesh.expressID, mesh);\r\n        this.model.AddMeshToRootNode (mesh);\r\n    }\r\n\r\n    ImportProperties (modelID)\r\n    {\r\n        const lines = this.ifc.GetLineIDsWithType (modelID, WebIFC.IFCRELDEFINESBYPROPERTIES);\r\n        for (let i = 0; i < lines.size (); i++) {\r\n            const relID = lines.get (i);\r\n            const rel = this.ifc.GetLine (modelID, relID);\r\n            if (Array.isArray (rel.RelatingPropertyDefinition)) {\r\n                continue;\r\n            }\r\n            rel.RelatedObjects.forEach ((objectRelID) => {\r\n                let element = null;\r\n                if (this.expressIDToMesh.has (objectRelID.value)) {\r\n                    element = this.expressIDToMesh.get (objectRelID.value);\r\n                } else {\r\n                    let propSetOwner = this.ifc.GetLine (modelID, objectRelID.value, true);\r\n                    if (propSetOwner.type === WebIFC.IFCBUILDING) {\r\n                        element = this.model;\r\n                    }\r\n                }\r\n                if (element === null) {\r\n                    return;\r\n                }\r\n                let propSetDef = rel.RelatingPropertyDefinition;\r\n                let propSet = this.ifc.GetLine (modelID, propSetDef.value, true);\r\n                if (!propSet || !propSet.HasProperties) {\r\n                    return;\r\n                }\r\n                let propertyGroup = new PropertyGroup (propSet.Name.value);\r\n                propSet.HasProperties.forEach ((property) => {\r\n                    if (!property || !property.Name) {\r\n                        return;\r\n                    }\r\n                    if (!property.NominalValue || !property.NominalValue.constructor) {\r\n                        return;\r\n                    }\r\n                    if (property.type !== WebIFC.IFCPROPERTYSINGLEVALUE) {\r\n                        return;\r\n                    }\r\n                    let propertyName = this.GetIFCString (property.Name.value);\r\n                    let elemProperty = null;\r\n                    let strValue = null;\r\n                    switch (property.NominalValue.constructor.name) {\r\n                        case 'IfcText':\r\n                        case 'IfcLabel':\r\n                        case 'IfcIdentifier':\r\n                        case WebIFC.IFCLABEL:\r\n                            elemProperty = new Property (PropertyType.Text, propertyName, this.GetIFCString (property.NominalValue.value));\r\n                            break;\r\n                        case 'IfcBoolean':\r\n                        case 'IfcLogical':\r\n                            strValue = Loc ('Unknown');\r\n                            if (property.NominalValue.value === 'T') {\r\n                                strValue = Loc ('True');\r\n                            } else if (property.NominalValue.value === 'F') {\r\n                                strValue = Loc ('False');\r\n                            }\r\n                            elemProperty = new Property (PropertyType.Text, propertyName, strValue);\r\n                            break;\r\n                        case 'IfcInteger':\r\n                        case 'IfcCountMeasure':\r\n                            elemProperty = new Property (PropertyType.Integer, propertyName, property.NominalValue.value);\r\n                            break;\r\n                        case 'IfcReal':\r\n                        case 'IfcLengthMeasure':\r\n                        case 'IfcPositiveLengthMeasure':\r\n                        case 'IfcAreaMeasure':\r\n                        case 'IfcVolumeMeasure':\r\n                        case 'IfcRatioMeasure':\r\n                        case 'IfcPositiveRatioMeasure':\r\n                        case 'IfcMassMeasure':\r\n                        case 'IfcMassPerLengthMeasure':\r\n                        case 'IfcPlaneAngleMeasure':\r\n                        case 'IfcThermalTransmittanceMeasure':\r\n                            elemProperty = new Property (PropertyType.Number, propertyName, property.NominalValue.value);\r\n                            break;\r\n                        default:\r\n                            // TODO\r\n                            console.log (property);\r\n                            break;\r\n                    }\r\n                    if (elemProperty !== null) {\r\n                        propertyGroup.AddProperty (elemProperty);\r\n                    }\r\n                });\r\n                if (propertyGroup.PropertyCount () > 0) {\r\n                    element.AddPropertyGroup (propertyGroup);\r\n                }\r\n            });\r\n        }\r\n    }\r\n\r\n    GetMaterialIndexByColor (ifcColor)\r\n    {\r\n        const color = RGBColorFromFloatComponents (ifcColor.x, ifcColor.y, ifcColor.z);\r\n        const alpha = parseInt (ifcColor.w * 255.0, 10);\r\n        return this.colorToMaterial.GetMaterialIndex (color.r, color.g, color.b, alpha);\r\n    }\r\n\r\n    GetIFCString (ifcString)\r\n    {\r\n        let decoded = this.DecodeIFCString (ifcString);\r\n        if (decoded.length === 0) {\r\n            decoded = '-';\r\n        }\r\n        return decoded;\r\n    }\r\n\r\n    DecodeIFCString (ifcString)\r\n    {\r\n        // TODO: https://github.com/tomvandig/web-ifc/issues/58\r\n        const ifcUnicodeRegEx = /\\\\X2\\\\(.*?)\\\\X0\\\\/uig;\r\n        let resultString = ifcString;\r\n        let match = ifcUnicodeRegEx.exec (ifcString);\r\n        while (match) {\r\n            const unicodeChar = String.fromCharCode (parseInt (match[1], 16));\r\n            resultString = resultString.replace (match[0], unicodeChar);\r\n            match = ifcUnicodeRegEx.exec (ifcString);\r\n        }\r\n        return resultString;\r\n    }\r\n}\n\nclass ObjMeshConverter\r\n{\r\n    constructor (mesh)\r\n    {\r\n        this.mesh = mesh;\r\n        this.globalToMeshVertices = new Map ();\r\n        this.globalToMeshVertexColors = new Map ();\r\n        this.globalToMeshNormals = new Map ();\r\n        this.globalToMeshUvs = new Map ();\r\n    }\r\n\r\n    AddVertex (globalIndex, globalVertices)\r\n    {\r\n        return this.GetMeshIndex (globalIndex, globalVertices, this.globalToMeshVertices, (val) => {\r\n            return this.mesh.AddVertex (new Coord3D (val.x, val.y, val.z));\r\n        });\r\n    }\r\n\r\n    AddVertexColor (globalIndex, globalVertexColors)\r\n    {\r\n        return this.GetMeshIndex (globalIndex, globalVertexColors, this.globalToMeshVertexColors, (val) => {\r\n            return this.mesh.AddVertexColor (new RGBColor (val.r, val.g, val.b));\r\n        });\r\n    }\r\n\r\n    AddNormal (globalIndex, globalNormals)\r\n    {\r\n        return this.GetMeshIndex (globalIndex, globalNormals, this.globalToMeshNormals, (val) => {\r\n            return this.mesh.AddNormal (new Coord3D (val.x, val.y, val.z));\r\n        });\r\n    }\r\n\r\n    AddUV (globalIndex, globalUvs)\r\n    {\r\n        return this.GetMeshIndex (globalIndex, globalUvs, this.globalToMeshUvs, (val) => {\r\n            return this.mesh.AddTextureUV (new Coord2D (val.x, val.y));\r\n        });\r\n    }\r\n\r\n    AddLine (line)\r\n    {\r\n        this.mesh.AddLine (line);\r\n    }\r\n\r\n    AddTriangle (triangle)\r\n    {\r\n        this.mesh.AddTriangle (triangle);\r\n    }\r\n\r\n    GetMeshIndex (globalIndex, globalValueArray, globalToMeshIndices, valueAdderFunc)\r\n    {\r\n        if (isNaN (globalIndex) || globalIndex < 0 || globalIndex >= globalValueArray.length) {\r\n            return null;\r\n        }\r\n        if (globalToMeshIndices.has (globalIndex)) {\r\n            return globalToMeshIndices.get (globalIndex);\r\n        } else {\r\n            let globalValue = globalValueArray[globalIndex];\r\n            let meshIndex = valueAdderFunc (globalValue);\r\n            globalToMeshIndices.set (globalIndex, meshIndex);\r\n            return meshIndex;\r\n        }\r\n    }\r\n}\r\n\r\nfunction CreateColor (r, g, b)\r\n{\r\n    return RGBColorFromFloatComponents (\r\n        parseFloat (r),\r\n        parseFloat (g),\r\n        parseFloat (b)\r\n    );\r\n}\r\n\r\nclass ImporterObj extends ImporterBase\r\n{\r\n    constructor ()\r\n    {\r\n        super ();\r\n    }\r\n\r\n    CanImportExtension (extension)\r\n    {\r\n        return extension === 'obj';\r\n    }\r\n\r\n    GetUpDirection ()\r\n    {\r\n        return Direction.Y;\r\n    }\r\n\r\n    ClearContent ()\r\n    {\r\n        this.globalVertices = null;\r\n        this.globalVertexColors = null;\r\n        this.globalNormals = null;\r\n        this.globalUvs = null;\r\n\r\n        this.currentMeshConverter = null;\r\n        this.currentMaterial = null;\r\n        this.currentMaterialIndex = null;\r\n\r\n        this.meshNameToConverter = null;\r\n        this.materialNameToIndex = null;\r\n    }\r\n\r\n    ResetContent ()\r\n    {\r\n        this.globalVertices = [];\r\n        this.globalVertexColors = [];\r\n        this.globalNormals = [];\r\n        this.globalUvs = [];\r\n\r\n        this.currentMeshConverter = null;\r\n        this.currentMaterial = null;\r\n        this.currentMaterialIndex = null;\r\n\r\n        this.meshNameToConverter = new Map ();\r\n        this.materialNameToIndex = new Map ();\r\n    }\r\n\r\n    ImportContent (fileContent, onFinish)\r\n    {\r\n        let textContent = ArrayBufferToUtf8String (fileContent);\r\n        ReadLines (textContent, (line) => {\r\n            if (!this.WasError ()) {\r\n                this.ProcessLine (line);\r\n            }\r\n        });\r\n        onFinish ();\r\n    }\r\n\r\n    ProcessLine (line)\r\n    {\r\n        if (line[0] === '#') {\r\n            return;\r\n        }\r\n\r\n        let parameters = ParametersFromLine (line, '#');\r\n        if (parameters.length === 0) {\r\n            return;\r\n        }\r\n\r\n        let keyword = parameters[0].toLowerCase ();\r\n        parameters.shift ();\r\n\r\n        if (this.ProcessMeshParameter (keyword, parameters, line)) {\r\n            return;\r\n        }\r\n\r\n        if (this.ProcessMaterialParameter (keyword, parameters, line)) {\r\n            return;\r\n        }\r\n    }\r\n\r\n    AddNewMesh (name)\r\n    {\r\n        if (this.meshNameToConverter.has (name)) {\r\n            this.currentMeshConverter = this.meshNameToConverter.get (name);\r\n        } else {\r\n            let mesh = new Mesh ();\r\n            mesh.SetName (name);\r\n            this.model.AddMeshToRootNode (mesh);\r\n            this.currentMeshConverter = new ObjMeshConverter (mesh);\r\n            this.meshNameToConverter.set (name, this.currentMeshConverter);\r\n        }\r\n    }\r\n\r\n    ProcessMeshParameter (keyword, parameters, line)\r\n    {\r\n        if (keyword === 'g' || keyword === 'o') {\r\n            if (parameters.length === 0) {\r\n                return true;\r\n            }\r\n            let name = NameFromLine (line, keyword.length, '#');\r\n            this.AddNewMesh (name);\r\n            return true;\r\n        } else if (keyword === 'v') {\r\n            if (parameters.length < 3) {\r\n                return true;\r\n            }\r\n            this.globalVertices.push (new Coord3D (\r\n                parseFloat (parameters[0]),\r\n                parseFloat (parameters[1]),\r\n                parseFloat (parameters[2])\r\n            ));\r\n            if (parameters.length >= 6) {\r\n                this.globalVertexColors.push (CreateColor (parameters[3], parameters[4], parameters[5]));\r\n            }\r\n            return true;\r\n        } else if (keyword === 'vn') {\r\n            if (parameters.length < 3) {\r\n                return true;\r\n            }\r\n            this.globalNormals.push (new Coord3D (\r\n                parseFloat (parameters[0]),\r\n                parseFloat (parameters[1]),\r\n                parseFloat (parameters[2])\r\n            ));\r\n            return true;\r\n        } else if (keyword === 'vt') {\r\n            if (parameters.length < 2) {\r\n                return true;\r\n            }\r\n            this.globalUvs.push (new Coord2D (\r\n                parseFloat (parameters[0]),\r\n                parseFloat (parameters[1])\r\n            ));\r\n            return true;\r\n        } else if (keyword === 'l') {\r\n            if (parameters.length < 2) {\r\n                return true;\r\n            }\r\n            this.ProcessLineCommand (parameters);\r\n        } else if (keyword === 'f') {\r\n            if (parameters.length < 3) {\r\n                return true;\r\n            }\r\n            this.ProcessFaceCommand (parameters);\r\n            return true;\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    ProcessMaterialParameter (keyword, parameters, line)\r\n    {\r\n        function ExtractTextureParameters (parameters)\r\n        {\r\n            let textureParameters = new Map ();\r\n            let lastParameter = null;\r\n            for (let i = 0; i < parameters.length - 1; i++) {\r\n                let parameter = parameters[i];\r\n                if (parameter.startsWith ('-')) {\r\n                    lastParameter = parameter;\r\n                    textureParameters.set (lastParameter, []);\r\n                    continue;\r\n                }\r\n                if (lastParameter !== null) {\r\n                    textureParameters.get (lastParameter).push (parameter);\r\n                }\r\n            }\r\n            return textureParameters;\r\n        }\r\n\r\n        function CreateTexture (parameters, callbacks)\r\n        {\r\n            let texture = new TextureMap ();\r\n            let textureName = parameters[parameters.length - 1];\r\n            let textureBuffer = callbacks.getFileBuffer (textureName);\r\n            texture.name = textureName;\r\n            texture.buffer = textureBuffer;\r\n\r\n            let textureParameters = ExtractTextureParameters (parameters);\r\n            if (textureParameters.has ('-o')) {\r\n                let offsetParameters = textureParameters.get ('-o');\r\n                if (offsetParameters.length > 0) {\r\n                    texture.offset.x = parseFloat (offsetParameters[0]);\r\n                }\r\n                if (offsetParameters.length > 1) {\r\n                    texture.offset.y = parseFloat (offsetParameters[1]);\r\n                }\r\n            }\r\n\r\n            if (textureParameters.has ('-s')) {\r\n                let scaleParameters = textureParameters.get ('-s');\r\n                if (scaleParameters.length > 0) {\r\n                    texture.scale.x = parseFloat (scaleParameters[0]);\r\n                }\r\n                if (scaleParameters.length > 1) {\r\n                    texture.scale.y = parseFloat (scaleParameters[1]);\r\n                }\r\n            }\r\n\r\n            return texture;\r\n        }\r\n\r\n        if (keyword === 'newmtl') {\r\n            if (parameters.length === 0) {\r\n                return true;\r\n            }\r\n\r\n            let material = new PhongMaterial ();\r\n            let materialName = NameFromLine (line, keyword.length, '#');\r\n            let materialIndex = this.model.AddMaterial (material);\r\n            material.name = materialName;\r\n            this.currentMaterial = material;\r\n            this.materialNameToIndex.set (materialName, materialIndex);\r\n            return true;\r\n        } else if (keyword === 'usemtl') {\r\n            if (parameters.length === 0) {\r\n                return true;\r\n            }\r\n\r\n            let materialName = NameFromLine (line, keyword.length, '#');\r\n            if (this.materialNameToIndex.has (materialName)) {\r\n                this.currentMaterialIndex = this.materialNameToIndex.get (materialName);\r\n            }\r\n            return true;\r\n        } else if (keyword === 'mtllib') {\r\n            if (parameters.length === 0) {\r\n                return true;\r\n            }\r\n            let fileName = NameFromLine (line, keyword.length, '#');\r\n            let fileBuffer = this.callbacks.getFileBuffer (fileName);\r\n            if (fileBuffer !== null) {\r\n                let textContent = ArrayBufferToUtf8String (fileBuffer);\r\n                ReadLines (textContent, (line) => {\r\n                    if (!this.WasError ()) {\r\n                        this.ProcessLine (line);\r\n                    }\r\n                });\r\n            }\r\n            return true;\r\n        } else if (keyword === 'map_kd') {\r\n            if (this.currentMaterial === null || parameters.length === 0) {\r\n                return true;\r\n            }\r\n            this.currentMaterial.diffuseMap = CreateTexture (parameters, this.callbacks);\r\n            UpdateMaterialTransparency (this.currentMaterial);\r\n            return true;\r\n        } else if (keyword === 'map_ks') {\r\n            if (this.currentMaterial === null || parameters.length === 0) {\r\n                return true;\r\n            }\r\n            this.currentMaterial.specularMap = CreateTexture (parameters, this.callbacks);\r\n            return true;\r\n        } else if (keyword === 'map_bump' || keyword === 'bump') {\r\n            if (this.currentMaterial === null || parameters.length === 0) {\r\n                return true;\r\n            }\r\n            this.currentMaterial.bumpMap = CreateTexture (parameters, this.callbacks);\r\n            return true;\r\n        } else if (keyword === 'ka') {\r\n            if (this.currentMaterial === null || parameters.length < 3) {\r\n                return true;\r\n            }\r\n            this.currentMaterial.ambient = CreateColor (parameters[0], parameters[1], parameters[2]);\r\n            return true;\r\n        } else if (keyword === 'kd') {\r\n            if (this.currentMaterial === null || parameters.length < 3) {\r\n                return true;\r\n            }\r\n            this.currentMaterial.color = CreateColor (parameters[0], parameters[1], parameters[2]);\r\n            return true;\r\n        } else if (keyword === 'ks') {\r\n            if (this.currentMaterial === null || parameters.length < 3) {\r\n                return true;\r\n            }\r\n            this.currentMaterial.specular = CreateColor (parameters[0], parameters[1], parameters[2]);\r\n            return true;\r\n        } else if (keyword === 'ns') {\r\n            if (this.currentMaterial === null || parameters.length < 1) {\r\n                return true;\r\n            }\r\n            this.currentMaterial.shininess = parseFloat (parameters[0]) / 1000.0;\r\n            return true;\r\n        } else if (keyword === 'tr') {\r\n            if (this.currentMaterial === null || parameters.length < 1) {\r\n                return true;\r\n            }\r\n            this.currentMaterial.opacity = 1.0 - parseFloat (parameters[0]);\r\n            UpdateMaterialTransparency (this.currentMaterial);\r\n            return true;\r\n        } else if (keyword === 'd') {\r\n            if (this.currentMaterial === null || parameters.length < 1) {\r\n                return true;\r\n            }\r\n            this.currentMaterial.opacity = parseFloat (parameters[0]);\r\n            UpdateMaterialTransparency (this.currentMaterial);\r\n            return true;\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    ProcessLineCommand (parameters)\r\n    {\r\n        if (this.currentMeshConverter === null) {\r\n            this.AddNewMesh ('');\r\n        }\r\n\r\n        let vertices = [];\r\n        for (let i = 0; i < parameters.length; i++) {\r\n            let vertexParams = parameters[i].split ('/');\r\n            let vertexIndex = this.GetRelativeIndex (parseInt (vertexParams[0], 10), this.globalVertices.length);\r\n            let meshVertexIndex = this.currentMeshConverter.AddVertex (vertexIndex, this.globalVertices);\r\n            if (meshVertexIndex === null) {\r\n                this.SetError (Loc ('Invalid vertex index.'));\r\n                break;\r\n            }\r\n            vertices.push (meshVertexIndex);\r\n        }\r\n\r\n        let line = new Line (vertices);\r\n        if (this.currentMaterialIndex !== null) {\r\n            line.mat = this.currentMaterialIndex;\r\n        }\r\n\r\n        this.currentMeshConverter.AddLine (line);\r\n    }\r\n\r\n    ProcessFaceCommand (parameters)\r\n    {\r\n        let vertices = [];\r\n        let colors = [];\r\n        let normals = [];\r\n        let uvs = [];\r\n\r\n        if (this.currentMeshConverter === null) {\r\n            this.AddNewMesh ('');\r\n        }\r\n\r\n        for (let i = 0; i < parameters.length; i++) {\r\n            let vertexParams = parameters[i].split ('/');\r\n            vertices.push (this.GetRelativeIndex (parseInt (vertexParams[0], 10), this.globalVertices.length));\r\n            if (this.globalVertices.length === this.globalVertexColors.length) {\r\n                colors.push (this.GetRelativeIndex (parseInt (vertexParams[0], 10), this.globalVertices.length));\r\n            }\r\n            if (vertexParams.length > 1 && vertexParams[1].length > 0) {\r\n                uvs.push (this.GetRelativeIndex (parseInt (vertexParams[1], 10), this.globalUvs.length));\r\n            }\r\n            if (vertexParams.length > 2 && vertexParams[2].length > 0) {\r\n                normals.push (this.GetRelativeIndex (parseInt (vertexParams[2], 10), this.globalNormals.length));\r\n            }\r\n        }\r\n\r\n        for (let i = 0; i < vertices.length - 2; i++) {\r\n            let v0 = this.currentMeshConverter.AddVertex (vertices[0], this.globalVertices);\r\n            let v1 = this.currentMeshConverter.AddVertex (vertices[i + 1], this.globalVertices);\r\n            let v2 = this.currentMeshConverter.AddVertex (vertices[i + 2], this.globalVertices);\r\n            if (v0 === null || v1 === null || v2 === null) {\r\n                this.SetError (Loc ('Invalid vertex index.'));\r\n                break;\r\n            }\r\n\r\n            let triangle = new Triangle (v0, v1, v2);\r\n\r\n            if (colors.length === vertices.length) {\r\n                let c0 = this.currentMeshConverter.AddVertexColor (colors[0], this.globalVertexColors);\r\n                let c1 = this.currentMeshConverter.AddVertexColor (colors[i + 1], this.globalVertexColors);\r\n                let c2 = this.currentMeshConverter.AddVertexColor (colors[i + 2], this.globalVertexColors);\r\n                if (c0 === null || c1 === null || c2 === null) {\r\n                    this.SetError (Loc ('Invalid vertex color index.'));\r\n                    break;\r\n                }\r\n                triangle.SetVertexColors (c0, c1, c2);\r\n            }\r\n\r\n            if (normals.length === vertices.length) {\r\n                let n0 = this.currentMeshConverter.AddNormal (normals[0], this.globalNormals);\r\n                let n1 = this.currentMeshConverter.AddNormal (normals[i + 1], this.globalNormals);\r\n                let n2 = this.currentMeshConverter.AddNormal (normals[i + 2], this.globalNormals);\r\n                if (n0 === null || n1 === null || n2 === null) {\r\n                    this.SetError (Loc ('Invalid normal index.'));\r\n                    break;\r\n                }\r\n                triangle.SetNormals (n0, n1, n2);\r\n            }\r\n\r\n            if (uvs.length === vertices.length) {\r\n                let u0 = this.currentMeshConverter.AddUV (uvs[0], this.globalUvs);\r\n                let u1 = this.currentMeshConverter.AddUV (uvs[i + 1], this.globalUvs);\r\n                let u2 = this.currentMeshConverter.AddUV (uvs[i + 2], this.globalUvs);\r\n                if (u0 === null || u1 === null || u2 === null) {\r\n                    this.SetError (Loc ('Invalid uv index.'));\r\n                    break;\r\n                }\r\n                triangle.SetTextureUVs (u0, u1, u2);\r\n            }\r\n\r\n            if (this.currentMaterialIndex !== null) {\r\n                triangle.mat = this.currentMaterialIndex;\r\n            }\r\n\r\n            this.currentMeshConverter.AddTriangle (triangle);\r\n        }\r\n    }\r\n\r\n    GetRelativeIndex (index, count)\r\n    {\r\n        if (index > 0) {\r\n            return index - 1;\r\n        } else {\r\n            return count + index;\r\n        }\r\n    }\r\n}\n\nclass ImporterOff extends ImporterBase\r\n{\r\n    constructor ()\r\n    {\r\n        super ();\r\n    }\r\n\r\n    CanImportExtension (extension)\r\n    {\r\n        return extension === 'off';\r\n    }\r\n\r\n    GetUpDirection ()\r\n    {\r\n        return Direction.Y;\r\n    }\r\n\r\n    ClearContent ()\r\n    {\r\n        this.mesh = null;\r\n        this.status = null;\r\n        this.colorToMaterial = null;\r\n    }\r\n\r\n    ResetContent ()\r\n    {\r\n        this.mesh = new Mesh ();\r\n        this.model.AddMeshToRootNode (this.mesh);\r\n        this.status = {\r\n            vertexCount : 0,\r\n            faceCount : 0,\r\n            foundVertex : 0,\r\n            foundFace : 0\r\n        };\r\n        this.colorToMaterial = new ColorToMaterialConverter (this.model);\r\n    }\r\n\r\n    ImportContent (fileContent, onFinish)\r\n    {\r\n        let textContent = ArrayBufferToUtf8String (fileContent);\r\n        ReadLines (textContent, (line) => {\r\n            if (!this.WasError ()) {\r\n                this.ProcessLine (line);\r\n            }\r\n        });\r\n        onFinish ();\r\n    }\r\n\r\n    ProcessLine (line)\r\n    {\r\n        function CreateColorComponent (str)\r\n        {\r\n            if (str.indexOf ('.') !== -1) {\r\n                return ColorComponentFromFloat (parseFloat (str));\r\n            } else {\r\n                return parseInt (str, 10);\r\n            }\r\n        }\r\n\r\n        if (line[0] === '#') {\r\n            return;\r\n        }\r\n\r\n        let parameters = ParametersFromLine (line, '#');\r\n        if (parameters.length === 0) {\r\n            return;\r\n        }\r\n\r\n        if (parameters[0] === 'OFF') {\r\n            return;\r\n        }\r\n\r\n        if (this.status.vertexCount === 0 && this.status.faceCount === 0) {\r\n            if (parameters.length > 1) {\r\n                this.status.vertexCount = parseInt (parameters[0], 10);\r\n                this.status.faceCount = parseInt (parameters[1], 10);\r\n            }\r\n            return;\r\n        }\r\n\r\n        if (this.status.foundVertex < this.status.vertexCount) {\r\n            if (parameters.length >= 3) {\r\n                this.mesh.AddVertex (new Coord3D (\r\n                    parseFloat (parameters[0]),\r\n                    parseFloat (parameters[1]),\r\n                    parseFloat (parameters[2])\r\n                ));\r\n                this.status.foundVertex += 1;\r\n            }\r\n            if (parameters.length >= 6) {\r\n                this.mesh.AddVertexColor (new RGBColor (\r\n                    CreateColorComponent (parameters[3]),\r\n                    CreateColorComponent (parameters[4]),\r\n                    CreateColorComponent (parameters[5])\r\n                ));\r\n            }\r\n            return;\r\n        }\r\n\r\n        let hasVertexColors = (this.mesh.VertexCount () ===this.mesh.VertexColorCount ());\r\n        if (this.status.foundFace < this.status.faceCount) {\r\n            if (parameters.length >= 4) {\r\n                let vertexCount = parseInt (parameters[0], 10);\r\n                if (parameters.length < vertexCount + 1) {\r\n                    return;\r\n                }\r\n                let materialIndex = null;\r\n                if (!hasVertexColors && parameters.length >= vertexCount + 4) {\r\n                    let color = new RGBColor (\r\n                        CreateColorComponent (parameters[vertexCount + 1]),\r\n                        CreateColorComponent (parameters[vertexCount + 2]),\r\n                        CreateColorComponent (parameters[vertexCount + 3])\r\n                    );\r\n                    materialIndex = this.colorToMaterial.GetMaterialIndex (color.r, color.g, color.b);\r\n                }\r\n                for (let i = 0; i < vertexCount - 2; i++) {\r\n                    let v0 = parseInt (parameters[1]);\r\n                    let v1 = parseInt (parameters[i + 2]);\r\n                    let v2 = parseInt (parameters[i + 3]);\r\n                    let triangle = new Triangle (v0, v1, v2);\r\n                    if (hasVertexColors) {\r\n                        triangle.SetVertexColors (v0, v1, v2);\r\n                    } else {\r\n                        triangle.SetMaterial (materialIndex);\r\n                    }\r\n                    this.mesh.AddTriangle (triangle);\r\n                }\r\n                this.status.foundFace += 1;\r\n            }\r\n            return;\r\n        }\r\n    }\r\n}\n\nconst PlyHeaderCheckResult =\r\n{\r\n    Ok : 1,\r\n    NoVertices : 2,\r\n    NoFaces : 3,\r\n    UnknownError : 4\r\n};\r\n\r\nclass PlyHeader\r\n{\r\n    constructor ()\r\n    {\r\n        this.format = null;\r\n        this.elements = [];\r\n    }\r\n\r\n    SetFormat (format)\r\n    {\r\n        this.format = format;\r\n    }\r\n\r\n    AddElement (name, count)\r\n    {\r\n        this.elements.push ({\r\n            name : name,\r\n            count : count,\r\n            format : []\r\n        });\r\n    }\r\n\r\n    GetElements ()\r\n    {\r\n        return this.elements;\r\n    }\r\n\r\n    AddSingleFormat (elemType, name)\r\n    {\r\n        let lastElement = this.elements[this.elements.length - 1];\r\n        lastElement.format.push ({\r\n            name : name,\r\n            isSingle : true,\r\n            elemType : elemType\r\n        });\r\n    }\r\n\r\n    AddListFormat (countType, elemType, name)\r\n    {\r\n        let lastElement = this.elements[this.elements.length - 1];\r\n        lastElement.format.push ({\r\n            name : name,\r\n            isSingle : false,\r\n            countType : countType,\r\n            elemType : elemType\r\n        });\r\n    }\r\n\r\n    GetElement (name)\r\n    {\r\n        for (let i = 0; i < this.elements.length; i++) {\r\n            let element = this.elements[i];\r\n            if (element.name === name) {\r\n                return element;\r\n            }\r\n        }\r\n        return null;\r\n    }\r\n\r\n    Check ()\r\n    {\r\n        let vertex = this.GetElement ('vertex');\r\n        if (vertex === null || vertex.length === 0 || vertex.format.length < 3) {\r\n            return PlyHeaderCheckResult.NoVertices;\r\n        }\r\n\r\n        let face = this.GetElement ('face');\r\n        if (this.format === 'ascii') {\r\n            if (face === null || face.count === 0 || face.format.length < 0) {\r\n                return PlyHeaderCheckResult.NoFaces;\r\n            }\r\n        } else if (this.format === 'binary_little_endian' || this.format === 'binary_big_endian') {\r\n            let triStrips = this.GetElement ('tristrips');\r\n            let hasFaces = (face !== null && face.count > 0 && face.format.length > 0);\r\n            let hasTriStrips = (triStrips !== null && triStrips.count > 0 && triStrips.format.length > 0);\r\n            if (!hasFaces && !hasTriStrips) {\r\n                return PlyHeaderCheckResult.NoFaces;\r\n            }\r\n        } else {\r\n            return PlyHeaderCheckResult.UnknownError;\r\n        }\r\n\r\n        return PlyHeaderCheckResult.Ok;\r\n    }\r\n}\r\n\r\nclass PlyMaterialHandler\r\n{\r\n    constructor (model)\r\n    {\r\n        this.model = model;\r\n        this.colorToMaterial = new Map ();\r\n    }\r\n\r\n    GetMaterialIndexByColor (color)\r\n    {\r\n        let materialName = 'Color ' +\r\n            IntegerToHexString (color[0]) +\r\n            IntegerToHexString (color[1]) +\r\n            IntegerToHexString (color[2]) +\r\n            IntegerToHexString (color[3]);\r\n\r\n        if (this.colorToMaterial.has (materialName)) {\r\n            return this.colorToMaterial.get (materialName);\r\n        } else {\r\n            let material = new PhongMaterial ();\r\n            material.name = materialName;\r\n            material.color = new RGBColor (color[0], color[1], color[2]);\r\n            material.opacity = color[3] / 255.0;\r\n            UpdateMaterialTransparency (material);\r\n            let materialIndex = this.model.AddMaterial (material);\r\n            this.colorToMaterial.set (materialName, materialIndex);\r\n            return materialIndex;\r\n        }\r\n    }\r\n}\r\n\r\nclass ImporterPly extends ImporterBase\r\n{\r\n    constructor ()\r\n    {\r\n        super ();\r\n    }\r\n\r\n    CanImportExtension (extension)\r\n    {\r\n        return extension === 'ply';\r\n    }\r\n\r\n    GetUpDirection ()\r\n    {\r\n        return Direction.Y;\r\n    }\r\n\r\n    ClearContent ()\r\n    {\r\n        this.mesh = null;\r\n    }\r\n\r\n    ResetContent ()\r\n    {\r\n        this.mesh = new Mesh ();\r\n        this.model.AddMeshToRootNode (this.mesh);\r\n    }\r\n\r\n    ImportContent (fileContent, onFinish)\r\n    {\r\n        let headerString = this.GetHeaderContent (fileContent);\r\n        let header = this.ReadHeader (headerString);\r\n        let checkResult = header.Check ();\r\n        if (checkResult === PlyHeaderCheckResult.Ok) {\r\n            if (header.format === 'ascii') {\r\n                let contentString = ArrayBufferToUtf8String (fileContent);\r\n                contentString = contentString.substring (headerString.length);\r\n                this.ReadAsciiContent (header, contentString);\r\n            } else if (header.format === 'binary_little_endian' || header.format === 'binary_big_endian') {\r\n                this.ReadBinaryContent (header, fileContent, headerString.length);\r\n            }\r\n        } else {\r\n            if (checkResult === PlyHeaderCheckResult.NoVertices) {\r\n                this.SetError (Loc ('The model contains no vertices.'));\r\n            } else if (checkResult === PlyHeaderCheckResult.NoFaces) {\r\n                this.SetError (Loc ('The model contains no faces.'));\r\n            } else {\r\n                this.SetError (Loc ('Invalid header information.'));\r\n            }\r\n        }\r\n        onFinish ();\r\n    }\r\n\r\n    GetHeaderContent (fileContent)\r\n    {\r\n        let headerContent = '';\r\n        let bufferView = new Uint8Array (fileContent);\r\n        let bufferIndex = 0;\r\n        for (bufferIndex = 0; bufferIndex < fileContent.byteLength; bufferIndex++) {\r\n            headerContent += String.fromCharCode (bufferView[bufferIndex]);\r\n            if (headerContent.endsWith ('end_header')) {\r\n                break;\r\n            }\r\n        }\r\n        bufferIndex += 1;\r\n        while (bufferIndex < fileContent.byteLength) {\r\n            let char = String.fromCharCode (bufferView[bufferIndex]);\r\n            headerContent += char;\r\n            bufferIndex += 1;\r\n            if (char === '\\n') {\r\n                break;\r\n            }\r\n        }\r\n        return headerContent;\r\n    }\r\n\r\n    ReadHeader (headerContent)\r\n    {\r\n        let header = new PlyHeader ();\r\n        ReadLines (headerContent, (line) => {\r\n            let parameters = ParametersFromLine (line, null);\r\n            if (parameters.length === 0 || parameters[0] === 'comment') {\r\n                return;\r\n            }\r\n\r\n            if (parameters[0] === 'ply') {\r\n                return;\r\n            } else if (parameters[0] === 'format' && parameters.length >= 2) {\r\n                header.SetFormat (parameters[1]);\r\n            } else if (parameters[0] === 'element' && parameters.length >= 3) {\r\n                header.AddElement (parameters[1], parseInt (parameters[2], 10));\r\n            } else if (parameters[0] === 'property' && parameters.length >= 3) {\r\n                if (parameters[1] === 'list' && parameters.length >= 5) {\r\n                    header.AddListFormat (parameters[2], parameters[3], parameters[4]);\r\n                } else {\r\n                    header.AddSingleFormat (parameters[1], parameters[2]);\r\n                }\r\n            }\r\n        });\r\n\r\n        return header;\r\n    }\r\n\r\n    ReadAsciiContent (header, fileContent)\r\n    {\r\n        let vertex = header.GetElement ('vertex');\r\n        let face = header.GetElement ('face');\r\n        let foundVertex = 0;\r\n        let foundFace = 0;\r\n        ReadLines (fileContent, (line) => {\r\n            if (this.WasError ()) {\r\n                return;\r\n            }\r\n\r\n            let parameters = ParametersFromLine (line, null);\r\n            if (parameters.length === 0 || parameters[0] === 'comment') {\r\n                return;\r\n            }\r\n\r\n            if (foundVertex < vertex.count) {\r\n                if (parameters.length >= 3) {\r\n                    this.mesh.AddVertex (new Coord3D (\r\n                        parseFloat (parameters[0]),\r\n                        parseFloat (parameters[1]),\r\n                        parseFloat (parameters[2])\r\n                    ));\r\n                    foundVertex += 1;\r\n                }\r\n                return;\r\n            }\r\n\r\n            if (face !== null && foundFace < face.count) {\r\n                if (parameters.length >= 4) {\r\n                    let vertexCount = parseInt (parameters[0], 10);\r\n                    if (parameters.length < vertexCount + 1) {\r\n                        return;\r\n                    }\r\n                    for (let i = 0; i < vertexCount - 2; i++) {\r\n                        let v0 = parseInt (parameters[1]);\r\n                        let v1 = parseInt (parameters[i + 2]);\r\n                        let v2 = parseInt (parameters[i + 3]);\r\n                        let triangle = new Triangle (v0, v1, v2);\r\n                        this.mesh.AddTriangle (triangle);\r\n                    }\r\n                    foundFace += 1;\r\n                }\r\n                return;\r\n            }\r\n        });\r\n    }\r\n\r\n    ReadBinaryContent (header, fileContent, headerLength)\r\n    {\r\n        function ReadByFormat (reader, format)\r\n        {\r\n            function ReadType (reader, type)\r\n            {\r\n                if (type === 'char' || type === 'int8') {\r\n                    return reader.ReadCharacter8 ();\r\n                } else if (type === 'uchar' || type === 'uint8') {\r\n                    return reader.ReadUnsignedCharacter8 ();\r\n                } else if (type === 'short' || type === 'int16') {\r\n                    return reader.ReadInteger16 ();\r\n                } else if (type === 'ushort' || type === 'uint16') {\r\n                    return reader.ReadUnsignedInteger16 ();\r\n                } else if (type === 'int' || type === 'int32') {\r\n                    return reader.ReadInteger32 ();\r\n                } else if (type === 'uint' || type === 'uint32') {\r\n                    return reader.ReadUnsignedInteger32 ();\r\n                } else if (type === 'float' || type === 'float32') {\r\n                    return reader.ReadFloat32 ();\r\n                } else if (type === 'double' || type === 'double64') {\r\n                    return reader.ReadDouble64 ();\r\n                }\r\n                return null;\r\n            }\r\n\r\n            if (format.isSingle) {\r\n                return ReadType (reader, format.elemType);\r\n            } else {\r\n                let list = [];\r\n                let count = ReadType (reader, format.countType);\r\n                for (let i = 0; i < count; i++) {\r\n                    list.push (ReadType (reader, format.elemType));\r\n                }\r\n                return list;\r\n            }\r\n        }\r\n\r\n        function SkipFormat (reader, format, startIndex)\r\n        {\r\n            for (let i = startIndex; i < format.length; i++) {\r\n                ReadByFormat (reader, format[i]);\r\n            }\r\n        }\r\n\r\n        function SkipAndGetColor (reader, format, startIndex)\r\n        {\r\n            let r = null;\r\n            let g = null;\r\n            let b = null;\r\n            let a = 255;\r\n\r\n            for (let i = startIndex; i < format.length; i++) {\r\n                let currFormat = format[i];\r\n                let val = ReadByFormat (reader, currFormat);\r\n                if (currFormat.name === 'red') {\r\n                    r = val;\r\n                } else if (currFormat.name === 'green') {\r\n                    g = val;\r\n                } else if (currFormat.name === 'blue') {\r\n                    b = val;\r\n                } else if (currFormat.name === 'alpha') {\r\n                    a = val;\r\n                }\r\n            }\r\n\r\n            if (r !== null && g !== null && b !== null) {\r\n                return [r, g, b, a];\r\n            }\r\n\r\n            return null;\r\n        }\r\n\r\n        let reader = null;\r\n        if (header.format === 'binary_little_endian') {\r\n            reader = new BinaryReader (fileContent, true);\r\n        } else if (header.format === 'binary_big_endian') {\r\n            reader = new BinaryReader (fileContent, false);\r\n        } else {\r\n            return;\r\n        }\r\n        reader.Skip (headerLength);\r\n\r\n        let materialHandler = new PlyMaterialHandler (this.model);\r\n        let elements = header.GetElements ();\r\n        for (let elementIndex = 0; elementIndex < elements.length; elementIndex++) {\r\n            let element = elements[elementIndex];\r\n            if (element.name === 'vertex') {\r\n                for (let vertexIndex = 0; vertexIndex < element.count; vertexIndex++) {\r\n                    let x = ReadByFormat (reader, element.format[0]);\r\n                    let y = ReadByFormat (reader, element.format[1]);\r\n                    let z = ReadByFormat (reader, element.format[2]);\r\n                    let color = SkipAndGetColor (reader, element.format, 3);\r\n                    if (color !== null) {\r\n                        this.mesh.AddVertexColor (new RGBColor (color[0], color[1], color[2]));\r\n                    }\r\n                    this.mesh.AddVertex (new Coord3D (x, y, z));\r\n                }\r\n            } else if (element.name === 'face') {\r\n                for (let faceIndex = 0; faceIndex < element.count; faceIndex++) {\r\n                    let vertices = ReadByFormat (reader, element.format[0]);\r\n                    let faceColor = SkipAndGetColor (reader, element.format, 1);\r\n                    for (let i = 0; i < vertices.length - 2; i++) {\r\n                        let v0 = vertices[0];\r\n                        let v1 = vertices[i + 1];\r\n                        let v2 = vertices[i + 2];\r\n                        let triangle = new Triangle (v0, v1, v2);\r\n                        if (faceColor !== null) {\r\n                            triangle.mat = materialHandler.GetMaterialIndexByColor (faceColor);\r\n                        } else if (this.mesh.VertexColorCount () > 0) {\r\n                            triangle.SetVertexColors (v0, v1, v2);\r\n                        }\r\n                        this.mesh.AddTriangle (triangle);\r\n                    }\r\n                }\r\n            } else if (element.name === 'tristrips') {\r\n                for (let triStripIndex = 0; triStripIndex < element.count; triStripIndex++) {\r\n                    let vertices = ReadByFormat (reader, element.format[0]);\r\n                    SkipFormat (reader, element.format, 1);\r\n                    let ccw = true;\r\n                    for (let i = 0; i < vertices.length - 2; i++) {\r\n                        let v0 = vertices[i];\r\n                        let v1 = vertices[i + 1];\r\n                        let v2 = vertices[i + 2];\r\n                        if (v2 === -1) {\r\n                            i += 2;\r\n                            ccw = true;\r\n                            continue;\r\n                        }\r\n                        if (!ccw) {\r\n                            let tmp = v1;\r\n                            v1 = v2;\r\n                            v2 = tmp;\r\n                        }\r\n                        ccw = !ccw;\r\n                        let triangle = new Triangle (v0, v1, v2);\r\n                        this.mesh.AddTriangle (triangle);\r\n                    }\r\n                }\r\n            } else {\r\n                SkipFormat (reader, element.format, 0);\r\n            }\r\n        }\r\n    }\r\n}\n\nclass ImporterOcct extends ImporterBase\r\n{\r\n    constructor ()\r\n    {\r\n        super ();\r\n\t\tthis.worker = null;\r\n    }\r\n\r\n    CanImportExtension (extension)\r\n    {\r\n        return extension === 'stp' || extension === 'step' || extension === 'igs' || extension === 'iges' || extension === 'brp' || extension === 'brep';\r\n    }\r\n\r\n    GetUpDirection ()\r\n    {\r\n        return Direction.Y;\r\n    }\r\n\r\n\tClearContent ()\r\n\t{\r\n        if (this.worker !== null) {\r\n            this.worker.terminate ();\r\n            this.worker = null;\r\n        }\r\n\t}\r\n\r\n    ResetContent ()\r\n    {\r\n        this.worker = null;\r\n    }\r\n\r\n    ImportContent (fileContent, onFinish)\r\n    {\r\n        CreateOcctWorker ().then ((worker) => {\r\n            this.worker = worker;\r\n            this.worker.addEventListener ('message', (ev) => {\r\n                this.ImportResultJson (ev.data, onFinish);\r\n            });\r\n            this.worker.addEventListener ('error', (ev) => {\r\n                this.SetError (Loc ('Failed to load occt-import-js.'));\r\n                onFinish ();\r\n            });\r\n\r\n            let format = null;\r\n            if (this.extension === 'stp' || this.extension === 'step') {\r\n                format = 'step';\r\n            } else if (this.extension === 'igs' || this.extension === 'iges') {\r\n                format = 'iges';\r\n            } else if (this.extension === 'brp' || this.extension === 'brep') {\r\n                format = 'brep';\r\n            } else {\r\n                onFinish ();\r\n                return;\r\n            }\r\n\r\n            if (format === 'step' || format === 'iges') {\r\n                this.model.SetUnit (Unit.Millimeter);\r\n            }\r\n\r\n            let params = {\r\n                linearUnit: 'millimeter',\r\n                linearDeflectionType: 'bounding_box_ratio',\r\n                linearDeflection: 0.001,\r\n                angularDeflection: 0.5\r\n            };\r\n            let fileBuffer = new Uint8Array (fileContent);\r\n            this.worker.postMessage ({\r\n                format : format,\r\n                buffer : fileBuffer,\r\n                params : params\r\n            });\r\n        }).catch (() => {\r\n            this.SetError (Loc ('Failed to load occt-import-js.'));\r\n            onFinish ();\r\n        });\r\n    }\r\n\r\n\tImportResultJson (resultContent, onFinish)\r\n\t{\r\n        if (!resultContent.success) {\r\n            onFinish ();\r\n            return;\r\n        }\r\n        let colorToMaterial = new ColorToMaterialConverter (this.model);\r\n        let rootNode = this.model.GetRootNode ();\r\n        this.ImportNode (resultContent, resultContent.root, rootNode, colorToMaterial);\r\n        onFinish ();\r\n\t}\r\n\r\n    ImportNode (resultContent, occtNode, parentNode, colorToMaterial)\r\n    {\r\n        for (let nodeMeshIndex of occtNode.meshes) {\r\n            let occtMesh = resultContent.meshes[nodeMeshIndex];\r\n            let mesh = this.ImportMesh (occtMesh, colorToMaterial);\r\n            let meshIndex = this.model.AddMesh (mesh);\r\n            parentNode.AddMeshIndex (meshIndex);\r\n        }\r\n        for (let childOcctNode of occtNode.children) {\r\n            let childNode = new Node ();\r\n            childNode.SetName (childOcctNode.name);\r\n            parentNode.AddChildNode (childNode);\r\n            this.ImportNode (resultContent, childOcctNode, childNode, colorToMaterial);\r\n        }\r\n    }\r\n\r\n    ImportMesh (occtMesh, colorToMaterial)\r\n    {\r\n        let materialIndex = null;\r\n        if (occtMesh.color) {\r\n            let color = RGBColorFromFloatComponents (occtMesh.color[0], occtMesh.color[1], occtMesh.color[2]);\r\n            materialIndex = colorToMaterial.GetMaterialIndex (color.r, color.g, color.b, null);\r\n        }\r\n        let mesh = ConvertThreeGeometryToMesh (occtMesh, materialIndex, null);\r\n        if (occtMesh.name) {\r\n            mesh.SetName (occtMesh.name);\r\n        }\r\n        for (let brepFace of occtMesh.brep_faces) {\r\n            if (brepFace.color === null) {\r\n                continue;\r\n            }\r\n            let faceColor = RGBColorFromFloatComponents (brepFace.color[0], brepFace.color[1], brepFace.color[2]);\r\n            let faceMaterialIndex = colorToMaterial.GetMaterialIndex (faceColor.r, faceColor.g, faceColor.b, null);\r\n            for (let i = brepFace.first; i <= brepFace.last; i++) {\r\n                let triangle = mesh.GetTriangle (i);\r\n                triangle.SetMaterial (faceMaterialIndex);\r\n            }\r\n        }\r\n        return mesh;\r\n    }\r\n}\n\nclass ImporterStl extends ImporterBase\r\n{\r\n    constructor ()\r\n    {\r\n        super ();\r\n    }\r\n\r\n    CanImportExtension (extension)\r\n    {\r\n        return extension === 'stl';\r\n    }\r\n\r\n    GetUpDirection ()\r\n    {\r\n        return Direction.Z;\r\n    }\r\n\r\n    ClearContent ()\r\n    {\r\n        this.mesh = null;\r\n        this.triangle = null;\r\n    }\r\n\r\n    ResetContent ()\r\n    {\r\n        this.mesh = new Mesh ();\r\n        this.model.AddMeshToRootNode (this.mesh);\r\n        this.triangle = null;\r\n    }\r\n\r\n    ImportContent (fileContent, onFinish)\r\n    {\r\n        if (this.IsBinaryStlFile (fileContent)) {\r\n            this.ProcessBinary (fileContent);\r\n        } else {\r\n            let textContent = ArrayBufferToUtf8String (fileContent);\r\n            ReadLines (textContent, (line) => {\r\n                if (!this.WasError ()) {\r\n                    this.ProcessLine (line);\r\n                }\r\n            });\r\n        }\r\n        onFinish ();\r\n    }\r\n\r\n    IsBinaryStlFile (fileContent)\r\n    {\r\n        let byteLength = fileContent.byteLength;\r\n        if (byteLength < 84) {\r\n            return false;\r\n        }\r\n\r\n        let reader = new BinaryReader (fileContent, true);\r\n        reader.Skip (80);\r\n\r\n        let triangleCount = reader.ReadUnsignedInteger32 ();\r\n        if (byteLength !== triangleCount * 50 + 84) {\r\n            return false;\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    ProcessLine (line)\r\n    {\r\n        if (line[0] === '#') {\r\n            return;\r\n        }\r\n\r\n        let parameters = ParametersFromLine (line, '#');\r\n        if (parameters.length === 0) {\r\n            return;\r\n        }\r\n\r\n        let keyword = parameters[0];\r\n        if (keyword === 'solid') {\r\n            if (parameters.length > 1) {\r\n                let name = NameFromLine (line, keyword.length, '#');\r\n                this.mesh.SetName (name);\r\n            }\r\n            return;\r\n        }\r\n\r\n        if (keyword === 'facet') {\r\n            this.triangle = new Triangle (-1, -1, -1);\r\n            if (parameters.length >= 5 && parameters[1] === 'normal') {\r\n                let normalVector = new Coord3D (\r\n                    parseFloat (parameters[2]),\r\n                    parseFloat (parameters[3]),\r\n                    parseFloat (parameters[4])\r\n                );\r\n                if (IsPositive (normalVector.Length ())) {\r\n                    let normalIndex = this.mesh.AddNormal (normalVector);\r\n                    this.triangle.SetNormals (\r\n                        normalIndex,\r\n                        normalIndex,\r\n                        normalIndex\r\n                    );\r\n                }\r\n            }\r\n            return;\r\n        }\r\n\r\n        if (keyword === 'vertex' && this.triangle !== null) {\r\n            if (parameters.length >= 4) {\r\n                let vertexIndex = this.mesh.AddVertex (new Coord3D (\r\n                    parseFloat (parameters[1]),\r\n                    parseFloat (parameters[2]),\r\n                    parseFloat (parameters[3])\r\n                ));\r\n                if (this.triangle.v0 === -1) {\r\n                    this.triangle.v0 = vertexIndex;\r\n                } else if (this.triangle.v1 === -1) {\r\n                    this.triangle.v1 = vertexIndex;\r\n                } else if (this.triangle.v2 === -1) {\r\n                    this.triangle.v2 = vertexIndex;\r\n                }\r\n            }\r\n            return;\r\n        }\r\n\r\n        if (keyword === 'endfacet' && this.triangle !== null) {\r\n            if (this.triangle.v0 !== -1 && this.triangle.v1 !== -1 && this.triangle.v2 !== null) {\r\n                this.mesh.AddTriangle (this.triangle);\r\n            }\r\n            this.triangle = null;\r\n            return;\r\n        }\r\n    }\r\n\r\n    ProcessBinary (fileContent)\r\n    {\r\n        function ReadVector (reader)\r\n        {\r\n            let coord = new Coord3D ();\r\n            coord.x = reader.ReadFloat32 ();\r\n            coord.y = reader.ReadFloat32 ();\r\n            coord.z = reader.ReadFloat32 ();\r\n            return coord;\r\n        }\r\n\r\n        function AddVertex (mesh, reader)\r\n        {\r\n            let coord = ReadVector (reader);\r\n            return mesh.AddVertex (coord);\r\n        }\r\n\r\n        let reader = new BinaryReader (fileContent, true);\r\n        reader.Skip (80);\r\n        let triangleCount = reader.ReadUnsignedInteger32 ();\r\n        for (let i = 0; i < triangleCount; i++) {\r\n            let normalVector = ReadVector (reader);\r\n            let v0 = AddVertex (this.mesh, reader);\r\n            let v1 = AddVertex (this.mesh, reader);\r\n            let v2 = AddVertex (this.mesh, reader);\r\n            reader.Skip (2);\r\n            let triangle = new Triangle (v0, v1, v2);\r\n            if (IsPositive (normalVector.Length ())) {\r\n                let normal = this.mesh.AddNormal (normalVector);\r\n                triangle.SetNormals (normal, normal, normal);\r\n            }\r\n            this.mesh.AddTriangle (triangle);\r\n        }\r\n    }\r\n}\n\nclass ImporterBim extends ImporterBase\r\n{\r\n    constructor ()\r\n    {\r\n        super ();\r\n    }\r\n\r\n    CanImportExtension (extension)\r\n    {\r\n        return extension === 'bim';\r\n    }\r\n\r\n    GetUpDirection ()\r\n    {\r\n        return Direction.Z;\r\n    }\r\n\r\n    ClearContent ()\r\n    {\r\n        this.meshIdToMesh = null;\r\n        this.colorToMaterial = null;\r\n    }\r\n\r\n    ResetContent ()\r\n    {\r\n        this.meshIdToMesh = new Map ();\r\n        this.colorToMaterial = new ColorToMaterialConverter (this.model);\r\n    }\r\n\r\n    ImportContent (fileContent, onFinish)\r\n    {\r\n        this.model.SetUnit (Unit.Meter);\r\n\r\n        let textContent = ArrayBufferToUtf8String (fileContent);\r\n        let bimJson = null;\r\n        try {\r\n            bimJson = JSON.parse (textContent);\r\n        } catch (err) {\r\n            this.SetError (Loc ('Failed to parse bim file.'));\r\n            onFinish ();\r\n            return;\r\n        }\r\n\r\n        for (let bimMesh of bimJson.meshes) {\r\n            this.meshIdToMesh.set (bimMesh.mesh_id, bimMesh);\r\n        }\r\n\r\n        this.ImportProperties (bimJson, this.model);\r\n        for (let bimElement of bimJson.elements) {\r\n            let mesh = this.ImportElement (bimElement);\r\n            mesh.SetName (bimElement.type);\r\n            this.ImportProperties (bimElement, mesh);\r\n        }\r\n\r\n        onFinish ();\r\n    }\r\n\r\n    ImportElement (bimElement)\r\n    {\r\n        let defaultMaterialIndex = null;\r\n        if (bimElement.color)\r\n        {\r\n            defaultMaterialIndex = this.colorToMaterial.GetMaterialIndex (\r\n                bimElement.color.r,\r\n                bimElement.color.g,\r\n                bimElement.color.b,\r\n                bimElement.color.a\r\n            );\r\n        }\r\n\r\n        let rootNode = this.model.GetRootNode ();\r\n\r\n        let bimMesh = this.meshIdToMesh.get (bimElement.mesh_id);\r\n        let mesh = this.ImportMesh (bimMesh, (triangleIndex) => {\r\n            if (bimElement.face_colors) {\r\n                let faceMaterialIndex = this.colorToMaterial.GetMaterialIndex (\r\n                    bimElement.face_colors[triangleIndex * 4 + 0],\r\n                    bimElement.face_colors[triangleIndex * 4 + 1],\r\n                    bimElement.face_colors[triangleIndex * 4 + 2],\r\n                    bimElement.face_colors[triangleIndex * 4 + 3]\r\n                );\r\n                return faceMaterialIndex;\r\n            } else {\r\n                return defaultMaterialIndex;\r\n            }\r\n        });\r\n        let meshIndex = this.model.AddMesh (mesh);\r\n\r\n        let elementNode = new Node ();\r\n        elementNode.AddMeshIndex (meshIndex);\r\n\r\n        let translation = new Coord3D (0.0, 0.0, 0.0);\r\n        if (bimElement.vector) {\r\n            translation = new Coord3D (\r\n                bimElement.vector.x,\r\n                bimElement.vector.y,\r\n                bimElement.vector.z\r\n            );\r\n        }\r\n        let rotation = new Quaternion (0.0, 0.0, 0.0, 1.0);\r\n        if (bimElement.rotation) {\r\n            rotation = new Quaternion (\r\n                bimElement.rotation.qx,\r\n                bimElement.rotation.qy,\r\n                bimElement.rotation.qz,\r\n                bimElement.rotation.qw\r\n            );\r\n        }\r\n        let scale = new Coord3D (1.0, 1.0, 1.0);\r\n        let matrix = new Matrix ().ComposeTRS (translation, rotation, scale);\r\n        elementNode.SetTransformation (new Transformation (matrix));\r\n\r\n        rootNode.AddChildNode (elementNode);\r\n        return mesh;\r\n    }\r\n\r\n    ImportMesh (bimMesh, getMaterialIndex)\r\n    {\r\n        let mesh = new Mesh ();\r\n\r\n        for (let i = 0; i < bimMesh.coordinates.length; i += 3) {\r\n            mesh.AddVertex (new Coord3D (\r\n                bimMesh.coordinates[i + 0],\r\n                bimMesh.coordinates[i + 1],\r\n                bimMesh.coordinates[i + 2]\r\n            ));\r\n        }\r\n\r\n        for (let i = 0; i < bimMesh.indices.length; i += 3) {\r\n            let triangle = new Triangle (\r\n                bimMesh.indices[i + 0],\r\n                bimMesh.indices[i + 1],\r\n                bimMesh.indices[i + 2]\r\n            );\r\n            triangle.SetMaterial (getMaterialIndex (i / 3));\r\n            mesh.AddTriangle (triangle);\r\n        }\r\n\r\n        return mesh;\r\n    }\r\n\r\n    ImportProperties (source, target)\r\n    {\r\n        function AddProperty (group, name, value)\r\n        {\r\n            if (value === undefined || value === null) {\r\n                return;\r\n            }\r\n            let property = new Property (PropertyType.Text, name, value);\r\n            group.AddProperty (property);\r\n        }\r\n\r\n        if (!source.info || IsObjectEmpty (source.info)) {\r\n            return;\r\n        }\r\n\r\n        let info = source.info;\r\n        let propertyGroup = new PropertyGroup (Loc ('Info'));\r\n        AddProperty (propertyGroup, Loc ('Guid'), source.guid);\r\n        AddProperty (propertyGroup, Loc ('Type'), source.type);\r\n        for (let propertyName in info) {\r\n            if (Object.prototype.hasOwnProperty.call (info, propertyName)) {\r\n                if (typeof info[propertyName] === 'string') {\r\n                    AddProperty (propertyGroup, propertyName, info[propertyName]);\r\n                }\r\n            }\r\n        }\r\n        target.AddPropertyGroup (propertyGroup);\r\n    }\r\n}\n\nclass ImporterThreeBase extends ImporterBase\r\n{\r\n    constructor ()\r\n    {\r\n        super ();\r\n\r\n        this.colorConverter = null;\r\n    }\r\n\r\n    CreateLoader (manager)\r\n    {\r\n        return null;\r\n    }\r\n\r\n    GetMainObject (loadedObject)\r\n    {\r\n        return loadedObject;\r\n    }\r\n\r\n    IsMeshVisible (mesh)\r\n    {\r\n        return true;\r\n    }\r\n\r\n    ClearContent ()\r\n    {\r\n        this.loader = null;\r\n        this.materialIdToIndex = null;\r\n        this.objectUrlToFileName = null;\r\n    }\r\n\r\n    ResetContent ()\r\n    {\r\n        this.loader = null;\r\n        this.materialIdToIndex = new Map ();\r\n        this.objectUrlToFileName = new Map ();\r\n    }\r\n\r\n    ImportContent (fileContent, onFinish)\r\n    {\r\n        this.LoadModel (fileContent, onFinish);\r\n    }\r\n\r\n    LoadModel (fileContent, onFinish)\r\n    {\r\n        let isAllLoadersDone = false;\r\n        let loadingManager = new THREE.LoadingManager (() => {\r\n            isAllLoadersDone = true;\r\n        });\r\n\r\n        const mainFileUrl = CreateObjectUrl (fileContent);\r\n        loadingManager.setURLModifier ((url) => {\r\n            if (url === mainFileUrl) {\r\n                return url;\r\n            }\r\n            const name = GetFileName (url);\r\n            const extension = GetFileExtension (url);\r\n            if (extension.length > 0) {\r\n                const buffer = this.callbacks.getFileBuffer (url);\r\n                if (buffer !== null) {\r\n                    let objectUrl = CreateObjectUrl (buffer);\r\n                    this.objectUrlToFileName.set (objectUrl, name);\r\n                    return objectUrl;\r\n                }\r\n            }\r\n            return url;\r\n        });\r\n\r\n        const threeLoader = this.CreateLoader (loadingManager);\r\n        if (threeLoader === null) {\r\n            onFinish ();\r\n            return;\r\n        }\r\n\r\n        threeLoader.load (mainFileUrl,\r\n            (object) => {\r\n                WaitWhile (() => {\r\n                    if (isAllLoadersDone) {\r\n                        this.OnThreeObjectsLoaded (object, onFinish);\r\n                        return false;\r\n                    }\r\n                    return true;\r\n                });\r\n            },\r\n            () => {\r\n            },\r\n            (err) => {\r\n                this.SetError (err);\r\n                onFinish ();\r\n            }\r\n        );\r\n    }\r\n\r\n    OnThreeObjectsLoaded (loadedObject, onFinish)\r\n    {\r\n        function GetObjectTransformation (threeObject)\r\n        {\r\n            let matrix = new Matrix ().CreateIdentity ();\r\n            threeObject.updateMatrix ();\r\n            if (threeObject.matrix !== undefined && threeObject.matrix !== null) {\r\n                matrix.Set (threeObject.matrix.elements);\r\n            }\r\n            return new Transformation (matrix);\r\n        }\r\n\r\n        function AddObject (importer, model, threeObject, parentNode)\r\n        {\r\n            let node = new Node ();\r\n            if (threeObject.name !== undefined) {\r\n                node.SetName (threeObject.name);\r\n            }\r\n            node.SetTransformation (GetObjectTransformation (threeObject));\r\n            parentNode.AddChildNode (node);\r\n\r\n            for (let childObject of threeObject.children) {\r\n                AddObject (importer, model, childObject, node);\r\n            }\r\n            if (threeObject.isMesh && importer.IsMeshVisible (threeObject)) {\r\n                let mesh = importer.ConvertThreeMesh (threeObject);\r\n                let meshIndex = model.AddMesh (mesh);\r\n                node.AddMeshIndex (meshIndex);\r\n            }\r\n        }\r\n\r\n        let mainObject = this.GetMainObject (loadedObject);\r\n        let rootNode = this.model.GetRootNode ();\r\n        rootNode.SetTransformation (GetObjectTransformation (mainObject));\r\n        for (let childObject of mainObject.children) {\r\n            AddObject (this, this.model, childObject, rootNode);\r\n        }\r\n\r\n        onFinish ();\r\n    }\r\n\r\n    ConvertThreeMesh (threeMesh)\r\n    {\r\n        let mesh = null;\r\n        if (Array.isArray (threeMesh.material)) {\r\n            mesh = ConvertThreeGeometryToMesh (threeMesh.geometry, null, this.colorConverter);\r\n            if (threeMesh.geometry.attributes.color === undefined || threeMesh.geometry.attributes.color === null) {\r\n                let materialIndices = [];\r\n                for (let i = 0; i < threeMesh.material.length; i++) {\r\n                    const material = threeMesh.material[i];\r\n                    const materialIndex = this.FindOrCreateMaterial (material);\r\n                    materialIndices.push (materialIndex);\r\n                }\r\n                for (let i = 0; i < threeMesh.geometry.groups.length; i++) {\r\n                    let group = threeMesh.geometry.groups[i];\r\n                    let groupEnd = null;\r\n                    if (group.count === Infinity) {\r\n                        groupEnd = mesh.TriangleCount ();\r\n                    } else {\r\n                        groupEnd = group.start / 3 + group.count / 3;\r\n                    }\r\n                    for (let j = group.start / 3; j < groupEnd; j++) {\r\n                        let triangle = mesh.GetTriangle (j);\r\n                        triangle.SetMaterial (materialIndices[group.materialIndex]);\r\n                    }\r\n                }\r\n            }\r\n        } else {\r\n            const materialIndex = this.FindOrCreateMaterial (threeMesh.material);\r\n            mesh = ConvertThreeGeometryToMesh (threeMesh.geometry, materialIndex, this.colorConverter);\r\n        }\r\n        if (threeMesh.name !== undefined && threeMesh.name !== null) {\r\n            mesh.SetName (threeMesh.name);\r\n        }\r\n        return mesh;\r\n    }\r\n\r\n    FindOrCreateMaterial (threeMaterial)\r\n    {\r\n        if (this.materialIdToIndex.has (threeMaterial.id)) {\r\n            return this.materialIdToIndex.get (threeMaterial.id);\r\n        }\r\n        let material = this.ConvertThreeMaterial (threeMaterial);\r\n        let materialIndex = null;\r\n        if (material !== null) {\r\n            materialIndex = this.model.AddMaterial (material);\r\n        }\r\n        this.materialIdToIndex.set (threeMaterial.id, materialIndex);\r\n        return materialIndex;\r\n    }\r\n\r\n    ConvertThreeMaterial (threeMaterial)\r\n    {\r\n        function CreateTexture (threeMap, objectUrlToFileName)\r\n        {\r\n            function GetDataUrl (img)\r\n            {\r\n                if (img.data !== undefined && img.data !== null) {\r\n                    let imageData = new ImageData (img.width, img.height);\r\n                    let imageSize = img.width * img.height * 4;\r\n                    for (let i = 0; i < imageSize; i++) {\r\n                        imageData.data[i] = img.data[i];\r\n                    }\r\n                    return THREE.ImageUtils.getDataURL (imageData);\r\n                } else {\r\n                    return THREE.ImageUtils.getDataURL (img);\r\n                }\r\n            }\r\n\r\n            if (threeMap === undefined || threeMap === null) {\r\n                return null;\r\n            }\r\n\r\n            if (threeMap.image === undefined || threeMap.image === null) {\r\n                return null;\r\n            }\r\n\r\n            try {\r\n                const dataUrl = GetDataUrl (threeMap.image);\r\n                const base64Buffer = Base64DataURIToArrayBuffer (dataUrl);\r\n                let texture = new TextureMap ();\r\n                let textureName = null;\r\n                if (objectUrlToFileName.has (threeMap.image.src)) {\r\n                    textureName = objectUrlToFileName.get (threeMap.image.src);\r\n                } else if (threeMap.name !== undefined && threeMap.name !== null) {\r\n                    textureName = threeMap.name + '.' + GetFileExtensionFromMimeType (base64Buffer.mimeType);\r\n                } else {\r\n                    textureName = 'Embedded_' + threeMap.id.toString () + '.' + GetFileExtensionFromMimeType (base64Buffer.mimeType);\r\n                }\r\n                texture.name = textureName;\r\n                texture.mimeType = base64Buffer.mimeType;\r\n                texture.buffer = base64Buffer.buffer;\r\n                texture.rotation = threeMap.rotation;\r\n                texture.offset.x = threeMap.offset.x;\r\n                texture.offset.y = threeMap.offset.y;\r\n                texture.scale.x = threeMap.repeat.x;\r\n                texture.scale.y = threeMap.repeat.y;\r\n                return texture;\r\n            } catch (err) {\r\n                return null;\r\n            }\r\n        }\r\n\r\n        if (threeMaterial.name === THREE.Loader.DEFAULT_MATERIAL_NAME) {\r\n            return null;\r\n        }\r\n\r\n        let material = new PhongMaterial ();\r\n        material.name = threeMaterial.name;\r\n        material.color = this.ConvertThreeColor (threeMaterial.color);\r\n        material.opacity = threeMaterial.opacity;\r\n        material.transparent = threeMaterial.transparent;\r\n        material.alphaTest = threeMaterial.alphaTest;\r\n        if (threeMaterial.type === 'MeshPhongMaterial') {\r\n            material.specular = this.ConvertThreeColor (threeMaterial.specular);\r\n            material.shininess = threeMaterial.shininess / 100.0;\r\n        }\r\n        material.diffuseMap = CreateTexture (threeMaterial.map, this.objectUrlToFileName);\r\n        material.normalMap = CreateTexture (threeMaterial.normalMap, this.objectUrlToFileName);\r\n        material.bumpMap = CreateTexture (threeMaterial.bumpMap, this.objectUrlToFileName);\r\n\r\n        return material;\r\n    }\r\n\r\n    ConvertThreeColor (threeColor)\r\n    {\r\n        if (this.colorConverter !== null) {\r\n            threeColor = this.colorConverter.Convert (threeColor);\r\n        }\r\n        return ConvertThreeColorToColor (threeColor);\r\n    }\r\n}\r\n\r\nclass ImporterThreeFbx extends ImporterThreeBase\r\n{\r\n    constructor ()\r\n    {\r\n        super ();\r\n    }\r\n\r\n    CanImportExtension (extension)\r\n    {\r\n        return extension === 'fbx';\r\n    }\r\n\r\n    GetUpDirection ()\r\n    {\r\n        return Direction.Y;\r\n    }\r\n\r\n    CreateLoader (manager)\r\n    {\r\n        manager.addHandler (/\\.tga$/i, new TGALoader (manager));\r\n        return new FBXLoader (manager);\r\n    }\r\n\r\n    GetMainObject (loadedObject)\r\n    {\r\n        return loadedObject;\r\n    }\r\n}\r\n\r\nclass ImporterThreeDae extends ImporterThreeBase\r\n{\r\n    constructor ()\r\n    {\r\n        super ();\r\n    }\r\n\r\n    CanImportExtension (extension)\r\n    {\r\n        return extension === 'dae';\r\n    }\r\n\r\n    GetUpDirection ()\r\n    {\r\n        return Direction.Y;\r\n    }\r\n\r\n    CreateLoader (manager)\r\n    {\r\n        manager.addHandler (/\\.tga$/i, new TGALoader (manager));\r\n        return new ColladaLoader (manager);\r\n    }\r\n\r\n    GetMainObject (loadedObject)\r\n    {\r\n        return loadedObject.scene;\r\n    }\r\n}\r\n\r\nclass ImporterThreeWrl extends ImporterThreeBase\r\n{\r\n    constructor ()\r\n    {\r\n        super ();\r\n    }\r\n\r\n    CanImportExtension (extension)\r\n    {\r\n        return extension === 'wrl';\r\n    }\r\n\r\n    GetUpDirection ()\r\n    {\r\n        return Direction.Y;\r\n    }\r\n\r\n    CreateLoader (manager)\r\n    {\r\n        return new VRMLLoader (manager);\r\n    }\r\n\r\n    GetMainObject (loadedObject)\r\n    {\r\n        return loadedObject;\r\n    }\r\n\r\n    IsMeshVisible (mesh)\r\n    {\r\n        let isVisible = true;\r\n        if (Array.isArray (mesh.material)) {\r\n            for (let i = 0; i < mesh.material.length; i++) {\r\n                if (mesh.material[i].side === THREE.BackSide) {\r\n                    isVisible = false;\r\n                    break;\r\n                }\r\n            }\r\n        } else {\r\n            isVisible = (mesh.material.side !== THREE.BackSide);\r\n        }\r\n        return isVisible;\r\n    }\r\n}\r\n\r\nclass ImporterThree3mf extends ImporterThreeBase\r\n{\r\n    constructor ()\r\n    {\r\n        super ();\r\n        this.colorConverter = new ThreeSRGBToLinearColorConverter ();\r\n    }\r\n\r\n    CanImportExtension (extension)\r\n    {\r\n        return extension === '3mf';\r\n    }\r\n\r\n    GetUpDirection ()\r\n    {\r\n        return Direction.Z;\r\n    }\r\n\r\n    CreateLoader (manager)\r\n    {\r\n        return new ThreeMFLoader (manager);\r\n    }\r\n\r\n    GetMainObject (loadedObject)\r\n    {\r\n        return loadedObject;\r\n    }\r\n}\r\n\r\nclass ImporterThreeAmf extends ImporterThreeBase\r\n{\r\n    constructor ()\r\n    {\r\n        super ();\r\n    }\r\n\r\n    CanImportExtension (extension)\r\n    {\r\n        return extension === 'amf';\r\n    }\r\n\r\n    GetUpDirection ()\r\n    {\r\n        return Direction.Z;\r\n    }\r\n\r\n    CreateLoader (manager)\r\n    {\r\n        return new AMFLoader (manager);\r\n    }\r\n\r\n    GetMainObject (loadedObject)\r\n    {\r\n        return loadedObject;\r\n    }\r\n}\n\nconst DocumentInitResult =\r\n{\r\n    Success : 0,\r\n    NoDocumentXml : 1\r\n};\r\n\r\nclass FreeCadObject\r\n{\r\n    constructor (name, type)\r\n    {\r\n        this.name = name;\r\n        this.type = type;\r\n        this.shapeName = null;\r\n        this.isVisible = false;\r\n        this.color = null;\r\n        this.fileName = null;\r\n        this.fileContent = null;\r\n        this.inLinkCount = 0;\r\n        this.properties = null;\r\n    }\r\n\r\n    IsConvertible ()\r\n    {\r\n        if (this.fileName === null || this.fileContent === null) {\r\n            return false;\r\n        }\r\n        if (!this.isVisible) {\r\n            return false;\r\n        }\r\n        if (this.inLinkCount > 0) {\r\n            return false;\r\n        }\r\n        return true;\r\n    }\r\n}\r\n\r\nclass FreeCadDocument\r\n{\r\n    constructor ()\r\n    {\r\n        this.files = null;\r\n        this.properties = null;\r\n        this.objectNames = [];\r\n        this.objectData = new Map ();\r\n    }\r\n\r\n    Init (fileContent)\r\n    {\r\n        let fileContentBuffer = new Uint8Array (fileContent);\r\n        this.files = fflate.unzipSync (fileContentBuffer);\r\n        if (!this.LoadDocumentXml ()) {\r\n            return DocumentInitResult.NoDocumentXml;\r\n        }\r\n\r\n        this.LoadGuiDocumentXml ();\r\n        return DocumentInitResult.Success;\r\n    }\r\n\r\n    GetObjectListToConvert ()\r\n    {\r\n        let objectList = [];\r\n        for (let objectName of this.objectNames) {\r\n            let object = this.objectData.get (objectName);\r\n            if (!object.IsConvertible ()) {\r\n                continue;\r\n            }\r\n            objectList.push (object);\r\n        }\r\n        return objectList;\r\n    }\r\n\r\n    IsSupportedType (type)\r\n    {\r\n        if (!type.startsWith ('Part::') && !type.startsWith ('PartDesign::')) {\r\n            return false;\r\n        }\r\n        if (type.indexOf ('Part2D') !== -1) {\r\n            return false;\r\n        }\r\n        return true;\r\n    }\r\n\r\n    HasFile (fileName)\r\n    {\r\n        return (fileName in this.files);\r\n    }\r\n\r\n    LoadDocumentXml ()\r\n    {\r\n        let documentXml = this.GetXMLContent ('Document.xml');\r\n        if (documentXml === null) {\r\n            return false;\r\n        }\r\n\r\n        this.properties = new PropertyGroup (Loc ('Properties'));\r\n        let documentElements = documentXml.getElementsByTagName ('Document');\r\n        for (let documentElement of documentElements) {\r\n            for (let childNode of documentElement.childNodes) {\r\n                if (childNode.tagName === 'Properties') {\r\n                    this.GetPropertiesFromElement (childNode, this.properties);\r\n                }\r\n            }\r\n        }\r\n\r\n        let objectsElements = documentXml.getElementsByTagName ('Objects');\r\n        for (let objectsElement of objectsElements) {\r\n            let objectElements = objectsElement.getElementsByTagName ('Object');\r\n            for (let objectElement of objectElements) {\r\n                let name = objectElement.getAttribute ('name');\r\n                let type = objectElement.getAttribute ('type');\r\n                if (!this.IsSupportedType (type)) {\r\n                    continue;\r\n                }\r\n                let object = new FreeCadObject (name, type);\r\n                this.objectNames.push (name);\r\n                this.objectData.set (name, object);\r\n            }\r\n        }\r\n\r\n        let objectDataElements = documentXml.getElementsByTagName ('ObjectData');\r\n        for (let objectDataElement of objectDataElements) {\r\n            let objectElements = objectDataElement.getElementsByTagName ('Object');\r\n            for (let objectElement of objectElements) {\r\n                let name = objectElement.getAttribute ('name');\r\n                if (!this.objectData.has (name)) {\r\n                    continue;\r\n                }\r\n\r\n                let object = this.objectData.get (name);\r\n                object.properties = new PropertyGroup (Loc ('Properties'));\r\n                for (let childNode of objectElement.childNodes) {\r\n                    if (childNode.tagName === 'Properties') {\r\n                        this.GetPropertiesFromElement (childNode, object.properties);\r\n                    }\r\n                }\r\n\r\n                let propertyElements = objectElement.getElementsByTagName ('Property');\r\n                for (let propertyElement of propertyElements) {\r\n                    let propertyName = propertyElement.getAttribute ('name');\r\n                    if (propertyName === 'Label') {\r\n                        object.shapeName = this.GetFirstChildValue (propertyElement, 'String', 'value');\r\n                    } else if (propertyName === 'Visibility') {\r\n                        let isVisibleString = this.GetFirstChildValue (propertyElement, 'Bool', 'value');\r\n                        object.isVisible = (isVisibleString === 'true');\r\n                    } else if (propertyName === 'Visible') {\r\n                        let isVisibleString = this.GetFirstChildValue (propertyElement, 'Bool', 'value');\r\n                        object.isVisible = (isVisibleString === 'true');\r\n                    } else if (propertyName === 'Shape') {\r\n                        let fileName = this.GetFirstChildValue (propertyElement, 'Part', 'file');\r\n                        if (!this.HasFile (fileName)) {\r\n                            continue;\r\n                        }\r\n                        let extension = GetFileExtension (fileName);\r\n                        if (extension !== 'brp' && extension !== 'brep') {\r\n                            continue;\r\n                        }\r\n                        object.fileName = fileName;\r\n                        object.fileContent = this.files[fileName];\r\n                    }\r\n                }\r\n\r\n                let linkElements = objectElement.getElementsByTagName ('Link');\r\n                for (let linkElement of linkElements) {\r\n                    let linkedName = linkElement.getAttribute ('value');\r\n                    if (this.objectData.has (linkedName)) {\r\n                        let linkedObject = this.objectData.get (linkedName);\r\n                        linkedObject.inLinkCount += 1;\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    LoadGuiDocumentXml ()\r\n    {\r\n        let documentXml = this.GetXMLContent ('GuiDocument.xml');\r\n        if (documentXml === null) {\r\n            return false;\r\n        }\r\n\r\n        let viewProviderElements = documentXml.getElementsByTagName ('ViewProvider');\r\n        for (let viewProviderElement of viewProviderElements) {\r\n            let name = viewProviderElement.getAttribute ('name');\r\n            if (!this.objectData.has (name)) {\r\n                continue;\r\n            }\r\n\r\n            let object = this.objectData.get (name);\r\n            let propertyElements = viewProviderElement.getElementsByTagName ('Property');\r\n            for (let propertyElement of propertyElements) {\r\n                let propertyName = propertyElement.getAttribute ('name');\r\n                if (propertyName === 'Visibility') {\r\n                    let isVisibleString = this.GetFirstChildValue (propertyElement, 'Bool', 'value');\r\n                    object.isVisible = (isVisibleString === 'true');\r\n                } else if (propertyName === 'ShapeColor') {\r\n                    let colorString = this.GetFirstChildValue (propertyElement, 'PropertyColor', 'value');\r\n                    let rgba = parseInt (colorString, 10);\r\n                    object.color = new RGBAColor (\r\n                        rgba >> 24 & 0xff,\r\n                        rgba >> 16 & 0xff,\r\n                        rgba >> 8 & 0xff,\r\n                        255\r\n                    );\r\n                }\r\n            }\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    GetPropertiesFromElement (propertiesElement, propertyGroup)\r\n    {\r\n        let propertyElements = propertiesElement.getElementsByTagName ('Property');\r\n        for (let propertyElement of propertyElements) {\r\n            let propertyName = propertyElement.getAttribute ('name');\r\n            let propertyType = propertyElement.getAttribute ('type');\r\n\r\n            let property = null;\r\n            if (propertyType === 'App::PropertyBool') {\r\n                let propertyValue = this.GetFirstChildValue (propertyElement, 'String', 'bool');\r\n                if (propertyValue !== null && propertyValue.length > 0) {\r\n                    property = new Property (PropertyType.Boolean, propertyName, propertyValue === 'true');\r\n                }\r\n            } else if (propertyType === 'App::PropertyInteger') {\r\n                let propertyValue = this.GetFirstChildValue (propertyElement, 'Integer', 'value');\r\n                if (propertyValue !== null && propertyValue.length > 0) {\r\n                    property = new Property (PropertyType.Integer, propertyName, parseInt (propertyValue));\r\n                }\r\n            } else if (propertyType === 'App::PropertyString') {\r\n                let propertyValue = this.GetFirstChildValue (propertyElement, 'String', 'value');\r\n                if (propertyValue !== null && propertyValue.length > 0) {\r\n                    property = new Property (PropertyType.Text, propertyName, propertyValue);\r\n                }\r\n            } else if (propertyType === 'App::PropertyUUID') {\r\n                let propertyValue = this.GetFirstChildValue (propertyElement, 'Uuid', 'value');\r\n                if (propertyValue !== null && propertyValue.length > 0) {\r\n                    property = new Property (PropertyType.Text, propertyName, propertyValue);\r\n                }\r\n            } else if (propertyType === 'App::PropertyFloat' || propertyType === 'App::PropertyLength' || propertyType === 'App::PropertyDistance' || propertyType === 'App::PropertyArea' || propertyType === 'App::PropertyVolume') {\r\n                let propertyValue = this.GetFirstChildValue (propertyElement, 'Float', 'value');\r\n                if (propertyValue !== null && propertyValue.length > 0) {\r\n                    property = new Property (PropertyType.Number, propertyName, parseFloat (propertyValue));\r\n                }\r\n            }\r\n            if (property !== null) {\r\n                propertyGroup.AddProperty (property);\r\n            }\r\n        }\r\n    }\r\n\r\n    GetXMLContent (xmlFileName)\r\n    {\r\n        if (!this.HasFile (xmlFileName)) {\r\n            return null;\r\n        }\r\n\r\n        let xmlParser = new DOMParser ();\r\n        let xmlString = ArrayBufferToUtf8String (this.files[xmlFileName]);\r\n        return xmlParser.parseFromString (xmlString, 'text/xml');\r\n    }\r\n\r\n    GetFirstChildValue (element, childTagName, childAttribute)\r\n    {\r\n        let childObjects = element.getElementsByTagName (childTagName);\r\n        if (childObjects.length === 0) {\r\n            return null;\r\n        }\r\n        return childObjects[0].getAttribute (childAttribute);\r\n    }\r\n}\r\n\r\nclass ImporterFcstd extends ImporterBase\r\n{\r\n    constructor ()\r\n    {\r\n        super ();\r\n        this.worker = null;\r\n        this.document = null;\r\n    }\r\n\r\n    CanImportExtension (extension)\r\n    {\r\n        return extension === 'fcstd';\r\n    }\r\n\r\n    GetUpDirection ()\r\n    {\r\n        return Direction.Z;\r\n    }\r\n\r\n\tClearContent ()\r\n\t{\r\n        if (this.worker !== null) {\r\n            this.worker.terminate ();\r\n            this.worker = null;\r\n        }\r\n        this.document = null;\r\n\t}\r\n\r\n    ResetContent ()\r\n    {\r\n        this.worker = null;\r\n        this.document = new FreeCadDocument ();\r\n    }\r\n\r\n    ImportContent (fileContent, onFinish)\r\n    {\r\n        let result = this.document.Init (fileContent);\r\n        if (result === DocumentInitResult.NoDocumentXml) {\r\n            this.SetError (Loc ('No Document.xml found.'));\r\n            onFinish ();\r\n            return;\r\n        }\r\n\r\n        if (this.document.properties !== null && this.document.properties.PropertyCount () > 0) {\r\n            this.model.AddPropertyGroup (this.document.properties);\r\n        }\r\n\r\n        let objectsToConvert = this.document.GetObjectListToConvert ();\r\n        if (objectsToConvert.length === 0) {\r\n            this.SetError (Loc ('No importable object found.'));\r\n            onFinish ();\r\n            return;\r\n        }\r\n\r\n        this.ConvertObjects (objectsToConvert, onFinish);\r\n    }\r\n\r\n    ConvertObjects (objects, onFinish)\r\n    {\r\n        CreateOcctWorker ().then ((worker) => {\r\n            this.worker = worker;\r\n            this.worker.addEventListener ('message', (ev) => {\r\n                onFileConverted (ev.data);\r\n            });\r\n\r\n            this.worker.addEventListener ('error', (ev) => {\r\n                onFileConverted (null);\r\n            });\r\n\r\n            let convertedObjectCount = 0;\r\n            let colorToMaterial = new ColorToMaterialConverter (this.model);\r\n            let onFileConverted = (resultContent) => {\r\n                if (resultContent !== null) {\r\n                    let currentObject = objects[convertedObjectCount];\r\n                    this.OnFileConverted (currentObject, resultContent, colorToMaterial);\r\n                }\r\n                convertedObjectCount += 1;\r\n                if (convertedObjectCount === objects.length) {\r\n                    onFinish ();\r\n                } else {\r\n                    let currentObject = objects[convertedObjectCount];\r\n                    this.worker.postMessage ({\r\n                        format : 'brep',\r\n                        buffer : currentObject.fileContent\r\n                    });\r\n                }\r\n            };\r\n\r\n            let currentObject = objects[convertedObjectCount];\r\n            this.worker.postMessage ({\r\n                format : 'brep',\r\n                buffer : currentObject.fileContent\r\n            });\r\n        }).catch (() => {\r\n            this.SetError (Loc ('Failed to load occt-import-js.'));\r\n            onFinish ();\r\n        });\r\n    }\r\n\r\n    OnFileConverted (object, resultContent, colorToMaterial)\r\n    {\r\n        if (!resultContent.success || resultContent.meshes.length === 0) {\r\n            return;\r\n        }\r\n\r\n        let objectNode = new Node ();\r\n        if (object.shapeName !== null) {\r\n            objectNode.SetName (object.shapeName);\r\n        }\r\n\r\n        let objectMeshIndex = 1;\r\n        for (let resultMesh of resultContent.meshes) {\r\n            let materialIndex = null;\r\n            if (object.color !== null) {\r\n                materialIndex = colorToMaterial.GetMaterialIndex (\r\n                    object.color.r,\r\n                    object.color.g,\r\n                    object.color.b,\r\n                    object.color.a\r\n                );\r\n            }\r\n            let mesh = ConvertThreeGeometryToMesh (resultMesh, materialIndex, null);\r\n            if (object.shapeName !== null) {\r\n                let indexString = objectMeshIndex.toString ().padStart (3, '0');\r\n                mesh.SetName (object.shapeName + ' ' + indexString);\r\n            }\r\n\r\n            if (object.properties !== null && object.properties.PropertyCount () > 0) {\r\n                mesh.AddPropertyGroup (object.properties);\r\n            }\r\n\r\n            let meshIndex = this.model.AddMesh (mesh);\r\n            objectNode.AddMeshIndex (meshIndex);\r\n            objectMeshIndex += 1;\r\n        }\r\n\r\n        let rootNode = this.model.GetRootNode ();\r\n        rootNode.AddChildNode (objectNode);\r\n    }\r\n}\n\nclass ImportSettings\r\n{\r\n    constructor ()\r\n    {\r\n        this.defaultLineColor = new RGBColor (100, 100, 100);\r\n        this.defaultColor = new RGBColor (200, 200, 200);\r\n    }\r\n}\r\n\r\nconst ImportErrorCode =\r\n{\r\n    NoImportableFile : 1,\r\n    FailedToLoadFile : 2,\r\n    ImportFailed : 3,\r\n    UnknownError : 4\r\n};\r\n\r\nclass ImportError\r\n{\r\n    constructor (code)\r\n    {\r\n        this.code = code;\r\n        this.mainFile = null;\r\n        this.message = null;\r\n    }\r\n}\r\n\r\nclass ImportResult\r\n{\r\n    constructor ()\r\n    {\r\n        this.model = null;\r\n        this.mainFile = null;\r\n        this.upVector = null;\r\n        this.usedFiles = null;\r\n        this.missingFiles = null;\r\n    }\r\n}\r\n\r\nclass ImporterFileAccessor\r\n{\r\n    constructor (getBufferCallback)\r\n    {\r\n        this.getBufferCallback = getBufferCallback;\r\n        this.fileBuffers = new Map ();\r\n    }\r\n\r\n    GetFileBuffer (filePath)\r\n    {\r\n        let fileName = GetFileName (filePath);\r\n        if (this.fileBuffers.has (fileName)) {\r\n            return this.fileBuffers.get (fileName);\r\n        }\r\n        let buffer = this.getBufferCallback (fileName);\r\n        this.fileBuffers.set (fileName, buffer);\r\n        return buffer;\r\n    }\r\n}\r\n\r\nclass Importer\r\n{\r\n    constructor ()\r\n    {\r\n        this.importers = [\r\n            new ImporterObj (),\r\n            new ImporterStl (),\r\n            new ImporterOff (),\r\n            new ImporterPly (),\r\n            new Importer3ds (),\r\n            new ImporterGltf (),\r\n            new ImporterBim (),\r\n            new Importer3dm (),\r\n            new ImporterIfc (),\r\n            new ImporterOcct (),\r\n            new ImporterFcstd (),\r\n            new ImporterThreeFbx (),\r\n            new ImporterThreeDae (),\r\n            new ImporterThreeWrl (),\r\n            new ImporterThree3mf (),\r\n            new ImporterThreeAmf ()\r\n        ];\r\n        this.fileList = new ImporterFileList ();\r\n        this.model = null;\r\n        this.usedFiles = [];\r\n        this.missingFiles = [];\r\n    }\r\n\r\n\tAddImporter (importer)\r\n\t{\r\n\t\tthis.importers.push (importer);\r\n\t}\r\n\r\n    ImportFiles (inputFiles, settings, callbacks)\r\n    {\r\n        callbacks.onLoadStart ();\r\n        this.LoadFiles (inputFiles, {\r\n            onReady : () => {\r\n                callbacks.onImportStart ();\r\n                RunTaskAsync (() => {\r\n                    this.DecompressArchives (this.fileList, () => {\r\n                        this.ImportLoadedFiles (settings, callbacks);\r\n                    });\r\n                });\r\n            },\r\n            onFileListProgress : callbacks.onFileListProgress,\r\n            onFileLoadProgress : callbacks.onFileLoadProgress\r\n        });\r\n    }\r\n\r\n    LoadFiles (inputFiles, callbacks)\r\n    {\r\n        let newFileList = new ImporterFileList ();\r\n        newFileList.FillFromInputFiles (inputFiles);\r\n\r\n        let reset = false;\r\n        if (this.HasImportableFile (newFileList)) {\r\n            reset = true;\r\n        } else {\r\n            let foundMissingFile = false;\r\n            for (let i = 0; i < this.missingFiles.length; i++) {\r\n                let missingFile = this.missingFiles[i];\r\n                if (newFileList.ContainsFileByPath (missingFile)) {\r\n                    foundMissingFile = true;\r\n                }\r\n            }\r\n            if (!foundMissingFile) {\r\n                reset = true;\r\n            } else {\r\n                this.fileList.ExtendFromFileList (newFileList);\r\n                reset = false;\r\n            }\r\n        }\r\n        if (reset) {\r\n            this.fileList = newFileList;\r\n        }\r\n        this.fileList.GetContent ({\r\n            onReady : callbacks.onReady,\r\n            onFileListProgress : callbacks.onFileListProgress,\r\n            onFileLoadProgress : callbacks.onFileLoadProgress\r\n        });\r\n    }\r\n\r\n    ImportLoadedFiles (settings, callbacks)\r\n    {\r\n        let importableFiles = this.GetImportableFiles (this.fileList);\r\n        if (importableFiles.length === 0) {\r\n            callbacks.onImportError (new ImportError (ImportErrorCode.NoImportableFile));\r\n            return;\r\n        }\r\n\r\n        if (importableFiles.length === 1 || !callbacks.onSelectMainFile) {\r\n            let mainFile = importableFiles[0];\r\n            this.ImportLoadedMainFile (mainFile, settings, callbacks);\r\n        } else {\r\n            let fileNames = importableFiles.map (importableFile => importableFile.file.name);\r\n            callbacks.onSelectMainFile (fileNames, (mainFileIndex) => {\r\n                if (mainFileIndex === null) {\r\n                    callbacks.onImportError (new ImportError (ImportErrorCode.NoImportableFile));\r\n                    return;\r\n                }\r\n                RunTaskAsync (() => {\r\n                    let mainFile = importableFiles[mainFileIndex];\r\n                    this.ImportLoadedMainFile (mainFile, settings, callbacks);\r\n                });\r\n            });\r\n        }\r\n    }\r\n\r\n    ImportLoadedMainFile (mainFile, settings, callbacks)\r\n    {\r\n        if (mainFile === null || mainFile.file === null || mainFile.file.content === null) {\r\n            let error = new ImportError (ImportErrorCode.FailedToLoadFile);\r\n            if (mainFile !== null && mainFile.file !== null) {\r\n                error.mainFile = mainFile.file.name;\r\n            }\r\n            callbacks.onImportError (error);\r\n            return;\r\n        }\r\n\r\n        this.model = null;\r\n        this.usedFiles = [];\r\n        this.missingFiles = [];\r\n        this.usedFiles.push (mainFile.file.name);\r\n\r\n        let importer = mainFile.importer;\r\n        let fileAccessor = new ImporterFileAccessor ((fileName) => {\r\n            let fileBuffer = null;\r\n            let file = this.fileList.FindFileByPath (fileName);\r\n            if (file === null || file.content === null) {\r\n                this.missingFiles.push (fileName);\r\n                fileBuffer = null;\r\n            } else {\r\n                this.usedFiles.push (fileName);\r\n                fileBuffer = file.content;\r\n            }\r\n            return fileBuffer;\r\n        });\r\n\r\n        importer.Import (mainFile.file.name, mainFile.file.extension, mainFile.file.content, {\r\n            getDefaultLineMaterialColor : () => {\r\n                return settings.defaultLineColor;\r\n            },\r\n            getDefaultMaterialColor : () => {\r\n                return settings.defaultColor;\r\n            },\r\n            getFileBuffer : (filePath) => {\r\n                return fileAccessor.GetFileBuffer (filePath);\r\n            },\r\n            onSuccess : () => {\r\n                this.model = importer.GetModel ();\r\n                let result = new ImportResult ();\r\n                result.mainFile = mainFile.file.name;\r\n                result.model = this.model;\r\n                result.usedFiles = this.usedFiles;\r\n                result.missingFiles = this.missingFiles;\r\n                result.upVector = importer.GetUpDirection ();\r\n                callbacks.onImportSuccess (result);\r\n            },\r\n            onError : () => {\r\n                let error = new ImportError (ImportErrorCode.ImportFailed);\r\n                error.mainFile = mainFile.file.name;\r\n                error.message = importer.GetErrorMessage ();\r\n                callbacks.onImportError (error);\r\n            },\r\n            onComplete : () => {\r\n                importer.Clear ();\r\n            }\r\n        });\r\n    }\r\n\r\n    DecompressArchives (fileList, onReady)\r\n    {\r\n        let files = fileList.GetFiles ();\r\n        let archives = [];\r\n        for (let file of files) {\r\n            if (file.extension === 'zip') {\r\n                archives.push (file);\r\n            }\r\n        }\r\n        if (archives.length === 0) {\r\n            onReady ();\r\n            return;\r\n        }\r\n        for (let i = 0; i < archives.length; i++) {\r\n            const archiveFile = archives[i];\r\n            const archiveBuffer = new Uint8Array (archiveFile.content);\r\n            const decompressed = fflate.unzipSync (archiveBuffer);\r\n            for (const fileName in decompressed) {\r\n                if (Object.prototype.hasOwnProperty.call (decompressed, fileName)) {\r\n                    let file = new ImporterFile (fileName, FileSource.Decompressed, null);\r\n                    file.SetContent (decompressed[fileName].buffer);\r\n                    fileList.AddFile (file);\r\n                }\r\n            }\r\n        }\r\n        onReady ();\r\n    }\r\n\r\n    GetFileList ()\r\n    {\r\n        return this.fileList;\r\n    }\r\n\r\n    HasImportableFile (fileList)\r\n    {\r\n        let importableFiles = this.GetImportableFiles (fileList);\r\n        return importableFiles.length > 0;\r\n    }\r\n\r\n    GetImportableFiles (fileList)\r\n    {\r\n        function FindImporter (file, importers)\r\n        {\r\n            for (let importerIndex = 0; importerIndex < importers.length; importerIndex++) {\r\n                let importer = importers[importerIndex];\r\n                if (importer.CanImportExtension (file.extension)) {\r\n                    return importer;\r\n                }\r\n            }\r\n            return null;\r\n        }\r\n\r\n        let importableFiles = [];\r\n        let files = fileList.GetFiles ();\r\n        for (let fileIndex = 0; fileIndex < files.length; fileIndex++) {\r\n            let file = files[fileIndex];\r\n            let importer = FindImporter (file, this.importers);\r\n            if (importer !== null) {\r\n                importableFiles.push ({\r\n                    file : file,\r\n                    importer : importer\r\n                });\r\n            }\r\n        }\r\n        return importableFiles;\r\n    }\r\n}\n\nclass ImporterThreeSvg extends ImporterThreeBase\r\n{\r\n    constructor ()\r\n    {\r\n        super ();\r\n    }\r\n\r\n    CanImportExtension (extension)\r\n    {\r\n        return extension === 'svg';\r\n    }\r\n\r\n    GetUpDirection ()\r\n    {\r\n        return Direction.Z;\r\n    }\r\n\r\n    CreateLoader (manager)\r\n    {\r\n        return new SVGLoader (manager);\r\n    }\r\n\r\n    GetMainObject (loadedObject)\r\n    {\r\n        function ShowFill (path)\r\n        {\r\n            const style = path.userData.style;\r\n            if (style.fill === undefined || style.fill === 'none') {\r\n                return false;\r\n            }\r\n            return true;\r\n        }\r\n\r\n        function GetOrCreateMaterial (materials, style, opacity)\r\n        {\r\n            let material = null;\r\n            for (let existingMaterial of materials) {\r\n                if (existingMaterial.style === style && existingMaterial.opacity === opacity) {\r\n                    material = existingMaterial.material;\r\n                    break;\r\n                }\r\n            }\r\n            if (material === null) {\r\n                material = new THREE.MeshPhongMaterial ({\r\n                    color: new THREE.Color ().setStyle (style),\r\n                    opacity: opacity,\r\n                    transparent: opacity < 1.0\r\n                });\r\n                materials.push ({\r\n                    style : style,\r\n                    opacity : opacity,\r\n                    material : material\r\n                });\r\n            }\r\n            return material;\r\n        }\r\n\r\n        let materials = [];\r\n\r\n        let object = new THREE.Object3D ();\r\n        object.rotation.x = Math.PI;\r\n\r\n        for (let path of loadedObject.paths) {\r\n            const shapes = SVGLoader.createShapes (path);\r\n            if (ShowFill (path)) {\r\n                let pathStyle = path.userData.style;\r\n                let pathMaterial = GetOrCreateMaterial (materials, pathStyle.fill, pathStyle.opacity);\r\n                for (const shape of shapes) {\r\n                    const geometry = new THREE.ExtrudeGeometry (shape, {\r\n                        depth: 10,\r\n                        bevelEnabled: false\r\n                    });\r\n                    const mesh = new THREE.Mesh (geometry, pathMaterial);\r\n                    mesh.name = path.userData.node.id;\r\n                    object.add (mesh);\r\n                }\r\n            }\r\n        }\r\n        return object;\r\n    }\r\n}\n\nclass GeneratorParams\r\n{\r\n    constructor ()\r\n    {\r\n        this.name = null;\r\n        this.material = null;\r\n    }\r\n\r\n    SetName (name)\r\n    {\r\n        this.name = name;\r\n        return this;\r\n    }\r\n\r\n    SetMaterial (material)\r\n    {\r\n        this.material = material;\r\n        return this;\r\n    }\r\n}\r\n\r\nclass Generator\r\n{\r\n    constructor (params)\r\n    {\r\n        this.params = params || new GeneratorParams ();\r\n        this.mesh = new Mesh ();\r\n        if (this.params.name !== null) {\r\n            this.mesh.SetName (this.params.name);\r\n        }\r\n        this.curve = null;\r\n    }\r\n\r\n    GetMesh ()\r\n    {\r\n        return this.mesh;\r\n    }\r\n\r\n    AddVertex (x, y, z)\r\n    {\r\n        let coord = new Coord3D (x, y, z);\r\n        return this.mesh.AddVertex (coord);\r\n    }\r\n\r\n    AddVertices (vertices)\r\n    {\r\n        let indices = [];\r\n        for (let i = 0; i < vertices.length; i++) {\r\n            let vertex = vertices[i];\r\n            indices.push (this.AddVertex (vertex.x, vertex.y, vertex.z));\r\n        }\r\n        return indices;\r\n    }\r\n\r\n    SetCurve (curve)\r\n    {\r\n        this.curve = curve;\r\n    }\r\n\r\n    ResetCurve ()\r\n    {\r\n        this.curve = null;\r\n    }\r\n\r\n    AddTriangle (v0, v1, v2)\r\n    {\r\n        let triangle = new Triangle (v0, v1, v2);\r\n        if (this.params.material !== null) {\r\n            triangle.mat = this.params.material;\r\n        }\r\n        if (this.curve !== null) {\r\n            triangle.SetCurve (this.curve);\r\n        }\r\n        return this.mesh.AddTriangle (triangle);\r\n    }\r\n\r\n    AddTriangleInverted (v0, v1, v2)\r\n    {\r\n        this.AddTriangle (v0, v2, v1);\r\n    }\r\n\r\n    AddConvexPolygon (vertices)\r\n    {\r\n        for (let vertexIndex = 0; vertexIndex < vertices.length - 2; vertexIndex++) {\r\n            this.AddTriangle (\r\n                vertices[0],\r\n                vertices[vertexIndex + 1],\r\n                vertices[vertexIndex + 2]\r\n            );\r\n        }\r\n    }\r\n\r\n    AddConvexPolygonInverted (vertices)\r\n    {\r\n        for (let vertexIndex = 0; vertexIndex < vertices.length - 2; vertexIndex++) {\r\n            this.AddTriangleInverted (\r\n                vertices[0],\r\n                vertices[vertexIndex + 1],\r\n                vertices[vertexIndex + 2]\r\n            );\r\n        }\r\n    }\r\n}\r\n\r\nclass GeneratorHelper\r\n{\r\n    constructor (generator)\r\n    {\r\n        this.generator = generator;\r\n    }\r\n\r\n    GenerateSurfaceBetweenPolygons (startIndices, endIndices)\r\n    {\r\n        if (startIndices.length !== endIndices.length) {\r\n            return;\r\n        }\r\n        const vertexCount = startIndices.length;\r\n        for (let i = 0; i < vertexCount; i++) {\r\n            const index = i;\r\n            const nextIndex = (i < vertexCount - 1) ? index + 1 : 0;\r\n            this.generator.AddConvexPolygon ([\r\n                startIndices[index],\r\n                startIndices[nextIndex],\r\n                endIndices[nextIndex],\r\n                endIndices[index]\r\n            ]);\r\n        }\r\n    }\r\n\r\n    GenerateTriangleFan (startIndices, endIndex)\r\n    {\r\n        const vertexCount = startIndices.length;\r\n        for (let i = 0; i < vertexCount; i++) {\r\n            const index = i;\r\n            const nextIndex = (i < vertexCount - 1) ? index + 1 : 0;\r\n            this.generator.AddTriangle (\r\n                endIndex,\r\n                startIndices[index],\r\n                startIndices[nextIndex]\r\n            );\r\n        }\r\n    }\r\n}\r\n\r\nfunction GetCylindricalCoord (radius, angle)\r\n{\r\n    return new Coord2D (\r\n        radius * Math.cos (angle),\r\n        radius * Math.sin (angle)\r\n    );\r\n}\r\n\r\nfunction GenerateCuboid (genParams, xSize, ySize, zSize)\r\n{\r\n    if (!IsPositive (xSize) || !IsPositive (ySize) || !IsPositive (zSize)) {\r\n        return null;\r\n    }\r\n\r\n    let generator = new Generator (genParams);\r\n\r\n    generator.AddVertex (0.0, 0.0, 0.0);\r\n    generator.AddVertex (xSize, 0.0, 0.0);\r\n    generator.AddVertex (xSize, ySize, 0.0);\r\n    generator.AddVertex (0.0, ySize, 0.0);\r\n    generator.AddVertex (0.0, 0.0, zSize);\r\n    generator.AddVertex (xSize, 0.0, zSize);\r\n    generator.AddVertex (xSize, ySize, zSize);\r\n    generator.AddVertex (0.0, ySize, zSize);\r\n\r\n    generator.AddConvexPolygon ([0, 3, 2, 1]);\r\n    generator.AddConvexPolygon ([0, 1, 5, 4]);\r\n    generator.AddConvexPolygon ([1, 2, 6, 5]);\r\n    generator.AddConvexPolygon ([2, 3, 7, 6]);\r\n    generator.AddConvexPolygon ([3, 0, 4, 7]);\r\n    generator.AddConvexPolygon ([4, 5, 6, 7]);\r\n\r\n    return generator.GetMesh ();\r\n}\r\n\r\nfunction GenerateCone (genParams, topRadius, bottomRadius, height, segments, smooth)\r\n{\r\n    if (IsNegative (topRadius) || IsNegative (bottomRadius)) {\r\n        return null;\r\n    }\r\n\r\n    if (!IsPositive (height) || segments < 3) {\r\n        return null;\r\n    }\r\n\r\n    let isZeroTop = IsZero (topRadius);\r\n    let isZeroBottom = IsZero (bottomRadius);\r\n    if (isZeroTop && isZeroBottom) {\r\n        return null;\r\n    }\r\n\r\n    let generator = new Generator (genParams);\r\n    let helper = new GeneratorHelper (generator);\r\n    const step = 2.0 * Math.PI / segments;\r\n    const curve = (smooth ? 1 : null);\r\n\r\n    let topPolygon = [];\r\n    if (isZeroTop) {\r\n        topPolygon.push (generator.AddVertex (0.0, 0.0, height));\r\n    } else {\r\n        for (let i = 0; i < segments; i++) {\r\n            let topVertex = GetCylindricalCoord (topRadius, i * step);\r\n            topPolygon.push (generator.AddVertex (topVertex.x, topVertex.y, height));\r\n        }\r\n    }\r\n\r\n    let bottomPolygon = [];\r\n    if (isZeroBottom) {\r\n        bottomPolygon.push (generator.AddVertex (0.0, 0.0, 0.0));\r\n    } else {\r\n        for (let i = 0; i < segments; i++) {\r\n            let bottomVertex = GetCylindricalCoord (bottomRadius, i * step);\r\n            bottomPolygon.push (generator.AddVertex (bottomVertex.x, bottomVertex.y, 0.0));\r\n        }\r\n    }\r\n\r\n    if (isZeroTop) {\r\n        generator.SetCurve (curve);\r\n        helper.GenerateTriangleFan (bottomPolygon, topPolygon[0]);\r\n        generator.ResetCurve ();\r\n        generator.AddConvexPolygonInverted (bottomPolygon);\r\n    } else if (isZeroBottom) {\r\n        generator.SetCurve (curve);\r\n        helper.GenerateTriangleFan (topPolygon.slice ().reverse (), bottomPolygon[0]);\r\n        generator.ResetCurve ();\r\n        generator.AddConvexPolygon (topPolygon);\r\n    } else {\r\n        generator.SetCurve (curve);\r\n        helper.GenerateSurfaceBetweenPolygons (bottomPolygon, topPolygon);\r\n        generator.ResetCurve ();\r\n        generator.AddConvexPolygonInverted (bottomPolygon);\r\n        generator.AddConvexPolygon (topPolygon);\r\n    }\r\n\r\n    return generator.GetMesh ();\r\n}\r\n\r\nfunction GenerateCylinder (genParams, radius, height, segments, smooth)\r\n{\r\n    return GenerateCone (genParams, radius, radius, height, segments, smooth);\r\n}\r\n\r\nfunction GenerateSphere (genParams, radius, segments, smooth)\r\n{\r\n    function GetSphericalCoord (radius, theta, phi)\r\n    {\r\n        return new Coord3D (\r\n            radius * Math.sin (theta) * Math.cos (phi),\r\n            radius * Math.sin (theta) * Math.sin (phi),\r\n            radius * Math.cos (theta)\r\n        );\r\n    }\r\n\r\n    if (!IsPositive (radius) || segments < 3) {\r\n        return null;\r\n    }\r\n\r\n    let generator = new Generator (genParams);\r\n    let helper = new GeneratorHelper (generator);\r\n\r\n    generator.SetCurve (smooth ? 1 : null);\r\n\r\n    let allLevelVertices = [];\r\n    let levels = segments + 1;\r\n    const levelStep = Math.PI / segments;\r\n\tconst cylindricalStep = 2.0 * Math.PI / segments;\r\n    for (let levelIndex = 1; levelIndex < levels - 1; levelIndex++) {\r\n        let levelVertices = [];\r\n        let theta = levelIndex * levelStep;\r\n        for (let cylindricalIndex = 0; cylindricalIndex < segments; cylindricalIndex++) {\r\n            let phi = cylindricalIndex * cylindricalStep;\r\n            let vertex = GetSphericalCoord (radius, theta, -phi);\r\n            levelVertices.push (generator.AddVertex (vertex.x, vertex.y, vertex.z));\r\n        }\r\n        if (levelIndex > 1) {\r\n            helper.GenerateSurfaceBetweenPolygons (allLevelVertices[allLevelVertices.length - 1], levelVertices);\r\n        }\r\n        allLevelVertices.push (levelVertices);\r\n    }\r\n\r\n    let topVertex = generator.AddVertex (0.0, 0.0, radius);\r\n    let bottomVertex = generator.AddVertex (0.0, 0.0, -radius);\r\n    helper.GenerateTriangleFan (allLevelVertices[0].slice ().reverse (), topVertex);\r\n    helper.GenerateTriangleFan (allLevelVertices[allLevelVertices.length - 1], bottomVertex);\r\n\r\n    generator.ResetCurve ();\r\n\r\n    return generator.GetMesh ();\r\n}\r\n\r\nfunction GeneratePlatonicSolid (genParams, type, radius)\r\n{\r\n    function AddVertex (generator, radius, x, y, z)\r\n    {\r\n        let vertex = new Coord3D (x, y, z);\r\n        vertex.MultiplyScalar (radius / vertex.Length ());\r\n        generator.AddVertex (vertex.x, vertex.y, vertex.z);\r\n    }\r\n\r\n    if (!IsPositive (radius)) {\r\n        return null;\r\n    }\r\n\r\n    let generator = new Generator (genParams);\r\n    if (type === 'tetrahedron') {\r\n        AddVertex (generator, radius, 1, 1, 1);\r\n        AddVertex (generator, radius, -1, -1, 1);\r\n        AddVertex (generator, radius, -1, 1, -1);\r\n        AddVertex (generator, radius, 1, -1, -1);\r\n        generator.AddTriangle (0, 1, 3);\r\n        generator.AddTriangle (0, 2, 1);\r\n        generator.AddTriangle (0, 3, 2);\r\n        generator.AddTriangle (1, 2, 3);\r\n    } else if (type === 'hexahedron') {\r\n        AddVertex (generator, radius, 1, 1, 1);\r\n        AddVertex (generator, radius, 1, 1, -1);\r\n        AddVertex (generator, radius, 1, -1, 1);\r\n        AddVertex (generator, radius, 1, -1, -1);\r\n        AddVertex (generator, radius, -1, 1, 1);\r\n        AddVertex (generator, radius, -1, 1, -1);\r\n        AddVertex (generator, radius, -1, -1, 1);\r\n        AddVertex (generator, radius, -1, -1, -1);\r\n        generator.AddConvexPolygon ([0, 1, 5, 4]);\r\n        generator.AddConvexPolygon ([0, 2, 3, 1]);\r\n        generator.AddConvexPolygon ([0, 4, 6, 2]);\r\n        generator.AddConvexPolygon ([1, 3, 7, 5]);\r\n        generator.AddConvexPolygon ([2, 6, 7, 3]);\r\n        generator.AddConvexPolygon ([4, 5, 7, 6]);\r\n    } else if (type === 'octahedron') {\r\n        AddVertex (generator, radius, 1, 0, 0);\r\n        AddVertex (generator, radius, -1, 0, 0);\r\n        AddVertex (generator, radius, 0, 1, 0);\r\n        AddVertex (generator, radius, 0, -1, 0);\r\n        AddVertex (generator, radius, 0, 0, 1);\r\n        AddVertex (generator, radius, 0, 0, -1);\r\n        generator.AddTriangle (0, 2, 4);\r\n        generator.AddTriangle (0, 3, 5);\r\n        generator.AddTriangle (0, 4, 3);\r\n        generator.AddTriangle (0, 5, 2);\r\n        generator.AddTriangle (1, 2, 5);\r\n        generator.AddTriangle (1, 3, 4);\r\n        generator.AddTriangle (1, 4, 2);\r\n        generator.AddTriangle (1, 5, 3);\r\n    } else if (type === 'dodecahedron') {\r\n        let c = (1.0 + Math.sqrt (5.0)) / 2.0;\r\n        let d = 1.0 / c;\r\n        AddVertex (generator, radius, 1, 1, 1);\r\n        AddVertex (generator, radius, 1, 1, -1);\r\n        AddVertex (generator, radius, 1, -1, 1);\r\n        AddVertex (generator, radius, -1, 1, 1);\r\n        AddVertex (generator, radius, 1, -1, -1);\r\n        AddVertex (generator, radius, -1, 1, -1);\r\n        AddVertex (generator, radius, -1, -1, 1);\r\n        AddVertex (generator, radius, -1, -1, -1);\r\n        AddVertex (generator, radius, 0, +d, +c);\r\n        AddVertex (generator, radius, 0, +d, -c);\r\n        AddVertex (generator, radius, 0, -d, +c);\r\n        AddVertex (generator, radius, 0, -d, -c);\r\n        AddVertex (generator, radius, +d, +c, 0);\r\n        AddVertex (generator, radius, +d, -c, 0);\r\n        AddVertex (generator, radius, -d, +c, 0);\r\n        AddVertex (generator, radius, -d, -c, 0);\r\n        AddVertex (generator, radius, +c, 0, +d);\r\n        AddVertex (generator, radius, -c, 0, +d);\r\n        AddVertex (generator, radius, +c, 0, -d);\r\n        AddVertex (generator, radius, -c, 0, -d);\r\n        generator.AddConvexPolygon ([0, 8, 10, 2, 16]);\r\n        generator.AddConvexPolygon ([0, 16, 18, 1, 12]);\r\n        generator.AddConvexPolygon ([0, 12, 14, 3, 8]);\r\n        generator.AddConvexPolygon ([1, 9, 5, 14, 12]);\r\n        generator.AddConvexPolygon ([1, 18, 4, 11, 9]);\r\n        generator.AddConvexPolygon ([2, 10, 6, 15, 13]);\r\n        generator.AddConvexPolygon ([2, 13, 4, 18, 16]);\r\n        generator.AddConvexPolygon ([3, 14, 5, 19, 17]);\r\n        generator.AddConvexPolygon ([3, 17, 6, 10, 8]);\r\n        generator.AddConvexPolygon ([4, 13, 15, 7, 11]);\r\n        generator.AddConvexPolygon ([5, 9, 11, 7, 19]);\r\n        generator.AddConvexPolygon ([6, 17, 19, 7, 15]);\r\n    } else if (type === 'icosahedron') {\r\n        let c = (1.0 + Math.sqrt (5.0)) / 2.0;\r\n        AddVertex (generator, radius, 0, 1, +c);\r\n        AddVertex (generator, radius, 0, 1, -c);\r\n        AddVertex (generator, radius, 0, -1, +c);\r\n        AddVertex (generator, radius, 0, -1, -c);\r\n        AddVertex (generator, radius, 1, +c, 0);\r\n        AddVertex (generator, radius, 1, -c, 0);\r\n        AddVertex (generator, radius, -1, +c, 0);\r\n        AddVertex (generator, radius, -1, -c, 0);\r\n        AddVertex (generator, radius, +c, 0, 1);\r\n        AddVertex (generator, radius, +c, 0, -1);\r\n        AddVertex (generator, radius, -c, 0, 1);\r\n        AddVertex (generator, radius, -c, 0, -1);\r\n        generator.AddTriangle (0, 2, 8);\r\n        generator.AddTriangle (0, 4, 6);\r\n        generator.AddTriangle (0, 6, 10);\r\n        generator.AddTriangle (0, 8, 4);\r\n        generator.AddTriangle (0, 10, 2);\r\n        generator.AddTriangle (1, 3, 11);\r\n        generator.AddTriangle (1, 4, 9);\r\n        generator.AddTriangle (1, 6, 4);\r\n        generator.AddTriangle (1, 9, 3);\r\n        generator.AddTriangle (1, 11, 6);\r\n        generator.AddTriangle (2, 5, 8);\r\n        generator.AddTriangle (2, 7, 5);\r\n        generator.AddTriangle (2, 10, 7);\r\n        generator.AddTriangle (3, 5, 7);\r\n        generator.AddTriangle (3, 7, 11);\r\n        generator.AddTriangle (3, 9, 5);\r\n        generator.AddTriangle (4, 8, 9);\r\n        generator.AddTriangle (5, 9, 8);\r\n        generator.AddTriangle (6, 11, 10);\r\n        generator.AddTriangle (7, 10, 11);\r\n    }\r\n    return generator.GetMesh ();\r\n}\n\nfunction GetTriangleArea (v0, v1, v2)\r\n{\r\n    const a = CoordDistance3D (v0, v1);\r\n    const b = CoordDistance3D (v1, v2);\r\n    const c = CoordDistance3D (v0, v2);\r\n    const s = (a + b + c) / 2.0;\r\n    const areaSquare = s * (s - a) * (s - b) * (s - c);\r\n    if (areaSquare < 0.0) {\r\n        return 0.0;\r\n    }\r\n    return Math.sqrt (areaSquare);\r\n}\r\n\r\nfunction GetTetrahedronSignedVolume (v0, v1, v2)\r\n{\r\n    return DotVector3D (v0, CrossVector3D (v1, v2)) / 6.0;\r\n}\r\n\r\nfunction CalculateVolume (object3D)\r\n{\r\n    if (object3D instanceof Model) {\r\n        let volume = 0.0;\r\n        object3D.EnumerateMeshInstances ((meshInstance) => {\r\n            volume += CalculateVolume (meshInstance);\r\n        });\r\n        return volume;\r\n    } else {\r\n        let volume = 0.0;\r\n        object3D.EnumerateTriangleVertices ((v0, v1, v2) => {\r\n            volume += GetTetrahedronSignedVolume (v0, v1, v2);\r\n        });\r\n        return volume;\r\n    }\r\n}\r\n\r\nfunction CalculateSurfaceArea (object3D)\r\n{\r\n    let surface = 0.0;\r\n    object3D.EnumerateTriangleVertices ((v0, v1, v2) => {\r\n        surface += GetTriangleArea (v0, v1, v2);\r\n    });\r\n    return surface;\r\n}\n\n/**\r\n * Camera navigation mode.\r\n * @enum\r\n */\r\nconst NavigationMode =\r\n{\r\n    /** Fixed up vector. */\r\n\tFixedUpVector : 1,\r\n    /** Free orbit. */\r\n\tFreeOrbit : 2\r\n};\r\n\r\n/**\r\n * Camera projection mode.\r\n * @enum\r\n */\r\nconst ProjectionMode =\r\n{\r\n    /** Perspective projection. */\r\n\tPerspective : 1,\r\n    /** Orthographic projection. */\r\n\tOrthographic : 2\r\n};\r\n\r\n/**\r\n * Camera object.\r\n */\r\nclass Camera\r\n{\r\n    /**\r\n     * @param {Coord3D} eye Eye position.\r\n     * @param {Coord3D} center Center position. Sometimes it's called target or look at position.\r\n     * @param {Coord3D} up Up vector.\r\n     * @param {number} fov Field of view in degrees.\r\n     */\r\n    constructor (eye, center, up, fov)\r\n    {\r\n        this.eye = eye;\r\n        this.center = center;\r\n        this.up = up;\r\n        this.fov = fov;\r\n    }\r\n\r\n    /**\r\n     * Creates a clone of the object.\r\n     * @returns {Camera}\r\n     */\r\n    Clone ()\r\n    {\r\n        return new Camera (\r\n            this.eye.Clone (),\r\n            this.center.Clone (),\r\n            this.up.Clone (),\r\n            this.fov\r\n        );\r\n    }\r\n}\r\n\r\nfunction CameraIsEqual3D (a, b)\r\n{\r\n\treturn CoordIsEqual3D (a.eye, b.eye) && CoordIsEqual3D (a.center, b.center) && CoordIsEqual3D (a.up, b.up) && IsEqual (a.fov, b.fov);\r\n}\n\nconst LineThresholdInPixels = 10.0;\r\n\r\nconst IntersectionMode =\r\n{\r\n\tMeshOnly : 1,\r\n    MeshAndLine : 2\r\n};\r\n\r\nfunction SetThreeMeshPolygonOffset (mesh, offset)\r\n{\r\n    function SetMaterialsPolygonOffset (materials, offset)\r\n    {\r\n        for (let material of materials) {\r\n            material.polygonOffset = offset;\r\n            material.polygonOffsetUnit = 1;\r\n            material.polygonOffsetFactor = 1;\r\n        }\r\n    }\r\n\r\n    SetMaterialsPolygonOffset (mesh.material, offset);\r\n    if (mesh.userData.threeMaterials) {\r\n        SetMaterialsPolygonOffset (mesh.userData.threeMaterials, offset);\r\n    }\r\n}\r\n\r\nclass ViewerModel\r\n{\r\n    constructor (scene)\r\n    {\r\n        this.scene = scene;\r\n        this.rootObject = null;\r\n    }\r\n\r\n    IsEmpty ()\r\n    {\r\n        return this.rootObject === null;\r\n    }\r\n\r\n    SetRootObject (rootObject)\r\n    {\r\n        if (this.rootObject !== null) {\r\n            this.Clear ();\r\n        }\r\n        this.rootObject = rootObject;\r\n        this.scene.add (this.rootObject);\r\n    }\r\n\r\n    GetRootObject ()\r\n    {\r\n        return this.rootObject;\r\n    }\r\n\r\n    AddObject (object)\r\n    {\r\n        if (this.rootObject === null) {\r\n            let newRootObject = new THREE.Object3D ();\r\n            this.SetRootObject (newRootObject);\r\n        }\r\n        this.rootObject.add (object);\r\n    }\r\n\r\n    Traverse (enumerator)\r\n    {\r\n        if (this.rootObject === null) {\r\n            return;\r\n        }\r\n        this.rootObject.traverse ((obj) => {\r\n            enumerator (obj);\r\n        });\r\n    }\r\n\r\n    UpdateWorldMatrix ()\r\n    {\r\n        if (this.rootObject !== null) {\r\n            this.rootObject.updateWorldMatrix (true, true);\r\n        }\r\n    }\r\n\r\n    Clear ()\r\n    {\r\n        DisposeThreeObjects (this.rootObject);\r\n        this.scene.remove (this.rootObject);\r\n        this.rootObject = null;\r\n    }\r\n}\r\n\r\n/**\r\n * Edge settings object.\r\n */\r\nclass EdgeSettings\r\n{\r\n    /**\r\n     * @param {boolean} showEdges Show edges.\r\n     * @param {RGBColor} edgeColor Color of the edges.\r\n     * @param {number} edgeThreshold Minimum angle between faces to show edges between them in.\r\n     * The value must be in degrees.\r\n     */\r\n    constructor (showEdges, edgeColor, edgeThreshold)\r\n    {\r\n        this.showEdges = showEdges;\r\n        this.edgeColor = edgeColor;\r\n        this.edgeThreshold = edgeThreshold;\r\n    }\r\n\r\n    /**\r\n     * Creates a clone of the object.\r\n     * @returns {EdgeSettings}\r\n     */\r\n    Clone ()\r\n    {\r\n        return new EdgeSettings (this.showEdges, this.edgeColor.Clone (), this.edgeThreshold);\r\n    }\r\n}\r\n\r\nclass ViewerMainModel\r\n{\r\n    constructor (scene)\r\n    {\r\n        this.scene = scene;\r\n\r\n        this.mainModel = new ViewerModel (this.scene);\r\n        this.edgeModel = new ViewerModel (this.scene);\r\n\r\n        this.edgeSettings = new EdgeSettings (false, new RGBColor (0, 0, 0), 1);\r\n        this.hasLines = false;\r\n        this.hasPolygonOffset = false;\r\n    }\r\n\r\n    SetMainObject (mainObject)\r\n    {\r\n        this.mainModel.SetRootObject (mainObject);\r\n        this.hasLines = false;\r\n        this.hasPolygonOffset = false;\r\n\r\n        this.EnumerateLines ((line) => {\r\n            this.hasLines = true;\r\n        });\r\n\r\n        if (this.edgeSettings.showEdges) {\r\n            this.GenerateEdgeModel ();\r\n        }\r\n        this.UpdatePolygonOffset ();\r\n    }\r\n\r\n    UpdateWorldMatrix ()\r\n    {\r\n        this.mainModel.UpdateWorldMatrix ();\r\n        this.edgeModel.UpdateWorldMatrix ();\r\n    }\r\n\r\n    SetEdgeSettings (edgeSettings)\r\n    {\r\n        let needToGenerate = false;\r\n        if (edgeSettings.showEdges && (!this.edgeSettings.showEdges || this.edgeSettings.edgeThreshold !== edgeSettings.edgeThreshold)) {\r\n            needToGenerate = true;\r\n        }\r\n\r\n        this.edgeSettings = edgeSettings;\r\n\r\n        if (this.mainModel.IsEmpty ()) {\r\n            return;\r\n        }\r\n\r\n        if (this.edgeSettings.showEdges) {\r\n            if (needToGenerate) {\r\n                this.ClearEdgeModel ();\r\n                this.GenerateEdgeModel ();\r\n            } else {\r\n                let edgeColor = ConvertColorToThreeColor (this.edgeSettings.edgeColor);\r\n                this.EnumerateEdges ((edge) => {\r\n                    edge.material.color = edgeColor;\r\n                });\r\n            }\r\n        } else {\r\n            this.ClearEdgeModel ();\r\n        }\r\n    }\r\n\r\n    GenerateEdgeModel ()\r\n    {\r\n        let edgeColor = ConvertColorToThreeColor (this.edgeSettings.edgeColor);\r\n\r\n        this.UpdateWorldMatrix ();\r\n        this.EnumerateMeshes ((mesh) => {\r\n            let edges = new THREE.EdgesGeometry (mesh.geometry, this.edgeSettings.edgeThreshold);\r\n            let line = new THREE.LineSegments (edges, new THREE.LineBasicMaterial ({\r\n                color: edgeColor\r\n            }));\r\n            line.applyMatrix4 (mesh.matrixWorld);\r\n            line.userData = mesh.userData;\r\n            line.visible = mesh.visible;\r\n            this.edgeModel.AddObject (line);\r\n        });\r\n\r\n        this.UpdatePolygonOffset ();\r\n    }\r\n\r\n    GetBoundingBox (needToProcess)\r\n    {\r\n        let hasMesh = false;\r\n        let boundingBox = new THREE.Box3 ();\r\n        this.EnumerateMeshesAndLines ((mesh) => {\r\n            if (needToProcess (mesh.userData)) {\r\n                boundingBox.union (new THREE.Box3 ().setFromObject (mesh));\r\n                hasMesh = true;\r\n            }\r\n        });\r\n        if (!hasMesh) {\r\n            return null;\r\n        }\r\n        return boundingBox;\r\n    }\r\n\r\n    GetBoundingSphere (needToProcess)\r\n    {\r\n        let boundingBox = this.GetBoundingBox (needToProcess);\r\n        if (boundingBox === null) {\r\n            return null;\r\n        }\r\n\r\n        let boundingSphere = new THREE.Sphere ();\r\n        boundingBox.getBoundingSphere (boundingSphere);\r\n        return boundingSphere;\r\n    }\r\n\r\n    Clear ()\r\n    {\r\n        this.mainModel.Clear ();\r\n        this.ClearEdgeModel ();\r\n    }\r\n\r\n    ClearEdgeModel ()\r\n    {\r\n        if (this.edgeModel.IsEmpty ()) {\r\n            return;\r\n        }\r\n\r\n        this.UpdatePolygonOffset ();\r\n        this.edgeModel.Clear ();\r\n    }\r\n\r\n    EnumerateMeshes (enumerator)\r\n    {\r\n        this.mainModel.Traverse ((obj) => {\r\n            if (obj.isMesh) {\r\n                enumerator (obj);\r\n            }\r\n        });\r\n    }\r\n\r\n    EnumerateLines (enumerator)\r\n    {\r\n        this.mainModel.Traverse ((obj) => {\r\n            if (obj.isLineSegments) {\r\n                enumerator (obj);\r\n            }\r\n        });\r\n    }\r\n\r\n    EnumerateMeshesAndLines (enumerator)\r\n    {\r\n        this.mainModel.Traverse ((obj) => {\r\n            if (obj.isMesh) {\r\n                enumerator (obj);\r\n            } else if (obj.isLineSegments) {\r\n                enumerator (obj);\r\n            }\r\n        });\r\n    }\r\n\r\n    EnumerateEdges (enumerator)\r\n    {\r\n        this.edgeModel.Traverse ((obj) => {\r\n            if (obj.isLineSegments) {\r\n                enumerator (obj);\r\n            }\r\n        });\r\n    }\r\n\r\n    HasLinesOrEdges ()\r\n    {\r\n        return this.hasLines || this.edgeSettings.showEdges;\r\n    }\r\n\r\n    UpdatePolygonOffset ()\r\n    {\r\n        let needPolygonOffset = this.HasLinesOrEdges ();\r\n        if (needPolygonOffset !== this.hasPolygonOffset) {\r\n            this.EnumerateMeshes ((mesh) => {\r\n                SetThreeMeshPolygonOffset (mesh, needPolygonOffset);\r\n            });\r\n            this.hasPolygonOffset = needPolygonOffset;\r\n        }\r\n    }\r\n\r\n    GetMeshIntersectionUnderMouse (intersectionMode, mouseCoords, camera, width, height)\r\n    {\r\n        if (this.mainModel.IsEmpty ()) {\r\n            return null;\r\n        }\r\n\r\n        if (mouseCoords.x < 0.0 || mouseCoords.x > width || mouseCoords.y < 0.0 || mouseCoords.y > height) {\r\n            return null;\r\n        }\r\n\r\n        let mousePos = new THREE.Vector2 ();\r\n        mousePos.x = (mouseCoords.x / width) * 2 - 1;\r\n        mousePos.y = -(mouseCoords.y / height) * 2 + 1;\r\n\r\n        let raycaster = new THREE.Raycaster ();\r\n        raycaster.setFromCamera (mousePos, camera);\r\n        raycaster.params.Line.threshold = 10.0;\r\n\r\n        let iSectObjects = raycaster.intersectObject (this.mainModel.GetRootObject (), true);\r\n        for (let i = 0; i < iSectObjects.length; i++) {\r\n            let iSectObject = iSectObjects[i];\r\n            if (!iSectObject.object.visible) {\r\n                continue;\r\n            }\r\n            if (iSectObject.object.isMesh) {\r\n                return iSectObject;\r\n            } else if (iSectObject.object.isLineSegments) {\r\n                if (intersectionMode === IntersectionMode.MeshOnly) {\r\n                    continue;\r\n                }\r\n                let distance = GetLineSegmentsProjectedDistance (camera, width, height, iSectObject.object, mouseCoords);\r\n                if (distance > LineThresholdInPixels) {\r\n                    continue;\r\n                }\r\n                return iSectObject;\r\n            }\r\n        }\r\n\r\n        return null;\r\n    }\r\n}\n\nlet ParameterConverter =\r\n{\r\n    IntegerToString (integer)\r\n    {\r\n        return integer.toString ();\r\n    },\r\n\r\n    StringToInteger (str)\r\n    {\r\n        return parseInt (str, 10);\r\n    },\r\n\r\n    NumberToString (number)\r\n    {\r\n        let precision = 5;\r\n        return number.toFixed (precision);\r\n    },\r\n\r\n    StringToNumber (str)\r\n    {\r\n        return parseFloat (str);\r\n    },\r\n\r\n    ModelUrlsToString : function (urls)\r\n    {\r\n        if (urls === null) {\r\n            return null;\r\n        }\r\n        return urls.join (',');\r\n    },\r\n\r\n    StringToModelUrls : function (str)\r\n    {\r\n        if (str === null || str.length === 0) {\r\n            return null;\r\n        }\r\n        return str.split (',');\r\n    },\r\n\r\n    CameraToString : function (camera)\r\n    {\r\n        if (camera === null) {\r\n            return null;\r\n        }\r\n        let cameraParameters = [\r\n            this.NumberToString (camera.eye.x), this.NumberToString (camera.eye.y), this.NumberToString (camera.eye.z),\r\n            this.NumberToString (camera.center.x), this.NumberToString (camera.center.y), this.NumberToString (camera.center.z),\r\n            this.NumberToString (camera.up.x), this.NumberToString (camera.up.y), this.NumberToString (camera.up.z),\r\n            this.NumberToString (camera.fov)\r\n        ].join (',');\r\n        return cameraParameters;\r\n    },\r\n\r\n    ProjectionModeToString : function (projectionMode)\r\n    {\r\n        if (projectionMode === ProjectionMode.Perspective) {\r\n            return 'perspective';\r\n        } else if (projectionMode === ProjectionMode.Orthographic) {\r\n            return 'orthographic';\r\n        }\r\n        return null;\r\n    },\r\n\r\n    StringToCamera : function (str)\r\n    {\r\n        if (str === null || str.length === 0) {\r\n            return null;\r\n        }\r\n        let paramParts = str.split (',');\r\n        if (paramParts.length !== 9 && paramParts.length !== 10) {\r\n            return null;\r\n        }\r\n\r\n        let fieldOfView = 45.0;\r\n        if (paramParts.length >= 10) {\r\n            fieldOfView = this.StringToNumber (paramParts[9]);\r\n        }\r\n\r\n        let camera = new Camera (\r\n            new Coord3D (this.StringToNumber (paramParts[0]), this.StringToNumber (paramParts[1]), this.StringToNumber (paramParts[2])),\r\n            new Coord3D (this.StringToNumber (paramParts[3]), this.StringToNumber (paramParts[4]), this.StringToNumber (paramParts[5])),\r\n            new Coord3D (this.StringToNumber (paramParts[6]), this.StringToNumber (paramParts[7]), this.StringToNumber (paramParts[8])),\r\n            fieldOfView\r\n        );\r\n        return camera;\r\n    },\r\n\r\n    StringToProjectionMode : function (str)\r\n    {\r\n        if (str === 'perspective') {\r\n            return ProjectionMode.Perspective;\r\n        } else if (str === 'orthographic') {\r\n            return ProjectionMode.Orthographic;\r\n        }\r\n        return null;\r\n    },\r\n\r\n    RGBColorToString : function (color)\r\n    {\r\n        if (color === null) {\r\n            return null;\r\n        }\r\n        return [\r\n            this.IntegerToString (color.r),\r\n            this.IntegerToString (color.g),\r\n            this.IntegerToString (color.b)\r\n        ].join (',');\r\n    },\r\n\r\n    RGBAColorToString : function (color)\r\n    {\r\n        if (color === null) {\r\n            return null;\r\n        }\r\n        return [\r\n            this.IntegerToString (color.r),\r\n            this.IntegerToString (color.g),\r\n            this.IntegerToString (color.b),\r\n            this.IntegerToString (color.a)\r\n        ].join (',');\r\n    },\r\n\r\n    StringToRGBColor : function (str)\r\n    {\r\n        if (str === null || str.length === 0) {\r\n            return null;\r\n        }\r\n        let paramParts = str.split (',');\r\n        if (paramParts.length !== 3) {\r\n            return null;\r\n        }\r\n        return new RGBColor (\r\n            this.StringToInteger (paramParts[0]),\r\n            this.StringToInteger (paramParts[1]),\r\n            this.StringToInteger (paramParts[2])\r\n        );\r\n    },\r\n\r\n    StringToRGBAColor : function (str)\r\n    {\r\n        if (str === null || str.length === 0) {\r\n            return null;\r\n        }\r\n        let paramParts = str.split (',');\r\n        if (paramParts.length !== 3 && paramParts.length !== 4) {\r\n            return null;\r\n        }\r\n        let color = new RGBAColor (\r\n            this.StringToInteger (paramParts[0]),\r\n            this.StringToInteger (paramParts[1]),\r\n            this.StringToInteger (paramParts[2]),\r\n            255\r\n        );\r\n        if (paramParts.length === 4) {\r\n            color.a = this.StringToInteger (paramParts[3]);\r\n        }\r\n        return color;\r\n    },\r\n\r\n    EnvironmentSettingsToString (environmentSettings)\r\n    {\r\n        if (environmentSettings === null) {\r\n            return null;\r\n        }\r\n        let environmentSettingsParameters = [\r\n            environmentSettings.environmentMapName,\r\n            environmentSettings.backgroundIsEnvMap ? 'on' : 'off'\r\n        ].join (',');\r\n        return environmentSettingsParameters;\r\n    },\r\n\r\n    StringToEnvironmentSettings : function (str)\r\n    {\r\n        if (str === null || str.length === 0) {\r\n            return null;\r\n        }\r\n        let paramParts = str.split (',');\r\n        if (paramParts.length !== 2) {\r\n            return null;\r\n        }\r\n        let environmentSettings = {\r\n            environmentMapName : paramParts[0],\r\n            backgroundIsEnvMap : paramParts[1] === 'on' ? true : false\r\n        };\r\n        return environmentSettings;\r\n    },\r\n\r\n    EdgeSettingsToString : function (edgeSettings)\r\n    {\r\n        if (edgeSettings === null) {\r\n            return null;\r\n        }\r\n        let edgeSettingsParameters = [\r\n            edgeSettings.showEdges ? 'on' : 'off',\r\n            this.RGBColorToString (edgeSettings.edgeColor),\r\n            this.IntegerToString (edgeSettings.edgeThreshold),\r\n        ].join (',');\r\n        return edgeSettingsParameters;\r\n    },\r\n\r\n    StringToEdgeSettings : function (str)\r\n    {\r\n        if (str === null || str.length === 0) {\r\n            return null;\r\n        }\r\n        let paramParts = str.split (',');\r\n        if (paramParts.length !== 5) {\r\n            return null;\r\n        }\r\n        let edgeSettings = new EdgeSettings (\r\n            paramParts[0] === 'on' ? true : false,\r\n            new RGBColor (\r\n                this.StringToInteger (paramParts[1]),\r\n                this.StringToInteger (paramParts[2]),\r\n                this.StringToInteger (paramParts[3])\r\n            ),\r\n            this.StringToInteger (paramParts[4])\r\n        );\r\n        return edgeSettings;\r\n    }\r\n};\r\n\r\nclass ParameterListBuilder\r\n{\r\n    constructor (separator)\r\n    {\r\n        this.separator = separator;\r\n        this.paramList = '';\r\n    }\r\n\r\n    AddModelUrls (urls)\r\n    {\r\n        this.AddUrlPart ('model', ParameterConverter.ModelUrlsToString (urls));\r\n        return this;\r\n    }\r\n\r\n    AddCamera (camera)\r\n    {\r\n        this.AddUrlPart ('camera', ParameterConverter.CameraToString (camera));\r\n        return this;\r\n    }\r\n\r\n    AddProjectionMode (projectionMode)\r\n    {\r\n        this.AddUrlPart ('projectionmode', ParameterConverter.ProjectionModeToString (projectionMode));\r\n        return this;\r\n    }\r\n\r\n    AddEnvironmentSettings (envSettings)\r\n    {\r\n        this.AddUrlPart ('envsettings', ParameterConverter.EnvironmentSettingsToString (envSettings));\r\n        return this;\r\n    }\r\n\r\n    AddBackgroundColor (background)\r\n    {\r\n        this.AddUrlPart ('backgroundcolor', ParameterConverter.RGBAColorToString (background));\r\n        return this;\r\n    }\r\n\r\n    AddDefaultColor (color)\r\n    {\r\n        this.AddUrlPart ('defaultcolor', ParameterConverter.RGBColorToString (color));\r\n        return this;\r\n    }\r\n\r\n    AddDefaultLineColor (color)\r\n    {\r\n        this.AddUrlPart ('defaultlinecolor', ParameterConverter.RGBColorToString (color));\r\n        return this;\r\n    }\r\n\r\n    AddEdgeSettings (edgeSettings)\r\n    {\r\n        this.AddUrlPart ('edgesettings', ParameterConverter.EdgeSettingsToString (edgeSettings));\r\n        return this;\r\n    }\r\n\r\n    AddUrlPart (keyword, urlPart)\r\n    {\r\n        if (keyword === null || urlPart === null) {\r\n            return;\r\n        }\r\n        if (this.paramList.length > 0) {\r\n            this.paramList += this.separator;\r\n        }\r\n        this.paramList += keyword + '=' + urlPart;\r\n    }\r\n\r\n    GetParameterList ()\r\n    {\r\n        return this.paramList;\r\n    }\r\n}\r\n\r\nclass ParameterListParser\r\n{\r\n    constructor (paramList, separator)\r\n    {\r\n        this.separator = separator;\r\n        this.paramList = paramList;\r\n    }\r\n\r\n    GetModelUrls ()\r\n    {\r\n        // detect legacy links\r\n        if (this.paramList.indexOf ('=') === -1) {\r\n            return this.paramList.split (',');\r\n        }\r\n\r\n        let keywordParams = this.GetKeywordParams ('model');\r\n        return ParameterConverter.StringToModelUrls (keywordParams);\r\n    }\r\n\r\n    GetCamera ()\r\n    {\r\n        let keywordParams = this.GetKeywordParams ('camera');\r\n        return ParameterConverter.StringToCamera (keywordParams);\r\n    }\r\n\r\n    GetProjectionMode ()\r\n    {\r\n        let keywordParams = this.GetKeywordParams ('cameramode'); // for compatibility\r\n        if (keywordParams === null) {\r\n            keywordParams = this.GetKeywordParams ('projectionmode');\r\n        }\r\n        return ParameterConverter.StringToProjectionMode (keywordParams);\r\n    }\r\n\r\n    GetEnvironmentSettings ()\r\n    {\r\n        let environmentSettingsParams = this.GetKeywordParams ('envsettings');\r\n        return ParameterConverter.StringToEnvironmentSettings (environmentSettingsParams);\r\n    }\r\n\r\n    GetBackgroundColor ()\r\n    {\r\n        let backgroundParams = this.GetKeywordParams ('backgroundcolor');\r\n        return ParameterConverter.StringToRGBAColor (backgroundParams);\r\n    }\r\n\r\n    GetDefaultColor ()\r\n    {\r\n        let colorParams = this.GetKeywordParams ('defaultcolor');\r\n        return ParameterConverter.StringToRGBColor (colorParams);\r\n    }\r\n\r\n    GetDefaultLineColor ()\r\n    {\r\n        let colorParams = this.GetKeywordParams ('defaultlinecolor');\r\n        return ParameterConverter.StringToRGBColor (colorParams);\r\n    }\r\n\r\n    GetEdgeSettings ()\r\n    {\r\n        let edgeSettingsParams = this.GetKeywordParams ('edgesettings');\r\n        return ParameterConverter.StringToEdgeSettings (edgeSettingsParams);\r\n    }\r\n\r\n    GetKeywordParams (keyword)\r\n    {\r\n        if (this.paramList === null || this.paramList.length === 0) {\r\n            return null;\r\n        }\r\n        let keywordToken = keyword + '=';\r\n        let urlParts = this.paramList.split (this.separator);\r\n        for (let i = 0; i < urlParts.length; i++) {\r\n            let urlPart = urlParts[i];\r\n            if (urlPart.startsWith (keywordToken)) {\r\n                return urlPart.substring (keywordToken.length);\r\n            }\r\n        }\r\n        return null;\r\n    }\r\n}\r\n\r\nfunction CreateUrlBuilder ()\r\n{\r\n    return new ParameterListBuilder ('$');\r\n}\r\n\r\nfunction CreateUrlParser (urlParams)\r\n{\r\n    return new ParameterListParser (urlParams, '$');\r\n}\r\n\r\nfunction CreateModelUrlParameters (urls)\r\n{\r\n    let builder = CreateUrlBuilder ();\r\n    builder.AddModelUrls (urls);\r\n    return builder.GetParameterList ();\r\n}\n\nconst MaterialGeometryType =\r\n{\r\n\tLine : 1,\r\n\tFace : 2\r\n};\r\n\r\nclass ModelToThreeConversionParams\r\n{\r\n\tconstructor ()\r\n\t{\r\n\t\tthis.forceMediumpForMaterials = false;\r\n\t}\r\n}\r\n\r\nclass ModelToThreeConversionOutput\r\n{\r\n\tconstructor ()\r\n\t{\r\n\t\tthis.defaultMaterials = [];\r\n\t\tthis.objectUrls = [];\r\n\t}\r\n}\r\n\r\nclass ThreeConversionStateHandler\r\n{\r\n\tconstructor (callbacks)\r\n\t{\r\n\t\tthis.callbacks = callbacks;\r\n\t\tthis.texturesNeeded = 0;\r\n\t\tthis.texturesLoaded = 0;\r\n\t\tthis.threeObject = null;\r\n\t}\r\n\r\n\tOnTextureNeeded ()\r\n\t{\r\n\t\tthis.texturesNeeded += 1;\r\n\t}\r\n\r\n\tOnTextureLoaded ()\r\n\t{\r\n\t\tthis.texturesLoaded += 1;\r\n\t\tthis.callbacks.onTextureLoaded ();\r\n\t\tthis.Finish ();\r\n\t}\r\n\r\n\tOnModelLoaded (threeObject)\r\n\t{\r\n\t\tthis.threeObject = threeObject;\r\n\t\tthis.Finish ();\r\n\t}\r\n\r\n\tFinish ()\r\n\t{\r\n\t\tif (this.threeObject !== null && this.texturesNeeded === this.texturesLoaded) {\r\n\t\t\tthis.callbacks.onModelLoaded (this.threeObject);\r\n\t\t}\r\n\t}\r\n}\r\n\r\nclass ThreeNodeTree\r\n{\r\n\tconstructor (model, threeRootNode)\r\n\t{\r\n\t\tthis.model = model;\r\n\t\tthis.threeNodeItems = [];\r\n\t\tthis.AddNode (model.GetRootNode (), threeRootNode);\r\n\t}\r\n\r\n\tAddNode (node, threeNode)\r\n\t{\r\n\t\tlet matrix = node.GetTransformation ().GetMatrix ();\r\n\t\tlet threeMatrix = new THREE.Matrix4 ().fromArray (matrix.Get ());\r\n\t\tthreeNode.applyMatrix4 (threeMatrix);\r\n\r\n\t\tfor (let childNode of node.GetChildNodes ()) {\r\n\t\t\tlet threeChildNode = new THREE.Object3D ();\r\n\t\t\tthreeNode.add (threeChildNode);\r\n\t\t\tthis.AddNode (childNode, threeChildNode);\r\n\t\t}\r\n\t\tfor (let meshIndex of node.GetMeshIndices ()) {\r\n\t\t\tlet id = new MeshInstanceId (node.GetId (), meshIndex);\r\n\t\t\tlet mesh = this.model.GetMesh (meshIndex);\r\n\t\t\tthis.threeNodeItems.push ({\r\n\t\t\t\tmeshInstance : new MeshInstance (id, node, mesh),\r\n\t\t\t\tthreeNode : threeNode\r\n\t\t\t});\r\n\t\t}\r\n\t}\r\n\r\n\tGetNodeItems ()\r\n\t{\r\n\t\treturn this.threeNodeItems;\r\n\t}\r\n}\r\n\r\nclass ThreeMaterialHandler\r\n{\r\n\tconstructor (model, stateHandler, conversionParams, conversionOutput)\r\n\t{\r\n\t\tthis.model = model;\r\n\t\tthis.stateHandler = stateHandler;\r\n\t\tthis.conversionParams = conversionParams;\r\n\t\tthis.conversionOutput = conversionOutput;\r\n\r\n\t\tthis.shadingType = GetShadingType (model);\r\n\t\tthis.modelToThreeLineMaterial = new Map ();\r\n\t\tthis.modelToThreeMaterial = new Map ();\r\n\t}\r\n\r\n\tGetThreeMaterial (modelMaterialIndex, geometryType)\r\n\t{\r\n\t\tif (geometryType === MaterialGeometryType.Face) {\r\n\t\t\tif (!this.modelToThreeMaterial.has (modelMaterialIndex)) {\r\n\t\t\t\tlet threeMaterial = this.CreateThreeFaceMaterial (modelMaterialIndex);\r\n\t\t\t\tthis.modelToThreeMaterial.set (modelMaterialIndex, threeMaterial);\r\n\t\t\t}\r\n\t\t\treturn this.modelToThreeMaterial.get (modelMaterialIndex);\r\n\t\t} else if (geometryType === MaterialGeometryType.Line) {\r\n\t\t\tif (!this.modelToThreeLineMaterial.has (modelMaterialIndex)) {\r\n\t\t\t\tlet threeMaterial = this.CreateThreeLineMaterial (modelMaterialIndex);\r\n\t\t\t\tthis.modelToThreeLineMaterial.set (modelMaterialIndex, threeMaterial);\r\n\t\t\t}\r\n\t\t\treturn this.modelToThreeLineMaterial.get (modelMaterialIndex);\r\n\t\t} else {\r\n\t\t\treturn null;\r\n\t\t}\r\n\t}\r\n\r\n\tCreateThreeFaceMaterial (materialIndex)\r\n\t{\r\n\t\tlet material = this.model.GetMaterial (materialIndex);\r\n\t\tlet baseColor = ConvertColorToThreeColor (material.color);\r\n\t\tif (material.vertexColors) {\r\n\t\t\tbaseColor.setRGB (1.0, 1.0, 1.0);\r\n\t\t}\r\n\r\n\t\tlet materialParams = {\r\n\t\t\tcolor : baseColor,\r\n\t\t\tvertexColors : material.vertexColors,\r\n\t\t\topacity : material.opacity,\r\n\t\t\ttransparent : material.transparent,\r\n\t\t\talphaTest : material.alphaTest,\r\n\t\t\tside : THREE.DoubleSide\r\n\t\t};\r\n\r\n\t\tif (this.conversionParams.forceMediumpForMaterials) {\r\n\t\t\tmaterialParams.precision = 'mediump';\r\n\t\t}\r\n\r\n\t\tlet threeMaterial = null;\r\n\t\tif (this.shadingType === ShadingType.Phong) {\r\n\t\t\tthreeMaterial = new THREE.MeshPhongMaterial (materialParams);\r\n\t\t\tif (material.type === MaterialType.Phong) {\r\n\t\t\t\tlet specularColor = ConvertColorToThreeColor (material.specular);\r\n\t\t\t\tif (IsEqual (material.shininess, 0.0)) {\r\n\t\t\t\t\tspecularColor.setRGB (0.0, 0.0, 0.0);\r\n\t\t\t\t}\r\n\t\t\t\tthreeMaterial.specular = specularColor;\r\n\t\t\t\tthreeMaterial.shininess = material.shininess * 100.0;\r\n\t\t\t\tthis.LoadFaceTexture (threeMaterial, material.specularMap, (threeTexture) => {\r\n\t\t\t\t\tthreeMaterial.specularMap = threeTexture;\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t} else if (this.shadingType === ShadingType.Physical) {\r\n\t\t\tthreeMaterial = new THREE.MeshStandardMaterial (materialParams);\r\n\t\t\tif (material.type === MaterialType.Physical) {\r\n\t\t\t\tthreeMaterial.metalness = material.metalness;\r\n\t\t\t\tthreeMaterial.roughness = material.roughness;\r\n\t\t\t\tthis.LoadFaceTexture (threeMaterial, material.metalnessMap, (threeTexture) => {\r\n\t\t\t\t\tthreeMaterial.metalness = 1.0;\r\n\t\t\t\t\tthreeMaterial.roughness = 1.0;\r\n\t\t\t\t\tthreeMaterial.metalnessMap = threeTexture;\r\n\t\t\t\t\tthreeMaterial.roughnessMap = threeTexture;\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tlet emissiveColor = ConvertColorToThreeColor (material.emissive);\r\n\t\tthreeMaterial.emissive = emissiveColor;\r\n\r\n\t\tthis.LoadFaceTexture (threeMaterial, material.diffuseMap, (threeTexture) => {\r\n\t\t\tif (!material.multiplyDiffuseMap) {\r\n\t\t\t\tthreeMaterial.color.setRGB (1.0, 1.0, 1.0);\r\n\t\t\t}\r\n\t\t\tthreeMaterial.map = threeTexture;\r\n\t\t});\r\n\t\tthis.LoadFaceTexture (threeMaterial, material.bumpMap, (threeTexture) => {\r\n\t\t\tthreeMaterial.bumpMap = threeTexture;\r\n\t\t});\r\n\t\tthis.LoadFaceTexture (threeMaterial, material.normalMap, (threeTexture) => {\r\n\t\t\tthreeMaterial.normalMap = threeTexture;\r\n\t\t});\r\n\t\tthis.LoadFaceTexture (threeMaterial, material.emissiveMap, (threeTexture) => {\r\n\t\t\tthreeMaterial.emissiveMap = threeTexture;\r\n\t\t});\r\n\r\n\t\tif (material.source !== MaterialSource.Model) {\r\n\t\t\tthreeMaterial.userData.source = material.source;\r\n\t\t\tthis.conversionOutput.defaultMaterials.push (threeMaterial);\r\n\t\t}\r\n\r\n\t\treturn threeMaterial;\r\n\t}\r\n\r\n\tCreateThreeLineMaterial (materialIndex)\r\n\t{\r\n\t\tlet material = this.model.GetMaterial (materialIndex);\r\n\t\tlet baseColor = ConvertColorToThreeColor (material.color);\r\n\t\tlet materialParams = {\r\n\t\t\tcolor : baseColor,\r\n\t\t\topacity : material.opacity\r\n\t\t};\r\n\r\n\t\tif (this.conversionParams.forceMediumpForMaterials) {\r\n\t\t\tmaterialParams.precision = 'mediump';\r\n\t\t}\r\n\r\n\t\tlet threeMaterial = new THREE.LineBasicMaterial (materialParams);\r\n\t\tif (material.source !== MaterialSource.Model) {\r\n\t\t\tthreeMaterial.userData.source = material.source;\r\n\t\t\tthis.conversionOutput.defaultMaterials.push (threeMaterial);\r\n\t\t}\r\n\r\n\t\treturn threeMaterial;\r\n\t}\r\n\r\n\tLoadFaceTexture (threeMaterial, texture, onTextureLoaded)\r\n\t{\r\n\t\tfunction SetTextureParameters (texture, threeTexture)\r\n\t\t{\r\n\t\t\tthreeTexture.wrapS = THREE.RepeatWrapping;\r\n\t\t\tthreeTexture.wrapT = THREE.RepeatWrapping;\r\n\t\t\tthreeTexture.rotation = texture.rotation;\r\n\t\t\tthreeTexture.offset.x = texture.offset.x;\r\n\t\t\tthreeTexture.offset.y = texture.offset.y;\r\n\t\t\tthreeTexture.repeat.x = texture.scale.x;\r\n\t\t\tthreeTexture.repeat.y = texture.scale.y;\r\n\t\t}\r\n\r\n\t\tif (texture === null || !texture.IsValid ()) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tlet loader = new THREE.TextureLoader ();\r\n\t\tthis.stateHandler.OnTextureNeeded ();\r\n\t\tlet textureObjectUrl = null;\r\n\t\tif (texture.mimeType !== null) {\r\n\t\t\ttextureObjectUrl = CreateObjectUrlWithMimeType (texture.buffer, texture.mimeType);\r\n\t\t} else {\r\n\t\t\ttextureObjectUrl = CreateObjectUrl (texture.buffer);\r\n\t\t}\r\n\t\tthis.conversionOutput.objectUrls.push (textureObjectUrl);\r\n\t\tloader.load (textureObjectUrl,\r\n\t\t\t(threeTexture) => {\r\n\t\t\t\tSetTextureParameters (texture, threeTexture);\r\n\t\t\t\tthreeMaterial.needsUpdate = true;\r\n\t\t\t\tonTextureLoaded (threeTexture);\r\n\t\t\t\tthis.stateHandler.OnTextureLoaded ();\r\n\t\t\t},\r\n\t\t\tnull,\r\n\t\t\t(err) => {\r\n\t\t\t\tthis.stateHandler.OnTextureLoaded ();\r\n\t\t\t}\r\n\t\t);\r\n\t}\r\n}\r\n\r\nclass ThreeMeshMaterialHandler\r\n{\r\n\tconstructor (threeGeometry, geometryType, materialHandler)\r\n\t{\r\n\t\tthis.threeGeometry = threeGeometry;\r\n\t\tthis.geometryType = geometryType;\r\n\t\tthis.materialHandler = materialHandler;\r\n\r\n\t\tthis.itemVertexCount = null;\r\n\t\tif (geometryType === MaterialGeometryType.Face) {\r\n\t\t\tthis.itemVertexCount = 3;\r\n\t\t} else if (geometryType === MaterialGeometryType.Line) {\r\n\t\t\tthis.itemVertexCount = 2;\r\n\t\t}\r\n\r\n\t\tthis.meshThreeMaterials = [];\r\n\t\tthis.meshOriginalMaterials = [];\r\n\r\n\t\tthis.groupStart = null;\r\n\t\tthis.previousMaterialIndex = null;\r\n\t}\r\n\r\n\tProcessItem (itemIndex, materialIndex)\r\n\t{\r\n\t\tif (this.previousMaterialIndex !== materialIndex) {\r\n\t\t\tif (this.groupStart !== null) {\r\n\t\t\t\tthis.AddGroup (this.groupStart, itemIndex - 1);\r\n\t\t\t}\r\n\t\t\tthis.groupStart = itemIndex;\r\n\r\n\t\t\tlet threeMaterial = this.materialHandler.GetThreeMaterial (materialIndex, this.geometryType);\r\n\t\t\tthis.meshThreeMaterials.push (threeMaterial);\r\n\t\t\tthis.meshOriginalMaterials.push (materialIndex);\r\n\r\n\t\t\tthis.previousMaterialIndex = materialIndex;\r\n\t\t}\r\n\t}\r\n\r\n\tFinalize (itemCount)\r\n\t{\r\n\t\tthis.AddGroup (this.groupStart, itemCount - 1);\r\n\t}\r\n\r\n\tAddGroup (start, end)\r\n\t{\r\n\t\tlet materialIndex = this.meshThreeMaterials.length - 1;\r\n\t\tthis.threeGeometry.addGroup (start * this.itemVertexCount, (end - start + 1) * this.itemVertexCount, materialIndex);\r\n\t}\r\n}\r\n\r\nfunction ConvertModelToThreeObject (model, conversionParams, conversionOutput, callbacks)\r\n{\r\n\tfunction CreateThreeTriangleMesh (meshInstance, materialHandler)\r\n\t{\r\n\t\tlet mesh = meshInstance.mesh;\r\n\t\tlet triangleCount = mesh.TriangleCount ();\r\n\t\tif (triangleCount === 0) {\r\n\t\t\treturn null;\r\n\t\t}\r\n\r\n\t\tlet triangleIndices = [];\r\n\t\tfor (let i = 0; i < triangleCount; i++) {\r\n\t\t\ttriangleIndices.push (i);\r\n\t\t}\r\n\t\ttriangleIndices.sort ((a, b) => {\r\n\t\t\tlet aTriangle = mesh.GetTriangle (a);\r\n\t\t\tlet bTriangle = mesh.GetTriangle (b);\r\n\t\t\treturn aTriangle.mat - bTriangle.mat;\r\n\t\t});\r\n\r\n\t\tlet threeGeometry = new THREE.BufferGeometry ();\r\n\t\tlet meshMaterialHandler = new ThreeMeshMaterialHandler (threeGeometry, MaterialGeometryType.Face, materialHandler);\r\n\r\n\t\tlet vertices = [];\r\n\t\tlet vertexColors = [];\r\n\t\tlet normals = [];\r\n\t\tlet uvs = [];\r\n\r\n\t\tlet meshHasVertexColors = (mesh.VertexColorCount () > 0);\r\n\t\tlet meshHasUVs = (mesh.TextureUVCount () > 0);\r\n\t\tlet processedTriangleCount = 0;\r\n\t\tfor (let triangleIndex of triangleIndices) {\r\n\t\t\tlet triangle = mesh.GetTriangle (triangleIndex);\r\n\r\n\t\t\tlet v0 = mesh.GetVertex (triangle.v0);\r\n\t\t\tlet v1 = mesh.GetVertex (triangle.v1);\r\n\t\t\tlet v2 = mesh.GetVertex (triangle.v2);\r\n\t\t\tvertices.push (v0.x, v0.y, v0.z, v1.x, v1.y, v1.z, v2.x, v2.y, v2.z);\r\n\r\n\t\t\tif (triangle.HasVertexColors ()) {\r\n\t\t\t\tlet vc0 = ConvertColorToThreeColor (mesh.GetVertexColor (triangle.c0));\r\n\t\t\t\tlet vc1 = ConvertColorToThreeColor (mesh.GetVertexColor (triangle.c1));\r\n\t\t\t\tlet vc2 = ConvertColorToThreeColor (mesh.GetVertexColor (triangle.c2));\r\n\t\t\t\tvertexColors.push (\r\n\t\t\t\t\tvc0.r, vc0.g, vc0.b,\r\n\t\t\t\t\tvc1.r, vc1.g, vc1.b,\r\n\t\t\t\t\tvc2.r, vc2.g, vc2.b\r\n\t\t\t\t);\r\n\t\t\t} else if (meshHasVertexColors) {\r\n\t\t\t\tvertexColors.push (\r\n\t\t\t\t\t0.0, 0.0, 0.0,\r\n\t\t\t\t\t0.0, 0.0, 0.0,\r\n\t\t\t\t\t0.0, 0.0, 0.0\r\n\t\t\t\t);\r\n\t\t\t}\r\n\r\n\t\t\tlet n0 = mesh.GetNormal (triangle.n0);\r\n\t\t\tlet n1 = mesh.GetNormal (triangle.n1);\r\n\t\t\tlet n2 = mesh.GetNormal (triangle.n2);\r\n\t\t\tnormals.push (n0.x, n0.y, n0.z, n1.x, n1.y, n1.z, n2.x, n2.y, n2.z);\r\n\r\n\t\t\tif (triangle.HasTextureUVs ()) {\r\n\t\t\t\tlet u0 = mesh.GetTextureUV (triangle.u0);\r\n\t\t\t\tlet u1 = mesh.GetTextureUV (triangle.u1);\r\n\t\t\t\tlet u2 = mesh.GetTextureUV (triangle.u2);\r\n\t\t\t\tuvs.push (u0.x, u0.y, u1.x, u1.y, u2.x, u2.y);\r\n\t\t\t} else if (meshHasUVs) {\r\n\t\t\t\tuvs.push (0.0, 0.0, 0.0, 0.0, 0.0, 0.0);\r\n\t\t\t}\r\n\r\n\t\t\tmeshMaterialHandler.ProcessItem (processedTriangleCount, triangle.mat);\r\n\t\t\tprocessedTriangleCount += 1;\r\n\t\t}\r\n\t\tmeshMaterialHandler.Finalize (processedTriangleCount);\r\n\r\n\t\tthreeGeometry.setAttribute ('position', new THREE.Float32BufferAttribute (vertices, 3));\r\n\t\tif (vertexColors.length !== 0) {\r\n\t\t\tthreeGeometry.setAttribute ('color', new THREE.Float32BufferAttribute (vertexColors, 3));\r\n\t\t}\r\n\t\tthreeGeometry.setAttribute ('normal', new THREE.Float32BufferAttribute (normals, 3));\r\n\t\tif (uvs.length !== 0) {\r\n\t\t\tthreeGeometry.setAttribute ('uv', new THREE.Float32BufferAttribute (uvs, 2));\r\n\t\t}\r\n\r\n\t\tlet threeMesh = new THREE.Mesh (threeGeometry, meshMaterialHandler.meshThreeMaterials);\r\n\t\tthreeMesh.name = mesh.GetName ();\r\n\t\tthreeMesh.userData = {\r\n\t\t\toriginalMeshInstance : meshInstance,\r\n\t\t\toriginalMaterials : meshMaterialHandler.meshOriginalMaterials,\r\n\t\t\tthreeMaterials : null\r\n\t\t};\r\n\r\n\t\treturn threeMesh;\r\n\t}\r\n\r\n\tfunction CreateThreeLineMesh (meshInstance, materialHandler)\r\n\t{\r\n\t\tlet mesh = meshInstance.mesh;\r\n\t\tlet lineCount = mesh.LineCount ();\r\n\t\tif (lineCount === 0) {\r\n\t\t\treturn null;\r\n\t\t}\r\n\r\n\t\tlet lineIndices = [];\r\n\t\tfor (let i = 0; i < lineCount; i++) {\r\n\t\t\tlineIndices.push (i);\r\n\t\t}\r\n\t\tlineIndices.sort ((a, b) => {\r\n\t\t\tlet aLine = mesh.GetLine (a);\r\n\t\t\tlet bLine = mesh.GetLine (b);\r\n\t\t\treturn aLine.mat - bLine.mat;\r\n\t\t});\r\n\r\n\t\tlet threeGeometry = new THREE.BufferGeometry ();\r\n\t\tlet meshMaterialHandler = new ThreeMeshMaterialHandler (threeGeometry, MaterialGeometryType.Line, materialHandler);\r\n\r\n\t\tlet vertices = [];\r\n\t\tlet segmentCount = 0;\r\n\t\tfor (let i = 0; i < lineIndices.length; i++) {\r\n\t\t\tlet line = mesh.GetLine (lineIndices[i]);\r\n\t\t\tlet lineVertices = line.GetVertices ();\r\n\t\t\tfor (let i = 0; i < lineVertices.length; i++) {\r\n\t\t\t\tlet vertexIndex = lineVertices[i];\r\n\t\t\t\tlet vertex = mesh.GetVertex (vertexIndex);\r\n\t\t\t\tvertices.push (vertex.x, vertex.y, vertex.z);\r\n\t\t\t\tif (i > 0 && i < lineVertices.length - 1) {\r\n\t\t\t\t\tvertices.push (vertex.x, vertex.y, vertex.z);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tmeshMaterialHandler.ProcessItem (segmentCount, line.mat);\r\n\t\t\tsegmentCount += line.SegmentCount ();\r\n\t\t}\r\n\t\tmeshMaterialHandler.Finalize (segmentCount);\r\n\r\n\t\tthreeGeometry.setAttribute ('position', new THREE.Float32BufferAttribute (vertices, 3));\r\n\r\n\t\tlet threeLine = new THREE.LineSegments (threeGeometry, meshMaterialHandler.meshThreeMaterials);\r\n\t\tthreeLine.userData = {\r\n\t\t\toriginalMeshInstance : meshInstance,\r\n\t\t\toriginalMaterials : meshMaterialHandler.meshOriginalMaterials,\r\n\t\t\tthreeMaterials : null\r\n\t\t};\r\n\t\treturn threeLine;\r\n\t}\r\n\r\n\tfunction ConvertMesh (threeObject, meshInstance, materialHandler)\r\n\t{\r\n\t\tif (IsEmptyMesh (meshInstance.mesh)) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tlet triangleMesh = CreateThreeTriangleMesh (meshInstance, materialHandler);\r\n\t\tif (triangleMesh !== null) {\r\n\t\t\tthreeObject.add (triangleMesh);\r\n\t\t}\r\n\r\n\t\tlet lineMesh = CreateThreeLineMesh (meshInstance, materialHandler);\r\n\t\tif (lineMesh !== null) {\r\n\t\t\tthreeObject.add (lineMesh);\r\n\t\t}\r\n\t}\r\n\r\n\tfunction ConvertNodeHierarchy (threeRootNode, model, materialHandler, stateHandler)\r\n\t{\r\n\t\tlet nodeTree = new ThreeNodeTree (model, threeRootNode);\r\n\t\tlet threeNodeItems = nodeTree.GetNodeItems ();\r\n\r\n\t\tRunTasksBatch (threeNodeItems.length, 100, {\r\n\t\t\trunTask : (firstMeshInstanceIndex, lastMeshInstanceIndex, onReady) => {\r\n\t\t\t\tfor (let meshInstanceIndex = firstMeshInstanceIndex; meshInstanceIndex <= lastMeshInstanceIndex; meshInstanceIndex++) {\r\n\t\t\t\t\tlet nodeItem = threeNodeItems[meshInstanceIndex];\r\n\t\t\t\t\tConvertMesh (nodeItem.threeNode, nodeItem.meshInstance, materialHandler);\r\n\t\t\t\t}\r\n\t\t\t\tonReady ();\r\n\t\t\t},\r\n\t\t\tonReady : () => {\r\n\t\t\t\tstateHandler.OnModelLoaded (threeRootNode);\r\n\t\t\t}\r\n\t\t});\r\n\t}\r\n\r\n\tlet stateHandler = new ThreeConversionStateHandler (callbacks);\r\n\tlet materialHandler = new ThreeMaterialHandler (model, stateHandler, conversionParams, conversionOutput);\r\n\tlet threeObject = new THREE.Object3D ();\r\n\tConvertNodeHierarchy (threeObject, model, materialHandler, stateHandler);\r\n}\n\nclass ThreeModelLoader\r\n{\r\n    constructor ()\r\n    {\r\n        this.importer = new Importer ();\r\n        this.inProgress = false;\r\n        this.defaultMaterials = null;\r\n        this.objectUrls = null;\r\n        this.hasHighpDriverIssue = HasHighpDriverIssue ();\r\n    }\r\n\r\n    InProgress ()\r\n    {\r\n        return this.inProgress;\r\n    }\r\n\r\n    LoadModel (inputFiles, settings, callbacks)\r\n    {\r\n        if (this.inProgress) {\r\n            return;\r\n        }\r\n\r\n        this.inProgress = true;\r\n        this.RevokeObjectUrls ();\r\n        this.importer.ImportFiles (inputFiles, settings, {\r\n            onLoadStart : () => {\r\n                callbacks.onLoadStart ();\r\n            },\r\n            onFileListProgress : (current, total) => {\r\n                callbacks.onFileListProgress (current, total);\r\n            },\r\n            onFileLoadProgress : (current, total) => {\r\n                callbacks.onFileLoadProgress (current, total);\r\n            },\r\n            onImportStart : () => {\r\n                callbacks.onImportStart ();\r\n            },\r\n            onSelectMainFile : (fileNames, selectFile) => {\r\n                if (!callbacks.onSelectMainFile) {\r\n                    selectFile (0);\r\n                } else {\r\n                    callbacks.onSelectMainFile (fileNames, selectFile);\r\n                }\r\n            },\r\n            onImportSuccess : (importResult) => {\r\n                callbacks.onVisualizationStart ();\r\n                let params = new ModelToThreeConversionParams ();\r\n                params.forceMediumpForMaterials = this.hasHighpDriverIssue;\r\n                let output = new ModelToThreeConversionOutput ();\r\n                ConvertModelToThreeObject (importResult.model, params, output, {\r\n                    onTextureLoaded : () => {\r\n                        callbacks.onTextureLoaded ();\r\n                    },\r\n                    onModelLoaded : (threeObject) => {\r\n                        this.defaultMaterials = output.defaultMaterials;\r\n                        this.objectUrls = output.objectUrls;\r\n                        if (importResult.upVector === Direction.X) {\r\n                            let rotation = new THREE.Quaternion ().setFromAxisAngle (new THREE.Vector3 (0.0, 0.0, 1.0), Math.PI / 2.0);\r\n                            threeObject.quaternion.multiply (rotation);\r\n                        } else if (importResult.upVector === Direction.Z) {\r\n                            let rotation = new THREE.Quaternion ().setFromAxisAngle (new THREE.Vector3 (1.0, 0.0, 0.0), -Math.PI / 2.0);\r\n                            threeObject.quaternion.multiply (rotation);\r\n                        }\r\n                        callbacks.onModelFinished (importResult, threeObject);\r\n                        this.inProgress = false;\r\n                    }\r\n                });\r\n            },\r\n            onImportError : (importError) => {\r\n                callbacks.onLoadError (importError);\r\n                this.inProgress = false;\r\n            }\r\n        });\r\n    }\r\n\r\n    GetImporter ()\r\n    {\r\n        return this.importer;\r\n    }\r\n\r\n    GetDefaultMaterials ()\r\n    {\r\n        return this.defaultMaterials;\r\n    }\r\n\r\n    ReplaceDefaultMaterialsColor (defaultColor, defaultLineColor)\r\n    {\r\n        if (this.defaultMaterials !== null) {\r\n            for (let defaultMaterial of this.defaultMaterials) {\r\n                if (!defaultMaterial.vertexColors) {\r\n                    if (defaultMaterial.userData.source === MaterialSource.DefaultFace) {\r\n                        defaultMaterial.color = ConvertColorToThreeColor (defaultColor);\r\n                    } else if (defaultMaterial.userData.source === MaterialSource.DefaultLine) {\r\n                        defaultMaterial.color = ConvertColorToThreeColor (defaultLineColor);\r\n                    }\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    RevokeObjectUrls ()\r\n    {\r\n        if (this.objectUrls === null) {\r\n            return;\r\n        }\r\n        for (let objectUrl of this.objectUrls) {\r\n            RevokeObjectUrl (objectUrl);\r\n        }\r\n        this.objectUrls = null;\r\n    }\r\n\r\n    Destroy ()\r\n    {\r\n        this.RevokeObjectUrls ();\r\n        this.importer = null;\r\n    }\r\n}\n\nfunction GetIntegerFromStyle (parameter)\r\n{\r\n    return Math.round (parseFloat (parameter));\r\n}\r\n\r\nfunction GetDomElementExternalWidth (style)\r\n{\r\n    let padding = GetIntegerFromStyle (style.paddingLeft) + GetIntegerFromStyle (style.paddingRight);\r\n    let border = GetIntegerFromStyle (style.borderLeftWidth) + GetIntegerFromStyle (style.borderRightWidth);\r\n    let margin = GetIntegerFromStyle (style.marginLeft) + GetIntegerFromStyle (style.marginRight);\r\n    return padding + border + margin;\r\n}\r\n\r\nfunction GetDomElementExternalHeight (style)\r\n{\r\n    let padding = GetIntegerFromStyle (style.paddingTop) + GetIntegerFromStyle (style.paddingBottom);\r\n    let border = GetIntegerFromStyle (style.borderTopWidth) + GetIntegerFromStyle (style.borderBottomWidth);\r\n    let margin = GetIntegerFromStyle (style.marginTop) + GetIntegerFromStyle (style.marginBottom);\r\n    return padding + border + margin;\r\n}\r\n\r\nfunction GetDomElementInnerDimensions (element, outerWidth, outerHeight)\r\n{\r\n    let style = getComputedStyle (element);\r\n    let width = outerWidth - GetDomElementExternalWidth (style);\r\n    let height = outerHeight - GetDomElementExternalHeight (style);\r\n    return {\r\n        width : width,\r\n        height : height\r\n    };\r\n}\r\n\r\nfunction GetDomElementClientCoordinates (element, clientX, clientY)\r\n{\r\n    if (element.getBoundingClientRect) {\r\n        let clientRect = element.getBoundingClientRect ();\r\n        clientX -= clientRect.left;\r\n        clientY -= clientRect.top;\r\n    }\r\n    if (window.pageXOffset && window.pageYOffset) {\r\n        clientX += window.pageXOffset;\r\n        clientY += window.pageYOffset;\r\n    }\r\n    return (new Coord2D (clientX, clientY));\r\n}\r\n\r\nfunction CreateDomElement (elementType, className, innerHTML)\r\n{\r\n    let element = document.createElement (elementType);\r\n    if (className) {\r\n        element.className = className;\r\n    }\r\n    if (innerHTML) {\r\n        element.innerHTML = innerHTML;\r\n    }\r\n    return element;\r\n}\r\n\r\nfunction AddDomElement (parentElement, elementType, className, innerHTML)\r\n{\r\n    let element = CreateDomElement (elementType, className, innerHTML);\r\n    parentElement.appendChild (element);\r\n    return element;\r\n}\r\n\r\nfunction AddDiv (parentElement, className, innerHTML)\r\n{\r\n    return AddDomElement (parentElement, 'div', className, innerHTML);\r\n}\r\n\r\nfunction ClearDomElement (element)\r\n{\r\n    while (element.firstChild) {\r\n        element.removeChild (element.firstChild);\r\n    }\r\n}\r\n\r\nfunction InsertDomElementBefore (newElement, existingElement)\r\n{\r\n    existingElement.parentNode.insertBefore (newElement, existingElement);\r\n}\r\n\r\nfunction InsertDomElementAfter (newElement, existingElement)\r\n{\r\n    existingElement.parentNode.insertBefore (newElement, existingElement.nextSibling);\r\n}\r\n\r\nfunction ShowDomElement (element, show)\r\n{\r\n    if (show) {\r\n        element.style.display = 'block';\r\n    } else {\r\n        element.style.display = 'none';\r\n    }\r\n}\r\n\r\nfunction IsDomElementVisible (element)\r\n{\r\n    return element.offsetParent !== null;\r\n}\r\n\r\nfunction SetDomElementWidth (element, width)\r\n{\r\n    element.style.width = width.toString () + 'px';\r\n}\r\n\r\nfunction SetDomElementHeight (element, height)\r\n{\r\n    element.style.height = height.toString () + 'px';\r\n}\r\n\r\nfunction GetDomElementOuterWidth (element)\r\n{\r\n    let style = getComputedStyle (element);\r\n    return element.offsetWidth + GetIntegerFromStyle (style.marginLeft) + GetIntegerFromStyle (style.marginRight);\r\n}\r\n\r\nfunction GetDomElementOuterHeight (element)\r\n{\r\n    let style = getComputedStyle (element);\r\n    return element.offsetHeight + GetIntegerFromStyle (style.marginTop) + GetIntegerFromStyle (style.marginBottom);\r\n}\r\n\r\nfunction SetDomElementOuterWidth (element, width)\r\n{\r\n    let style = getComputedStyle (element);\r\n    SetDomElementWidth (element, width - GetDomElementExternalWidth (style));\r\n}\r\n\r\nfunction SetDomElementOuterHeight (element, height)\r\n{\r\n    let style = getComputedStyle (element);\r\n    SetDomElementHeight (element, height - GetDomElementExternalHeight (style));\r\n}\r\n\r\nfunction CreateDiv (className, innerHTML)\r\n{\r\n    return CreateDomElement ('div', className, innerHTML);\r\n}\n\nclass MouseInteraction\r\n{\r\n    constructor ()\r\n    {\r\n        this.prev = new Coord2D (0.0, 0.0);\r\n        this.curr = new Coord2D (0.0, 0.0);\r\n        this.diff = new Coord2D (0.0, 0.0);\r\n        this.buttons = [];\r\n    }\r\n\r\n    Down (canvas, ev)\r\n    {\r\n        this.buttons.push (ev.which);\r\n        this.curr = this.GetPositionFromEvent (canvas, ev);\r\n        this.prev = this.curr.Clone ();\r\n    }\r\n\r\n    Move (canvas, ev)\r\n    {\r\n        this.curr = this.GetPositionFromEvent (canvas, ev);\r\n\t\tthis.diff = SubCoord2D (this.curr, this.prev);\r\n\t\tthis.prev = this.curr.Clone ();\r\n\t}\r\n\r\n\tUp (canvas, ev)\r\n\t{\r\n\t\tlet buttonIndex = this.buttons.indexOf (ev.which);\r\n\t\tif (buttonIndex !== -1) {\r\n\t\t\tthis.buttons.splice (buttonIndex, 1);\r\n\t\t}\r\n\t\tthis.curr = this.GetPositionFromEvent (canvas, ev);\r\n\t}\r\n\r\n\tLeave (canvas, ev)\r\n\t{\r\n\t\tthis.buttons = [];\r\n\t\tthis.curr = this.GetPositionFromEvent (canvas, ev);\r\n\t}\r\n\r\n\tIsButtonDown ()\r\n\t{\r\n\t\treturn this.buttons.length > 0;\r\n\t}\r\n\r\n\tGetButton ()\r\n\t{\r\n\t\tlet length = this.buttons.length;\r\n\t\tif (length === 0) {\r\n\t\t\treturn 0;\r\n\t\t}\r\n\t\treturn this.buttons[length - 1];\r\n\t}\r\n\r\n\tGetPosition ()\r\n\t{\r\n\t\treturn this.curr;\r\n\t}\r\n\r\n\tGetMoveDiff ()\r\n\t{\r\n\t\treturn this.diff;\r\n\t}\r\n\r\n\tGetPositionFromEvent (canvas, ev)\r\n\t{\r\n\t\treturn GetDomElementClientCoordinates (canvas, ev.clientX, ev.clientY);\r\n\t}\r\n}\r\n\r\nclass TouchInteraction\r\n{\r\n\tconstructor ()\r\n\t{\r\n\t\tthis.prevPos = new Coord2D (0.0, 0.0);\r\n\t\tthis.currPos = new Coord2D (0.0, 0.0);\r\n\t\tthis.diffPos = new Coord2D (0.0, 0.0);\r\n\t\tthis.prevDist = 0.0;\r\n\t\tthis.currDist = 0.0;\r\n\t\tthis.diffDist = 0.0;\r\n\t\tthis.fingers = 0;\r\n\t}\r\n\r\n\tStart (canvas, ev)\r\n\t{\r\n\t\tif (ev.touches.length === 0) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tthis.fingers = ev.touches.length;\r\n\r\n\t\tthis.currPos = this.GetPositionFromEvent (canvas, ev);\r\n\t\tthis.prevPos = this.currPos.Clone ();\r\n\r\n\t\tthis.currDist = this.GetTouchDistanceFromEvent (canvas, ev);\r\n\t\tthis.prevDist = this.currDist;\r\n\t}\r\n\r\n\tMove (canvas, ev)\r\n\t{\r\n\t\tif (ev.touches.length === 0) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tthis.currPos = this.GetPositionFromEvent (canvas, ev);\r\n\t\tthis.diffPos = SubCoord2D (this.currPos, this.prevPos);\r\n\t\tthis.prevPos = this.currPos.Clone ();\r\n\r\n\t\tthis.currDist = this.GetTouchDistanceFromEvent (canvas, ev);\r\n\t\tthis.diffDist = this.currDist - this.prevDist;\r\n\t\tthis.prevDist = this.currDist;\r\n\t}\r\n\r\n\tEnd (canvas, ev)\r\n\t{\r\n\t\tif (ev.touches.length === 0) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tthis.fingers = 0;\r\n\t\tthis.currPos = this.GetPositionFromEvent (canvas, ev);\r\n\t\tthis.currDist = this.GetTouchDistanceFromEvent (canvas, ev);\r\n\t}\r\n\r\n\tIsFingerDown ()\r\n\t{\r\n\t\treturn this.fingers !== 0;\r\n\t}\r\n\r\n\tGetFingerCount ()\r\n\t{\r\n\t\treturn this.fingers;\r\n\t}\r\n\r\n\tGetPosition ()\r\n\t{\r\n\t\treturn this.currPos;\r\n\t}\r\n\r\n\tGetMoveDiff ()\r\n\t{\r\n\t\treturn this.diffPos;\r\n\t}\r\n\r\n\tGetDistanceDiff ()\r\n\t{\r\n\t\treturn this.diffDist;\r\n\t}\r\n\r\n\tGetPositionFromEvent (canvas, ev)\r\n\t{\r\n\t\tlet coord = null;\r\n\t\tif (ev.touches.length !== 0) {\r\n\t\t\tlet touchEv = ev.touches[0];\r\n\t\t\tcoord = GetDomElementClientCoordinates (canvas, touchEv.pageX, touchEv.pageY);\r\n\t\t}\r\n\t\treturn coord;\r\n\t}\r\n\r\n\tGetTouchDistanceFromEvent (canvas, ev)\r\n\t{\r\n\t\tif (ev.touches.length !== 2) {\r\n\t\t\treturn 0.0;\r\n\t\t}\r\n\t\tlet touchEv1 = ev.touches[0];\r\n\t\tlet touchEv2 = ev.touches[1];\r\n\t\tlet distance = CoordDistance2D (\r\n\t\t\tGetDomElementClientCoordinates (canvas, touchEv1.pageX, touchEv1.pageY),\r\n\t\t\tGetDomElementClientCoordinates (canvas, touchEv2.pageX, touchEv2.pageY)\r\n\t\t);\r\n\t\treturn distance;\r\n\t}\r\n}\r\n\r\nclass ClickDetector\r\n{\r\n\tconstructor ()\r\n\t{\r\n\t\tthis.isClick = false;\r\n\t\tthis.startPosition = null;\r\n\t}\r\n\r\n\tStart (startPosition)\r\n\t{\r\n\t\tthis.isClick = true;\r\n\t\tthis.startPosition = startPosition;\r\n\t}\r\n\r\n\tMove (currentPosition)\r\n\t{\r\n\t\tif (!this.isClick) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tif (this.startPosition !== null) {\r\n\t\t\tconst maxClickDistance = 3.0;\r\n\t\t\tconst currentDistance = CoordDistance2D (this.startPosition, currentPosition);\r\n\t\t\tif (currentDistance > maxClickDistance) {\r\n\t\t\t\tthis.Cancel ();\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\tthis.Cancel ();\r\n\t\t}\r\n\t}\r\n\r\n\tEnd ()\r\n\t{\r\n\t\tthis.startPosition = null;\r\n\t}\r\n\r\n\tCancel ()\r\n\t{\r\n\t\tthis.isClick = false;\r\n\t\tthis.startPosition = null;\r\n\t}\r\n\r\n\tIsClick ()\r\n\t{\r\n\t\treturn this.isClick;\r\n\t}\r\n}\r\n\r\nconst NavigationType =\r\n{\r\n\tNone : 0,\r\n\tOrbit : 1,\r\n\tPan : 2,\r\n\tZoom : 3\r\n};\r\n\r\nclass Navigation\r\n{\r\n\tconstructor (canvas, camera, callbacks)\r\n\t{\r\n\t\tthis.canvas = canvas;\r\n\t\tthis.camera = camera;\r\n\t\tthis.callbacks = callbacks;\r\n\t\tthis.navigationMode = NavigationMode.FixedUpVector;\r\n\r\n\t\tthis.mouse = new MouseInteraction ();\r\n\t\tthis.touch = new TouchInteraction ();\r\n\t\tthis.clickDetector = new ClickDetector ();\r\n\r\n\t\tthis.onMouseClick = null;\r\n\t\tthis.onMouseMove = null;\r\n\t\tthis.onContext = null;\r\n\r\n\t\tif (this.canvas.addEventListener) {\r\n\t\t\tthis.canvas.addEventListener ('mousedown', this.OnMouseDown.bind (this));\r\n\t\t\tthis.canvas.addEventListener ('wheel', this.OnMouseWheel.bind (this));\r\n\t\t\tthis.canvas.addEventListener ('touchstart', this.OnTouchStart.bind (this));\r\n\t\t\tthis.canvas.addEventListener ('touchmove', this.OnTouchMove.bind (this));\r\n\t\t\tthis.canvas.addEventListener ('touchcancel', this.OnTouchEnd.bind (this));\r\n\t\t\tthis.canvas.addEventListener ('touchend', this.OnTouchEnd.bind (this));\r\n\t\t\tthis.canvas.addEventListener ('contextmenu', this.OnContextMenu.bind (this));\r\n\t\t}\r\n\t\tif (document.addEventListener) {\r\n\t\t\tdocument.addEventListener ('mousemove', this.OnMouseMove.bind (this));\r\n\t\t\tdocument.addEventListener ('mouseup', this.OnMouseUp.bind (this));\r\n\t\t\tdocument.addEventListener ('mouseleave', this.OnMouseLeave.bind (this));\r\n\t\t}\r\n\t}\r\n\r\n\tSetMouseClickHandler (onMouseClick)\r\n\t{\r\n\t\tthis.onMouseClick = onMouseClick;\r\n\t}\r\n\r\n\tSetMouseMoveHandler (onMouseMove)\r\n\t{\r\n\t\tthis.onMouseMove = onMouseMove;\r\n\t}\r\n\r\n\tSetContextMenuHandler (onContext)\r\n\t{\r\n\t\tthis.onContext = onContext;\r\n\t}\r\n\r\n\tGetNavigationMode ()\r\n\t{\r\n\t\treturn this.navigationMode;\r\n\t}\r\n\r\n\tSetNavigationMode (navigationMode)\r\n\t{\r\n\t\tthis.navigationMode = navigationMode;\r\n\t}\r\n\r\n\tGetCamera ()\r\n\t{\r\n\t\treturn this.camera;\r\n\t}\r\n\r\n\tSetCamera (camera)\r\n\t{\r\n\t\tthis.camera = camera;\r\n\t}\r\n\r\n\tMoveCamera (newCamera, stepCount)\r\n\t{\r\n\t\tfunction Step (obj, steps, count, index)\r\n\t\t{\r\n\t\t\tobj.camera.eye = steps.eye[index];\r\n\t\t\tobj.camera.center = steps.center[index];\r\n\t\t\tobj.camera.up = steps.up[index];\r\n\t\t\tobj.Update ();\r\n\r\n\t\t\tif (index < count - 1) {\r\n\t\t\t\trequestAnimationFrame (() => {\r\n\t\t\t\t\tStep (obj, steps, count, index + 1);\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tif (newCamera === null) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tif (stepCount === 0 || CameraIsEqual3D (this.camera, newCamera)) {\r\n\t\t\tthis.camera = newCamera;\r\n\t\t} else {\r\n\t\t\tlet tweenFunc = ParabolicTweenFunction;\r\n\t\t\tlet steps = {\r\n\t\t\t\teye : TweenCoord3D (this.camera.eye, newCamera.eye, stepCount, tweenFunc),\r\n\t\t\t\tcenter : TweenCoord3D (this.camera.center, newCamera.center, stepCount, tweenFunc),\r\n\t\t\t\tup : TweenCoord3D (this.camera.up, newCamera.up, stepCount, tweenFunc)\r\n\t\t\t};\r\n\t\t\trequestAnimationFrame (() => {\r\n\t\t\t\tStep (this, steps, stepCount, 0);\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\tthis.Update ();\r\n\t}\r\n\r\n\tGetFitToSphereCamera (center, radius)\r\n\t{\r\n\t\tif (IsZero (radius)) {\r\n\t\t\treturn null;\r\n\t\t}\r\n\r\n\t\tlet fitCamera = this.camera.Clone ();\r\n\r\n\t\tlet offsetToOrigo = SubCoord3D (fitCamera.center, center);\r\n\t\tfitCamera.eye = SubCoord3D (fitCamera.eye, offsetToOrigo);\r\n\t\tfitCamera.center = center.Clone ();\r\n\r\n\t\tlet centerEyeDirection = SubCoord3D (fitCamera.eye, fitCamera.center).Normalize ();\r\n\t\tlet fieldOfView = this.camera.fov / 2.0;\r\n\t\tif (this.canvas.width < this.canvas.height) {\r\n\t\t\tfieldOfView = fieldOfView * this.canvas.width / this.canvas.height;\r\n\t\t}\r\n\t\tlet distance = radius / Math.sin (fieldOfView * DegRad);\r\n\r\n\t\tfitCamera.eye = fitCamera.center.Clone ().Offset (centerEyeDirection, distance);\r\n\r\n\t\treturn fitCamera;\r\n\t}\r\n\r\n\tOnMouseDown (ev)\r\n\t{\r\n\t\tev.preventDefault ();\r\n\r\n\t\tthis.mouse.Down (this.canvas, ev);\r\n\t\tthis.clickDetector.Start (this.mouse.GetPosition ());\r\n\t}\r\n\r\n\tOnMouseMove (ev)\r\n\t{\r\n\t\tthis.mouse.Move (this.canvas, ev);\r\n\t\tthis.clickDetector.Move (this.mouse.GetPosition ());\r\n\t\tif (this.onMouseMove) {\r\n\t\t\tlet mouseCoords = GetDomElementClientCoordinates (this.canvas, ev.clientX, ev.clientY);\r\n\t\t\tthis.onMouseMove (mouseCoords);\r\n\t\t}\r\n\r\n\t\tif (!this.mouse.IsButtonDown ()) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tlet moveDiff = this.mouse.GetMoveDiff ();\r\n\t\tlet mouseButton = this.mouse.GetButton ();\r\n\r\n\t\tlet navigationType = NavigationType.None;\r\n\t\tif (mouseButton === 1) {\r\n\t\t\tif (ev.ctrlKey) {\r\n\t\t\t\tnavigationType = NavigationType.Zoom;\r\n\t\t\t} else if (ev.shiftKey) {\r\n\t\t\t\tnavigationType = NavigationType.Pan;\r\n\t\t\t} else {\r\n\t\t\t\tnavigationType = NavigationType.Orbit;\r\n\t\t\t}\r\n\t\t} else if (mouseButton === 2 || mouseButton === 3) {\r\n\t\t\tnavigationType = NavigationType.Pan;\r\n\t\t}\r\n\r\n\t\tif (navigationType === NavigationType.Orbit) {\r\n\t\t\tlet orbitRatio = 0.5;\r\n\t\t\tthis.Orbit (moveDiff.x * orbitRatio, moveDiff.y * orbitRatio);\r\n\t\t} else if (navigationType === NavigationType.Pan) {\r\n\t\t\tlet eyeCenterDistance = CoordDistance3D (this.camera.eye, this.camera.center);\r\n\t\t\tlet panRatio = 0.001 * eyeCenterDistance;\r\n\t\t\tthis.Pan (moveDiff.x * panRatio, moveDiff.y * panRatio);\r\n\t\t} else if (navigationType === NavigationType.Zoom) {\r\n\t\t\tlet zoomRatio = 0.005;\r\n\t\t\tthis.Zoom (-moveDiff.y * zoomRatio);\r\n\t\t}\r\n\r\n\t\tthis.Update ();\r\n\t}\r\n\r\n\tOnMouseUp (ev)\r\n\t{\r\n\t\tthis.mouse.Up (this.canvas, ev);\r\n\t\tthis.clickDetector.End ();\r\n\r\n\t\tif (this.clickDetector.IsClick ()) {\r\n\t\t\tlet mouseCoords = this.mouse.GetPosition ();\r\n\t\t\tthis.Click (ev.which, mouseCoords);\r\n\t\t}\r\n\t}\r\n\r\n\tOnMouseLeave (ev)\r\n\t{\r\n\t\tthis.mouse.Leave (this.canvas, ev);\r\n\t\tthis.clickDetector.Cancel ();\r\n\t}\r\n\r\n\tOnTouchStart (ev)\r\n\t{\r\n\t\tev.preventDefault ();\r\n\r\n\t\tthis.touch.Start (this.canvas, ev);\r\n\t\tthis.clickDetector.Start (this.touch.GetPosition ());\r\n\t}\r\n\r\n\tOnTouchMove (ev)\r\n\t{\r\n\t\tev.preventDefault ();\r\n\r\n\t\tthis.touch.Move (this.canvas, ev);\r\n\t\tthis.clickDetector.Move (this.touch.GetPosition ());\r\n\t\tif (!this.touch.IsFingerDown ()) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tlet moveDiff = this.touch.GetMoveDiff ();\r\n\t\tlet distanceDiff = this.touch.GetDistanceDiff ();\r\n\t\tlet fingerCount = this.touch.GetFingerCount ();\r\n\r\n\t\tlet navigationType = NavigationType.None;\r\n\t\tif (fingerCount === 1) {\r\n\t\t\tnavigationType = NavigationType.Orbit;\r\n\t\t} else if (fingerCount === 2) {\r\n\t\t\tnavigationType = NavigationType.Pan;\r\n\t\t}\r\n\r\n\t\tif (navigationType === NavigationType.Orbit) {\r\n\t\t\tlet orbitRatio = 0.5;\r\n\t\t\tthis.Orbit (moveDiff.x * orbitRatio, moveDiff.y * orbitRatio);\r\n\t\t} else if (navigationType === NavigationType.Pan) {\r\n\t\t\tlet zoomRatio = 0.005;\r\n\t\t\tthis.Zoom (distanceDiff * zoomRatio);\r\n\t\t\tlet panRatio = 0.001 * CoordDistance3D (this.camera.eye, this.camera.center);\r\n\t\t\tthis.Pan (moveDiff.x * panRatio, moveDiff.y * panRatio);\r\n\t\t}\r\n\r\n\t\tthis.Update ();\r\n\t}\r\n\r\n\tOnTouchEnd (ev)\r\n\t{\r\n\t\tev.preventDefault ();\r\n\r\n\t\tthis.touch.End (this.canvas, ev);\r\n\t\tthis.clickDetector.End ();\r\n\r\n\t\tif (this.clickDetector.IsClick ()) {\r\n\t\t\tlet touchCoords = this.touch.GetPosition ();\r\n\t\t\tif (this.touch.GetFingerCount () === 1) {\r\n\t\t\t\tthis.Click (1, touchCoords);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tOnMouseWheel (ev)\r\n\t{\r\n\t\tlet params = ev || window.event;\r\n\t\tparams.preventDefault ();\r\n\r\n\t\tlet delta = -params.deltaY / 40;\r\n\t\tlet ratio = 0.1;\r\n\t\tif (delta < 0) {\r\n\t\t\tratio = ratio * -1;\r\n\t\t}\r\n\r\n\t\tthis.Zoom (ratio);\r\n\t\tthis.Update ();\r\n\t}\r\n\r\n\tOnContextMenu (ev)\r\n\t{\r\n\t\tev.preventDefault ();\r\n\r\n\t\tif (this.clickDetector.IsClick ()) {\r\n\t\t\tthis.Context (ev.clientX, ev.clientY);\r\n\t\t\tthis.clickDetector.Cancel ();\r\n\t\t}\r\n\t}\r\n\r\n\tOrbit (angleX, angleY)\r\n\t{\r\n\t\tlet radAngleX = angleX * DegRad;\r\n\t\tlet radAngleY = angleY * DegRad;\r\n\r\n\t\tlet viewDirection = SubCoord3D (this.camera.center, this.camera.eye).Normalize ();\r\n\t\tlet horizontalDirection = CrossVector3D (viewDirection, this.camera.up).Normalize ();\r\n\r\n\t\tif (this.navigationMode === NavigationMode.FixedUpVector) {\r\n\t\t\tlet originalAngle = VectorAngle3D (viewDirection, this.camera.up);\r\n\t\t\tlet newAngle = originalAngle + radAngleY;\r\n\t\t\tif (IsGreater (newAngle, 0.0) && IsLower (newAngle, Math.PI)) {\r\n\t\t\t\tthis.camera.eye.Rotate (horizontalDirection, -radAngleY, this.camera.center);\r\n\t\t\t}\r\n\t\t\tthis.camera.eye.Rotate (this.camera.up, -radAngleX, this.camera.center);\r\n\t\t} else if (this.navigationMode === NavigationMode.FreeOrbit) {\r\n\t\t\tlet verticalDirection = CrossVector3D (horizontalDirection, viewDirection).Normalize ();\r\n\t\t\tthis.camera.eye.Rotate (horizontalDirection, -radAngleY, this.camera.center);\r\n\t\t\tthis.camera.eye.Rotate (verticalDirection, -radAngleX, this.camera.center);\r\n\t\t\tthis.camera.up = verticalDirection;\r\n\t\t}\r\n\t}\r\n\r\n\tPan (moveX, moveY)\r\n\t{\r\n\t\tlet viewDirection = SubCoord3D (this.camera.center, this.camera.eye).Normalize ();\r\n\t\tlet horizontalDirection = CrossVector3D (viewDirection, this.camera.up).Normalize ();\r\n\t\tlet verticalDirection = CrossVector3D (horizontalDirection, viewDirection).Normalize ();\r\n\r\n\t\tthis.camera.eye.Offset (horizontalDirection, -moveX);\r\n\t\tthis.camera.center.Offset (horizontalDirection, -moveX);\r\n\r\n\t\tthis.camera.eye.Offset (verticalDirection, moveY);\r\n\t\tthis.camera.center.Offset (verticalDirection, moveY);\r\n\t}\r\n\r\n\tZoom (ratio)\r\n\t{\r\n\t\tlet direction = SubCoord3D (this.camera.center, this.camera.eye);\r\n\t\tlet distance = direction.Length ();\r\n\t\tlet move = distance * ratio;\r\n\t\tthis.camera.eye.Offset (direction, move);\r\n\t}\r\n\r\n\tUpdate ()\r\n\t{\r\n\t\tthis.callbacks.onUpdate ();\r\n\t}\r\n\r\n\tClick (button, mouseCoords)\r\n\t{\r\n\t\tif (this.onMouseClick) {\r\n\t\t\tthis.onMouseClick (button, mouseCoords);\r\n\t\t}\r\n\t}\r\n\r\n\tContext (clientX, clientY)\r\n\t{\r\n\t\tif (this.onContext) {\r\n\t\t\tlet globalCoords = {\r\n\t\t\t\tx : clientX,\r\n\t\t\t\ty : clientY\r\n\t\t\t};\r\n\t\t\tlet localCoords = GetDomElementClientCoordinates (this.canvas, clientX, clientY);\r\n\t\t\tthis.onContext (globalCoords, localCoords);\r\n\t\t}\r\n\t}\r\n}\n\n/**\r\n * Environment settings object.\r\n */\r\nclass EnvironmentSettings\r\n{\r\n    /**\r\n     * @param {string[]} textureNames Urls of the environment map images in this order:\r\n     * posx, negx, posy, negy, posz, negz.\r\n     * @param {boolean} backgroundIsEnvMap Use the environment map as background.\r\n     */\r\n    constructor (textureNames, backgroundIsEnvMap)\r\n    {\r\n        this.textureNames = textureNames;\r\n        this.backgroundIsEnvMap = backgroundIsEnvMap;\r\n    }\r\n\r\n    /**\r\n     * Creates a clone of the object.\r\n     * @returns {EnvironmentSettings}\r\n     */\r\n    Clone ()\r\n    {\r\n        let textureNames = null;\r\n        if (this.textureNames !== null) {\r\n            textureNames = [];\r\n            for (let textureName of this.textureNames) {\r\n                textureNames.push (textureName);\r\n            }\r\n        }\r\n        return new EnvironmentSettings (textureNames, this.backgroundIsEnvMap);\r\n    }\r\n}\r\n\r\nclass ShadingModel\r\n{\r\n    constructor (scene)\r\n    {\r\n        this.scene = scene;\r\n\r\n        this.type = ShadingType.Phong;\r\n        this.projectionMode = ProjectionMode.Perspective;\r\n        this.ambientLight = new THREE.AmbientLight (0x888888, 1.0 * Math.PI);\r\n        this.directionalLight = new THREE.DirectionalLight (0x888888, 1.0 * Math.PI);\r\n        this.environmentSettings = new EnvironmentSettings (null, false);\r\n        this.environment = null;\r\n\r\n        this.scene.add (this.ambientLight);\r\n        this.scene.add (this.directionalLight);\r\n    }\r\n\r\n    SetShadingType (type)\r\n    {\r\n        this.type = type;\r\n        this.UpdateShading ();\r\n    }\r\n\r\n    SetProjectionMode (projectionMode)\r\n    {\r\n        this.projectionMode = projectionMode;\r\n        this.UpdateShading ();\r\n    }\r\n\r\n    UpdateShading ()\r\n    {\r\n        if (this.type === ShadingType.Phong) {\r\n            this.ambientLight.color.set (0x888888);\r\n            this.directionalLight.color.set (0x888888);\r\n            this.scene.environment = null;\r\n        } else if (this.type === ShadingType.Physical) {\r\n            this.ambientLight.color.set (0x000000);\r\n            this.directionalLight.color.set (0x555555);\r\n            this.scene.environment = this.environment;\r\n        }\r\n        if (this.environmentSettings.backgroundIsEnvMap && this.projectionMode === ProjectionMode.Perspective) {\r\n            this.scene.background = this.environment;\r\n        } else {\r\n            this.scene.background = null;\r\n        }\r\n    }\r\n\r\n    SetEnvironmentMapSettings (environmentSettings, onLoaded)\r\n    {\r\n        let loader = new THREE.CubeTextureLoader ();\r\n        this.environment = loader.load (environmentSettings.textureNames, (texture) => {\r\n            texture.colorSpace = THREE.LinearSRGBColorSpace;\r\n            onLoaded ();\r\n        });\r\n        this.environmentSettings = environmentSettings;\r\n    }\r\n\r\n    UpdateByCamera (camera)\r\n    {\r\n        const lightDir = SubCoord3D (camera.eye, camera.center);\r\n        this.directionalLight.position.set (lightDir.x, lightDir.y, lightDir.z);\r\n    }\r\n}\n\nfunction GetDefaultCamera (direction)\r\n{\r\n    let fieldOfView = 45.0;\r\n    if (direction === Direction.X) {\r\n        return new Camera (\r\n            new Coord3D (2.0, -3, 1.5),\r\n            new Coord3D (0.0, 0.0, 0.0),\r\n            new Coord3D (1.0, 0.0, 0.0),\r\n            fieldOfView\r\n        );\r\n    } else if (direction === Direction.Y) {\r\n        return new Camera (\r\n            new Coord3D (-1.5, 2.0, 3.0),\r\n            new Coord3D (0.0, 0.0, 0.0),\r\n            new Coord3D (0.0, 1.0, 0.0),\r\n            fieldOfView\r\n        );\r\n    } else if (direction === Direction.Z) {\r\n        return new Camera (\r\n            new Coord3D (-1.5, -3, 2.0),\r\n            new Coord3D (0.0, 0.0, 0.0),\r\n            new Coord3D (0.0, 0.0, 1.0),\r\n            fieldOfView\r\n        );\r\n    }\r\n    return null;\r\n}\r\n\r\nfunction TraverseThreeObject (object, processor)\r\n{\r\n    if (!processor (object)) {\r\n        return false;\r\n    }\r\n    for (let child of object.children) {\r\n        if (!TraverseThreeObject (child, processor)) {\r\n            return false;\r\n        }\r\n    }\r\n    return true;\r\n}\r\n\r\nfunction GetShadingTypeOfObject (mainObject)\r\n{\r\n    let shadingType = null;\r\n    TraverseThreeObject (mainObject, (obj) => {\r\n        if (obj.isMesh) {\r\n            for (const material of obj.material) {\r\n                if (material.type === 'MeshPhongMaterial') {\r\n                    shadingType = ShadingType.Phong;\r\n                } else if (material.type === 'MeshStandardMaterial') {\r\n                    shadingType = ShadingType.Physical;\r\n                }\r\n                return false;\r\n            }\r\n        }\r\n        return true;\r\n    });\r\n    return shadingType;\r\n}\r\n\r\nclass CameraValidator\r\n{\r\n    constructor ()\r\n    {\r\n        this.eyeCenterDistance = 0.0;\r\n        this.forceUpdate = true;\r\n    }\r\n\r\n    ForceUpdate ()\r\n    {\r\n        this.forceUpdate = true;\r\n    }\r\n\r\n    ValidatePerspective ()\r\n    {\r\n        if (this.forceUpdate) {\r\n            this.forceUpdate = false;\r\n            return false;\r\n        }\r\n        return true;\r\n    }\r\n\r\n    ValidateOrthographic (eyeCenterDistance)\r\n    {\r\n        if (this.forceUpdate || !IsEqual (this.eyeCenterDistance, eyeCenterDistance)) {\r\n            this.eyeCenterDistance = eyeCenterDistance;\r\n            this.forceUpdate = false;\r\n            return false;\r\n        }\r\n        return true;\r\n    }\r\n}\r\n\r\nclass UpVector\r\n{\r\n    constructor ()\r\n    {\r\n        this.direction = Direction.Y;\r\n        this.isFixed = true;\r\n        this.isFlipped = false;\r\n    }\r\n\r\n    SetDirection (newDirection, oldCamera)\r\n    {\r\n        this.direction = newDirection;\r\n        this.isFlipped = false;\r\n\r\n        let defaultCamera = GetDefaultCamera (this.direction);\r\n        let defaultDir = SubCoord3D (defaultCamera.eye, defaultCamera.center);\r\n\r\n        let distance = CoordDistance3D (oldCamera.center, oldCamera.eye);\r\n        let newEye = oldCamera.center.Clone ().Offset (defaultDir, distance);\r\n\r\n        let newCamera = oldCamera.Clone ();\r\n        if (this.direction === Direction.X) {\r\n            newCamera.up = new Coord3D (1.0, 0.0, 0.0);\r\n            newCamera.eye = newEye;\r\n        } else if (this.direction === Direction.Y) {\r\n            newCamera.up = new Coord3D (0.0, 1.0, 0.0);\r\n            newCamera.eye = newEye;\r\n        } else if (this.direction === Direction.Z) {\r\n            newCamera.up = new Coord3D (0.0, 0.0, 1.0);\r\n            newCamera.eye = newEye;\r\n        }\r\n        return newCamera;\r\n    }\r\n\r\n    SetFixed (isFixed, oldCamera)\r\n    {\r\n        this.isFixed = isFixed;\r\n        if (this.isFixed) {\r\n            return this.SetDirection (this.direction, oldCamera);\r\n        }\r\n        return null;\r\n    }\r\n\r\n    Flip (oldCamera)\r\n    {\r\n        this.isFlipped = !this.isFlipped;\r\n        let newCamera = oldCamera.Clone ();\r\n        newCamera.up.MultiplyScalar (-1);\r\n        return newCamera;\r\n    }\r\n}\r\n\r\nclass Viewer\r\n{\r\n    constructor ()\r\n    {\r\n        THREE.ColorManagement.enabled = false;\r\n\r\n        this.canvas = null;\r\n        this.renderer = null;\r\n        this.scene = null;\r\n        this.mainModel = null;\r\n        this.extraModel = null;\r\n        this.camera = null;\r\n        this.projectionMode = null;\r\n        this.cameraValidator = null;\r\n        this.shadingModel = null;\r\n        this.navigation = null;\r\n        this.upVector = null;\r\n        this.settings = {\r\n            animationSteps : 40\r\n        };\r\n    }\r\n\r\n    Init (canvas)\r\n    {\r\n        this.canvas = canvas;\r\n        this.canvas.id = 'viewer';\r\n\r\n        let parameters = {\r\n            canvas : this.canvas,\r\n            antialias : true\r\n        };\r\n\r\n        this.renderer = new THREE.WebGLRenderer (parameters);\r\n        this.renderer.outputColorSpace = THREE.LinearSRGBColorSpace;\r\n\r\n        if (window.devicePixelRatio) {\r\n            this.renderer.setPixelRatio (window.devicePixelRatio);\r\n        }\r\n        this.renderer.setClearColor ('#ffffff', 1.0);\r\n        this.renderer.setSize (this.canvas.width, this.canvas.height);\r\n\r\n        this.scene = new THREE.Scene ();\r\n        this.mainModel = new ViewerMainModel (this.scene);\r\n        this.extraModel = new ViewerModel (this.scene);\r\n\r\n        this.InitNavigation ();\r\n        this.InitShading ();\r\n\r\n        this.Render ();\r\n    }\r\n\r\n    SetMouseClickHandler (onMouseClick)\r\n    {\r\n        this.navigation.SetMouseClickHandler (onMouseClick);\r\n    }\r\n\r\n    SetMouseMoveHandler (onMouseMove)\r\n    {\r\n        this.navigation.SetMouseMoveHandler (onMouseMove);\r\n    }\r\n\r\n    SetContextMenuHandler (onContext)\r\n    {\r\n        this.navigation.SetContextMenuHandler (onContext);\r\n    }\r\n\r\n    SetEdgeSettings (edgeSettings)\r\n    {\r\n        let newEdgeSettings = edgeSettings.Clone ();\r\n        this.mainModel.SetEdgeSettings (newEdgeSettings);\r\n        this.Render ();\r\n    }\r\n\r\n    SetEnvironmentMapSettings (environmentSettings)\r\n    {\r\n        let newEnvironmentSettings = environmentSettings.Clone ();\r\n        this.shadingModel.SetEnvironmentMapSettings (newEnvironmentSettings, () => {\r\n            this.Render ();\r\n        });\r\n        this.shadingModel.UpdateShading ();\r\n        this.Render ();\r\n    }\r\n\r\n    SetBackgroundColor (color)\r\n    {\r\n        let bgColor = new THREE.Color (\r\n            ColorComponentToFloat (color.r),\r\n            ColorComponentToFloat (color.g),\r\n            ColorComponentToFloat (color.b)\r\n        );\r\n        let alpha = ColorComponentToFloat (color.a);\r\n        this.renderer.setClearColor (bgColor, alpha);\r\n        this.Render ();\r\n    }\r\n\r\n    GetCanvas ()\r\n    {\r\n        return this.canvas;\r\n    }\r\n\r\n    GetCamera ()\r\n    {\r\n        return this.navigation.GetCamera ();\r\n    }\r\n\r\n    GetProjectionMode ()\r\n    {\r\n        return this.projectionMode;\r\n    }\r\n\r\n    SetCamera (camera)\r\n    {\r\n        this.navigation.SetCamera (camera);\r\n        this.cameraValidator.ForceUpdate ();\r\n        this.Render ();\r\n    }\r\n\r\n    SetProjectionMode (projectionMode)\r\n    {\r\n        if (this.projectionMode === projectionMode) {\r\n            return;\r\n        }\r\n\r\n        this.scene.remove (this.camera);\r\n        if (projectionMode === ProjectionMode.Perspective) {\r\n            this.camera = new THREE.PerspectiveCamera (45.0, 1.0, 0.1, 1000.0);\r\n        } else if (projectionMode === ProjectionMode.Orthographic) {\r\n\t\t\tthis.camera = new THREE.OrthographicCamera (-1, 1.0, 1.0, -1, 0.1, 1000.0);\r\n        }\r\n        this.scene.add (this.camera);\r\n\r\n        this.projectionMode = projectionMode;\r\n        this.shadingModel.SetProjectionMode (projectionMode);\r\n        this.cameraValidator.ForceUpdate ();\r\n\r\n        this.AdjustClippingPlanes ();\r\n        this.Render ();\r\n    }\r\n\r\n    Resize (width, height)\r\n    {\r\n        let innerSize = GetDomElementInnerDimensions (this.canvas, width, height);\r\n        this.ResizeRenderer (innerSize.width, innerSize.height);\r\n    }\r\n\r\n    ResizeRenderer (width, height)\r\n    {\r\n        if (window.devicePixelRatio) {\r\n            this.renderer.setPixelRatio (window.devicePixelRatio);\r\n        }\r\n        this.renderer.setSize (width, height);\r\n        this.cameraValidator.ForceUpdate ();\r\n        this.Render ();\r\n    }\r\n\r\n    FitSphereToWindow (boundingSphere, animation)\r\n    {\r\n        if (boundingSphere === null) {\r\n            return;\r\n        }\r\n        let center = new Coord3D (boundingSphere.center.x, boundingSphere.center.y, boundingSphere.center.z);\r\n        let radius = boundingSphere.radius;\r\n\r\n        let newCamera = this.navigation.GetFitToSphereCamera (center, radius);\r\n        this.navigation.MoveCamera (newCamera, animation ? this.settings.animationSteps : 0);\r\n    }\r\n\r\n    AdjustClippingPlanes ()\r\n    {\r\n        let boundingSphere = this.GetBoundingSphere ((meshUserData) => {\r\n            return true;\r\n        });\r\n        this.AdjustClippingPlanesToSphere (boundingSphere);\r\n    }\r\n\r\n    AdjustClippingPlanesToSphere (boundingSphere)\r\n    {\r\n        if (boundingSphere === null) {\r\n            return;\r\n        }\r\n        if (boundingSphere.radius < 10.0) {\r\n            this.camera.near = 0.01;\r\n            this.camera.far = 100.0;\r\n        } else if (boundingSphere.radius < 100.0) {\r\n            this.camera.near = 0.1;\r\n            this.camera.far = 1000.0;\r\n        } else if (boundingSphere.radius < 1000.0) {\r\n            this.camera.near = 10.0;\r\n            this.camera.far = 10000.0;\r\n        } else {\r\n            this.camera.near = 100.0;\r\n            this.camera.far = 1000000.0;\r\n        }\r\n\r\n        this.cameraValidator.ForceUpdate ();\r\n        this.Render ();\r\n    }\r\n\r\n    GetNavigationMode ()\r\n    {\r\n        return this.navigation.GetNavigationMode ();\r\n    }\r\n\r\n    SetNavigationMode (navigationMode)\r\n    {\r\n        let oldCamera = this.navigation.GetCamera ();\r\n        let newCamera = this.upVector.SetFixed (navigationMode === NavigationMode.FixedUpVector, oldCamera);\r\n        this.navigation.SetNavigationMode (navigationMode);\r\n        if (newCamera !== null) {\r\n            this.navigation.MoveCamera (newCamera, this.settings.animationSteps);\r\n        }\r\n        this.Render ();\r\n    }\r\n\r\n    SetUpVector (upDirection, animate)\r\n    {\r\n        let oldCamera = this.navigation.GetCamera ();\r\n        let newCamera = this.upVector.SetDirection (upDirection, oldCamera);\r\n        let animationSteps = animate ? this.settings.animationSteps : 0;\r\n        this.navigation.MoveCamera (newCamera, animationSteps);\r\n        this.Render ();\r\n    }\r\n\r\n    FlipUpVector ()\r\n    {\r\n        let oldCamera = this.navigation.GetCamera ();\r\n        let newCamera = this.upVector.Flip (oldCamera);\r\n        this.navigation.MoveCamera (newCamera, 0);\r\n        this.Render ();\r\n    }\r\n\r\n    Render ()\r\n    {\r\n        let navigationCamera = this.navigation.GetCamera ();\r\n\r\n        this.camera.position.set (navigationCamera.eye.x, navigationCamera.eye.y, navigationCamera.eye.z);\r\n        this.camera.up.set (navigationCamera.up.x, navigationCamera.up.y, navigationCamera.up.z);\r\n        this.camera.lookAt (new THREE.Vector3 (navigationCamera.center.x, navigationCamera.center.y, navigationCamera.center.z));\r\n\r\n        if (this.projectionMode === ProjectionMode.Perspective) {\r\n            if (!this.cameraValidator.ValidatePerspective ()) {\r\n                this.camera.aspect = this.canvas.width / this.canvas.height;\r\n                this.camera.fov = navigationCamera.fov;\r\n                this.camera.updateProjectionMatrix ();\r\n            }\r\n        } else if (this.projectionMode === ProjectionMode.Orthographic) {\r\n            let eyeCenterDistance = CoordDistance3D (navigationCamera.eye, navigationCamera.center);\r\n            if (!this.cameraValidator.ValidateOrthographic (eyeCenterDistance)) {\r\n                let aspect = this.canvas.width / this.canvas.height;\r\n                let eyeCenterDistance = CoordDistance3D (navigationCamera.eye, navigationCamera.center);\r\n                let frustumHalfHeight = eyeCenterDistance * Math.tan (0.5 * navigationCamera.fov * DegRad);\r\n                this.camera.left = -frustumHalfHeight * aspect;\r\n                this.camera.right = frustumHalfHeight * aspect;\r\n                this.camera.top = frustumHalfHeight;\r\n                this.camera.bottom = -frustumHalfHeight;\r\n                this.camera.updateProjectionMatrix ();\r\n            }\r\n        }\r\n\r\n        this.shadingModel.UpdateByCamera (navigationCamera);\r\n        this.renderer.render (this.scene, this.camera);\r\n    }\r\n\r\n    SetMainObject (object)\r\n    {\r\n        const shadingType = GetShadingTypeOfObject (object);\r\n        this.mainModel.SetMainObject (object);\r\n        this.shadingModel.SetShadingType (shadingType);\r\n\r\n        this.Render ();\r\n    }\r\n\r\n    AddExtraObject (object)\r\n    {\r\n        this.extraModel.AddObject (object);\r\n        this.Render ();\r\n    }\r\n\r\n    Clear ()\r\n    {\r\n        this.mainModel.Clear ();\r\n        this.extraModel.Clear ();\r\n        this.Render ();\r\n    }\r\n\r\n    ClearExtra ()\r\n    {\r\n        this.extraModel.Clear ();\r\n        this.Render ();\r\n    }\r\n\r\n    SetMeshesVisibility (isVisible)\r\n    {\r\n        this.mainModel.EnumerateMeshesAndLines ((mesh) => {\r\n            let visible = isVisible (mesh.userData);\r\n            if (mesh.visible !== visible) {\r\n                mesh.visible = visible;\r\n            }\r\n        });\r\n        this.mainModel.EnumerateEdges ((edge) => {\r\n            let visible = isVisible (edge.userData);\r\n            if (edge.visible !== visible) {\r\n                edge.visible = visible;\r\n            }\r\n        });\r\n        this.Render ();\r\n    }\r\n\r\n    SetMeshesHighlight (highlightColor, isHighlighted)\r\n    {\r\n        let withPolygonOffset = this.mainModel.HasLinesOrEdges ();\r\n        this.mainModel.EnumerateMeshesAndLines ((mesh) => {\r\n            let highlighted = isHighlighted (mesh.userData);\r\n            if (highlighted) {\r\n                if (mesh.userData.threeMaterials === null) {\r\n                    mesh.userData.threeMaterials = mesh.material;\r\n                    mesh.material = CreateHighlightMaterials (mesh.userData.threeMaterials, highlightColor, withPolygonOffset);\r\n                }\r\n            } else {\r\n                if (mesh.userData.threeMaterials !== null) {\r\n                    mesh.material = mesh.userData.threeMaterials;\r\n                    mesh.userData.threeMaterials = null;\r\n                }\r\n            }\r\n        });\r\n\r\n        this.Render ();\r\n    }\r\n\r\n    GetMeshUserDataUnderMouse (intersectionMode, mouseCoords)\r\n    {\r\n        let intersection = this.GetMeshIntersectionUnderMouse (intersectionMode, mouseCoords);\r\n        if (intersection === null) {\r\n            return null;\r\n        }\r\n        return intersection.object.userData;\r\n    }\r\n\r\n    GetMeshIntersectionUnderMouse (intersectionMode, mouseCoords)\r\n    {\r\n        let canvasSize = this.GetCanvasSize ();\r\n        let intersection = this.mainModel.GetMeshIntersectionUnderMouse (intersectionMode, mouseCoords, this.camera, canvasSize.width, canvasSize.height);\r\n        if (intersection === null) {\r\n            return null;\r\n        }\r\n        return intersection;\r\n    }\r\n\r\n    GetBoundingBox (needToProcess)\r\n    {\r\n        return this.mainModel.GetBoundingBox (needToProcess);\r\n    }\r\n\r\n    GetBoundingSphere (needToProcess)\r\n    {\r\n        return this.mainModel.GetBoundingSphere (needToProcess);\r\n    }\r\n\r\n    EnumerateMeshesAndLinesUserData (enumerator)\r\n    {\r\n        this.mainModel.EnumerateMeshesAndLines ((mesh) => {\r\n            enumerator (mesh.userData);\r\n        });\r\n    }\r\n\r\n    InitNavigation ()\r\n    {\r\n        let camera = GetDefaultCamera (Direction.Y);\r\n        this.camera = new THREE.PerspectiveCamera (45.0, 1.0, 0.1, 1000.0);\r\n        this.projectionMode = ProjectionMode.Perspective;\r\n        this.cameraValidator = new CameraValidator ();\r\n        this.scene.add (this.camera);\r\n\r\n        let canvasElem = this.renderer.domElement;\r\n        this.navigation = new Navigation (canvasElem, camera, {\r\n            onUpdate : () => {\r\n                this.Render ();\r\n            }\r\n        });\r\n\r\n        this.upVector = new UpVector ();\r\n    }\r\n\r\n    InitShading  ()\r\n    {\r\n        this.shadingModel = new ShadingModel (this.scene);\r\n    }\r\n\r\n    GetShadingType ()\r\n    {\r\n        return this.shadingModel.type;\r\n    }\r\n\r\n    GetImageSize ()\r\n    {\r\n        let originalSize = new THREE.Vector2 ();\r\n        this.renderer.getSize (originalSize);\r\n        return {\r\n            width : parseInt (originalSize.x, 10),\r\n            height : parseInt (originalSize.y, 10)\r\n        };\r\n    }\r\n\r\n    GetCanvasSize ()\r\n    {\r\n        let width = this.canvas.width;\r\n        let height = this.canvas.height;\r\n        if (window.devicePixelRatio) {\r\n            width /= window.devicePixelRatio;\r\n            height /= window.devicePixelRatio;\r\n        }\r\n        return {\r\n            width : width,\r\n            height : height\r\n        };\r\n    }\r\n\r\n    GetImageAsDataUrl (width, height, isTransparent)\r\n    {\r\n        let originalSize = this.GetImageSize ();\r\n        let renderWidth = width;\r\n        let renderHeight = height;\r\n        if (window.devicePixelRatio) {\r\n            renderWidth /= window.devicePixelRatio;\r\n            renderHeight /= window.devicePixelRatio;\r\n        }\r\n        let clearAlpha = this.renderer.getClearAlpha ();\r\n        if (isTransparent) {\r\n            this.renderer.setClearAlpha (0.0);\r\n        }\r\n        this.ResizeRenderer (renderWidth, renderHeight);\r\n        this.Render ();\r\n        let url = this.renderer.domElement.toDataURL ();\r\n        this.ResizeRenderer (originalSize.width, originalSize.height);\r\n        this.renderer.setClearAlpha (clearAlpha);\r\n        return url;\r\n    }\r\n\r\n    Destroy ()\r\n    {\r\n        this.Clear ();\r\n        this.renderer.dispose ();\r\n    }\r\n}\n\n/**\r\n * This is the main object for embedding the viewer on a website.\r\n */\r\nclass EmbeddedViewer\r\n{\r\n    /**\r\n     * @param {HTMLElement} parentElement The parent element for the viewer canvas. It must be an\r\n     * existing DOM element and it will be the container for the canvas. The size of the viewer will\r\n     * be automatically adjusted to the size of the parent element.\r\n     * @param {object} parameters Parameters for embedding.\r\n     * @param {Camera} [parameters.camera] Camera to use. If not specified, the default camera will\r\n     * be used and the model will be fitted to the window.\r\n     * @param {ProjectionMode} [parameters.projectionMode] Camera projection mode.\r\n     * @param {RGBAColor} [parameters.backgroundColor] Background color of the canvas.\r\n     * @param {RGBColor} [parameters.defaultColor] Default color of the model. It has effect only\r\n     * if the imported model doesn't specify any color.\r\n     * @param {RGBColor} [parameters.defaultLineColor] Default line color of the model. It has effect only\r\n     * if the imported model doesn't specify any color.\r\n     * @param {EdgeSettings} [parameters.edgeSettings] Edge settings.\r\n     * @param {EnvironmentSettings} [parameters.environmentSettings] Environment settings.\r\n     * @param {function} [parameters.onModelLoaded] Callback that is called when the model with all\r\n     * of the textures is fully loaded.\r\n     * @param {function} [parameters.onModelLoadFailed] Callback that is called when the model load failed.\r\n    */\r\n    constructor (parentElement, parameters)\r\n    {\r\n        this.parentElement = parentElement;\r\n        this.parameters = {};\r\n        if (IsDefined (parameters)) {\r\n            this.parameters = parameters;\r\n        }\r\n\r\n        this.canvas = document.createElement ('canvas');\r\n        this.parentElement.appendChild (this.canvas);\r\n\r\n        this.viewer = new Viewer ();\r\n        this.viewer.Init (this.canvas);\r\n\r\n        let width = this.parentElement.clientWidth;\r\n        let height = this.parentElement.clientHeight;\r\n        this.viewer.Resize (width, height);\r\n\r\n        if (this.parameters.projectionMode) {\r\n            this.viewer.SetProjectionMode (this.parameters.projectionMode);\r\n        }\r\n\r\n        if (this.parameters.backgroundColor) {\r\n            this.viewer.SetBackgroundColor (this.parameters.backgroundColor);\r\n        }\r\n\r\n        if (this.parameters.edgeSettings) {\r\n            this.viewer.SetEdgeSettings (this.parameters.edgeSettings);\r\n        }\r\n\r\n        if (this.parameters.environmentSettings) {\r\n            this.viewer.SetEnvironmentMapSettings (this.parameters.environmentSettings);\r\n        }\r\n\r\n        this.model = null;\r\n        this.modelLoader = new ThreeModelLoader ();\r\n\r\n        this.progressDiv = null;\r\n        window.addEventListener ('resize', () => {\r\n            this.Resize ();\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Loads the model based on a list of urls. The list must contain the main model file and all\r\n     * of the referenced files. For example in case of an obj file the list must contain the\r\n     * corresponding mtl and texture files, too.\r\n     * @param {string[]} modelUrls Url list of model files.\r\n     */\r\n    LoadModelFromUrlList (modelUrls)\r\n    {\r\n        TransformFileHostUrls (modelUrls);\r\n        let inputFiles = InputFilesFromUrls (modelUrls);\r\n        this.LoadModelFromInputFiles (inputFiles);\r\n    }\r\n\r\n    /**\r\n     * Loads the model based on a list of {@link File} objects. The list must contain the main model\r\n     * file and all of the referenced files. You must use this method when you are using a file picker\r\n     * or drag and drop to select files from a computer.\r\n     * @param {File[]} fileList File object list of model files.\r\n     */\r\n    LoadModelFromFileList (fileList)\r\n    {\r\n        let inputFiles = InputFilesFromFileObjects (fileList);\r\n        this.LoadModelFromInputFiles (inputFiles);\r\n    }\r\n\r\n    /**\r\n     * Loads the model based on a list of {@link InputFile} objects. This method is used\r\n     * internally, you should use LoadModelFromUrlList or LoadModelFromFileList instead.\r\n     * @param {InputFile[]} inputFiles List of model files.\r\n     */\r\n    LoadModelFromInputFiles (inputFiles)\r\n    {\r\n        if (inputFiles === null || inputFiles.length === 0) {\r\n            return;\r\n        }\r\n\r\n        this.viewer.Clear ();\r\n        let settings = new ImportSettings ();\r\n        if (this.parameters.defaultColor) {\r\n            settings.defaultColor = this.parameters.defaultColor;\r\n        }\r\n        if (this.parameters.defaultLineColor) {\r\n            settings.defaultLineColor = this.parameters.defaultLineColor;\r\n        }\r\n\r\n        this.model = null;\r\n        if (this.progressDiv !== null) {\r\n            this.parentElement.removeChild (this.progressDiv);\r\n            this.progressDiv = null;\r\n        }\r\n        this.modelLoader.LoadModel (inputFiles, settings, {\r\n            onLoadStart : () => {\r\n                this.canvas.style.display = 'none';\r\n                this.progressDiv = document.createElement ('div');\r\n                this.progressDiv.innerHTML = Loc ('Loading model...');\r\n                this.parentElement.appendChild (this.progressDiv);\r\n            },\r\n            onFileListProgress : (current, total) => {\r\n            },\r\n            onFileLoadProgress : (current, total) => {\r\n            },\r\n            onImportStart : () => {\r\n                this.progressDiv.innerHTML = Loc ('Importing model...');\r\n            },\r\n            onVisualizationStart : () => {\r\n                this.progressDiv.innerHTML = Loc ('Visualizing model...');\r\n            },\r\n            onModelFinished : (importResult, threeObject) => {\r\n                this.parentElement.removeChild (this.progressDiv);\r\n                this.progressDiv = null;\r\n                this.canvas.style.display = 'inherit';\r\n                this.viewer.SetMainObject (threeObject);\r\n                let boundingSphere = this.viewer.GetBoundingSphere ((meshUserData) => {\r\n                    return true;\r\n                });\r\n                this.viewer.AdjustClippingPlanesToSphere (boundingSphere);\r\n                if (this.parameters.camera) {\r\n                    this.viewer.SetCamera (this.parameters.camera);\r\n                } else {\r\n                    this.viewer.SetUpVector (Direction.Y, false);\r\n                    this.viewer.FitSphereToWindow (boundingSphere, false);\r\n                }\r\n\r\n                this.model = importResult.model;\r\n                if (this.parameters.onModelLoaded) {\r\n                    this.parameters.onModelLoaded ();\r\n                }\r\n            },\r\n            onTextureLoaded : () => {\r\n                this.viewer.Render ();\r\n            },\r\n            onLoadError : (importError) => {\r\n                let message = Loc ('Unknown error.');\r\n                if (importError.code === ImportErrorCode.NoImportableFile) {\r\n                    message = Loc ('No importable file found.');\r\n                } else if (importError.code === ImportErrorCode.FailedToLoadFile) {\r\n                    message = Loc ('Failed to load file for import.');\r\n                } else if (importError.code === ImportErrorCode.ImportFailed) {\r\n                    message = Loc ('Failed to import model.');\r\n                }\r\n                if (importError.message !== null) {\r\n                    message += ' (' + importError.message + ')';\r\n                }\r\n                this.progressDiv.innerHTML = message;\r\n                if (this.parameters.onModelLoadFailed) {\r\n                    this.parameters.onModelLoadFailed ();\r\n                }\r\n            }\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Returns the underlying Viewer object.\r\n     * @returns {Viewer}\r\n     */\r\n    GetViewer ()\r\n    {\r\n        return this.viewer;\r\n    }\r\n\r\n    /**\r\n     * Returns the underlying Model object.\r\n     * @returns {Model}\r\n     */\r\n    GetModel ()\r\n    {\r\n        return this.model;\r\n    }\r\n\r\n    /**\r\n     * This method must be called when the size of the parent element changes to make sure that the\r\n     * context has the same dimensions as the parent element.\r\n     */\r\n    Resize ()\r\n    {\r\n        let width = this.parentElement.clientWidth;\r\n        let height = this.parentElement.clientHeight;\r\n        this.viewer.Resize (width, height);\r\n    }\r\n\r\n    /**\r\n     * Frees up all the memory that is allocated by the viewer. You should call this function if\r\n     * yo don't need the viewer anymore.\r\n     */\r\n    Destroy ()\r\n    {\r\n        this.modelLoader.Destroy ();\r\n        this.viewer.Destroy ();\r\n        this.model = null;\r\n    }\r\n}\r\n\r\n/**\r\n * Loads the model specified by urls.\r\n * @param {HTMLElement} parentElement The parent element for the viewer canvas.\r\n * @param {string[]} modelUrls Url list of model files.\r\n * @param {object} parameters See {@link EmbeddedViewer} constructor for details.\r\n * @returns {EmbeddedViewer}\r\n */\r\nfunction Init3DViewerFromUrlList (parentElement, modelUrls, parameters)\r\n{\r\n    let viewer = new EmbeddedViewer (parentElement, parameters);\r\n    viewer.LoadModelFromUrlList (modelUrls);\r\n    return viewer;\r\n}\r\n\r\n/**\r\n * Loads the model specified by File objects.\r\n * @param {HTMLElement} parentElement The parent element for the viewer canvas.\r\n * @param {File[]} models File object list of model files.\r\n * @param {object} parameters See {@link EmbeddedViewer} constructor for details.\r\n * @returns {EmbeddedViewer}\r\n */\r\nfunction Init3DViewerFromFileList (parentElement, models, parameters)\r\n{\r\n    let viewer = new EmbeddedViewer (parentElement, parameters);\r\n    viewer.LoadModelFromFileList (models);\r\n    return viewer;\r\n}\r\n\r\n/**\r\n * Loads all the models on the page. This function looks for all the elements with online_3d_viewer\r\n * class name, and loads the model according to the tag's parameters. It must be called after the\r\n * document is loaded.\r\n * @returns {EmbeddedViewer[]} Array of the created {@link EmbeddedViewer} objects.\r\n */\r\nfunction Init3DViewerElements (onReady)\r\n{\r\n    function LoadElement (element)\r\n    {\r\n        let camera = null;\r\n        let cameraParams = element.getAttribute ('camera');\r\n        if (cameraParams) {\r\n            camera = ParameterConverter.StringToCamera (cameraParams);\r\n        }\r\n\r\n        let projectionMode = null;\r\n        let cameraModeParams = element.getAttribute ('projectionmode');\r\n        if (cameraModeParams) {\r\n            projectionMode = ParameterConverter.StringToProjectionMode (cameraModeParams);\r\n        }\r\n\r\n        let backgroundColor = null;\r\n        let backgroundColorParams = element.getAttribute ('backgroundcolor');\r\n        if (backgroundColorParams) {\r\n            backgroundColor = ParameterConverter.StringToRGBAColor (backgroundColorParams);\r\n        }\r\n\r\n        let defaultColor = null;\r\n        let defaultColorParams = element.getAttribute ('defaultcolor');\r\n        if (defaultColorParams) {\r\n            defaultColor = ParameterConverter.StringToRGBColor (defaultColorParams);\r\n        }\r\n\r\n        let defaultLineColor = null;\r\n        let defaultLineColorParams = element.getAttribute ('defaultlinecolor');\r\n        if (defaultLineColorParams) {\r\n            defaultLineColor = ParameterConverter.StringToRGBColor (defaultLineColorParams);\r\n        }\r\n\r\n        let edgeSettings = null;\r\n        let edgeSettingsParams = element.getAttribute ('edgesettings');\r\n        if (edgeSettingsParams) {\r\n            edgeSettings = ParameterConverter.StringToEdgeSettings (edgeSettingsParams);\r\n        }\r\n\r\n        let environmentSettings = null;\r\n        let environmentMapParams = element.getAttribute ('environmentmap');\r\n        if (environmentMapParams) {\r\n            let environmentMapParts = environmentMapParams.split (',');\r\n            if (environmentMapParts.length === 6) {\r\n                let backgroundIsEnvMap = false;\r\n                let backgroundIsEnvMapParam = element.getAttribute ('environmentmapbg');\r\n                if (backgroundIsEnvMapParam && backgroundIsEnvMapParam === 'true') {\r\n                    backgroundIsEnvMap = true;\r\n                }\r\n                environmentSettings = new EnvironmentSettings (environmentMapParts, backgroundIsEnvMap);\r\n            }\r\n        }\r\n\r\n        let modelUrls = null;\r\n        let modelParams = element.getAttribute ('model');\r\n        if (modelParams) {\r\n            modelUrls = ParameterConverter.StringToModelUrls (modelParams);\r\n        }\r\n\r\n        return Init3DViewerFromUrlList (element, modelUrls, {\r\n            camera : camera,\r\n            projectionMode : projectionMode,\r\n            backgroundColor : backgroundColor,\r\n            defaultLineColor : defaultLineColor,\r\n            defaultColor : defaultColor,\r\n            edgeSettings : edgeSettings,\r\n            environmentSettings : environmentSettings\r\n        });\r\n    }\r\n\r\n    let viewerElements = [];\r\n    let elements = document.getElementsByClassName ('online_3d_viewer');\r\n    for (let i = 0; i < elements.length; i++) {\r\n        let element = elements[i];\r\n        let viewerElement = LoadElement (element);\r\n        viewerElements.push (viewerElement);\r\n    }\r\n    return viewerElements;\r\n}\n\nexport { AddCoord2D, AddCoord3D, AddDiv, AddDomElement, ArrayBufferToAsciiString, ArrayBufferToUtf8String, ArrayToCoord3D, ArrayToQuaternion, ArrayToRGBColor, AsciiStringToArrayBuffer, Base64DataURIToArrayBuffer, BezierTweenFunction, BigEps, BinaryReader, BinaryWriter, BoundingBoxCalculator3D, Box3D, CalculateSurfaceArea, CalculateTriangleNormal, CalculateVolume, Camera, CameraIsEqual3D, CameraValidator, CheckModel, ClearDomElement, ClickDetector, ColorComponentFromFloat, ColorComponentToFloat, ColorToMaterialConverter, ConvertColorToThreeColor, ConvertMeshToMeshBuffer, ConvertModelToThreeObject, ConvertThreeColorToColor, ConvertThreeGeometryToMesh, Coord2D, Coord3D, Coord4D, CoordDistance2D, CoordDistance3D, CoordIsEqual2D, CoordIsEqual3D, CopyObjectAttributes, CreateDiv, CreateDomElement, CreateHighlightMaterial, CreateHighlightMaterials, CreateModelUrlParameters, CreateObjectUrl, CreateObjectUrlWithMimeType, CreateOcctWorker, CreateUrlBuilder, CreateUrlParser, CrossVector3D, DegRad, Direction, DisposeThreeObjects, DotVector2D, DotVector3D, EdgeSettings, EmbeddedViewer, EnvironmentSettings, Eps, EscapeHtmlChars, EventNotifier, ExportedFile, Exporter, Exporter3dm, ExporterBase, ExporterBim, ExporterGltf, ExporterModel, ExporterObj, ExporterOff, ExporterPly, ExporterSettings, ExporterStl, FLoc, FaceMaterial, FileFormat, FileSource, FinalizeModel, FlipMeshTrianglesOrientation, FormatString, GenerateCone, GenerateCuboid, GenerateCylinder, GeneratePlatonicSolid, GenerateSphere, Generator, GeneratorHelper, GeneratorParams, GetBoundingBox, GetDefaultCamera, GetDefaultMaterials, GetDomElementClientCoordinates, GetDomElementExternalHeight, GetDomElementExternalWidth, GetDomElementInnerDimensions, GetDomElementOuterHeight, GetDomElementOuterWidth, GetFileExtension, GetFileExtensionFromMimeType, GetFileName, GetIntegerFromStyle, GetLineSegmentsProjectedDistance, GetShadingType, GetShadingTypeOfObject, GetTetrahedronSignedVolume, GetTopology, GetTriangleArea, HasHighpDriverIssue, HexStringToRGBAColor, HexStringToRGBColor, ImportError, ImportErrorCode, ImportResult, ImportSettings, Importer, Importer3dm, Importer3ds, ImporterBase, ImporterBim, ImporterFcstd, ImporterFile, ImporterFileAccessor, ImporterFileList, ImporterGltf, ImporterIfc, ImporterObj, ImporterOcct, ImporterOff, ImporterPly, ImporterStl, ImporterThree3mf, ImporterThreeAmf, ImporterThreeBase, ImporterThreeDae, ImporterThreeFbx, ImporterThreeSvg, ImporterThreeWrl, Init3DViewerElements, Init3DViewerFromFileList, Init3DViewerFromUrlList, InputFile, InputFilesFromFileObjects, InputFilesFromUrls, InsertDomElementAfter, InsertDomElementBefore, IntegerToHexString, IntersectionMode, IsDefined, IsDomElementVisible, IsEmptyMesh, IsEqual, IsEqualEps, IsGreater, IsGreaterOrEqual, IsLower, IsLowerOrEqual, IsModelEmpty, IsNegative, IsObjectEmpty, IsPositive, IsPowerOfTwo, IsTwoManifold, IsUrl, IsZero, Line, LinearToSRGB, LinearTweenFunction, LoadExternalLibrary, LoadExternalLibraryFromUrl, Loc, MaterialBase, MaterialGeometryType, MaterialSource, MaterialType, Matrix, MatrixIsEqual, Mesh, MeshBuffer, MeshInstance, MeshInstanceId, MeshPrimitiveBuffer, Model, ModelObject3D, ModelToThreeConversionOutput, ModelToThreeConversionParams, MouseInteraction, NameFromLine, Navigation, NavigationMode, NavigationType, NextPowerOfTwo, Node, Object3D, Octree, OctreeNode, ParabolicTweenFunction, ParameterConverter, ParameterListBuilder, ParameterListParser, ParametersFromLine, PhongMaterial, PhysicalMaterial, ProjectPointToSegment2D, ProjectionMode, Property, PropertyGroup, PropertyToString, PropertyType, Quaternion, QuaternionFromAxisAngle, QuaternionFromXYZ, QuaternionIsEqual, RGBAColor, RGBAColorToHexString, RGBColor, RGBColorFromFloatComponents, RGBColorIsEqual, RGBColorToHexString, RadDeg, ReadFile, ReadLines, ReplaceDefaultMaterialsColor, RequestUrl, RevokeObjectUrl, RunTaskAsync, RunTasks, RunTasksBatch, SRGBToLinear, Segment2D, SegmentPointDistance2D, SetDomElementHeight, SetDomElementOuterHeight, SetDomElementOuterWidth, SetDomElementWidth, SetLanguageCode, SetLocalizedStrings, SetThreeMeshPolygonOffset, ShadingModel, ShadingType, ShowDomElement, SubCoord2D, SubCoord3D, TaskRunner, TextWriter, TextureIsEqual, TextureMap, TextureMapIsEqual, ThreeColorConverter, ThreeConversionStateHandler, ThreeLinearToSRGBColorConverter, ThreeMaterialHandler, ThreeMeshMaterialHandler, ThreeModelLoader, ThreeNodeTree, ThreeSRGBToLinearColorConverter, Topology, TopologyEdge, TopologyTriangle, TopologyTriangleEdge, TopologyVertex, TouchInteraction, TransformFileHostUrls, TransformMesh, Transformation, TransformationIsEqual, TraverseThreeObject, Triangle, TweenCoord3D, Unit, UpVector, UpdateMaterialTransparency, Utf8StringToArrayBuffer, ValueOrDefault, VectorAngle3D, VectorLength3D, Viewer, ViewerMainModel, ViewerModel, WaitWhile };\n"]}