@xtctwins/tctwins-bimx-viewer 0.1.2 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/tctwins-bimx-viewer.min.es.js +9 -9
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +2 -2
- package/types/index.d.ts +2 -2
- package/types/src/BIMViewer.d.ts +6 -0
- package/types/src/BIMXViewer.d.ts +649 -0
- package/types/src/Controller.d.ts +1 -1
- package/types/src/toolbar/AnnotationTool.d.ts +32 -13
|
@@ -34,17 +34,17 @@ eval("// Aliyun OSS SDK for JavaScript v6.18.1\n// Copyright Aliyun.com, Inc. or
|
|
|
34
34
|
\******************/
|
|
35
35
|
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
36
36
|
|
|
37
|
-
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */
|
|
37
|
+
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ BIMXViewer: () => (/* reexport safe */ _src_BIMXViewer__WEBPACK_IMPORTED_MODULE_1__[\"default\"]),\n/* harmony export */ EventTrigger: () => (/* reexport safe */ _src_EventTrigger__WEBPACK_IMPORTED_MODULE_2__[\"default\"]),\n/* harmony export */ LocaleService: () => (/* reexport safe */ _xtctwins_tctwins_core__WEBPACK_IMPORTED_MODULE_0__.LocaleService),\n/* harmony export */ OSSClient: () => (/* reexport safe */ _src_server_OSSHelper__WEBPACK_IMPORTED_MODULE_4__[\"default\"]),\n/* harmony export */ Server: () => (/* reexport safe */ _src_server_Server__WEBPACK_IMPORTED_MODULE_3__[\"default\"])\n/* harmony export */ });\n/* harmony import */ var _xtctwins_tctwins_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @xtctwins/tctwins-core */ \"./node_modules/@xtctwins/tctwins-core/dist/tctwins-core.es5.js\");\n/* harmony import */ var _src_BIMXViewer__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./src/BIMXViewer */ \"./src/BIMXViewer.ts\");\n/* harmony import */ var _src_EventTrigger__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./src/EventTrigger */ \"./src/EventTrigger.ts\");\n/* harmony import */ var _src_server_Server__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./src/server/Server */ \"./src/server/Server.ts\");\n/* harmony import */ var _src_server_OSSHelper__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./src/server/OSSHelper */ \"./src/server/OSSHelper.ts\");\n\n\n\n\n\n\n\n\n//# sourceURL=webpack://@xtctwins/tctwins-bimx-viewer/./index.ts?");
|
|
38
38
|
|
|
39
39
|
/***/ }),
|
|
40
40
|
|
|
41
|
-
/***/ "./src/
|
|
42
|
-
|
|
43
|
-
!*** ./src/
|
|
44
|
-
|
|
41
|
+
/***/ "./src/BIMXViewer.ts":
|
|
42
|
+
/*!***************************!*\
|
|
43
|
+
!*** ./src/BIMXViewer.ts ***!
|
|
44
|
+
\***************************/
|
|
45
45
|
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
46
46
|
|
|
47
|
-
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (/* binding */ BIMViewer)\n/* harmony export */ });\n/* harmony import */ var _xtctwins_tctwins_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @xtctwins/tctwins-core */ \"./node_modules/@xtctwins/tctwins-core/dist/tctwins-core.es5.js\");\n/* harmony import */ var _messages__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./messages */ \"./src/messages.ts\");\n/* harmony import */ var _EventTrigger__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./EventTrigger */ \"./src/EventTrigger.ts\");\n/* harmony import */ var _Controller__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./Controller */ \"./src/Controller.ts\");\n/* harmony import */ var _toolbar_ResetAction__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./toolbar/ResetAction */ \"./src/toolbar/ResetAction.ts\");\n/* harmony import */ var _toolbar_FitAction__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./toolbar/FitAction */ \"./src/toolbar/FitAction.ts\");\n/* harmony import */ var _toolbar_FirstPersonMode__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./toolbar/FirstPersonMode */ \"./src/toolbar/FirstPersonMode.ts\");\n/* harmony import */ var _toolbar_HideTool__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./toolbar/HideTool */ \"./src/toolbar/HideTool.ts\");\n/* harmony import */ var _toolbar_ShowSpacesMode__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./toolbar/ShowSpacesMode */ \"./src/toolbar/ShowSpacesMode.ts\");\n/* harmony import */ var _toolbar_SectionTool__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./toolbar/SectionTool */ \"./src/toolbar/SectionTool.ts\");\n/* harmony import */ var _toolbar_NavCubeMode__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./toolbar/NavCubeMode */ \"./src/toolbar/NavCubeMode.ts\");\n/* harmony import */ var _explorer_ModelsExplorer__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./explorer/ModelsExplorer */ \"./src/explorer/ModelsExplorer.ts\");\n/* harmony import */ var _explorer_ObjectsExplorer__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./explorer/ObjectsExplorer */ \"./src/explorer/ObjectsExplorer.ts\");\n/* harmony import */ var _explorer_ClassesExplorer__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./explorer/ClassesExplorer */ \"./src/explorer/ClassesExplorer.ts\");\n/* harmony import */ var _explorer_StoreysExplorer__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./explorer/StoreysExplorer */ \"./src/explorer/StoreysExplorer.ts\");\n/* harmony import */ var _toolbar_ThreeDMode__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ./toolbar/ThreeDMode */ \"./src/toolbar/ThreeDMode.ts\");\n/* harmony import */ var _toolbar_OrthoMode__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ./toolbar/OrthoMode */ \"./src/toolbar/OrthoMode.ts\");\n/* harmony import */ var _collision_ObjectsKdTree3__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ./collision/ObjectsKdTree3 */ \"./src/collision/ObjectsKdTree3.ts\");\n/* harmony import */ var _toolbar_AnnotationTool__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ./toolbar/AnnotationTool */ \"./src/toolbar/AnnotationTool.ts\");\n/* harmony import */ var _toolbar_MeasureTool__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ./toolbar/MeasureTool */ \"./src/toolbar/MeasureTool.ts\");\n/* harmony import */ var _toolbar_CommentsTool__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! ./toolbar/CommentsTool */ \"./src/toolbar/CommentsTool.ts\");\n/* harmony import */ var _server_Server__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! ./server/Server */ \"./src/server/Server.ts\");\nvar __awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n};\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n/**\n * 核心模型视图窗口\n * @type {BIMViewer}\n */\nclass BIMViewer extends _Controller__WEBPACK_IMPORTED_MODULE_3__[\"default\"] {\n /**\n * Constructs a BIMViewer.\n * @param {Server} server Data access strategy.\n * @param {*} cfg Configuration.\n * @param {Boolean} [cfg.enableEditModels=false] Set ````true```` to show \"Add\", \"Edit\" and \"Delete\" options in the Models tab's context menu.\n * @param {Boolean} [cfg.keyboardEventsElement] Optional reference to HTML element on which key events should be handled. Defaults to the HTML Document.\n */\n constructor(cfg = {}) {\n if (!cfg.canvasElement) {\n throw new Error(\"Config expected: canvasElement\");\n }\n if (!cfg.navCubeCanvasElement) {\n throw new Error(\"Config expected: navCubeCanvasElement\");\n }\n const { canvasElement } = cfg;\n const { viewerElement } = cfg;\n const localeService = new _xtctwins_tctwins_core__WEBPACK_IMPORTED_MODULE_0__.LocaleService({\n messages: _messages__WEBPACK_IMPORTED_MODULE_1__[\"default\"],\n locale: \"ch\"\n });\n const viewer = new _xtctwins_tctwins_core__WEBPACK_IMPORTED_MODULE_0__.Viewer({\n passes: 5,\n localeService,\n canvasElement,\n viewerElement,\n transparent: true,\n alphaDepthMask: true,\n backgroundColorFromAmbientLight: true,\n snapRadius: cfg.snapRadius,\n antialias: true,\n saoEnabled: false,\n pbrEnabled: true,\n dtxEnabled: true,\n edgesEnabled: true,\n colorTextureEnabled: true,\n premultipliedAlpha: true,\n resolutionScale: window.devicePixelRatio,\n spinnerElementId: \"engine_spinner\"\n });\n const server = new _server_Server__WEBPACK_IMPORTED_MODULE_21__[\"default\"]({\n dataDir: \"./data\",\n filePath: \"testdemo\"\n });\n super(null, cfg, server, viewer);\n /** 是否是聚焦分布模式 */\n this._focusPartial = false;\n /** 根据构建检测检测得到的构建分布字符串数组结果 */\n this._partialObjectIds = [];\n /** 当前聚焦的分布索引 */\n this._partialFocusIndex = 0;\n /** 是否已加载metadata */\n this._metaLoaded = false;\n /**\n * 按照指定角度旋转相机\n * @param {number} angleInc\n * @returns\n */\n this.orbitYawCamera = (angleInc) => {\n return new Promise((resolve, reject) => {\n try {\n this.viewer.scene.camera.orbitYaw(angleInc);\n resolve(); // 执行成功时调用 resolve\n }\n catch (error) {\n reject(error); // 发生错误时调用 reject\n }\n });\n };\n this.cameraEnable = (pointerEnabled = !this.viewer.cameraControl.pointerEnabled) => {\n this.viewer.cameraControl.pointerEnabled = pointerEnabled;\n };\n /**\n * 模型截图\n * @param width\n * @param height\n * @param isDownload\n * @returns\n */\n this.shot = (width, height, isDownload) => {\n const canvas = document.getElementById(\"myCanvas\");\n const link = document.createElement(\"a\");\n link.download = \"screenshot.png\";\n const tempCanvas = document.createElement(\"canvas\");\n console.log(\"tempCanvas\", tempCanvas);\n const tempCtx = tempCanvas.getContext(\"2d\");\n if (canvas && tempCtx) {\n tempCanvas.width = width;\n tempCanvas.height = height;\n const scaleX = width / canvas.width;\n const scaleY = height / canvas.height;\n const scale = Math.max(scaleX, scaleY);\n const scaledWidth = canvas.width * scale;\n const scaledHeight = canvas.height * scale;\n const offsetX = (width - scaledWidth) / 2;\n const offsetY = (height - scaledHeight) / 2;\n tempCtx.clearRect(0, 0, width, height);\n tempCtx.fillStyle = \"transparent\"; // 设置透明色\n tempCtx.fillRect(0, 0, width, height);\n tempCtx.drawImage(canvas, 0, 0, canvas.width, canvas.height, 0, 0, 1, 1);\n // tempCtx.drawImage(canvas, 0, 0, canvas.width, canvas.height, offsetX, offsetY, scaledWidth, scaledHeight);\n if (isDownload) {\n tempCanvas.toBlob(function (blob) {\n const url = URL.createObjectURL(blob);\n link.href = url;\n link.click();\n URL.revokeObjectURL(url);\n });\n }\n return tempCanvas.toDataURL(\"image/png\");\n }\n return \"\";\n };\n this._configs = {};\n this._eventTrigger = new _EventTrigger__WEBPACK_IMPORTED_MODULE_2__[\"default\"]();\n this.navCubeCanvasElement = cfg.navCubeCanvasElement;\n this.viewerElement = cfg.viewerElement;\n this._modelId = cfg.modelId;\n this._hasOutlier = false;\n this._outlierObjectIds = [];\n this.navCubeCanvasElement.oncontextmenu = (e) => {\n e.preventDefault();\n };\n this.viewer = viewer;\n this._objectsKdTree3 = new _collision_ObjectsKdTree3__WEBPACK_IMPORTED_MODULE_17__[\"default\"]({\n viewer\n });\n this._customizeViewer();\n this._modelsExplorer = new _explorer_ModelsExplorer__WEBPACK_IMPORTED_MODULE_11__[\"default\"](this, {\n enableEditModels: false,\n modelFromOutSide: true,\n modelType: cfg.modelType,\n modelContent: cfg.modelContent,\n modelSrc: cfg.modelSrc ? cfg.modelSrc : \"/\",\n modelMetaData: cfg.modelMetaData,\n modelConfig: cfg.modelConfig,\n IfcAPI: cfg.IfcAPI,\n WebIFC: cfg.WebIFC\n });\n this._objectsExplorer = new _explorer_ObjectsExplorer__WEBPACK_IMPORTED_MODULE_12__[\"default\"](this, {\n modelType: cfg.modelType\n });\n this._classesExplorer = new _explorer_ClassesExplorer__WEBPACK_IMPORTED_MODULE_13__[\"default\"](this, {\n modelType: cfg.modelType\n });\n this._storeysExplorer = new _explorer_StoreysExplorer__WEBPACK_IMPORTED_MODULE_14__[\"default\"](this, {\n modelType: cfg.modelType\n });\n // 重置相机视角的按钮(小房子图标)\n this._resetAction = new _toolbar_ResetAction__WEBPACK_IMPORTED_MODULE_4__[\"default\"](this, {});\n // 将相机视角放到最合适的位置的图标\n this._fitAction = new _toolbar_FitAction__WEBPACK_IMPORTED_MODULE_5__[\"default\"](this, {});\n // Allows Three-D and First Person toggle buttons to cooperatively switch\n // CameraControl#navMode between \"orbit\", \"firstPerson\" and \"planView\" modes\n class NavModeMediator {\n constructor(bimViewer) {\n this.threeDActive = false;\n this.firstPersonActive = false;\n this.setThreeDModeActive = (active) => {\n if (active) {\n bimViewer._firstPersonMode.setActive(false);\n bimViewer.viewer.cameraControl.navMode = \"orbit\";\n }\n else {\n bimViewer._firstPersonMode.setActive(false);\n bimViewer.viewer.cameraControl.navMode = \"planView\";\n }\n this.threeDActive = active;\n };\n this.setFirstPersonModeActive = (active) => {\n bimViewer.viewer.cameraControl.navMode = active ? \"firstPerson\" : this.threeDActive ? \"orbit\" : \"planView\";\n this.firstPersonActive = active;\n };\n }\n }\n const cameraControlNavModeMediator = new NavModeMediator(this);\n this._threeDMode = new _toolbar_ThreeDMode__WEBPACK_IMPORTED_MODULE_15__[\"default\"](this, {\n cameraControlNavModeMediator\n });\n this._orthoMode = new _toolbar_OrthoMode__WEBPACK_IMPORTED_MODULE_16__[\"default\"](this, {});\n this._firstPersonMode = new _toolbar_FirstPersonMode__WEBPACK_IMPORTED_MODULE_6__[\"default\"](this, {\n cameraControlNavModeMediator\n });\n this._hideTool = new _toolbar_HideTool__WEBPACK_IMPORTED_MODULE_7__[\"default\"](this, {});\n this._annotationTool = new _toolbar_AnnotationTool__WEBPACK_IMPORTED_MODULE_18__[\"default\"](this, {\n modelId: this._modelId\n });\n this._measureTool = new _toolbar_MeasureTool__WEBPACK_IMPORTED_MODULE_19__[\"default\"](this, {});\n this._sectionTool = new _toolbar_SectionTool__WEBPACK_IMPORTED_MODULE_9__[\"default\"](this, {});\n this._commentsTool = new _toolbar_CommentsTool__WEBPACK_IMPORTED_MODULE_20__[\"default\"](this, {});\n this._showSpacesMode = new _toolbar_ShowSpacesMode__WEBPACK_IMPORTED_MODULE_8__[\"default\"](this, {});\n this._navCubeMode = new _toolbar_NavCubeMode__WEBPACK_IMPORTED_MODULE_10__[\"default\"](this, {\n navCubeCanvasElement: this.navCubeCanvasElement,\n viewerElement: this.viewerElement\n });\n this._threeDMode.setActive(true);\n this._firstPersonMode.setActive(false);\n this._navCubeMode.setActive(true);\n this._annotationTool.setActive(false);\n this._measureTool.setActive(false);\n this._modelsExplorer.on(\"modelLoaded\", (modelId) => {\n this.fire(\"modelLoaded\", modelId);\n });\n this._modelsExplorer.on(\"modelUnloaded\", (modelId) => {\n this.fire(\"modelUnloaded\", modelId);\n });\n this._resetAction.on(\"reset\", () => {\n this.fire(\"reset\", true);\n });\n this._mutexActivation([this._hideTool, this._sectionTool, this._annotationTool]);\n this._bcfViewpointsPlugin = new _xtctwins_tctwins_core__WEBPACK_IMPORTED_MODULE_0__.BCFViewpointsPlugin(this.viewer, {});\n this._initConfigs();\n this._initSingleClickEvent();\n this._initRightClickEvent();\n this._initDoubleClickEvent();\n let treeReady = 0;\n this.eventTrigger.on(\"treeReady\", () => {\n treeReady++;\n if (treeReady === 3) {\n this.eventTrigger.emit(\"treeAllReady\", {\n objectsData: this.objectsExplorer.rootNode,\n classesData: this.classesExplorer.rootNode,\n storeysData: this.storeysExplorer.rootNode\n });\n }\n });\n }\n //------------------------------------------------------------------------------------------------------------------\n // 信息和服务\n //------------------------------------------------------------------------------------------------------------------\n get eventTrigger() {\n return this._eventTrigger;\n }\n /**\n * Returns the LocaleService that was configured on this Viewer.\n *\n * @return {LocaleService} The LocaleService.\n */\n get localeService() {\n return this.viewer.localeService;\n }\n //------------------------------------------------------------------------------------------------------------------\n // 点击事件\n //------------------------------------------------------------------------------------------------------------------\n /**\n * 初始化单击事件\n */\n _initSingleClickEvent() {\n this.viewer.cameraControl.on(\"mouseDownEntity\", (e) => {\n if (this.measureAngleTool.getActive() || this.measureDistanceTool.getActive())\n return;\n if (this.sectionTool.getActive() || this.annotationTool.getActive())\n return;\n e.preventDefault;\n const hit = this.viewer.scene.pick({\n canvasPos: e.canvasPos\n });\n if (hit) {\n if (hit.entity) {\n this.singleChoseEntity(hit.entity);\n this._eventTrigger.emit(\"pickedEntity\", hit.entity);\n }\n }\n });\n this.viewer.cameraControl.on(\"mouseDownNothing\", () => {\n if (this.measureAngleTool.getActive() || this.measureDistanceTool.getActive())\n return;\n if (this.sectionTool.getActive() || this.annotationTool.getActive())\n return;\n this.singleChosedSpace();\n this._eventTrigger.emit(\"pickedNothing\");\n });\n this.viewer.cameraControl.on(\"touchPicked\", (e) => {\n if (this.measureAngleTool.getActive() || this.measureDistanceTool.getActive())\n return;\n if (this.sectionTool.getActive() || this.annotationTool.getActive())\n return;\n e.preventDefault;\n const hit = this.viewer.scene.pick({\n canvasPos: e.canvasPos\n });\n if (hit) {\n if (hit.entity) {\n this.singleChoseEntity(hit.entity);\n this._eventTrigger.emit(\"touchEntity\", hit.entity);\n }\n }\n });\n this.viewer.cameraControl.on(\"touchPickedNothing\", () => {\n if (this.measureAngleTool.getActive() || this.measureDistanceTool.getActive())\n return;\n if (this.sectionTool.getActive() || this.annotationTool.getActive())\n return;\n this.singleChosedSpace();\n this._eventTrigger.emit(\"pickedNothing\");\n });\n }\n /**\n * 初始化右键事件\n */\n _initRightClickEvent() {\n this.viewer.cameraControl.on(\"rightClick\", (e) => {\n e.preventDefault;\n const hit = this.viewer.scene.pick({\n canvasPos: e.canvasPos\n });\n if (hit)\n this._eventTrigger.emit(\"rightPicked\", hit.entity);\n else {\n this._eventTrigger.emit(\"rightPickedNothing\");\n }\n });\n }\n /**\n * 初始化双击事件\n */\n _initDoubleClickEvent() {\n this.viewer.cameraControl.on(\"doublePicked\", (e) => {\n if (this.measureAngleTool.getActive() || this.measureDistanceTool.getActive())\n return;\n if (this.sectionTool.getActive() || this.annotationTool.getActive())\n return;\n e.preventDefault;\n const hit = this.viewer.scene.pick({\n canvasPos: e.canvasPos\n });\n if (hit) {\n if (hit.entity) {\n this.doubleChoseEntity(hit.entity);\n this._eventTrigger.emit(\"doublePicked\", hit.entity);\n }\n }\n });\n this.viewer.cameraControl.on(\"doublePickedNothing\", () => {\n if (this.measureAngleTool.getActive() || this.measureDistanceTool.getActive())\n return;\n if (this.sectionTool.getActive() || this.annotationTool.getActive())\n return;\n this.choseSpace();\n this._eventTrigger.emit(\"doublePickedNothing\");\n });\n }\n //------------------------------------------------------------------------------------------------------------------\n // 配置\n //------------------------------------------------------------------------------------------------------------------\n _customizeViewer() {\n const { scene } = this.viewer;\n // Emphasis effects\n scene.xrayMaterial.fill = false;\n scene.xrayMaterial.fillAlpha = 0.3;\n scene.xrayMaterial.fillColor = [0, 0, 0];\n scene.xrayMaterial.edges = true;\n scene.xrayMaterial.edgeAlpha = 0.1;\n scene.xrayMaterial.edgeColor = [0, 0, 0];\n // scene.highlightMaterial.edges = false;\n // scene.highlightMaterial.edgeColor = [0, 0.6, 1];\n // scene.highlightMaterial.edgeAlpha = 0.9;\n // scene.highlightMaterial.fill = true;\n scene.highlightMaterial.fillAlpha = 0.1;\n scene.highlightMaterial.fillColor = [0.6, 0.7, 0.8];\n //------------------------------------------------------------------------------------------------------------------\n // Configure points material\n //------------------------------------------------------------------------------------------------------------------\n scene.pointsMaterial.pointSize = 1;\n scene.pointsMaterial.roundPoints = true;\n scene.pointsMaterial.perspectivePoints = true;\n scene.pointsMaterial.minPerspectivePointSize = 2;\n scene.pointsMaterial.maxPerspectivePointSize = 4;\n // Camera control\n this.viewer.cameraControl.panRightClick = true;\n this.viewer.cameraControl.followPointer = true;\n this.viewer.cameraControl.doublePickFlyTo = false;\n this.viewer.cameraControl.smartPivot = true;\n // Dolly tweaks for best precision when aligning camera for BCF snapshots\n this.viewer.cameraControl.keyboardDollyRate = 100.0;\n this.viewer.cameraControl.mouseWheelDollyRate = 100.0;\n this.viewer.cameraControl.dollyInertia = 0;\n this.viewer.cameraControl.dollyMinSpeed = 0.04;\n this.viewer.cameraControl.dollyProximityThreshold = 30.0;\n const cameraPivotElement = document\n .createRange()\n .createContextualFragment(\"<div class='tctwins-camera-pivot-marker'></div>\").firstChild;\n this.viewer.scene.canvas.canvas.parentNode.appendChild(cameraPivotElement);\n this.viewer.cameraControl.pivotElement = cameraPivotElement;\n scene.camera.perspective.near = 0.01;\n scene.camera.perspective.far = 3000.0;\n scene.camera.ortho.near = 0.01;\n scene.camera.ortho.far = 2000.0; //\n // Scalable Ambient Obscurance (SAO) defaults\n // Since SAO is non-interactive, set to higher-quality\n const { sao } = scene;\n sao.enabled = false;\n sao.numSamples = 50;\n sao.kernelRadius = 200;\n }\n _initConfigs() {\n this.setConfigs({\n cameraNear: \"0.05\",\n cameraFar: \"3000.0\",\n smartPivot: true,\n saoEnabled: false,\n pbrEnabled: true,\n saoBias: \"0.5\",\n saoIntensity: \"0.15\",\n saoNumSamples: \"40\",\n saoKernelRadius: \"100\",\n edgesEnabled: false,\n xrayContext: true,\n xrayPickable: true,\n selectedGlowThrough: true,\n highlightGlowThrough: true,\n backgroundTransparency: true,\n backgroundColor: [1, 1.0, 1.0],\n objectColorSource: \"model\",\n externalMetadata: false,\n dtxEnabled: true,\n snapRadius: 20\n });\n }\n /**\n * Sets a batch of viewer configurations.\n *\n * Note that this method is not to be confused with {@link BIMViewer#setViewerState}, which batch-updates various states of the viewer's UI and 3D view.\n *\n * See [Viewer Configurations] for the list of available configurations.\n *\n * @param {*} viewerConfigs Map of key-value configuration pairs.\n */\n setConfigs(viewerConfigs) {\n for (const name in viewerConfigs) {\n if (Object.prototype.hasOwnProperty.call(viewerConfigs, name)) {\n const value = viewerConfigs[name];\n this.setConfig(name, value);\n }\n }\n // viewerConfigs.forEach((name: string) => {\n // if (Object.prototype.hasOwnProperty.call(viewerConfigs, name)) {\n // const value = viewerConfigs[name];\n // this.setConfig(name, value);\n // }\n // });\n }\n /**\n * Sets a viewer configuration.\n *\n * See [Viewer Configurations] for the list of available configurations.\n *\n * @param {String} name Configuration name.\n * @param {*} value Configuration value.\n */\n setConfig(name, value) {\n function parseBool(value) {\n return value === true || value === \"true\";\n }\n try {\n switch (name) {\n case \"backgroundTransparency\":\n const transparent = value;\n this.setBackgroundTransparent(transparent);\n this._configs[name] = transparent;\n break;\n case \"backgroundColor\":\n if (this._configs.backgroundTransparency) {\n break;\n }\n const rgbColor = value;\n this.setBackgroundColor(rgbColor);\n this._configs[name] = rgbColor;\n break;\n case \"cameraNear\":\n const near = parseFloat(value);\n this.viewer.scene.camera.perspective.near = near;\n this.viewer.scene.camera.ortho.near = near;\n this._configs[name] = near;\n break;\n case \"cameraFar\":\n const far = parseFloat(value);\n this.viewer.scene.camera.perspective.far = far;\n // this.viewer.scene.camera.ortho.far = far;\n this._configs[name] = far;\n break;\n case \"smartPivot\":\n this.viewer.cameraControl.smartPivot = this._configs[name] = parseBool(value);\n break;\n case \"saoEnabled\":\n // todo:\n this.viewer.scene.saoEnabled = this._configs[name] = parseBool(value);\n break;\n case \"saoBias\":\n this.viewer.scene.sao.bias = parseFloat(value);\n break;\n case \"saoIntensity\":\n this.viewer.scene.sao.intensity = parseFloat(value);\n break;\n case \"saoKernelRadius\":\n this.viewer.scene.sao.kernelRadius = this._configs[name] = parseFloat(value);\n break;\n case \"saoNumSamples\":\n this.viewer.scene.sao.numSamples = this._configs[name] = parseFloat(value);\n break;\n case \"saoBlur\":\n this.viewer.scene.sao.blur = this._configs[name] = parseBool(value);\n break;\n case \"edgesEnabled\":\n this.setEdgesEnabled(value);\n break;\n case \"pbrEnabled\":\n // this.viewer.scene.pbrEnabled = this._configs[name] = parseBool(value);\n break;\n case \"viewFitFOV\":\n this.viewer.cameraFlight.fitFOV = this._configs[name] = parseFloat(value);\n break;\n case \"viewFitDuration\":\n this.viewer.cameraFlight.duration = this._configs[name] = parseFloat(value);\n break;\n case \"perspectiveFOV\":\n this.viewer.camera.perspective.fov = this._configs[name] = parseFloat(value);\n break;\n case \"excludeUnclassifiedObjects\":\n this._configs[name] = parseBool(value);\n break;\n case \"objectColorSource\":\n this.setObjectColorSource(value);\n this._configs[name] = value;\n break;\n case \"xrayContext\":\n this._configs[name] = value;\n break;\n case \"xrayPickable\":\n this._configs[name] = parseBool(value);\n break;\n case \"selectedGlowThrough\":\n const selectedGlowThrough = (this._configs[name] = parseBool(value));\n const { selectedMaterial } = this.viewer.scene;\n selectedMaterial.glowThrough = selectedGlowThrough;\n selectedMaterial.fillAlpha = selectedGlowThrough ? 0.5 : 1.0;\n selectedMaterial.edgeAlpha = selectedGlowThrough ? 0.5 : 1.0;\n break;\n case \"highlightGlowThrough\":\n const highlightGlowThrough = (this._configs[name] = parseBool(value));\n const { highlightMaterial } = this.viewer.scene;\n highlightMaterial.glowThrough = highlightGlowThrough;\n highlightMaterial.fillAlpha = highlightGlowThrough ? 0.1 : 1.0;\n highlightMaterial.edgeAlpha = highlightGlowThrough ? 0.1 : 1.0;\n break;\n case \"externalMetadata\":\n this._configs[name] = value;\n break;\n case \"showSpaces\":\n // this._configs[name] = parseBool(value);\n this._showSpacesMode.setActive(value);\n break;\n case \"dtxEnabled\":\n this._configs[name] = parseBool(value);\n this.viewer.scene.dtxEnabled = value;\n break;\n case \"snapRadius\":\n this.setSnapRadius(value);\n break;\n default:\n this.error(`setConfig() - unsupported configuration: '${name}'`);\n }\n }\n catch (e) {\n this.error(`setConfig() - failed to configure ${name}: ${e}`);\n }\n }\n /**\n * Gets the value of a viewer configuration.\n *\n * These are set with {@link BIMViewer#setConfig} and {@link BIMViewer#setConfigs}.\n *\n * @param {String} name Configuration name.\n * @ereturns {*} Configuration value.\n */\n getConfig(name) {\n return this._configs[name];\n }\n getConfigs() {\n return this._configs;\n }\n //------------------------------------------------------------------------------------------------------------------\n // 查询\n //------------------------------------------------------------------------------------------------------------------\n /**\n * Returns the IDs of the models in the currently loaded project.\n *\n * @returns {String[]} The IDs of the models in the currently loaded project.\n */\n modelId() {\n return this._modelId;\n }\n /**\n * Loads a model into the viewer.\n *\n * Assumes that the project containing the model is currently loaded.\n *\n * @param {String} modelId ID of the model to load. Must be the ID of one of the models in the currently loaded project.\n * @param {Function} done Callback invoked on success.\n * @param {Function} error Callback invoked on failure, into which the error message string is passed.\n */\n loadModel(done, error) {\n if (!done)\n done = () => { };\n if (!error)\n error = () => { };\n this._modelsExplorer.loadModel(this._modelId, () => {\n done();\n }, (errorMsg) => {\n this.error(`loadModel() - ${errorMsg}`);\n error(errorMsg);\n });\n }\n /**\n * 单独加载元数据\n * @param deflatedMetadata\n */\n loadMetadata(deflatedMetadata, force = true, done) {\n this._modelsExplorer.loadMetadata(this.viewer.metaScene.metaModels[this._modelId], deflatedMetadata, force, () => {\n this._metaLoaded = true;\n if (this._focusPartial) {\n this.viewFitPartial(0, done);\n }\n else {\n done;\n }\n });\n }\n /**\n * Sets where the colors for model objects will be loaded from.\n *\n * Options are:\n *\n * * \"model\" - (default) load colors from models, and\n * * \"viewer\" - load colors from the viewer's inbuilt table of colors for IFC types.\n *\n * This is \"model\" by default.\n *\n * @param {String} source Where colors will be loaded from - \"model\" or \"viewer\".\n */\n setObjectColorSource(source) {\n switch (source) {\n case \"model\":\n break;\n case \"viewer\":\n break;\n default:\n source = \"model\";\n this.error(\"setObjectColorSource() - Unsupported value - accepted values are 'model' and 'viewer' - defaulting to 'model'\");\n return;\n }\n this._objectColorSource = source;\n }\n /**\n * 获取构件属性\n * @param objectId\n * @returns\n */\n getObjectProperties(objectId) {\n const metaObject = this.viewer.metaScene.metaObjects[objectId];\n if (!metaObject) {\n return null;\n }\n const info = {\n id: metaObject.id,\n name: metaObject.name,\n type: metaObject.type,\n propertySets: []\n };\n const { propertySets } = metaObject;\n if (propertySets && propertySets.length > 0) {\n for (let i = 0; i < propertySets.length; i++) {\n const properties = propertySets[i].properties;\n const propertyList = [];\n for (let j = 0; j < properties.length; j++) {\n const properValue = {};\n properValue[properties[j].name] = properties[j].value;\n propertyList.push(properValue);\n }\n const propertyset = {\n id: propertySets[i].id,\n name: propertySets[i].name,\n properties: propertyList,\n type: propertySets[i].type\n };\n info.propertySets.push(propertyset);\n }\n }\n return info;\n }\n /**\n * 获取模型信息\n * @returns\n */\n getModelInfo() {\n const metaModel = this.viewer.metaScene.metaModels[this._modelId];\n const modelInfo = {\n id: metaModel.id,\n createDate: metaModel.createdAt ? metaModel.createdAt : \"\",\n author: metaModel.author ? metaModel.author : \"\",\n objectCount: metaModel.objectCount ? metaModel.objectCount : \"\",\n propertySetCount: metaModel.propertySetCount ? metaModel.propertySetCount : \"\"\n };\n return modelInfo;\n }\n //------------------------------------------------------------------------------------------------------------------\n // 视图设置\n //------------------------------------------------------------------------------------------------------------------\n /**\n * Sets whether or not the given objects are visible.\n *\n * @param {String[]} objectIds IDs of objects.\n * @param {Boolean} visible True to set objects visible, false to set them invisible.\n */\n setObjectsVisible(objectIds, visible) {\n this._withObjectsInSubtree(objectIds, (entity) => {\n entity.visible = visible;\n });\n }\n /**\n * Sets whether or not the given objects are selected.\n *\n * @param {String[]} objectIds IDs of objects.\n * @param {Boolean} selected Whether or not to set the objects selected.\n */\n setObjectsSelected(objectIds, selected) {\n this._withObjectsInSubtree(objectIds, (entity) => {\n entity.selected = selected;\n });\n }\n /**\n * Sets whether or not the given objects are X-rayed.\n *\n * @param {String[]} objectIds IDs of objects.\n * @param {Boolean} xrayed Whether or not to X-ray the objects.\n */\n setObjectsXRayed(objectIds, xrayed) {\n this._withObjectsInSubtree(objectIds, (entity) => {\n entity.xrayed = xrayed;\n });\n }\n _withObjectsInSubtree(objectIds, callback) {\n if (!objectIds) {\n this.error(\"Argument expected: objectIds\");\n return;\n }\n objectIds.forEach((objectId) => {\n // const objectId = objectIds[index];\n this.viewer.metaScene.withMetaObjectsInSubtree(objectId, (metaObject) => {\n const entity = this.viewer.scene.objects[metaObject.id];\n if (entity) {\n callback(entity);\n }\n });\n });\n }\n /**\n * Flies the camera to fit the given object in view.\n *\n * @param {String} objectId ID of the object\n * @param {Function} done Callback invoked on completion\n */\n flyToObject(objectId, done) {\n if (!objectId) {\n this.error(\"flyToObject() - Argument expected: objectId\");\n return;\n }\n const { viewer } = this;\n const { scene } = viewer;\n const objectIds = [];\n this.viewer.metaScene.withMetaObjectsInSubtree(objectId, (metaObject) => {\n if (scene.objects[metaObject.id]) {\n objectIds.push(metaObject.id);\n }\n });\n if (objectIds.length === 0) {\n this.error(`Object not found in viewer: '${objectId}'`);\n if (done) {\n done();\n }\n return;\n }\n scene.setObjectsVisible(objectIds, true);\n scene.setObjectsHighlighted(objectIds, true);\n const aabb = scene.getAABB(objectIds);\n viewer.cameraFlight.flyTo({\n aabb\n }, () => {\n if (done) {\n done();\n }\n setTimeout(() => {\n scene.setObjectsHighlighted(scene.highlightedObjectIds, false);\n }, 500);\n });\n viewer.cameraControl.pivotPos = _xtctwins_tctwins_core__WEBPACK_IMPORTED_MODULE_0__.math.getAABB3Center(aabb);\n }\n /**\n * Flies the camera to fit the given objects in view.\n *\n * @param {String[]} objectIds IDs of the objects\n * @param {Function} done Callback invoked on completion\n */\n viewFitObjects(objectIds, done) {\n if (!objectIds) {\n this.error(\"flyToObject() - Argument expected: objectIds\");\n return;\n }\n const { viewer } = this;\n const { scene } = viewer;\n const entityIds = [];\n objectIds.forEach((objectId) => {\n this.viewer.metaScene.withMetaObjectsInSubtree(objectId, (metaObject) => {\n if (scene.objects[metaObject.id]) {\n entityIds.push(metaObject.id);\n }\n });\n });\n if (entityIds.length === 0) {\n if (done) {\n done();\n }\n return;\n }\n scene.setObjectsVisible(entityIds, true);\n scene.setObjectsHighlighted(entityIds, true);\n const aabb = scene.getAABB(entityIds);\n viewer.cameraFlight.flyTo({\n aabb\n }, () => {\n if (done) {\n done();\n }\n setTimeout(() => {\n scene.setObjectsHighlighted(scene.highlightedObjectIds, false);\n }, 500);\n });\n viewer.cameraControl.pivotPos = _xtctwins_tctwins_core__WEBPACK_IMPORTED_MODULE_0__.math.getAABB3Center(aabb);\n }\n /**\n * 相机立刻聚焦到指定构建id的对象,没有转移视角动画\n * @param {String} objectId\n */\n jumpToObjects(objectIds) {\n if (!objectIds) {\n this.error(\"jumpToObject() - Argument expected: objectIds\");\n return;\n }\n const { viewer } = this;\n const { scene } = viewer;\n const entityIds = [];\n this.viewer.metaScene.withMetaObjectsInSubtree(objectIds, (metaObject) => {\n if (scene.objects[metaObject.id]) {\n entityIds.push(metaObject.id);\n }\n });\n if (entityIds.length === 0) {\n this.error(`Objects not found in viewer: '${objectIds}'`);\n return;\n }\n scene.setObjectsVisible(entityIds, true);\n const aabb = scene.getAABB(entityIds);\n viewer.cameraFlight.jumpTo({\n aabb\n });\n viewer.cameraControl.pivotPos = _xtctwins_tctwins_core__WEBPACK_IMPORTED_MODULE_0__.math.getAABB3Center(aabb);\n }\n /**\n * 设置相机位置\n * @param {Number[]} [params.eye] Eye position.\n * @param {Number[]} [params.look] Point of interest.\n * @param {Number[]} [params.up] Direction of \"up\".\n */\n setCamera(params) {\n const { viewer } = this;\n const { scene } = viewer;\n const { camera } = scene;\n if (params.eye) {\n camera.eye = params.eye;\n }\n if (params.look) {\n camera.look = params.look;\n }\n if (params.up) {\n camera.up = params.up;\n }\n }\n /**\n * 相机移动到指定视角\n * @param {Number[]} [params.eye] 相机位置.\n * @param {Number[]} [params.look] 相机视点\n * @param {Number[]} [params.up] 上方方向\n */\n flyToNewView(params) {\n this.viewer.cameraControl.pivotPos = params.look;\n this.viewer.cameraFlight.flyTo({\n look: params.look,\n eye: params.eye,\n up: params.up,\n duration: params.duration\n });\n }\n /**\n * Fits the given models in view.\n *\n * @param {String[]} modelIds ID of the models.\n * @param {Function} [done] Callback invoked on completion. Will be animated if this is given, otherwise will be instantaneous.\n */\n viewFitModels(modelIds, done) {\n if (!modelIds) {\n this.error(\"viewFitModels() - Argument expected: modelIds\");\n return;\n }\n const { viewer } = this;\n const { scene } = viewer;\n const aabb = _xtctwins_tctwins_core__WEBPACK_IMPORTED_MODULE_0__.math.AABB3();\n _xtctwins_tctwins_core__WEBPACK_IMPORTED_MODULE_0__.math.collapseAABB3(aabb);\n modelIds.forEach((modelId) => {\n const model = scene.models[modelId];\n if (model) {\n model.visible = true;\n model.highlighted = true;\n _xtctwins_tctwins_core__WEBPACK_IMPORTED_MODULE_0__.math.expandAABB3(aabb, model.aabb);\n }\n else {\n this.error(`Model not found in viewer: '${modelId}'`);\n }\n });\n if (done) {\n viewer.cameraFlight.flyTo({\n aabb\n }, () => {\n done();\n setTimeout(() => {\n scene.setObjectsHighlighted(scene.highlightedObjectIds, false);\n }, 500);\n });\n }\n else {\n viewer.cameraFlight.jumpTo({\n aabb\n });\n setTimeout(() => {\n scene.setObjectsHighlighted(scene.highlightedObjectIds, false);\n }, 500);\n }\n viewer.cameraControl.pivotPos = _xtctwins_tctwins_core__WEBPACK_IMPORTED_MODULE_0__.math.getAABB3Center(aabb);\n }\n /**\n * 切换模型分布 - 根据构建检测结果的模型分布情况聚焦不同分布区域\n *\n * 使用:\n * bimViewer.viewFitPartial(1, (partNum:number)=>{\n * console.log(partNum); //当前聚焦的模型分布索引\n * })\n *\n * bimViewer.viewFitPartial((partNum:number)=>{\n * console.log(partNum); //当前聚焦的模型分布索引\n * })\n *\n * bimViewer.viewFitPartial(1); //无回调方法。自动切换分布视角\n *\n * bimViewer.viewFitPartial(); //无指定索引输入,无回调方法。自动切换分布视角\n *\n *\n * @param {number} part - 模型分布索引(例如:根据检测结果,当前模型有三块模型分布,则可以输入[0-2]区间的数字)\n * @param {Function} done -\n */\n viewFitPartial(part, done) {\n let partNum;\n if (typeof part === \"function\") {\n done = part;\n partNum = this._partialFocusIndex += 1;\n }\n else {\n partNum = part !== null && part !== void 0 ? part : (this._partialFocusIndex += 1);\n }\n if (partNum >= 0 && partNum < this._partialObjectIds.length) {\n this.viewFitObjects(this._partialObjectIds[partNum], () => {\n for (let i = 0; i < this._partialObjectIds.length; i++) {\n if (partNum == i)\n this.setObjectsVisible(this._partialObjectIds[i], true);\n else\n this.setObjectsVisible(this._partialObjectIds[i], false);\n }\n done ? done(partNum) : done;\n });\n }\n else {\n partNum = this._partialFocusIndex = 0;\n this.viewFitObjects(this._partialObjectIds[partNum], () => {\n for (let i = 0; i < this._partialObjectIds.length; i++) {\n if (partNum == i)\n this.setObjectsVisible(this._partialObjectIds[i], true);\n else\n this.setObjectsVisible(this._partialObjectIds[i], false);\n }\n done ? done(partNum) : done;\n });\n }\n }\n /**\n * 设置模型分布 - 根据构建检测结果设置不同分布位置的模型构建ID数组\n * @param {string[][]} partialObjectIds\n */\n setPartialObjectIds(partialObjectIds) {\n const newPartialIdsList = [];\n for (let i = 0; i < partialObjectIds.length; i++) {\n newPartialIdsList.push(partialObjectIds[i]);\n }\n this._partialObjectIds = newPartialIdsList;\n this.viewer.cameraControl.smartPivot = false;\n this.navCubeMode.fitVisible = true;\n this._focusPartial = true;\n if (this._metaLoaded)\n this.viewFitPartial(0);\n }\n /// /////////部分操作////////////////////////////////////////\n /**\n * Transitions the viewer into an isolated view of the given building storey.\n *\n * Does nothing and logs an error if no object of the given ID is in the viewer, or if the object is not an ````IfcBuildingStorey````.\n *\n * @param {String} storeyObjectId ID of an ````IfcBuildingStorey```` object.\n * @param {Function} [done] Optional callback to invoke on completion. When provided, the transition will be animated, with the camera flying into position. Otherwise, the transition will be instant, with the camera jumping into position.\n */\n selectStorey(storeyObjectId, done = () => { }) {\n const { metaScene } = this.viewer;\n const storeyMetaObject = metaScene.metaObjects[storeyObjectId];\n if (!storeyMetaObject) {\n this.error(`selectStorey() - Object is not found: '${storeyObjectId}'`);\n return;\n }\n if (storeyMetaObject.type !== \"IfcBuildingStorey\") {\n this.error(`selectStorey() - Object is not an IfcBuildingStorey: '${storeyObjectId}'`);\n return;\n }\n this._storeysExplorer.selectStorey(storeyObjectId, done);\n }\n /**\n * Sets whether or not keyboard camera control is enabled.\n *\n * This is useful when we don't want key events over the canvas to clash with other UI elements outside the canvas.\n *\n * Default value is ````true````.\n *\n * @param {Boolean} enabled Set ````true```` to enable keyboard input.\n */\n setKeyboardEnabled(enabled) {\n this.viewer.scene.input.keyboardEnabled = enabled;\n }\n /**\n * Gets whether keyboard camera control is enabled.\n *\n * This is useful when we don't want key events over the canvas to clash with other UI elements outside the canvas.\n *\n * Default value is ````true````.\n *\n * @returns {Boolean} Returns ````true```` if keyboard input is enabled.\n */\n getKeyboardEnabled() {\n return this.viewer.scene.input.keyboardEnabled;\n }\n /**\n * 缓冲对象spinner显隐设置\n * @param show\n */\n showSpinner(show = !this.viewer.scene.canvas.spinner.visible) {\n this.viewer.scene.canvas.spinner.visible = show;\n }\n /**\n * 更新包围盒 - 排除异常构建并更新包围盒\n * @param exceptionIDs - 异常构建ID\n * @param callback - 回调\n */\n updateAABB(exceptionIDs, callback) {\n if (exceptionIDs.length > 0) {\n this._hasOutlier = true;\n this._outlierObjectIds = exceptionIDs;\n }\n const model = this.viewer.scene.models[this._modelId];\n const newExceptionsIds = exceptionIDs.concat(model.exceptionIds);\n model.exceptionIds = newExceptionsIds;\n this.viewer.scene.setObjectsVisible(newExceptionsIds, false);\n this.viewer.scene.on(\"aabb\", () => {\n if (typeof callback === \"function\")\n callback();\n });\n }\n /**\n * 销毁\n */\n destroy(callback) {\n var _a;\n this.measureDistanceTool.destroy();\n this.measureAngleTool.destroy();\n this._annotationTool.destroy();\n this._commentsTool.destroy();\n this._bcfViewpointsPlugin.destroy();\n this._modelsExplorer.destroy();\n this._classesExplorer.destroy();\n this._objectsExplorer.destroy();\n this._storeysExplorer.destroy();\n this._eventTrigger.destroy();\n const dos = document.querySelector(\".tctwins-camera-pivot-marker\");\n if (dos) {\n (_a = dos.parentNode) === null || _a === void 0 ? void 0 : _a.removeChild(dos);\n }\n this.viewer.destroy(callback);\n }\n /// /////////右键菜单////////////////////////////////////////\n // 选中\n /**\n * 设置对象被选中与否\n * @param entity\n * @param selected\n */\n setEntitySelected(entity, selected = !entity.selected) {\n entity.selected = selected;\n }\n /**\n * 选中其他对象\n * @param entity\n */\n setOthersSelected(entity) {\n this.setAllObjectsSelected(true);\n this.setEntitySelected(entity, true);\n }\n /**\n * 设置全部选中与否\n * @param {Boolean} selected\n */\n setAllObjectsSelected(selected) {\n if (selected) {\n this.viewer.scene.setObjectsSelected(this.viewer.scene.objectIds, true);\n }\n else {\n this.viewer.scene.setObjectsSelected(this.viewer.scene.selectedObjectIds, false);\n }\n }\n // 聚焦\n /**\n * 设置相机适应选中对象\n * @param entity\n */\n viewFitEntity(entity) {\n const { scene } = this.viewer;\n this.viewer.cameraFlight.flyTo({\n aabb: entity.aabb,\n duration: 0.5\n }, () => {\n setTimeout(() => {\n scene.setObjectsHighlighted(scene.highlightedObjectIds, false);\n }, 500);\n });\n this.viewer.cameraControl.pivotPos = _xtctwins_tctwins_core__WEBPACK_IMPORTED_MODULE_0__.math.getAABB3Center(entity.aabb);\n }\n /**\n * 相机适应所有选中对象\n */\n viewFitSelectedObjects() {\n this.viewFitObjects(this.viewer.scene.highlightedObjectIds, () => { });\n }\n /**\n * Flies the camera to fit all objects in view.\n *\n * @param {Function} done Callback invoked on completion\n */\n viewFitAll(done) {\n if (this._focusPartial) {\n this.viewFitPartial(this._partialFocusIndex, done);\n return;\n }\n this._fitAction.fit(done);\n }\n // 隐藏\n /**\n * 设置选中对象隐藏与否\n * @param entity\n */\n setEntityHide(entity, visible = !entity.visible) {\n entity.visible = visible;\n }\n /**\n * 隐藏选中对象以外的其他模型对象\n * @param entity\n * @returns\n */\n setOthersHide(entity) {\n const metaObject = this.viewer.metaScene.metaObjects[entity.id];\n if (!metaObject) {\n return;\n }\n this.viewer.scene.setObjectsVisible(this.viewer.scene.visibleObjectIds, false);\n metaObject.withMetaObjectsInSubtree((metaObject) => {\n const entity = this.viewer.scene.objects[metaObject.id];\n if (entity) {\n entity.visible = true;\n }\n });\n }\n /**\n * 显示所有对象\n * @param {Boolean} visible True to set objects visible, false to set them invisible.\n */\n setAllObjectsVisible(visible) {\n if (visible) {\n this.viewer.scene.setObjectsVisible(this.viewer.scene.objectIds, true);\n if (this._hasOutlier)\n this.viewer.scene.setObjectsVisible(this._outlierObjectIds, false);\n }\n else {\n this.viewer.scene.setObjectsVisible(this.viewer.scene.visibleObjectIds, false);\n }\n }\n // 透视\n /**\n * 设置选中对象透视与否\n * @param entity\n * @param xrayed\n */\n setEntityXRayed(entity, xrayed = !entity.xrayed) {\n entity.xrayed = xrayed;\n entity.pickable = this.getConfig(\"xrayPickable\");\n }\n /**\n * 设置其他对象透视\n * @param entity\n * @returns\n */\n setOthersXRayed(entity) {\n const { scene } = this.viewer;\n const metaObject = this.viewer.metaScene.metaObjects[entity.id];\n if (!metaObject) {\n return;\n }\n scene.setObjectsVisible(scene.objectIds, true);\n scene.setObjectsXRayed(scene.objectIds, true);\n if (!this.getConfig(\"xrayPickable\")) {\n scene.setObjectsPickable(scene.objectIds, false);\n }\n metaObject.withMetaObjectsInSubtree((metaObject) => {\n const entity = scene.objects[metaObject.id];\n if (entity) {\n entity.xrayed = false;\n entity.pickable = true;\n }\n });\n }\n /**\n * 设置所有对象透视与否\n * @param {Boolean} xrayed Whether or not to set all objects X-rayed.\n */\n setAllObjectsXRayed(xrayed) {\n if (xrayed) {\n this.viewer.scene.setObjectsXRayed(this.viewer.scene.objectIds, true);\n }\n else {\n this.viewer.scene.setObjectsXRayed(this.viewer.scene.xrayedObjectIds, false);\n }\n }\n // 判断\n entityVisble(entity) {\n return entity.visible;\n }\n entityXRayed(entity) {\n return entity.xrayed;\n }\n entityChosed(entity) {\n return entity.selected;\n }\n /**\n * 判断是否有被隐藏的\n * @returns\n */\n hiddenMoreThanOne() {\n return this.viewer.scene.numObjects - this.viewer.scene.numVisibleObjects > 0;\n }\n /**\n * 判断是否有被透视的\n * @returns\n */\n xRayedMoreThanOne() {\n return this.viewer.scene.numXRayedObjects > 0;\n }\n /**\n * 判断是否有被选中的\n * @returns\n */\n SelectedMoreThanOne() {\n return this.viewer.scene.numSelectedObjects > 0;\n }\n /// /////////设置背景颜色,透明,边缘等 初始设置///////////////////////////\n /**\n * Sets the viewer's background color.\n *\n * @param {boolean}\n */\n setBackgroundTransparent(trans = !this.viewer.scene.backgroundTransparent) {\n this.viewer.scene.backgroundTransparent = trans;\n this.viewer.scene.render(true);\n }\n /**\n * Sets the viewer's background color.\n *\n * @param {Number[]} rgbColor Three-element array of RGB values, each in range ````[0..1]````.\n */\n setBackgroundColor(rgbColor) {\n this.viewer.scene.backgroundColor = rgbColor;\n this.viewer.scene.render(true);\n }\n /**\n * 设置导航盒尺寸\n * @param {number} size 默认是200\n */\n setNavCubeSize(size) {\n this.navCubeCanvasElement.style.width = `${size.toString()}px`;\n this.navCubeCanvasElement.style.height = `${size.toString()}px`;\n }\n /**\n * 设置导航盒的位置\n * @param {string} direction e.g.\"left\",\"right\",\"top\",\"bottom\"\n * @param {number} pos\n */\n setNavCubePosition(direction, pos) {\n switch (direction) {\n case \"top\":\n this.navCubeCanvasElement.style.top = `${pos.toString()}px`;\n this.navCubeCanvasElement.style.bottom = \"\";\n break;\n case \"bottom\":\n this.navCubeCanvasElement.style.top = \"\";\n this.navCubeCanvasElement.style.bottom = `${pos.toString()}px`;\n break;\n case \"right\":\n this.navCubeCanvasElement.style.left = \"\";\n this.navCubeCanvasElement.style.right = `${pos.toString()}px`;\n break;\n case \"left\":\n this.navCubeCanvasElement.style.right = \"\";\n this.navCubeCanvasElement.style.left = `${pos.toString()}px`;\n break;\n }\n }\n /**\n * 更新canvas\n */\n updateCanvas() {\n this.viewer.scene.canvas.dirtyBoundary = true;\n }\n /**\n * 设置测量鼠标偏移量\n * @param offsetX\n * @param offsetY\n */\n setMeasureOffSet(offsetX, offsetY) {\n this._measureTool.setMeasureOffSet(offsetX, offsetY);\n }\n /**\n * 设置批注鼠标偏移量\n * @param offsetX\n * @param offsetY\n */\n setCommentsOffset(offsetX, offsetY) {\n this._commentsTool.offsetX = offsetX;\n this._commentsTool.offsetY = offsetY;\n }\n /**\n * 设置测量鼠标吸附点灵敏度\n * @param radius\n */\n setSnapRadius(radius) {\n this.measureTool.setSnapRadius(radius);\n }\n /**\n * 设置是否是触屏模式\n * @param {boolean} isTouch\n */\n setIsTouch(isTouch) {\n this.sectionTool.isTouch = isTouch;\n this.commentTool.isTouch = isTouch;\n }\n /**\n * 调整光照强度 0-100\n * @param num\n */\n setLightIntensity(num) {\n if (num < 0 || num > 100)\n return;\n for (let name in this.viewer.scene.lightsObject) {\n this.viewer.scene.lightsObject[name].intensity = 0.63 + (num - 50) / 200;\n }\n }\n /**\n * 设置空间构建的颜色模式;默认 1\n * @param {number} colorState\n */\n setSpaceMaterialColor(colorState) {\n if (colorState === 1)\n this.viewer.scene.highlightMaterial.fillColor = [0.6, 0.7, 0.8];\n else if (colorState === 2)\n this.viewer.scene.highlightMaterial.fillColor = [0.2, 0.3, 0.4];\n }\n /////////////渲染设置//////////////////////\n /**\n * set edges Enable\n * @param {boolean} edgesEnabled\n */\n setEdgesEnabled(edgesEnabled = !this.viewer.scene.edgesEnabled) {\n this.viewer.scene.edgesEnabled = edgesEnabled;\n this.viewer.scene.render(true);\n }\n /**\n * 是否开启环境光\n * @param {boolean} saoEnabled\n */\n setSAOEnabled(saoEnabled = !this.viewer.scene.saoEnabled) {\n this.viewer.scene.saoEnabled = saoEnabled;\n }\n setDTXEnabled(dtxEnabled = !this.viewer.scene.dtxEnabled) {\n this.viewer.scene.dtxEnabled = dtxEnabled;\n }\n setPBREnabled(pbrEnabled = !this.viewer.scene.pbrEnabled) {\n this.viewer.scene.pbrEnabled = pbrEnabled;\n }\n /**\n * 视图复位 - 恢复默认视图\n */\n resetView(callback) {\n if (this._focusPartial) {\n this.setDirection(25);\n return;\n }\n this._resetAction.reset(callback);\n }\n /**\n * 自适应 - 在当前相机视角适应视图填充画面\n */\n fitView(callback) {\n if (this._focusPartial) {\n this.viewFitPartial(this._partialFocusIndex, callback);\n return;\n }\n this._fitAction.fit();\n }\n /**\n * 标注开关\n * @param active\n * @param callback\n */\n SetAnnotationToolActive(active = !this._annotationTool.getActive(), callback) {\n this._annotationTool.setActive(active);\n if (callback)\n callback(this._annotationTool.getActive());\n }\n /**\n * 批注开关\n * @param active\n * @param callback\n */\n SetCommentsToolActive(active = !this._commentsTool.getActive(), callback) {\n this._commentsTool.setActive(active);\n if (callback)\n callback(this._commentsTool.getActive());\n }\n /**\n * 第一人称视角\n * @param active\n * @param callback\n */\n SetFirstPersonModeActive(active = !this._firstPersonMode.getActive(), callback) {\n this._firstPersonMode.setActive(active);\n if (callback)\n callback(this._firstPersonMode.getActive());\n }\n /**\n * 测量工具统一开关\n * @param active\n * @param callback\n */\n SetMeasureToolActive(active = !this.measureAngleTool.getActive(), callback) {\n this._measureTool.setActive(active);\n if (callback)\n callback(this._measureTool.getActive());\n }\n /**\n * 角度测量开关\n * @param active\n * @param callback\n */\n SetMeasureAngleActive(active = !this.measureAngleTool.getActive(), callback) {\n this._measureTool.SetMeasureAngleActive(active);\n if (callback)\n callback(this.measureAngleTool.getActive());\n }\n /**\n * 距离测量开关\n * @param active\n * @param callback\n */\n SetMeasureDistanceActive(active = !this.measureDistanceTool.getActive(), callback) {\n this._measureTool.SetMeasureDistanceActive(active);\n if (callback)\n callback(this.measureDistanceTool.getActive());\n }\n /**\n * 剖切工具开关\n * @param active\n * @param callback\n */\n SetSectionToolActive(active = !this._sectionTool.getActive(), callback) {\n this._sectionTool.setActive(active);\n if (callback)\n callback(this._sectionTool.getActive());\n }\n /**\n * 隐藏工具开关\n * @param active\n * @param callback\n */\n SetHideToolActive(active, callback) {\n this._hideTool.setActive(active);\n if (callback)\n callback();\n }\n /**\n * 框选开关\n * @param active\n * @param callback\n */\n SetMarqueeSelectionActive(active, callback) {\n // this._marqueeSelectionTool.setActive(active);\n if (callback)\n callback();\n }\n /**\n * 相机视角开关\n * @param active\n * @param callback\n */\n SetOrthoModeActive(active = !this._orthoMode.getActive(), callback) {\n this._orthoMode.setActive(active, callback);\n }\n /**\n * 3d/2d视角开关\n * @param active\n * @param callback\n */\n SetThreeDModeActive(active = !this._threeDMode.getActive(), callback) {\n this._threeDMode.setActive(active, callback);\n }\n /**\n * 显示空间功能开关\n * @param active\n * @param callback\n */\n SetShowSpaceModeActive(active = !this._showSpacesMode.getActive(), callback) {\n this._showSpacesMode.setActive(active, callback);\n }\n /// ///////////////功能对象/////////////////////\n /**\n * 漫游\n */\n get firstPersonMode() {\n return this._firstPersonMode;\n }\n /**\n * 测量管理工具\n */\n get measureTool() {\n return this._measureTool;\n }\n /**\n * 角度测量\n */\n get measureAngleTool() {\n return this._measureTool.measureAngleTool;\n }\n /**\n * 距离测量\n */\n get measureDistanceTool() {\n return this._measureTool.measureDistanceTool;\n }\n /**\n * 剖切\n */\n get sectionTool() {\n return this._sectionTool;\n }\n /**\n * 批注\n */\n get commentTool() {\n return this._commentsTool;\n }\n /**\n * 标注\n */\n get annotationTool() {\n return this._annotationTool;\n }\n /**\n * 结构树object(对象)\n */\n get objectsExplorer() {\n return this._objectsExplorer;\n }\n /**\n * 结构树class(类别)\n */\n get classesExplorer() {\n return this._classesExplorer;\n }\n /**\n * 结构树storey(楼层)\n */\n get storeysExplorer() {\n return this._storeysExplorer;\n }\n /**\n * 模型加载器\n */\n get modelsExplorer() {\n return this._modelsExplorer;\n }\n /**\n * 相机视角\n */\n get orthoMode() {\n return this._orthoMode;\n }\n get threeDMode() {\n return this._threeDMode;\n }\n get navCubeMode() {\n return this._navCubeMode;\n }\n /////////////////////导航//////////////////////////\n /**\n * 设置相机方向\n * @param {number} dirNum\n */\n setDirection(dirNum) {\n this._navCubeMode.flyByClick(dirNum);\n }\n /**\n * 单击模型对象\n * @param entity\n */\n singleChoseEntity(entity) {\n // this.showObjectProperties(entity.id.toString()); //显示构建属性\n this.setAllObjectsSelected(false); //所有构件高亮取消\n this.setEntitySelected(entity); //选中构件高亮\n }\n /**\n * 单击点击空白\n */\n singleChosedSpace() {\n this.setAllObjectsSelected(false); //所有构件高亮取消\n }\n /**\n * 双击模型对象\n * @param entity\n */\n doubleChoseEntity(entity) {\n this.viewFitEntity(entity); //聚焦构件\n this.setAllObjectsSelected(false); //所有构件高亮取消\n this.setEntitySelected(entity); //选中构件高亮\n }\n /**\n * 回到正常视图\n */\n choseSpace() {\n this.setAllObjectsSelected(false);\n this.viewFitAll();\n }\n /**\n * 初始预览环周截图\n * @param sizeOrCallback\n * @param done\n * @returns\n */\n getPreShot(sizeOrCallback, done) {\n const cameraEnable = this.cameraEnable;\n cameraEnable(false);\n let size = typeof sizeOrCallback === \"function\" ? 1024 : sizeOrCallback;\n if (typeof sizeOrCallback === \"function\")\n done = sizeOrCallback;\n const orbitYawCamera = this.orbitYawCamera;\n const viewer = this.viewer;\n const canvas = document.createElement(\"canvas\");\n const ctx = canvas.getContext(\"2d\");\n const canvasWidth = size * 15;\n const canvasHeight = size;\n canvas.width = canvasWidth;\n canvas.height = canvasHeight;\n const imagesPromises = Array.from({ length: 15 }, () => processImage);\n function processImage() {\n return __awaiter(this, void 0, void 0, function* () {\n yield orbitYawCamera(-18);\n yield delay(100); // 添加延迟,确保相机完成旋转\n return getshot(size);\n });\n }\n function delay(ms) {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n function getshot(size) {\n return __awaiter(this, void 0, void 0, function* () {\n const canvas = viewer.scene.canvas.canvas;\n const tempCanvas = document.createElement(\"canvas\");\n const tempCtx = tempCanvas.getContext(\"2d\");\n if (canvas && tempCtx) {\n tempCanvas.width = size;\n tempCanvas.height = size;\n const scaleX = size / canvas.width;\n const scaleY = size / canvas.height;\n const scale = Math.max(scaleX, scaleY);\n const scaledWidth = canvas.width * scale;\n const scaledHeight = canvas.height * scale;\n const offsetX = (size - scaledWidth) / 2;\n const offsetY = (size - scaledHeight) / 2;\n tempCtx.clearRect(0, 0, size, size);\n tempCtx.fillStyle = \"transparent\"; // 设置透明色\n tempCtx.fillRect(0, 0, size, size);\n tempCtx.drawImage(canvas, 0, 0, canvas.width, canvas.height, offsetX, offsetY, scaledWidth, scaledHeight);\n return new Promise((resolve, reject) => {\n const img = new Image();\n img.onload = () => resolve(img);\n img.onerror = reject;\n img.src = tempCanvas.toDataURL(); // 将 Canvas 转换为 data URL\n });\n }\n else {\n return Promise.reject(new Error(\"Canvas or context not found.\"));\n }\n });\n }\n function handleCanvasResult(download) {\n const imageData = canvas.toDataURL(\"image/png\");\n if (download) {\n const downloadLink = document.createElement(\"a\");\n downloadLink.href = imageData;\n downloadLink.download = \"combined_image.png\";\n downloadLink.click();\n }\n cameraEnable(true);\n if (done)\n done(imageData);\n return imageData;\n }\n (() => __awaiter(this, void 0, void 0, function* () {\n for (let i = 0; i < imagesPromises.length; i++) {\n try {\n const img = (yield imagesPromises[i]());\n if (ctx)\n ctx.drawImage(img, i * size, 0);\n }\n catch (error) {\n cameraEnable(true);\n console.error(\"获取图片内容失败:\", error);\n }\n }\n handleCanvasResult(false);\n }))();\n return \"\";\n }\n /**\n * 设置遮挡截图\n * @param callback\n */\n setShelterCanvas(callback) {\n const canvas = this.viewer.scene.canvas.canvas;\n const canvasImage = this.shot(canvas.width, canvas.height, false);\n const shelterImage = document.createElement(\"img\");\n shelterImage.src = canvasImage;\n shelterImage.style.position = \"absolute\";\n shelterImage.style.top = \"0px\";\n shelterImage.style.left = \"0px\";\n shelterImage.style.right = \"0px\";\n shelterImage.style.bottom = \"0px\";\n canvas.parentNode.appendChild(shelterImage);\n if (typeof callback == \"function\")\n callback(shelterImage);\n }\n}\n\n\n//# sourceURL=webpack://@xtctwins/tctwins-bimx-viewer/./src/BIMViewer.ts?");
|
|
47
|
+
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (/* binding */ BIMXViewer)\n/* harmony export */ });\n/* harmony import */ var _xtctwins_tctwins_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @xtctwins/tctwins-core */ \"./node_modules/@xtctwins/tctwins-core/dist/tctwins-core.es5.js\");\n/* harmony import */ var _messages__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./messages */ \"./src/messages.ts\");\n/* harmony import */ var _EventTrigger__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./EventTrigger */ \"./src/EventTrigger.ts\");\n/* harmony import */ var _Controller__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./Controller */ \"./src/Controller.ts\");\n/* harmony import */ var _toolbar_ResetAction__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./toolbar/ResetAction */ \"./src/toolbar/ResetAction.ts\");\n/* harmony import */ var _toolbar_FitAction__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./toolbar/FitAction */ \"./src/toolbar/FitAction.ts\");\n/* harmony import */ var _toolbar_FirstPersonMode__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./toolbar/FirstPersonMode */ \"./src/toolbar/FirstPersonMode.ts\");\n/* harmony import */ var _toolbar_HideTool__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./toolbar/HideTool */ \"./src/toolbar/HideTool.ts\");\n/* harmony import */ var _toolbar_ShowSpacesMode__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./toolbar/ShowSpacesMode */ \"./src/toolbar/ShowSpacesMode.ts\");\n/* harmony import */ var _toolbar_SectionTool__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./toolbar/SectionTool */ \"./src/toolbar/SectionTool.ts\");\n/* harmony import */ var _toolbar_NavCubeMode__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./toolbar/NavCubeMode */ \"./src/toolbar/NavCubeMode.ts\");\n/* harmony import */ var _explorer_ModelsExplorer__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./explorer/ModelsExplorer */ \"./src/explorer/ModelsExplorer.ts\");\n/* harmony import */ var _explorer_ObjectsExplorer__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./explorer/ObjectsExplorer */ \"./src/explorer/ObjectsExplorer.ts\");\n/* harmony import */ var _explorer_ClassesExplorer__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./explorer/ClassesExplorer */ \"./src/explorer/ClassesExplorer.ts\");\n/* harmony import */ var _explorer_StoreysExplorer__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./explorer/StoreysExplorer */ \"./src/explorer/StoreysExplorer.ts\");\n/* harmony import */ var _toolbar_ThreeDMode__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ./toolbar/ThreeDMode */ \"./src/toolbar/ThreeDMode.ts\");\n/* harmony import */ var _toolbar_OrthoMode__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ./toolbar/OrthoMode */ \"./src/toolbar/OrthoMode.ts\");\n/* harmony import */ var _collision_ObjectsKdTree3__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ./collision/ObjectsKdTree3 */ \"./src/collision/ObjectsKdTree3.ts\");\n/* harmony import */ var _toolbar_AnnotationTool__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ./toolbar/AnnotationTool */ \"./src/toolbar/AnnotationTool.ts\");\n/* harmony import */ var _toolbar_MeasureTool__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ./toolbar/MeasureTool */ \"./src/toolbar/MeasureTool.ts\");\n/* harmony import */ var _toolbar_CommentsTool__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! ./toolbar/CommentsTool */ \"./src/toolbar/CommentsTool.ts\");\n/* harmony import */ var _server_Server__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! ./server/Server */ \"./src/server/Server.ts\");\nvar __awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n};\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n/**\n * 核心模型视图窗口\n * @type {BIMViewer}\n */\nclass BIMXViewer extends _Controller__WEBPACK_IMPORTED_MODULE_3__[\"default\"] {\n /**\n * Constructs a BIMViewer.\n * @param {Server} server Data access strategy.\n * @param {*} cfg Configuration.\n * @param {Boolean} [cfg.enableEditModels=false] Set ````true```` to show \"Add\", \"Edit\" and \"Delete\" options in the Models tab's context menu.\n * @param {Boolean} [cfg.keyboardEventsElement] Optional reference to HTML element on which key events should be handled. Defaults to the HTML Document.\n */\n constructor(cfg = {}) {\n if (!cfg.canvasElement) {\n throw new Error(\"Config expected: canvasElement\");\n }\n if (!cfg.navCubeCanvasElement) {\n throw new Error(\"Config expected: navCubeCanvasElement\");\n }\n const { canvasElement } = cfg;\n const { viewerElement } = cfg;\n const localeService = new _xtctwins_tctwins_core__WEBPACK_IMPORTED_MODULE_0__.LocaleService({\n messages: _messages__WEBPACK_IMPORTED_MODULE_1__[\"default\"],\n locale: \"ch\"\n });\n const viewer = new _xtctwins_tctwins_core__WEBPACK_IMPORTED_MODULE_0__.Viewer({\n passes: 5,\n localeService,\n canvasElement,\n viewerElement,\n transparent: true,\n alphaDepthMask: true,\n backgroundColorFromAmbientLight: true,\n snapRadius: cfg.snapRadius,\n antialias: true,\n saoEnabled: false,\n pbrEnabled: true,\n dtxEnabled: true,\n edgesEnabled: true,\n colorTextureEnabled: true,\n premultipliedAlpha: true,\n resolutionScale: window.devicePixelRatio,\n spinnerElementId: \"engine_spinner\"\n });\n const server = new _server_Server__WEBPACK_IMPORTED_MODULE_21__[\"default\"]({\n dataDir: \"./data\",\n filePath: \"testdemo\"\n });\n super(null, cfg, server, viewer);\n /** 是否是聚焦分布模式 */\n this._focusPartial = false;\n /** 根据构建检测检测得到的构建分布字符串数组结果 */\n this._partialObjectIds = [];\n /** 当前聚焦的分布索引 */\n this._partialFocusIndex = 0;\n /** 是否已加载metadata */\n this._metaLoaded = false;\n /**\n * 按照指定角度旋转相机\n * @param {number} angleInc\n * @returns\n */\n this.orbitYawCamera = (angleInc) => {\n return new Promise((resolve, reject) => {\n try {\n this.viewer.scene.camera.orbitYaw(angleInc);\n resolve(); // 执行成功时调用 resolve\n }\n catch (error) {\n reject(error); // 发生错误时调用 reject\n }\n });\n };\n this.cameraEnable = (pointerEnabled = !this.viewer.cameraControl.pointerEnabled) => {\n this.viewer.cameraControl.pointerEnabled = pointerEnabled;\n };\n /**\n * 模型截图\n * @param width\n * @param height\n * @param isDownload\n * @returns\n */\n this.shot = (width, height, isDownload) => {\n const canvas = document.getElementById(\"myCanvas\");\n const link = document.createElement(\"a\");\n link.download = \"screenshot.png\";\n const tempCanvas = document.createElement(\"canvas\");\n console.log(\"tempCanvas\", tempCanvas);\n const tempCtx = tempCanvas.getContext(\"2d\");\n if (canvas && tempCtx) {\n tempCanvas.width = width;\n tempCanvas.height = height;\n const scaleX = width / canvas.width;\n const scaleY = height / canvas.height;\n const scale = Math.max(scaleX, scaleY);\n const scaledWidth = canvas.width * scale;\n const scaledHeight = canvas.height * scale;\n const offsetX = (width - scaledWidth) / 2;\n const offsetY = (height - scaledHeight) / 2;\n tempCtx.clearRect(0, 0, width, height);\n tempCtx.fillStyle = \"transparent\"; // 设置透明色\n tempCtx.fillRect(0, 0, width, height);\n tempCtx.drawImage(canvas, 0, 0, canvas.width, canvas.height, 0, 0, 1, 1);\n // tempCtx.drawImage(canvas, 0, 0, canvas.width, canvas.height, offsetX, offsetY, scaledWidth, scaledHeight);\n if (isDownload) {\n tempCanvas.toBlob(function (blob) {\n const url = URL.createObjectURL(blob);\n link.href = url;\n link.click();\n URL.revokeObjectURL(url);\n });\n }\n return tempCanvas.toDataURL(\"image/png\");\n }\n return \"\";\n };\n this._configs = {};\n this._eventTrigger = new _EventTrigger__WEBPACK_IMPORTED_MODULE_2__[\"default\"]();\n this.navCubeCanvasElement = cfg.navCubeCanvasElement;\n this.viewerElement = cfg.viewerElement;\n this._modelId = cfg.modelId;\n this._hasOutlier = false;\n this._outlierObjectIds = [];\n this.navCubeCanvasElement.oncontextmenu = (e) => {\n e.preventDefault();\n };\n this.viewer = viewer;\n this._objectsKdTree3 = new _collision_ObjectsKdTree3__WEBPACK_IMPORTED_MODULE_17__[\"default\"]({\n viewer\n });\n this._customizeViewer();\n this._modelsExplorer = new _explorer_ModelsExplorer__WEBPACK_IMPORTED_MODULE_11__[\"default\"](this, {\n enableEditModels: false,\n modelFromOutSide: true,\n modelType: cfg.modelType,\n modelContent: cfg.modelContent,\n modelSrc: cfg.modelSrc ? cfg.modelSrc : \"/\",\n modelMetaData: cfg.modelMetaData,\n modelConfig: cfg.modelConfig,\n IfcAPI: cfg.IfcAPI,\n WebIFC: cfg.WebIFC\n });\n this._objectsExplorer = new _explorer_ObjectsExplorer__WEBPACK_IMPORTED_MODULE_12__[\"default\"](this, {\n modelType: cfg.modelType\n });\n this._classesExplorer = new _explorer_ClassesExplorer__WEBPACK_IMPORTED_MODULE_13__[\"default\"](this, {\n modelType: cfg.modelType\n });\n this._storeysExplorer = new _explorer_StoreysExplorer__WEBPACK_IMPORTED_MODULE_14__[\"default\"](this, {\n modelType: cfg.modelType\n });\n // 重置相机视角的按钮(小房子图标)\n this._resetAction = new _toolbar_ResetAction__WEBPACK_IMPORTED_MODULE_4__[\"default\"](this, {});\n // 将相机视角放到最合适的位置的图标\n this._fitAction = new _toolbar_FitAction__WEBPACK_IMPORTED_MODULE_5__[\"default\"](this, {});\n // Allows Three-D and First Person toggle buttons to cooperatively switch\n // CameraControl#navMode between \"orbit\", \"firstPerson\" and \"planView\" modes\n class NavModeMediator {\n constructor(bimViewer) {\n this.threeDActive = false;\n this.firstPersonActive = false;\n this.setThreeDModeActive = (active) => {\n if (active) {\n bimViewer._firstPersonMode.setActive(false);\n bimViewer.viewer.cameraControl.navMode = \"orbit\";\n }\n else {\n bimViewer._firstPersonMode.setActive(false);\n bimViewer.viewer.cameraControl.navMode = \"planView\";\n }\n this.threeDActive = active;\n };\n this.setFirstPersonModeActive = (active) => {\n bimViewer.viewer.cameraControl.navMode = active ? \"firstPerson\" : this.threeDActive ? \"orbit\" : \"planView\";\n this.firstPersonActive = active;\n };\n }\n }\n const cameraControlNavModeMediator = new NavModeMediator(this);\n this._threeDMode = new _toolbar_ThreeDMode__WEBPACK_IMPORTED_MODULE_15__[\"default\"](this, {\n cameraControlNavModeMediator\n });\n this._orthoMode = new _toolbar_OrthoMode__WEBPACK_IMPORTED_MODULE_16__[\"default\"](this, {});\n this._firstPersonMode = new _toolbar_FirstPersonMode__WEBPACK_IMPORTED_MODULE_6__[\"default\"](this, {\n cameraControlNavModeMediator\n });\n this._hideTool = new _toolbar_HideTool__WEBPACK_IMPORTED_MODULE_7__[\"default\"](this, {});\n this._annotationTool = new _toolbar_AnnotationTool__WEBPACK_IMPORTED_MODULE_18__[\"default\"](this, {\n modelId: this._modelId\n });\n this._measureTool = new _toolbar_MeasureTool__WEBPACK_IMPORTED_MODULE_19__[\"default\"](this, {});\n this._sectionTool = new _toolbar_SectionTool__WEBPACK_IMPORTED_MODULE_9__[\"default\"](this, {});\n this._commentsTool = new _toolbar_CommentsTool__WEBPACK_IMPORTED_MODULE_20__[\"default\"](this, {});\n this._showSpacesMode = new _toolbar_ShowSpacesMode__WEBPACK_IMPORTED_MODULE_8__[\"default\"](this, {});\n this._navCubeMode = new _toolbar_NavCubeMode__WEBPACK_IMPORTED_MODULE_10__[\"default\"](this, {\n navCubeCanvasElement: this.navCubeCanvasElement,\n viewerElement: this.viewerElement\n });\n this._threeDMode.setActive(true);\n this._firstPersonMode.setActive(false);\n this._navCubeMode.setActive(true);\n this._annotationTool.setActive(false);\n this._measureTool.setActive(false);\n this._modelsExplorer.on(\"modelLoaded\", (modelId) => {\n this.fire(\"modelLoaded\", modelId);\n });\n this._modelsExplorer.on(\"modelUnloaded\", (modelId) => {\n this.fire(\"modelUnloaded\", modelId);\n });\n this._resetAction.on(\"reset\", () => {\n this.fire(\"reset\", true);\n });\n this._mutexActivation([this._hideTool, this._sectionTool, this._annotationTool]);\n this._bcfViewpointsPlugin = new _xtctwins_tctwins_core__WEBPACK_IMPORTED_MODULE_0__.BCFViewpointsPlugin(this.viewer, {});\n this._initConfigs();\n this._initSingleClickEvent();\n this._initRightClickEvent();\n this._initDoubleClickEvent();\n let treeReady = 0;\n this.eventTrigger.on(\"treeReady\", () => {\n treeReady++;\n if (treeReady === 3) {\n this.eventTrigger.emit(\"treeAllReady\", {\n objectsData: this.objectsExplorer.rootNode,\n classesData: this.classesExplorer.rootNode,\n storeysData: this.storeysExplorer.rootNode\n });\n }\n });\n }\n //------------------------------------------------------------------------------------------------------------------\n // 信息和服务\n //------------------------------------------------------------------------------------------------------------------\n get eventTrigger() {\n return this._eventTrigger;\n }\n /**\n * Returns the LocaleService that was configured on this Viewer.\n *\n * @return {LocaleService} The LocaleService.\n */\n get localeService() {\n return this.viewer.localeService;\n }\n //------------------------------------------------------------------------------------------------------------------\n // 点击事件\n //------------------------------------------------------------------------------------------------------------------\n /**\n * 初始化单击事件\n */\n _initSingleClickEvent() {\n this.viewer.cameraControl.on(\"mouseDownEntity\", (e) => {\n if (this.measureAngleTool.getActive() || this.measureDistanceTool.getActive())\n return;\n if (this.sectionTool.getActive() || this.annotationTool.getActive())\n return;\n e.preventDefault;\n const hit = this.viewer.scene.pick({\n canvasPos: e.canvasPos\n });\n if (hit) {\n if (hit.entity) {\n this.singleChoseEntity(hit.entity);\n this._eventTrigger.emit(\"pickedEntity\", hit.entity);\n }\n }\n });\n this.viewer.cameraControl.on(\"mouseDownNothing\", () => {\n if (this.measureAngleTool.getActive() || this.measureDistanceTool.getActive())\n return;\n if (this.sectionTool.getActive() || this.annotationTool.getActive())\n return;\n this.singleChosedSpace();\n this._eventTrigger.emit(\"pickedNothing\");\n });\n this.viewer.cameraControl.on(\"touchPicked\", (e) => {\n if (this.measureAngleTool.getActive() || this.measureDistanceTool.getActive())\n return;\n if (this.sectionTool.getActive() || this.annotationTool.getActive())\n return;\n e.preventDefault;\n const hit = this.viewer.scene.pick({\n canvasPos: e.canvasPos\n });\n if (hit) {\n if (hit.entity) {\n this.singleChoseEntity(hit.entity);\n this._eventTrigger.emit(\"touchEntity\", hit.entity);\n }\n }\n });\n this.viewer.cameraControl.on(\"touchPickedNothing\", () => {\n if (this.measureAngleTool.getActive() || this.measureDistanceTool.getActive())\n return;\n if (this.sectionTool.getActive() || this.annotationTool.getActive())\n return;\n this.singleChosedSpace();\n this._eventTrigger.emit(\"pickedNothing\");\n });\n }\n /**\n * 初始化右键事件\n */\n _initRightClickEvent() {\n this.viewer.cameraControl.on(\"rightClick\", (e) => {\n e.preventDefault;\n const hit = this.viewer.scene.pick({\n canvasPos: e.canvasPos\n });\n if (hit)\n this._eventTrigger.emit(\"rightPicked\", hit.entity);\n else {\n this._eventTrigger.emit(\"rightPickedNothing\");\n }\n });\n }\n /**\n * 初始化双击事件\n */\n _initDoubleClickEvent() {\n this.viewer.cameraControl.on(\"doublePicked\", (e) => {\n if (this.measureAngleTool.getActive() || this.measureDistanceTool.getActive())\n return;\n if (this.sectionTool.getActive() || this.annotationTool.getActive())\n return;\n e.preventDefault;\n const hit = this.viewer.scene.pick({\n canvasPos: e.canvasPos\n });\n if (hit) {\n if (hit.entity) {\n this.doubleChoseEntity(hit.entity);\n this._eventTrigger.emit(\"doublePicked\", hit.entity);\n }\n }\n });\n this.viewer.cameraControl.on(\"doublePickedNothing\", () => {\n if (this.measureAngleTool.getActive() || this.measureDistanceTool.getActive())\n return;\n if (this.sectionTool.getActive() || this.annotationTool.getActive())\n return;\n this.choseSpace();\n this._eventTrigger.emit(\"doublePickedNothing\");\n });\n }\n //------------------------------------------------------------------------------------------------------------------\n // 配置\n //------------------------------------------------------------------------------------------------------------------\n _customizeViewer() {\n const { scene } = this.viewer;\n // Emphasis effects\n scene.xrayMaterial.fill = false;\n scene.xrayMaterial.fillAlpha = 0.3;\n scene.xrayMaterial.fillColor = [0, 0, 0];\n scene.xrayMaterial.edges = true;\n scene.xrayMaterial.edgeAlpha = 0.1;\n scene.xrayMaterial.edgeColor = [0, 0, 0];\n // scene.highlightMaterial.edges = false;\n // scene.highlightMaterial.edgeColor = [0, 0.6, 1];\n // scene.highlightMaterial.edgeAlpha = 0.9;\n // scene.highlightMaterial.fill = true;\n scene.highlightMaterial.fillAlpha = 0.1;\n scene.highlightMaterial.fillColor = [0.6, 0.7, 0.8];\n //------------------------------------------------------------------------------------------------------------------\n // Configure points material\n //------------------------------------------------------------------------------------------------------------------\n scene.pointsMaterial.pointSize = 1;\n scene.pointsMaterial.roundPoints = true;\n scene.pointsMaterial.perspectivePoints = true;\n scene.pointsMaterial.minPerspectivePointSize = 2;\n scene.pointsMaterial.maxPerspectivePointSize = 4;\n // Camera control\n this.viewer.cameraControl.panRightClick = true;\n this.viewer.cameraControl.followPointer = true;\n this.viewer.cameraControl.doublePickFlyTo = false;\n this.viewer.cameraControl.smartPivot = true;\n // Dolly tweaks for best precision when aligning camera for BCF snapshots\n this.viewer.cameraControl.keyboardDollyRate = 100.0;\n this.viewer.cameraControl.mouseWheelDollyRate = 100.0;\n this.viewer.cameraControl.dollyInertia = 0;\n this.viewer.cameraControl.dollyMinSpeed = 0.04;\n this.viewer.cameraControl.dollyProximityThreshold = 30.0;\n const cameraPivotElement = document\n .createRange()\n .createContextualFragment(\"<div class='tctwins-camera-pivot-marker'></div>\").firstChild;\n this.viewer.scene.canvas.canvas.parentNode.appendChild(cameraPivotElement);\n this.viewer.cameraControl.pivotElement = cameraPivotElement;\n scene.camera.perspective.near = 0.01;\n scene.camera.perspective.far = 3000.0;\n scene.camera.ortho.near = 0.01;\n scene.camera.ortho.far = 2000.0; //\n // Scalable Ambient Obscurance (SAO) defaults\n // Since SAO is non-interactive, set to higher-quality\n const { sao } = scene;\n sao.enabled = false;\n sao.numSamples = 50;\n sao.kernelRadius = 200;\n }\n _initConfigs() {\n this.setConfigs({\n cameraNear: \"0.05\",\n cameraFar: \"3000.0\",\n smartPivot: true,\n saoEnabled: false,\n pbrEnabled: true,\n saoBias: \"0.5\",\n saoIntensity: \"0.15\",\n saoNumSamples: \"40\",\n saoKernelRadius: \"100\",\n edgesEnabled: false,\n xrayContext: true,\n xrayPickable: true,\n selectedGlowThrough: true,\n highlightGlowThrough: true,\n backgroundTransparency: true,\n backgroundColor: [1, 1.0, 1.0],\n objectColorSource: \"model\",\n externalMetadata: false,\n dtxEnabled: true,\n snapRadius: 20\n });\n }\n /**\n * Sets a batch of viewer configurations.\n *\n * Note that this method is not to be confused with {@link BIMViewer#setViewerState}, which batch-updates various states of the viewer's UI and 3D view.\n *\n * See [Viewer Configurations] for the list of available configurations.\n *\n * @param {*} viewerConfigs Map of key-value configuration pairs.\n */\n setConfigs(viewerConfigs) {\n for (const name in viewerConfigs) {\n if (Object.prototype.hasOwnProperty.call(viewerConfigs, name)) {\n const value = viewerConfigs[name];\n this.setConfig(name, value);\n }\n }\n // viewerConfigs.forEach((name: string) => {\n // if (Object.prototype.hasOwnProperty.call(viewerConfigs, name)) {\n // const value = viewerConfigs[name];\n // this.setConfig(name, value);\n // }\n // });\n }\n /**\n * Sets a viewer configuration.\n *\n * See [Viewer Configurations] for the list of available configurations.\n *\n * @param {String} name Configuration name.\n * @param {*} value Configuration value.\n */\n setConfig(name, value) {\n function parseBool(value) {\n return value === true || value === \"true\";\n }\n try {\n switch (name) {\n case \"backgroundTransparency\":\n const transparent = value;\n this.setBackgroundTransparent(transparent);\n this._configs[name] = transparent;\n break;\n case \"backgroundColor\":\n if (this._configs.backgroundTransparency) {\n break;\n }\n const rgbColor = value;\n this.setBackgroundColor(rgbColor);\n this._configs[name] = rgbColor;\n break;\n case \"cameraNear\":\n const near = parseFloat(value);\n this.viewer.scene.camera.perspective.near = near;\n this.viewer.scene.camera.ortho.near = near;\n this._configs[name] = near;\n break;\n case \"cameraFar\":\n const far = parseFloat(value);\n this.viewer.scene.camera.perspective.far = far;\n // this.viewer.scene.camera.ortho.far = far;\n this._configs[name] = far;\n break;\n case \"smartPivot\":\n this.viewer.cameraControl.smartPivot = this._configs[name] = parseBool(value);\n break;\n case \"saoEnabled\":\n // todo:\n this.viewer.scene.saoEnabled = this._configs[name] = parseBool(value);\n break;\n case \"saoBias\":\n this.viewer.scene.sao.bias = parseFloat(value);\n break;\n case \"saoIntensity\":\n this.viewer.scene.sao.intensity = parseFloat(value);\n break;\n case \"saoKernelRadius\":\n this.viewer.scene.sao.kernelRadius = this._configs[name] = parseFloat(value);\n break;\n case \"saoNumSamples\":\n this.viewer.scene.sao.numSamples = this._configs[name] = parseFloat(value);\n break;\n case \"saoBlur\":\n this.viewer.scene.sao.blur = this._configs[name] = parseBool(value);\n break;\n case \"edgesEnabled\":\n this.setEdgesEnabled(value);\n break;\n case \"pbrEnabled\":\n // this.viewer.scene.pbrEnabled = this._configs[name] = parseBool(value);\n break;\n case \"viewFitFOV\":\n this.viewer.cameraFlight.fitFOV = this._configs[name] = parseFloat(value);\n break;\n case \"viewFitDuration\":\n this.viewer.cameraFlight.duration = this._configs[name] = parseFloat(value);\n break;\n case \"perspectiveFOV\":\n this.viewer.camera.perspective.fov = this._configs[name] = parseFloat(value);\n break;\n case \"excludeUnclassifiedObjects\":\n this._configs[name] = parseBool(value);\n break;\n case \"objectColorSource\":\n this.setObjectColorSource(value);\n this._configs[name] = value;\n break;\n case \"xrayContext\":\n this._configs[name] = value;\n break;\n case \"xrayPickable\":\n this._configs[name] = parseBool(value);\n break;\n case \"selectedGlowThrough\":\n const selectedGlowThrough = (this._configs[name] = parseBool(value));\n const { selectedMaterial } = this.viewer.scene;\n selectedMaterial.glowThrough = selectedGlowThrough;\n selectedMaterial.fillAlpha = selectedGlowThrough ? 0.5 : 1.0;\n selectedMaterial.edgeAlpha = selectedGlowThrough ? 0.5 : 1.0;\n break;\n case \"highlightGlowThrough\":\n const highlightGlowThrough = (this._configs[name] = parseBool(value));\n const { highlightMaterial } = this.viewer.scene;\n highlightMaterial.glowThrough = highlightGlowThrough;\n highlightMaterial.fillAlpha = highlightGlowThrough ? 0.1 : 1.0;\n highlightMaterial.edgeAlpha = highlightGlowThrough ? 0.1 : 1.0;\n break;\n case \"externalMetadata\":\n this._configs[name] = value;\n break;\n case \"showSpaces\":\n // this._configs[name] = parseBool(value);\n this._showSpacesMode.setActive(value);\n break;\n case \"dtxEnabled\":\n this._configs[name] = parseBool(value);\n this.viewer.scene.dtxEnabled = value;\n break;\n case \"snapRadius\":\n this.setSnapRadius(value);\n break;\n default:\n this.error(`setConfig() - unsupported configuration: '${name}'`);\n }\n }\n catch (e) {\n this.error(`setConfig() - failed to configure ${name}: ${e}`);\n }\n }\n /**\n * Gets the value of a viewer configuration.\n *\n * These are set with {@link BIMViewer#setConfig} and {@link BIMViewer#setConfigs}.\n *\n * @param {String} name Configuration name.\n * @ereturns {*} Configuration value.\n */\n getConfig(name) {\n return this._configs[name];\n }\n getConfigs() {\n return this._configs;\n }\n //------------------------------------------------------------------------------------------------------------------\n // 查询\n //------------------------------------------------------------------------------------------------------------------\n /**\n * Returns the IDs of the models in the currently loaded project.\n *\n * @returns {String[]} The IDs of the models in the currently loaded project.\n */\n modelId() {\n return this._modelId;\n }\n /**\n * Loads a model into the viewer.\n *\n * Assumes that the project containing the model is currently loaded.\n *\n * @param {String} modelId ID of the model to load. Must be the ID of one of the models in the currently loaded project.\n * @param {Function} done Callback invoked on success.\n * @param {Function} error Callback invoked on failure, into which the error message string is passed.\n */\n loadModel(done, error) {\n if (!done)\n done = () => { };\n if (!error)\n error = () => { };\n this._modelsExplorer.loadModel(this._modelId, () => {\n done();\n }, (errorMsg) => {\n // this.error(`loadModel() - ${errorMsg}`);\n error(errorMsg);\n });\n }\n /**\n * 单独加载元数据\n * @param deflatedMetadata\n */\n loadMetadata(deflatedMetadata, force = true, done) {\n this._modelsExplorer.loadMetadata(this.viewer.metaScene.metaModels[this._modelId], deflatedMetadata, force, () => {\n this._metaLoaded = true;\n if (this._focusPartial) {\n this.viewFitPartial(0, done);\n }\n else {\n done;\n }\n });\n }\n /**\n * Sets where the colors for model objects will be loaded from.\n *\n * Options are:\n *\n * * \"model\" - (default) load colors from models, and\n * * \"viewer\" - load colors from the viewer's inbuilt table of colors for IFC types.\n *\n * This is \"model\" by default.\n *\n * @param {String} source Where colors will be loaded from - \"model\" or \"viewer\".\n */\n setObjectColorSource(source) {\n switch (source) {\n case \"model\":\n break;\n case \"viewer\":\n break;\n default:\n source = \"model\";\n this.error(\"setObjectColorSource() - Unsupported value - accepted values are 'model' and 'viewer' - defaulting to 'model'\");\n return;\n }\n this._objectColorSource = source;\n }\n /**\n * 获取构件属性\n * @param objectId\n * @returns\n */\n getObjectProperties(objectId) {\n const metaObject = this.viewer.metaScene.metaObjects[objectId];\n if (!metaObject) {\n return null;\n }\n const info = {\n id: metaObject.id,\n name: metaObject.name,\n type: metaObject.type,\n propertySets: []\n };\n const { propertySets } = metaObject;\n if (propertySets && propertySets.length > 0) {\n for (let i = 0; i < propertySets.length; i++) {\n const properties = propertySets[i].properties;\n const propertyList = [];\n for (let j = 0; j < properties.length; j++) {\n const properValue = {};\n properValue[properties[j].name] = properties[j].value;\n propertyList.push(properValue);\n }\n const propertyset = {\n id: propertySets[i].id,\n name: propertySets[i].name,\n properties: propertyList,\n type: propertySets[i].type\n };\n info.propertySets.push(propertyset);\n }\n }\n return info;\n }\n /**\n * 获取模型信息\n * @returns\n */\n getModelInfo() {\n const metaModel = this.viewer.metaScene.metaModels[this._modelId];\n const modelInfo = {\n id: metaModel.id,\n createDate: metaModel.createdAt ? metaModel.createdAt : \"\",\n author: metaModel.author ? metaModel.author : \"\",\n objectCount: metaModel.objectCount ? metaModel.objectCount : \"\",\n propertySetCount: metaModel.propertySetCount ? metaModel.propertySetCount : \"\"\n };\n return modelInfo;\n }\n //------------------------------------------------------------------------------------------------------------------\n // 视图设置\n //------------------------------------------------------------------------------------------------------------------\n /**\n * Sets whether or not the given objects are visible.\n *\n * @param {String[]} objectIds IDs of objects.\n * @param {Boolean} visible True to set objects visible, false to set them invisible.\n */\n setObjectsVisible(objectIds, visible) {\n this._withObjectsInSubtree(objectIds, (entity) => {\n entity.visible = visible;\n });\n }\n /**\n * Sets whether or not the given objects are selected.\n *\n * @param {String[]} objectIds IDs of objects.\n * @param {Boolean} selected Whether or not to set the objects selected.\n */\n setObjectsSelected(objectIds, selected) {\n this._withObjectsInSubtree(objectIds, (entity) => {\n entity.selected = selected;\n });\n }\n /**\n * Sets whether or not the given objects are X-rayed.\n *\n * @param {String[]} objectIds IDs of objects.\n * @param {Boolean} xrayed Whether or not to X-ray the objects.\n */\n setObjectsXRayed(objectIds, xrayed) {\n this._withObjectsInSubtree(objectIds, (entity) => {\n entity.xrayed = xrayed;\n });\n }\n _withObjectsInSubtree(objectIds, callback) {\n if (!objectIds) {\n this.error(\"Argument expected: objectIds\");\n return;\n }\n objectIds.forEach((objectId) => {\n // const objectId = objectIds[index];\n this.viewer.metaScene.withMetaObjectsInSubtree(objectId, (metaObject) => {\n const entity = this.viewer.scene.objects[metaObject.id];\n if (entity) {\n callback(entity);\n }\n });\n });\n }\n /**\n * Flies the camera to fit the given object in view.\n *\n * @param {String} objectId ID of the object\n * @param {Function} done Callback invoked on completion\n */\n flyToObject(objectId, done) {\n if (!objectId) {\n this.error(\"flyToObject() - Argument expected: objectId\");\n return;\n }\n const { viewer } = this;\n const { scene } = viewer;\n const objectIds = [];\n this.viewer.metaScene.withMetaObjectsInSubtree(objectId, (metaObject) => {\n if (scene.objects[metaObject.id]) {\n objectIds.push(metaObject.id);\n }\n });\n if (objectIds.length === 0) {\n this.error(`Object not found in viewer: '${objectId}'`);\n if (done) {\n done();\n }\n return;\n }\n scene.setObjectsVisible(objectIds, true);\n scene.setObjectsHighlighted(objectIds, true);\n const aabb = scene.getAABB(objectIds);\n viewer.cameraFlight.flyTo({\n aabb\n }, () => {\n if (done) {\n done();\n }\n setTimeout(() => {\n scene.setObjectsHighlighted(scene.highlightedObjectIds, false);\n }, 500);\n });\n viewer.cameraControl.pivotPos = _xtctwins_tctwins_core__WEBPACK_IMPORTED_MODULE_0__.math.getAABB3Center(aabb);\n }\n /**\n * Flies the camera to fit the given objects in view.\n *\n * @param {String[]} objectIds IDs of the objects\n * @param {Function} done Callback invoked on completion\n */\n viewFitObjects(objectIds, done) {\n if (!objectIds) {\n this.error(\"flyToObject() - Argument expected: objectIds\");\n return;\n }\n const { viewer } = this;\n const { scene } = viewer;\n const entityIds = [];\n objectIds.forEach((objectId) => {\n this.viewer.metaScene.withMetaObjectsInSubtree(objectId, (metaObject) => {\n if (scene.objects[metaObject.id]) {\n entityIds.push(metaObject.id);\n }\n });\n });\n if (entityIds.length === 0) {\n if (done) {\n done();\n }\n return;\n }\n scene.setObjectsVisible(entityIds, true);\n scene.setObjectsHighlighted(entityIds, true);\n const aabb = scene.getAABB(entityIds);\n viewer.cameraFlight.flyTo({\n aabb\n }, () => {\n if (done) {\n done();\n }\n setTimeout(() => {\n scene.setObjectsHighlighted(scene.highlightedObjectIds, false);\n }, 500);\n });\n viewer.cameraControl.pivotPos = _xtctwins_tctwins_core__WEBPACK_IMPORTED_MODULE_0__.math.getAABB3Center(aabb);\n }\n /**\n * 相机立刻聚焦到指定构建id的对象,没有转移视角动画\n * @param {String} objectId\n */\n jumpToObjects(objectIds) {\n if (!objectIds) {\n this.error(\"jumpToObject() - Argument expected: objectIds\");\n return;\n }\n const { viewer } = this;\n const { scene } = viewer;\n const entityIds = [];\n this.viewer.metaScene.withMetaObjectsInSubtree(objectIds, (metaObject) => {\n if (scene.objects[metaObject.id]) {\n entityIds.push(metaObject.id);\n }\n });\n if (entityIds.length === 0) {\n this.error(`Objects not found in viewer: '${objectIds}'`);\n return;\n }\n scene.setObjectsVisible(entityIds, true);\n const aabb = scene.getAABB(entityIds);\n viewer.cameraFlight.jumpTo({\n aabb\n });\n viewer.cameraControl.pivotPos = _xtctwins_tctwins_core__WEBPACK_IMPORTED_MODULE_0__.math.getAABB3Center(aabb);\n }\n /**\n * 设置相机位置\n * @param {Number[]} [params.eye] Eye position.\n * @param {Number[]} [params.look] Point of interest.\n * @param {Number[]} [params.up] Direction of \"up\".\n */\n setCamera(params) {\n const { viewer } = this;\n const { scene } = viewer;\n const { camera } = scene;\n if (params.eye) {\n camera.eye = params.eye;\n }\n if (params.look) {\n camera.look = params.look;\n }\n if (params.up) {\n camera.up = params.up;\n }\n }\n /**\n * 相机移动到指定视角\n * @param {Number[]} [params.eye] 相机位置.\n * @param {Number[]} [params.look] 相机视点\n * @param {Number[]} [params.up] 上方方向\n */\n flyToNewView(params) {\n this.viewer.cameraControl.pivotPos = params.look;\n this.viewer.cameraFlight.flyTo({\n look: params.look,\n eye: params.eye,\n up: params.up,\n duration: params.duration\n });\n }\n /**\n * Fits the given models in view.\n *\n * @param {String[]} modelIds ID of the models.\n * @param {Function} [done] Callback invoked on completion. Will be animated if this is given, otherwise will be instantaneous.\n */\n viewFitModels(modelIds, done) {\n if (!modelIds) {\n this.error(\"viewFitModels() - Argument expected: modelIds\");\n return;\n }\n const { viewer } = this;\n const { scene } = viewer;\n const aabb = _xtctwins_tctwins_core__WEBPACK_IMPORTED_MODULE_0__.math.AABB3();\n _xtctwins_tctwins_core__WEBPACK_IMPORTED_MODULE_0__.math.collapseAABB3(aabb);\n modelIds.forEach((modelId) => {\n const model = scene.models[modelId];\n if (model) {\n model.visible = true;\n model.highlighted = true;\n _xtctwins_tctwins_core__WEBPACK_IMPORTED_MODULE_0__.math.expandAABB3(aabb, model.aabb);\n }\n else {\n this.error(`Model not found in viewer: '${modelId}'`);\n }\n });\n if (done) {\n viewer.cameraFlight.flyTo({\n aabb\n }, () => {\n done();\n setTimeout(() => {\n scene.setObjectsHighlighted(scene.highlightedObjectIds, false);\n }, 500);\n });\n }\n else {\n viewer.cameraFlight.jumpTo({\n aabb\n });\n setTimeout(() => {\n scene.setObjectsHighlighted(scene.highlightedObjectIds, false);\n }, 500);\n }\n viewer.cameraControl.pivotPos = _xtctwins_tctwins_core__WEBPACK_IMPORTED_MODULE_0__.math.getAABB3Center(aabb);\n }\n /**\n * 切换模型分布 - 根据构建检测结果的模型分布情况聚焦不同分布区域\n *\n * 使用:\n * bimViewer.viewFitPartial(1, (partNum:number)=>{\n * console.log(partNum); //当前聚焦的模型分布索引\n * })\n *\n * bimViewer.viewFitPartial((partNum:number)=>{\n * console.log(partNum); //当前聚焦的模型分布索引\n * })\n *\n * bimViewer.viewFitPartial(1); //无回调方法。自动切换分布视角\n *\n * bimViewer.viewFitPartial(); //无指定索引输入,无回调方法。自动切换分布视角\n *\n *\n * @param {number} part - 模型分布索引(例如:根据检测结果,当前模型有三块模型分布,则可以输入[0-2]区间的数字)\n * @param {Function} done -\n */\n viewFitPartial(part, done) {\n let partNum;\n if (typeof part === \"function\") {\n done = part;\n partNum = this._partialFocusIndex += 1;\n }\n else {\n partNum = part !== null && part !== void 0 ? part : (this._partialFocusIndex += 1);\n }\n if (partNum >= 0 && partNum < this._partialObjectIds.length) {\n this.viewFitObjects(this._partialObjectIds[partNum], () => {\n for (let i = 0; i < this._partialObjectIds.length; i++) {\n if (partNum == i)\n this.setObjectsVisible(this._partialObjectIds[i], true);\n else\n this.setObjectsVisible(this._partialObjectIds[i], false);\n }\n done ? done(partNum) : done;\n });\n }\n else {\n partNum = this._partialFocusIndex = 0;\n this.viewFitObjects(this._partialObjectIds[partNum], () => {\n for (let i = 0; i < this._partialObjectIds.length; i++) {\n if (partNum == i)\n this.setObjectsVisible(this._partialObjectIds[i], true);\n else\n this.setObjectsVisible(this._partialObjectIds[i], false);\n }\n done ? done(partNum) : done;\n });\n }\n }\n /**\n * 设置模型分布 - 根据构建检测结果设置不同分布位置的模型构建ID数组\n * @param {string[][]} partialObjectIds\n */\n setPartialObjectIds(partialObjectIds) {\n const newPartialIdsList = [];\n for (let i = 0; i < partialObjectIds.length; i++) {\n newPartialIdsList.push(partialObjectIds[i]);\n }\n this._partialObjectIds = newPartialIdsList;\n this.viewer.cameraControl.smartPivot = false;\n this.navCubeMode.fitVisible = true;\n this._focusPartial = true;\n if (this._metaLoaded)\n this.viewFitPartial(0);\n }\n /// /////////部分操作////////////////////////////////////////\n /**\n * Transitions the viewer into an isolated view of the given building storey.\n *\n * Does nothing and logs an error if no object of the given ID is in the viewer, or if the object is not an ````IfcBuildingStorey````.\n *\n * @param {String} storeyObjectId ID of an ````IfcBuildingStorey```` object.\n * @param {Function} [done] Optional callback to invoke on completion. When provided, the transition will be animated, with the camera flying into position. Otherwise, the transition will be instant, with the camera jumping into position.\n */\n selectStorey(storeyObjectId, done = () => { }) {\n const { metaScene } = this.viewer;\n const storeyMetaObject = metaScene.metaObjects[storeyObjectId];\n if (!storeyMetaObject) {\n this.error(`selectStorey() - Object is not found: '${storeyObjectId}'`);\n return;\n }\n if (storeyMetaObject.type !== \"IfcBuildingStorey\") {\n this.error(`selectStorey() - Object is not an IfcBuildingStorey: '${storeyObjectId}'`);\n return;\n }\n this._storeysExplorer.selectStorey(storeyObjectId, done);\n }\n /**\n * Sets whether or not keyboard camera control is enabled.\n *\n * This is useful when we don't want key events over the canvas to clash with other UI elements outside the canvas.\n *\n * Default value is ````true````.\n *\n * @param {Boolean} enabled Set ````true```` to enable keyboard input.\n */\n setKeyboardEnabled(enabled) {\n this.viewer.scene.input.keyboardEnabled = enabled;\n }\n /**\n * Gets whether keyboard camera control is enabled.\n *\n * This is useful when we don't want key events over the canvas to clash with other UI elements outside the canvas.\n *\n * Default value is ````true````.\n *\n * @returns {Boolean} Returns ````true```` if keyboard input is enabled.\n */\n getKeyboardEnabled() {\n return this.viewer.scene.input.keyboardEnabled;\n }\n /**\n * 缓冲对象spinner显隐设置\n * @param show\n */\n showSpinner(show = !this.viewer.scene.canvas.spinner.visible) {\n this.viewer.scene.canvas.spinner.visible = show;\n }\n /**\n * 更新包围盒 - 排除异常构建并更新包围盒\n * @param exceptionIDs - 异常构建ID\n * @param callback - 回调\n */\n updateAABB(exceptionIDs, callback) {\n if (exceptionIDs.length > 0) {\n this._hasOutlier = true;\n this._outlierObjectIds = exceptionIDs;\n }\n const model = this.viewer.scene.models[this._modelId];\n const newExceptionsIds = exceptionIDs.concat(model.exceptionIds);\n model.exceptionIds = newExceptionsIds;\n this.viewer.scene.setObjectsVisible(newExceptionsIds, false);\n this.viewer.scene.on(\"aabb\", () => {\n if (typeof callback === \"function\")\n callback();\n });\n }\n /**\n * 销毁\n */\n destroy(callback) {\n var _a;\n this.measureDistanceTool.destroy();\n this.measureAngleTool.destroy();\n this._annotationTool.destroy();\n this._commentsTool.destroy();\n this._bcfViewpointsPlugin.destroy();\n this._modelsExplorer.destroy();\n this._classesExplorer.destroy();\n this._objectsExplorer.destroy();\n this._storeysExplorer.destroy();\n this._eventTrigger.destroy();\n const dos = document.querySelector(\".tctwins-camera-pivot-marker\");\n if (dos) {\n (_a = dos.parentNode) === null || _a === void 0 ? void 0 : _a.removeChild(dos);\n }\n this.viewer.destroy(callback);\n }\n /// /////////右键菜单////////////////////////////////////////\n // 选中\n /**\n * 设置对象被选中与否\n * @param entity\n * @param selected\n */\n setEntitySelected(entity, selected = !entity.selected) {\n entity.selected = selected;\n }\n /**\n * 选中其他对象\n * @param entity\n */\n setOthersSelected(entity) {\n this.setAllObjectsSelected(true);\n this.setEntitySelected(entity, true);\n }\n /**\n * 设置全部选中与否\n * @param {Boolean} selected\n */\n setAllObjectsSelected(selected) {\n if (selected) {\n this.viewer.scene.setObjectsSelected(this.viewer.scene.objectIds, true);\n }\n else {\n this.viewer.scene.setObjectsSelected(this.viewer.scene.selectedObjectIds, false);\n }\n }\n // 聚焦\n /**\n * 设置相机适应选中对象\n * @param entity\n */\n viewFitEntity(entity) {\n const { scene } = this.viewer;\n this.viewer.cameraFlight.flyTo({\n aabb: entity.aabb,\n duration: 0.5\n }, () => {\n setTimeout(() => {\n scene.setObjectsHighlighted(scene.highlightedObjectIds, false);\n }, 500);\n });\n this.viewer.cameraControl.pivotPos = _xtctwins_tctwins_core__WEBPACK_IMPORTED_MODULE_0__.math.getAABB3Center(entity.aabb);\n }\n /**\n * 相机适应所有选中对象\n */\n viewFitSelectedObjects() {\n this.viewFitObjects(this.viewer.scene.highlightedObjectIds, () => { });\n }\n /**\n * Flies the camera to fit all objects in view.\n *\n * @param {Function} done Callback invoked on completion\n */\n viewFitAll(done) {\n if (this._focusPartial) {\n this.viewFitPartial(this._partialFocusIndex, done);\n return;\n }\n this._fitAction.fit(done);\n }\n // 隐藏\n /**\n * 设置选中对象隐藏与否\n * @param entity\n */\n setEntityHide(entity, visible = !entity.visible) {\n entity.visible = visible;\n }\n /**\n * 隐藏选中对象以外的其他模型对象\n * @param entity\n * @returns\n */\n setOthersHide(entity) {\n const metaObject = this.viewer.metaScene.metaObjects[entity.id];\n if (!metaObject) {\n return;\n }\n this.viewer.scene.setObjectsVisible(this.viewer.scene.visibleObjectIds, false);\n metaObject.withMetaObjectsInSubtree((metaObject) => {\n const entity = this.viewer.scene.objects[metaObject.id];\n if (entity) {\n entity.visible = true;\n }\n });\n }\n /**\n * 显示所有对象\n * @param {Boolean} visible True to set objects visible, false to set them invisible.\n */\n setAllObjectsVisible(visible) {\n if (visible) {\n this.viewer.scene.setObjectsVisible(this.viewer.scene.objectIds, true);\n if (this._hasOutlier)\n this.viewer.scene.setObjectsVisible(this._outlierObjectIds, false);\n }\n else {\n this.viewer.scene.setObjectsVisible(this.viewer.scene.visibleObjectIds, false);\n }\n }\n // 透视\n /**\n * 设置选中对象透视与否\n * @param entity\n * @param xrayed\n */\n setEntityXRayed(entity, xrayed = !entity.xrayed) {\n entity.xrayed = xrayed;\n entity.pickable = this.getConfig(\"xrayPickable\");\n }\n /**\n * 设置其他对象透视\n * @param entity\n * @returns\n */\n setOthersXRayed(entity) {\n const { scene } = this.viewer;\n const metaObject = this.viewer.metaScene.metaObjects[entity.id];\n if (!metaObject) {\n return;\n }\n scene.setObjectsVisible(scene.objectIds, true);\n scene.setObjectsXRayed(scene.objectIds, true);\n if (!this.getConfig(\"xrayPickable\")) {\n scene.setObjectsPickable(scene.objectIds, false);\n }\n metaObject.withMetaObjectsInSubtree((metaObject) => {\n const entity = scene.objects[metaObject.id];\n if (entity) {\n entity.xrayed = false;\n entity.pickable = true;\n }\n });\n }\n /**\n * 设置所有对象透视与否\n * @param {Boolean} xrayed Whether or not to set all objects X-rayed.\n */\n setAllObjectsXRayed(xrayed) {\n if (xrayed) {\n this.viewer.scene.setObjectsXRayed(this.viewer.scene.objectIds, true);\n }\n else {\n this.viewer.scene.setObjectsXRayed(this.viewer.scene.xrayedObjectIds, false);\n }\n }\n // 判断\n entityVisble(entity) {\n return entity.visible;\n }\n entityXRayed(entity) {\n return entity.xrayed;\n }\n entityChosed(entity) {\n return entity.selected;\n }\n /**\n * 判断是否有被隐藏的\n * @returns\n */\n hiddenMoreThanOne() {\n return this.viewer.scene.numObjects - this.viewer.scene.numVisibleObjects > 0;\n }\n /**\n * 判断是否有被透视的\n * @returns\n */\n xRayedMoreThanOne() {\n return this.viewer.scene.numXRayedObjects > 0;\n }\n /**\n * 判断是否有被选中的\n * @returns\n */\n SelectedMoreThanOne() {\n return this.viewer.scene.numSelectedObjects > 0;\n }\n /// /////////设置背景颜色,透明,边缘等 初始设置///////////////////////////\n /**\n * Sets the viewer's background color.\n *\n * @param {boolean}\n */\n setBackgroundTransparent(trans = !this.viewer.scene.backgroundTransparent) {\n this.viewer.scene.backgroundTransparent = trans;\n this.viewer.scene.render(true);\n }\n /**\n * Sets the viewer's background color.\n *\n * @param {Number[]} rgbColor Three-element array of RGB values, each in range ````[0..1]````.\n */\n setBackgroundColor(rgbColor) {\n this.viewer.scene.backgroundColor = rgbColor;\n this.viewer.scene.render(true);\n }\n /**\n * 设置导航盒尺寸\n * @param {number} size 默认是200\n */\n setNavCubeSize(size) {\n this.navCubeCanvasElement.style.width = `${size.toString()}px`;\n this.navCubeCanvasElement.style.height = `${size.toString()}px`;\n }\n /**\n * 设置导航盒的位置\n * @param {string} direction e.g.\"left\",\"right\",\"top\",\"bottom\"\n * @param {number} pos\n */\n setNavCubePosition(direction, pos) {\n switch (direction) {\n case \"top\":\n this.navCubeCanvasElement.style.top = `${pos.toString()}px`;\n this.navCubeCanvasElement.style.bottom = \"\";\n break;\n case \"bottom\":\n this.navCubeCanvasElement.style.top = \"\";\n this.navCubeCanvasElement.style.bottom = `${pos.toString()}px`;\n break;\n case \"right\":\n this.navCubeCanvasElement.style.left = \"\";\n this.navCubeCanvasElement.style.right = `${pos.toString()}px`;\n break;\n case \"left\":\n this.navCubeCanvasElement.style.right = \"\";\n this.navCubeCanvasElement.style.left = `${pos.toString()}px`;\n break;\n }\n }\n /**\n * 更新canvas\n */\n updateCanvas() {\n this.viewer.scene.canvas.dirtyBoundary = true;\n }\n /**\n * 设置测量鼠标偏移量\n * @param offsetX\n * @param offsetY\n */\n setMeasureOffSet(offsetX, offsetY) {\n this._measureTool.setMeasureOffSet(offsetX, offsetY);\n }\n /**\n * 设置批注鼠标偏移量\n * @param offsetX\n * @param offsetY\n */\n setCommentsOffset(offsetX, offsetY) {\n this._commentsTool.offsetX = offsetX;\n this._commentsTool.offsetY = offsetY;\n }\n /**\n * 设置测量鼠标吸附点灵敏度\n * @param radius\n */\n setSnapRadius(radius) {\n this.measureTool.setSnapRadius(radius);\n }\n /**\n * 设置是否是触屏模式\n * @param {boolean} isTouch\n */\n setIsTouch(isTouch) {\n this.sectionTool.isTouch = isTouch;\n this.commentTool.isTouch = isTouch;\n }\n /**\n * 调整光照强度 0-100\n * @param num\n */\n setLightIntensity(num) {\n if (num < 0 || num > 100)\n return;\n for (let name in this.viewer.scene.lightsObject) {\n this.viewer.scene.lightsObject[name].intensity = 0.63 + (num - 50) / 200;\n }\n }\n /**\n * 设置空间构建的颜色模式;默认 1\n * @param {number} colorState\n */\n setSpaceMaterialColor(colorState) {\n if (colorState === 1)\n this.viewer.scene.highlightMaterial.fillColor = [0.6, 0.7, 0.8];\n else if (colorState === 2)\n this.viewer.scene.highlightMaterial.fillColor = [0.2, 0.3, 0.4];\n }\n /////////////渲染设置//////////////////////\n /**\n * set edges Enable\n * @param {boolean} edgesEnabled\n */\n setEdgesEnabled(edgesEnabled = !this.viewer.scene.edgesEnabled) {\n this.viewer.scene.edgesEnabled = edgesEnabled;\n this.viewer.scene.render(true);\n }\n /**\n * 是否开启环境光\n * @param {boolean} saoEnabled\n */\n setSAOEnabled(saoEnabled = !this.viewer.scene.saoEnabled) {\n this.viewer.scene.saoEnabled = saoEnabled;\n }\n setDTXEnabled(dtxEnabled = !this.viewer.scene.dtxEnabled) {\n this.viewer.scene.dtxEnabled = dtxEnabled;\n }\n setPBREnabled(pbrEnabled = !this.viewer.scene.pbrEnabled) {\n this.viewer.scene.pbrEnabled = pbrEnabled;\n }\n /**\n * 视图复位 - 恢复默认视图\n */\n resetView(callback) {\n if (this._focusPartial) {\n this.setDirection(25);\n return;\n }\n this._resetAction.reset(callback);\n }\n /**\n * 自适应 - 在当前相机视角适应视图填充画面\n */\n fitView(callback) {\n if (this._focusPartial) {\n this.viewFitPartial(this._partialFocusIndex, callback);\n return;\n }\n this._fitAction.fit();\n }\n /**\n * 标注开关\n * @param active\n * @param callback\n */\n SetAnnotationToolActive(active = !this._annotationTool.getActive(), callback) {\n this._annotationTool.setActive(active);\n if (callback)\n callback(this._annotationTool.getActive());\n }\n /**\n * 批注开关\n * @param active\n * @param callback\n */\n SetCommentsToolActive(active = !this._commentsTool.getActive(), callback) {\n this._commentsTool.setActive(active);\n if (callback)\n callback(this._commentsTool.getActive());\n }\n /**\n * 第一人称视角\n * @param active\n * @param callback\n */\n SetFirstPersonModeActive(active = !this._firstPersonMode.getActive(), callback) {\n this._firstPersonMode.setActive(active);\n if (callback)\n callback(this._firstPersonMode.getActive());\n }\n /**\n * 测量工具统一开关\n * @param active\n * @param callback\n */\n SetMeasureToolActive(active = !this.measureAngleTool.getActive(), callback) {\n this._measureTool.setActive(active);\n if (callback)\n callback(this._measureTool.getActive());\n }\n /**\n * 角度测量开关\n * @param active\n * @param callback\n */\n SetMeasureAngleActive(active = !this.measureAngleTool.getActive(), callback) {\n this._measureTool.SetMeasureAngleActive(active);\n if (callback)\n callback(this.measureAngleTool.getActive());\n }\n /**\n * 距离测量开关\n * @param active\n * @param callback\n */\n SetMeasureDistanceActive(active = !this.measureDistanceTool.getActive(), callback) {\n this._measureTool.SetMeasureDistanceActive(active);\n if (callback)\n callback(this.measureDistanceTool.getActive());\n }\n /**\n * 剖切工具开关\n * @param active\n * @param callback\n */\n SetSectionToolActive(active = !this._sectionTool.getActive(), callback) {\n this._sectionTool.setActive(active);\n if (callback)\n callback(this._sectionTool.getActive());\n }\n /**\n * 隐藏工具开关\n * @param active\n * @param callback\n */\n SetHideToolActive(active, callback) {\n this._hideTool.setActive(active);\n if (callback)\n callback();\n }\n /**\n * 框选开关\n * @param active\n * @param callback\n */\n SetMarqueeSelectionActive(active, callback) {\n // this._marqueeSelectionTool.setActive(active);\n if (callback)\n callback();\n }\n /**\n * 相机视角开关\n * @param active\n * @param callback\n */\n SetOrthoModeActive(active = !this._orthoMode.getActive(), callback) {\n this._orthoMode.setActive(active, callback);\n }\n /**\n * 3d/2d视角开关\n * @param active\n * @param callback\n */\n SetThreeDModeActive(active = !this._threeDMode.getActive(), callback) {\n this._threeDMode.setActive(active, callback);\n }\n /**\n * 显示空间功能开关\n * @param active\n * @param callback\n */\n SetShowSpaceModeActive(active = !this._showSpacesMode.getActive(), callback) {\n this._showSpacesMode.setActive(active, callback);\n }\n /// ///////////////功能对象/////////////////////\n /**\n * 漫游\n */\n get firstPersonMode() {\n return this._firstPersonMode;\n }\n /**\n * 测量管理工具\n */\n get measureTool() {\n return this._measureTool;\n }\n /**\n * 角度测量\n */\n get measureAngleTool() {\n return this._measureTool.measureAngleTool;\n }\n /**\n * 距离测量\n */\n get measureDistanceTool() {\n return this._measureTool.measureDistanceTool;\n }\n /**\n * 剖切\n */\n get sectionTool() {\n return this._sectionTool;\n }\n /**\n * 批注\n */\n get commentTool() {\n return this._commentsTool;\n }\n /**\n * 标注\n */\n get annotationTool() {\n return this._annotationTool;\n }\n /**\n * 结构树object(对象)\n */\n get objectsExplorer() {\n return this._objectsExplorer;\n }\n /**\n * 结构树class(类别)\n */\n get classesExplorer() {\n return this._classesExplorer;\n }\n /**\n * 结构树storey(楼层)\n */\n get storeysExplorer() {\n return this._storeysExplorer;\n }\n /**\n * 模型加载器\n */\n get modelsExplorer() {\n return this._modelsExplorer;\n }\n /**\n * 相机视角\n */\n get orthoMode() {\n return this._orthoMode;\n }\n /**\n * 2D/3D\n */\n get threeDMode() {\n return this._threeDMode;\n }\n /**\n * 导航盒控制器对象\n */\n get navCubeMode() {\n return this._navCubeMode;\n }\n /////////////////////导航//////////////////////////\n /**\n * 设置相机方向\n * @param {number} dirNum\n */\n setDirection(dirNum) {\n this._navCubeMode.flyByClick(dirNum);\n }\n /**\n * 单击模型对象\n * @param entity\n */\n singleChoseEntity(entity) {\n // this.showObjectProperties(entity.id.toString()); //显示构建属性\n this.setAllObjectsSelected(false); //所有构件高亮取消\n this.setEntitySelected(entity); //选中构件高亮\n }\n /**\n * 单击点击空白\n */\n singleChosedSpace() {\n this.setAllObjectsSelected(false); //所有构件高亮取消\n }\n /**\n * 双击模型对象\n * @param entity\n */\n doubleChoseEntity(entity) {\n this.viewFitEntity(entity); //聚焦构件\n this.setAllObjectsSelected(false); //所有构件高亮取消\n this.setEntitySelected(entity); //选中构件高亮\n }\n /**\n * 回到正常视图\n */\n choseSpace() {\n this.setAllObjectsSelected(false);\n this.viewFitAll();\n }\n /**\n * 初始预览环周截图\n * @param sizeOrCallback\n * @param done\n * @returns\n */\n getPreShot(sizeOrCallback, done) {\n const cameraEnable = this.cameraEnable;\n cameraEnable(false);\n let size = typeof sizeOrCallback === \"function\" ? 1024 : sizeOrCallback;\n if (typeof sizeOrCallback === \"function\")\n done = sizeOrCallback;\n const orbitYawCamera = this.orbitYawCamera;\n const viewer = this.viewer;\n const canvas = document.createElement(\"canvas\");\n const ctx = canvas.getContext(\"2d\");\n const canvasWidth = size * 15;\n const canvasHeight = size;\n canvas.width = canvasWidth;\n canvas.height = canvasHeight;\n const imagesPromises = Array.from({ length: 15 }, () => processImage);\n function processImage() {\n return __awaiter(this, void 0, void 0, function* () {\n yield orbitYawCamera(-18);\n yield delay(100); // 添加延迟,确保相机完成旋转\n return getshot(size);\n });\n }\n function delay(ms) {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n function getshot(size) {\n return __awaiter(this, void 0, void 0, function* () {\n const canvas = viewer.scene.canvas.canvas;\n const tempCanvas = document.createElement(\"canvas\");\n const tempCtx = tempCanvas.getContext(\"2d\");\n if (canvas && tempCtx) {\n tempCanvas.width = size;\n tempCanvas.height = size;\n const scaleX = size / canvas.width;\n const scaleY = size / canvas.height;\n const scale = Math.max(scaleX, scaleY);\n const scaledWidth = canvas.width * scale;\n const scaledHeight = canvas.height * scale;\n const offsetX = (size - scaledWidth) / 2;\n const offsetY = (size - scaledHeight) / 2;\n tempCtx.clearRect(0, 0, size, size);\n tempCtx.fillStyle = \"transparent\"; // 设置透明色\n tempCtx.fillRect(0, 0, size, size);\n tempCtx.drawImage(canvas, 0, 0, canvas.width, canvas.height, offsetX, offsetY, scaledWidth, scaledHeight);\n return new Promise((resolve, reject) => {\n const img = new Image();\n img.onload = () => resolve(img);\n img.onerror = reject;\n img.src = tempCanvas.toDataURL(); // 将 Canvas 转换为 data URL\n });\n }\n else {\n return Promise.reject(new Error(\"Canvas or context not found.\"));\n }\n });\n }\n function handleCanvasResult(download) {\n const imageData = canvas.toDataURL(\"image/png\");\n if (download) {\n const downloadLink = document.createElement(\"a\");\n downloadLink.href = imageData;\n downloadLink.download = \"combined_image.png\";\n downloadLink.click();\n }\n cameraEnable(true);\n if (done)\n done(imageData);\n return imageData;\n }\n (() => __awaiter(this, void 0, void 0, function* () {\n for (let i = 0; i < imagesPromises.length; i++) {\n try {\n const img = (yield imagesPromises[i]());\n if (ctx)\n ctx.drawImage(img, i * size, 0);\n }\n catch (error) {\n cameraEnable(true);\n console.error(\"获取图片内容失败:\", error);\n }\n }\n handleCanvasResult(false);\n }))();\n return \"\";\n }\n /**\n * 设置遮挡截图\n * @param callback\n */\n setShelterCanvas(callback) {\n const canvas = this.viewer.scene.canvas.canvas;\n const canvasImage = this.shot(canvas.width, canvas.height, false);\n const shelterImage = document.createElement(\"img\");\n shelterImage.src = canvasImage;\n shelterImage.style.position = \"absolute\";\n shelterImage.style.top = \"0px\";\n shelterImage.style.left = \"0px\";\n shelterImage.style.right = \"0px\";\n shelterImage.style.bottom = \"0px\";\n canvas.parentNode.appendChild(shelterImage);\n if (typeof callback == \"function\")\n callback(shelterImage);\n }\n}\n\n\n//# sourceURL=webpack://@xtctwins/tctwins-bimx-viewer/./src/BIMXViewer.ts?");
|
|
48
48
|
|
|
49
49
|
/***/ }),
|
|
50
50
|
|
|
@@ -164,7 +164,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
|
|
|
164
164
|
\***************************************/
|
|
165
165
|
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
166
166
|
|
|
167
|
-
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (/* binding */ AnnotationTool)\n/* harmony export */ });\n/* harmony import */ var _xtctwins_tctwins_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @xtctwins/tctwins-core */ \"./node_modules/@xtctwins/tctwins-core/dist/tctwins-core.es5.js\");\n/* harmony import */ var _Controller__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Controller */ \"./src/Controller.ts\");\n\n\n/**\n * 标注工具\n * @class\n */\nclass AnnotationTool extends _Controller__WEBPACK_IMPORTED_MODULE_1__[\"default\"] {\n /**\n 创建一个标注工具对象\n @param {*} parent\n @param {*} cfg\n */\n constructor(parent, cfg) {\n super(parent, cfg);\n this._AnnotationList = {};\n this._currentType = \"image\";\n this._modelId = cfg.modelId;\n this.eventTrigger = parent.eventTrigger;\n this.imageSrc = new Map();\n if (document.getElementById(\"myAnnotationDiv\")) {\n this.annotationWrapper = document.getElementById(\"myAnnotationDiv\");\n }\n else {\n this.annotationWrapper = document.createElement(\"div\");\n this.annotationWrapper.id = \"myAnnotationDiv\";\n const { canvas } = parent.viewer.scene.canvas;\n canvas.parentNode.insertBefore(this.annotationWrapper, canvas);\n }\n this.annotationsPlugin = new _xtctwins_tctwins_core__WEBPACK_IMPORTED_MODULE_0__.AnnotationsPlugin(this.viewer, {\n markerHTML: \"<div class='annotation-marker {{iconType}}' id='{{id}}'entityid='{{entityid}}' style='position:absolute;'><img src='{{iconPath}}'></div>\",\n container: this.annotationWrapper,\n values: {\n id: \"\",\n entityid: \"\",\n iconPath: \"\",\n iconType: \"\"\n }\n });\n this.bimViewer.on(\"reset\", () => {\n this.setActive(false);\n });\n this.on(\"active\", (active) => {\n if (active) {\n }\n else {\n }\n });\n // this.initCreateAnnotation();\n let chosedTarget;\n this.annotationsPlugin.on(\"markerClicked\", (annotation) => {\n this.eventTrigger.emit(\"markerClicked\", annotation);\n chosedTarget = annotation;\n });\n this.annotationsPlugin.on(\"markerDoubleClicked\", (annotation) => {\n this.eventTrigger.emit(\"markerDoubleClicked\", annotation);\n });\n const keyDownHandler = (e) => {\n if (!this._active)\n return;\n if (e.key === \"Delete\" || e.keyCode === 8) {\n this.eventTrigger.emit(\"requestDeleteMarker\", chosedTarget.id);\n // this.destroyAnnotationById(chosedTarget.id);\n }\n };\n document.addEventListener(\"keydown\", keyDownHandler.bind(this));\n this.on(\"destroy\", () => {\n document.removeEventListener(\"keydown\", keyDownHandler.bind(this));\n });\n }\n // 设置标注是否可见\n setAllVisible(visible) {\n for (const anno in this.annotationsPlugin.annotations) {\n this.annotationsPlugin.annotations[anno].setMarkerShown(visible);\n }\n }\n // 点击后调用,添加新的标注\n clickToCreateAnno(event) {\n if (!this.getActive()) {\n return;\n }\n if (!this.getEnabled()) {\n return;\n }\n const coords = this.getCanvasPos(event);\n const pickResult = this.viewer.scene.pick({\n canvasPos: coords,\n pickSurface: true // <<------ This causes picking to find the intersection point on the entity\n });\n if (pickResult) {\n const entityId = pickResult.entity.id;\n const annotationId = entityId + \"_\" + this._currentType + \"_\" + this.getTime();\n const newAnno = this.annotationsPlugin.createAnnotation({\n id: annotationId,\n pickResult,\n occludable: true,\n markerShown: true,\n labelShown: false,\n values: {\n id: annotationId,\n entityid: entityId,\n iconPath: this.getTypeImage(this._currentType),\n iconType: this._currentType\n }\n });\n this.currentAnnotation = {\n id: \"\",\n modelId: this._modelId,\n entityId: entityId,\n type: this._currentType,\n content: {\n worldPos: [pickResult.worldPos[0], pickResult.worldPos[1], pickResult.worldPos[2]],\n fileContent: {}\n }\n };\n this.eventTrigger.emit(\"createAnnotation\", {\n type: this._currentType,\n annotation: newAnno\n });\n }\n else {\n console.log(\"没有获取到合法的坐标,传入的内容:\", event);\n }\n }\n //获取创建时间\n getTime() {\n const Dates = new Date();\n const Year = Dates.getFullYear();\n const Months = Dates.getMonth() + 1 < 10 ? \"0\" + (Dates.getMonth() + 1) : Dates.getMonth() + 1;\n const Day = Dates.getDate() < 10 ? \"0\" + Dates.getDate() : Dates.getDate();\n const Hours = Dates.getHours() < 10 ? \"0\" + Dates.getHours() : Dates.getHours();\n const Minutes = Dates.getMinutes() < 10 ? \"0\" + Dates.getMinutes() : Dates.getMinutes();\n const Seconds = Dates.getSeconds() < 10 ? \"0\" + Dates.getSeconds() : Dates.getSeconds();\n return Year + Months + Day + Hours + Minutes + Seconds;\n }\n /**\n * @ignore\n * 获取鼠标或者屏幕点击事件对应坐标\n * @param event\n * @returns\n */\n getCanvasPos(event) {\n const mouseCanvasPos = [];\n if (!event) {\n event = window.event;\n mouseCanvasPos[0] = event.x;\n mouseCanvasPos[1] = event.y;\n }\n else if (\"TouchEvent\" in window && event instanceof TouchEvent) {\n if (!event.touches || event.touches.length === 0) {\n return;\n }\n const touch = event.touches[0]; // 获取第一个触摸点的信息\n let element = event.target;\n let totalOffsetLeft = 0;\n let totalOffsetTop = 0;\n while (element.offsetParent) {\n totalOffsetLeft += element.offsetLeft;\n totalOffsetTop += element.offsetTop;\n element = element.offsetParent;\n }\n mouseCanvasPos[0] = touch.pageX - totalOffsetLeft;\n mouseCanvasPos[1] = touch.pageY - totalOffsetTop;\n }\n else {\n let element = this.viewer.scene.canvas.canvas;\n let totalOffsetLeft = 0;\n let totalOffsetTop = 0;\n while (element.offsetParent) {\n totalOffsetLeft += element.offsetLeft;\n totalOffsetTop += element.offsetTop;\n element = element.offsetParent;\n }\n mouseCanvasPos[0] = event.pageX - totalOffsetLeft;\n mouseCanvasPos[1] = event.pageY - totalOffsetTop;\n }\n return mouseCanvasPos;\n }\n /**\n * 设置当前标注类型\n * @param {string} type\n */\n setCurrentType(type) {\n this._currentType = type;\n }\n // 创建标注事件\n initCreateAnnotation() {\n this.viewer.scene.input.on(\"touchclicked\", (coords) => {\n if (!this.getActive()) {\n return;\n }\n if (!this.getEnabled()) {\n return;\n }\n const pickResult = this.viewer.scene.pick({\n canvasPos: coords,\n pickSurface: true // <<------ This causes picking to find the intersection point on the entity\n });\n if (pickResult) {\n const entityId = pickResult.entity.id;\n const annotationId = entityId; // + \"_\" + this._currentType + \"_\" + this.getTime();\n const newAnno = this.annotationsPlugin.createAnnotation({\n id: annotationId,\n pickResult,\n occludable: true,\n markerShown: true,\n labelShown: false,\n values: {\n id: annotationId,\n iconPath: this.getTypeImage(this._currentType),\n iconType: this._currentType\n }\n });\n this.currentAnnotation = {\n id: \"\",\n modelId: this._modelId,\n entityId: annotationId,\n type: this._currentType,\n content: {\n worldPos: [pickResult.worldPos[0], pickResult.worldPos[1], pickResult.worldPos[2]],\n fileContent: {}\n }\n };\n this.eventTrigger.emit(\"createAnnotation\", {\n type: this._currentType,\n annotation: newAnno\n });\n }\n });\n }\n // 展示所有列表中的标注数据\n showAnnotationList() {\n this.clear();\n const annlist = JSON.parse(JSON.stringify(this._AnnotationList));\n if (Object.keys(annlist).length) {\n for (const element in annlist) {\n const ele = annlist[element];\n // console.log(ele);\n this.addAnnotation(ele.id.toString(), ele.content.worldPos, ele.type);\n }\n this.setAllVisible(true);\n }\n else {\n console.log(\"ann null\");\n }\n }\n addAnnotation(id, worldPos, type) {\n this.annotationsPlugin.createAnnotation({\n id,\n worldPos,\n occludable: true,\n markerShown: this.getActive(),\n labelShown: false,\n values: {\n id,\n iconPath: this.getTypeImage(type),\n iconType: type\n }\n });\n }\n // 清空所有展示标注\n clear() {\n // console.log(\"删除所有界面上的标注\");\n this.annotationsPlugin.clear();\n // console.log(\"重新展示所有界面上的标注\");\n }\n // 获取标注列表\n get AnnotationList() {\n return this._AnnotationList;\n }\n // 设置标注列表\n set AnnotationList(value) {\n this._AnnotationList = value;\n }\n // 获取当前类型图标\n getTypeImage(type) {\n if (this.imageSrc.size < 1)\n return document.getElementById(`annotation_tool_btn_img_${type}`).src;\n return this.imageSrc.get(type);\n }\n // 设置标注图片\n setTypeImage(urls) {\n for (let name in urls) {\n this.imageSrc.set(name, urls.name);\n }\n }\n // 删除指定id标注\n destroyAnnotationById(entityid) {\n this.annotationsPlugin.destroyAnnotation(entityid);\n if (this._AnnotationList[entityid])\n delete this._AnnotationList[entityid];\n }\n /**\n * 获取指定id的标注对象\n * @param {string} entityid\n * @return {} annotationsPlugin.annotations[entityid]\n * */\n getAnnotationById(entityid) {\n return this.annotationsPlugin.annotations[entityid];\n }\n /**\n * 获取标注插件标注列表\n * @return {} annotationsPlugin.annotations\n */\n get annotationPluginList() {\n return this.annotationsPlugin.annotations;\n }\n destroy() {\n var _a;\n this.fire(\"destroy\", true);\n this.clear();\n this.annotationsPlugin.destroy();\n if (this.annotationWrapper)\n (_a = this.annotationWrapper.parentNode) === null || _a === void 0 ? void 0 : _a.removeChild(this.annotationWrapper);\n }\n}\n\n\n//# sourceURL=webpack://@xtctwins/tctwins-bimx-viewer/./src/toolbar/AnnotationTool.ts?");
|
|
167
|
+
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (/* binding */ AnnotationTool)\n/* harmony export */ });\n/* harmony import */ var _xtctwins_tctwins_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @xtctwins/tctwins-core */ \"./node_modules/@xtctwins/tctwins-core/dist/tctwins-core.es5.js\");\n/* harmony import */ var _Controller__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Controller */ \"./src/Controller.ts\");\n\n\n/**\n * 标注工具\n * @class\n */\nclass AnnotationTool extends _Controller__WEBPACK_IMPORTED_MODULE_1__[\"default\"] {\n /**\n 创建一个标注工具对象\n @param {*} parent\n @param {*} cfg\n */\n constructor(parent, cfg) {\n super(parent, cfg);\n this._AnnotationList = {};\n this._currentType = \"image\";\n this._modelId = cfg.modelId;\n this.eventTrigger = parent.eventTrigger;\n this.imageSrc = new Map();\n if (document.getElementById(\"myAnnotationDiv\")) {\n this.annotationWrapper = document.getElementById(\"myAnnotationDiv\");\n }\n else {\n this.annotationWrapper = document.createElement(\"div\");\n this.annotationWrapper.id = \"myAnnotationDiv\";\n const { canvas } = parent.viewer.scene.canvas;\n canvas.parentNode.insertBefore(this.annotationWrapper, canvas);\n }\n this.annotationsPlugin = new _xtctwins_tctwins_core__WEBPACK_IMPORTED_MODULE_0__.AnnotationsPlugin(this.viewer, {\n markerHTML: \"<div class='annotation-marker {{iconType}}' id='{{id}}'entityid='{{entityid}}' style='position:absolute;'><img src='{{iconPath}}'></div>\",\n container: this.annotationWrapper,\n values: {\n id: \"\",\n entityid: \"\",\n iconPath: \"\",\n iconType: \"\"\n }\n });\n this.bimViewer.on(\"reset\", () => {\n this.setActive(false);\n });\n this.on(\"active\", (active) => {\n if (active) {\n }\n else {\n }\n });\n // this.initCreateAnnotation();\n let chosedTarget;\n this.annotationsPlugin.on(\"markerClicked\", (annotation) => {\n this.eventTrigger.emit(\"markerClicked\", annotation);\n chosedTarget = annotation;\n });\n this.annotationsPlugin.on(\"markerDoubleClicked\", (annotation) => {\n this.eventTrigger.emit(\"markerDoubleClicked\", annotation);\n });\n const keyDownHandler = (e) => {\n if (!this._active)\n return;\n if (e.key === \"Delete\" || e.keyCode === 8) {\n this.eventTrigger.emit(\"requestDeleteMarker\", chosedTarget.id);\n // this.destroyAnnotationById(chosedTarget.id);\n }\n };\n document.addEventListener(\"keydown\", keyDownHandler.bind(this));\n this.on(\"destroy\", () => {\n document.removeEventListener(\"keydown\", keyDownHandler.bind(this));\n });\n }\n /**\n * 设置所有标注是否可见\n * @param visible\n */\n setAllVisible(visible) {\n for (const anno in this.annotationsPlugin.annotations) {\n this.annotationsPlugin.annotations[anno].setMarkerShown(visible);\n }\n }\n /**\n * 点击后调用,添加新的标注\n * @param event - 传入点击事件\n * @returns\n */\n clickToCreateAnno(event) {\n if (!this.getActive()) {\n return;\n }\n if (!this.getEnabled()) {\n return;\n }\n const coords = this.getCanvasPos(event);\n const pickResult = this.viewer.scene.pick({\n canvasPos: coords,\n pickSurface: true // <<------ This causes picking to find the intersection point on the entity\n });\n if (pickResult) {\n const entityId = pickResult.entity.id;\n const annotationId = entityId + \"_\" + this._currentType + \"_\" + this.getTime();\n const newAnno = this.annotationsPlugin.createAnnotation({\n id: annotationId,\n pickResult,\n occludable: true,\n markerShown: true,\n labelShown: false,\n values: {\n id: annotationId,\n entityid: entityId,\n iconPath: this.getTypeImage(this._currentType),\n iconType: this._currentType\n }\n });\n this.currentAnnotation = {\n id: \"\",\n modelId: this._modelId,\n entityId: entityId,\n type: this._currentType,\n content: {\n worldPos: [pickResult.worldPos[0], pickResult.worldPos[1], pickResult.worldPos[2]],\n fileContent: {}\n }\n };\n this.eventTrigger.emit(\"createAnnotation\", {\n type: this._currentType,\n annotation: newAnno\n });\n }\n else {\n console.log(\"没有获取到合法的坐标,传入的内容:\", event);\n }\n }\n //获取创建时间\n getTime() {\n const Dates = new Date();\n const Year = Dates.getFullYear();\n const Months = Dates.getMonth() + 1 < 10 ? \"0\" + (Dates.getMonth() + 1) : Dates.getMonth() + 1;\n const Day = Dates.getDate() < 10 ? \"0\" + Dates.getDate() : Dates.getDate();\n const Hours = Dates.getHours() < 10 ? \"0\" + Dates.getHours() : Dates.getHours();\n const Minutes = Dates.getMinutes() < 10 ? \"0\" + Dates.getMinutes() : Dates.getMinutes();\n const Seconds = Dates.getSeconds() < 10 ? \"0\" + Dates.getSeconds() : Dates.getSeconds();\n return Year + Months + Day + Hours + Minutes + Seconds;\n }\n /**\n * @ignore\n * 获取鼠标或者屏幕点击事件对应坐标\n * @param event\n * @returns\n */\n getCanvasPos(event) {\n const mouseCanvasPos = [];\n if (!event) {\n event = window.event;\n mouseCanvasPos[0] = event.x;\n mouseCanvasPos[1] = event.y;\n }\n else if (\"TouchEvent\" in window && event instanceof TouchEvent) {\n if (!event.touches || event.touches.length === 0) {\n return;\n }\n const touch = event.touches[0]; // 获取第一个触摸点的信息\n let element = event.target;\n let totalOffsetLeft = 0;\n let totalOffsetTop = 0;\n while (element.offsetParent) {\n totalOffsetLeft += element.offsetLeft;\n totalOffsetTop += element.offsetTop;\n element = element.offsetParent;\n }\n mouseCanvasPos[0] = touch.pageX - totalOffsetLeft;\n mouseCanvasPos[1] = touch.pageY - totalOffsetTop;\n }\n else {\n let element = this.viewer.scene.canvas.canvas;\n let totalOffsetLeft = 0;\n let totalOffsetTop = 0;\n while (element.offsetParent) {\n totalOffsetLeft += element.offsetLeft;\n totalOffsetTop += element.offsetTop;\n element = element.offsetParent;\n }\n mouseCanvasPos[0] = event.pageX - totalOffsetLeft;\n mouseCanvasPos[1] = event.pageY - totalOffsetTop;\n }\n return mouseCanvasPos;\n }\n /**\n * 设置当前标注类型\n * @param {string} type\n */\n setCurrentType(type) {\n this._currentType = type;\n }\n /**\n * 展示所有列表中的标注数据\n */\n showAnnotationList() {\n this.clear();\n const annlist = JSON.parse(JSON.stringify(this._AnnotationList));\n if (Object.keys(annlist).length) {\n for (const element in annlist) {\n const ele = annlist[element];\n this.addAnnotation(ele.id.toString(), ele.content.worldPos, ele.type);\n }\n setTimeout(() => {\n this.setAllVisible(true);\n }, 30);\n }\n else {\n console.log(\"ann null\");\n }\n }\n /**\n * 手动添加标注\n * @param id\n * @param worldPos\n * @param type\n */\n addAnnotation(id, worldPos, type) {\n this.annotationsPlugin.createAnnotation({\n id,\n worldPos,\n occludable: true,\n markerShown: this.getActive(),\n labelShown: false,\n values: {\n id,\n iconPath: this.getTypeImage(type),\n iconType: type\n }\n });\n }\n // 清空所有展示标注\n clear() {\n // console.log(\"删除所有界面上的标注\");\n this.annotationsPlugin.clear();\n // console.log(\"重新展示所有界面上的标注\");\n }\n /**\n * 获取标注列表\n */\n get AnnotationList() {\n return this._AnnotationList;\n }\n /**\n * 设置标注列表\n */\n set AnnotationList(value) {\n this._AnnotationList = value;\n }\n // 获取当前类型图标\n getTypeImage(type) {\n if (this.imageSrc.size < 1)\n return document.getElementById(`annotation_tool_btn_img_${type}`).src;\n return this.imageSrc.get(type);\n }\n /**\n * 设置标注图片\n * @param urls\n */\n setTypeImage(urls) {\n for (let name in urls) {\n this.imageSrc.set(name, urls[name]);\n }\n }\n /**\n * 删除指定id标注\n * @param entityid\n */\n destroyAnnotationById(entityid) {\n this.annotationsPlugin.destroyAnnotation(entityid);\n if (this._AnnotationList[entityid])\n delete this._AnnotationList[entityid];\n }\n /**\n * 获取指定id的标注对象\n * @param {string} entityid\n * @return {} annotationsPlugin.annotations[entityid]\n * */\n getAnnotationById(entityid) {\n return this.annotationsPlugin.annotations[entityid];\n }\n /**\n * 获取标注插件标注列表\n * @return {} annotationsPlugin.annotations\n */\n get annotationPluginList() {\n return this.annotationsPlugin.annotations;\n }\n destroy() {\n var _a;\n this.fire(\"destroy\", true);\n this.clear();\n this.annotationsPlugin.destroy();\n if (this.annotationWrapper)\n (_a = this.annotationWrapper.parentNode) === null || _a === void 0 ? void 0 : _a.removeChild(this.annotationWrapper);\n }\n}\n\n\n//# sourceURL=webpack://@xtctwins/tctwins-bimx-viewer/./src/toolbar/AnnotationTool.ts?");
|
|
168
168
|
|
|
169
169
|
/***/ }),
|
|
170
170
|
|
|
@@ -828,10 +828,10 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
|
|
|
828
828
|
/******/ // Load entry module and return exports
|
|
829
829
|
/******/ // This entry module can't be inlined because the eval devtool is used.
|
|
830
830
|
/******/ var __webpack_exports__ = __webpack_require__("./index.ts");
|
|
831
|
-
/******/ var
|
|
831
|
+
/******/ var __webpack_exports__BIMXViewer = __webpack_exports__.BIMXViewer;
|
|
832
832
|
/******/ var __webpack_exports__EventTrigger = __webpack_exports__.EventTrigger;
|
|
833
833
|
/******/ var __webpack_exports__LocaleService = __webpack_exports__.LocaleService;
|
|
834
834
|
/******/ var __webpack_exports__OSSClient = __webpack_exports__.OSSClient;
|
|
835
835
|
/******/ var __webpack_exports__Server = __webpack_exports__.Server;
|
|
836
|
-
/******/ export {
|
|
836
|
+
/******/ export { __webpack_exports__BIMXViewer as BIMXViewer, __webpack_exports__EventTrigger as EventTrigger, __webpack_exports__LocaleService as LocaleService, __webpack_exports__OSSClient as OSSClient, __webpack_exports__Server as Server };
|
|
837
837
|
/******/
|
package/dist/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
|
|
2
|
-
export const VERSION = "0.1.
|
|
2
|
+
export const VERSION = "0.1.2";
|
package/dist/version.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
|
|
2
|
-
export const VERSION = "0.1.
|
|
2
|
+
export const VERSION = "0.1.2";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xtctwins/tctwins-bimx-viewer",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "BIM viewer built on xtctwins",
|
|
6
6
|
"main": "./dist/tctwins-bimx-viewer.min.es.js",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"eslint-plugin-import": "^2.29.0",
|
|
38
38
|
"puppeteer": "^10.1.0",
|
|
39
39
|
"ts-loader": "^9.5.1",
|
|
40
|
-
"typedoc": "^0.26.
|
|
40
|
+
"typedoc": "^0.26.4",
|
|
41
41
|
"typescript": "^5.4.5",
|
|
42
42
|
"webpack": "^5.90.1",
|
|
43
43
|
"webpack-cli": "^5.1.4",
|
package/types/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { LocaleService } from "@xtctwins/tctwins-core";
|
|
2
|
-
import
|
|
2
|
+
import BIMXViewer from "./src/BIMXViewer";
|
|
3
3
|
import EventTrigger from "./src/EventTrigger";
|
|
4
4
|
import Server from "./src/server/Server";
|
|
5
5
|
import OSSClient from "./src/server/OSSHelper";
|
|
6
|
-
export {
|
|
6
|
+
export { BIMXViewer, Server, LocaleService, OSSClient, EventTrigger };
|
package/types/src/BIMViewer.d.ts
CHANGED
|
@@ -588,7 +588,13 @@ export default class BIMViewer extends Controller {
|
|
|
588
588
|
* 相机视角
|
|
589
589
|
*/
|
|
590
590
|
get orthoMode(): OrthoMode;
|
|
591
|
+
/**
|
|
592
|
+
* 2D/3D
|
|
593
|
+
*/
|
|
591
594
|
get threeDMode(): ThreeDMode;
|
|
595
|
+
/**
|
|
596
|
+
* 导航盒控制器对象
|
|
597
|
+
*/
|
|
592
598
|
get navCubeMode(): NavCubeMode;
|
|
593
599
|
/**
|
|
594
600
|
* 设置相机方向
|
|
@@ -0,0 +1,649 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { BCFViewpointsPlugin, LocaleService, Viewer } from "@xtctwins/tctwins-core";
|
|
3
|
+
import EventTrigger from "./EventTrigger";
|
|
4
|
+
import Controller from "./Controller";
|
|
5
|
+
import ResetAction from "./toolbar/ResetAction";
|
|
6
|
+
import FitAction from "./toolbar/FitAction";
|
|
7
|
+
import FirstPersonMode from "./toolbar/FirstPersonMode";
|
|
8
|
+
import HideTool from "./toolbar/HideTool";
|
|
9
|
+
import ShowSpacesMode from "./toolbar/ShowSpacesMode";
|
|
10
|
+
import SectionTool from "./toolbar/SectionTool";
|
|
11
|
+
import NavCubeMode from "./toolbar/NavCubeMode";
|
|
12
|
+
import ModelsExplorer from "./explorer/ModelsExplorer";
|
|
13
|
+
import ObjectsExplorer from "./explorer/ObjectsExplorer";
|
|
14
|
+
import ClassesExplorer from "./explorer/ClassesExplorer";
|
|
15
|
+
import StoreysExplorer from "./explorer/StoreysExplorer";
|
|
16
|
+
import ThreeDMode from "./toolbar/ThreeDMode";
|
|
17
|
+
import OrthoMode from "./toolbar/OrthoMode";
|
|
18
|
+
import ObjectsKdTree3 from "./collision/ObjectsKdTree3";
|
|
19
|
+
import AnnotationTool from "./toolbar/AnnotationTool";
|
|
20
|
+
import MeasureTool from "./toolbar/MeasureTool";
|
|
21
|
+
import CommentsTool from "./toolbar/CommentsTool";
|
|
22
|
+
/**
|
|
23
|
+
* 核心模型视图窗口
|
|
24
|
+
* @type {BIMViewer}
|
|
25
|
+
*/
|
|
26
|
+
export default class BIMXViewer extends Controller {
|
|
27
|
+
viewer: Viewer;
|
|
28
|
+
protected _objectsKdTree3: ObjectsKdTree3;
|
|
29
|
+
protected _modelsExplorer: ModelsExplorer;
|
|
30
|
+
protected _objectsExplorer: ObjectsExplorer;
|
|
31
|
+
protected _classesExplorer: ClassesExplorer;
|
|
32
|
+
protected _storeysExplorer: StoreysExplorer;
|
|
33
|
+
protected _resetAction: ResetAction;
|
|
34
|
+
protected _fitAction: FitAction;
|
|
35
|
+
protected _threeDMode: ThreeDMode;
|
|
36
|
+
protected _hideTool: HideTool;
|
|
37
|
+
protected _orthoMode: OrthoMode;
|
|
38
|
+
protected _firstPersonMode: FirstPersonMode;
|
|
39
|
+
protected _annotationTool: AnnotationTool;
|
|
40
|
+
protected _measureTool: MeasureTool;
|
|
41
|
+
protected _sectionTool: SectionTool;
|
|
42
|
+
protected _commentsTool: CommentsTool;
|
|
43
|
+
protected _showSpacesMode: ShowSpacesMode;
|
|
44
|
+
protected _navCubeMode: NavCubeMode;
|
|
45
|
+
protected _bcfViewpointsPlugin: BCFViewpointsPlugin;
|
|
46
|
+
protected _objectColorSource?: string;
|
|
47
|
+
protected _eventTrigger: EventTrigger;
|
|
48
|
+
private navCubeCanvasElement;
|
|
49
|
+
private viewerElement;
|
|
50
|
+
private _modelId;
|
|
51
|
+
protected _configs: any;
|
|
52
|
+
/** 是否有异常构建 */
|
|
53
|
+
private _hasOutlier;
|
|
54
|
+
/** 异常构建ID */
|
|
55
|
+
private _outlierObjectIds;
|
|
56
|
+
/** 是否是聚焦分布模式 */
|
|
57
|
+
private _focusPartial;
|
|
58
|
+
/** 根据构建检测检测得到的构建分布字符串数组结果 */
|
|
59
|
+
private _partialObjectIds;
|
|
60
|
+
/** 当前聚焦的分布索引 */
|
|
61
|
+
private _partialFocusIndex;
|
|
62
|
+
/** 是否已加载metadata */
|
|
63
|
+
private _metaLoaded;
|
|
64
|
+
/**
|
|
65
|
+
* Constructs a BIMViewer.
|
|
66
|
+
* @param {Server} server Data access strategy.
|
|
67
|
+
* @param {*} cfg Configuration.
|
|
68
|
+
* @param {Boolean} [cfg.enableEditModels=false] Set ````true```` to show "Add", "Edit" and "Delete" options in the Models tab's context menu.
|
|
69
|
+
* @param {Boolean} [cfg.keyboardEventsElement] Optional reference to HTML element on which key events should be handled. Defaults to the HTML Document.
|
|
70
|
+
*/
|
|
71
|
+
constructor(cfg?: any);
|
|
72
|
+
get eventTrigger(): EventTrigger;
|
|
73
|
+
/**
|
|
74
|
+
* Returns the LocaleService that was configured on this Viewer.
|
|
75
|
+
*
|
|
76
|
+
* @return {LocaleService} The LocaleService.
|
|
77
|
+
*/
|
|
78
|
+
get localeService(): LocaleService;
|
|
79
|
+
/**
|
|
80
|
+
* 初始化单击事件
|
|
81
|
+
*/
|
|
82
|
+
protected _initSingleClickEvent(): void;
|
|
83
|
+
/**
|
|
84
|
+
* 初始化右键事件
|
|
85
|
+
*/
|
|
86
|
+
protected _initRightClickEvent(): void;
|
|
87
|
+
/**
|
|
88
|
+
* 初始化双击事件
|
|
89
|
+
*/
|
|
90
|
+
protected _initDoubleClickEvent(): void;
|
|
91
|
+
protected _customizeViewer(): void;
|
|
92
|
+
protected _initConfigs(): void;
|
|
93
|
+
/**
|
|
94
|
+
* Sets a batch of viewer configurations.
|
|
95
|
+
*
|
|
96
|
+
* Note that this method is not to be confused with {@link BIMViewer#setViewerState}, which batch-updates various states of the viewer's UI and 3D view.
|
|
97
|
+
*
|
|
98
|
+
* See [Viewer Configurations] for the list of available configurations.
|
|
99
|
+
*
|
|
100
|
+
* @param {*} viewerConfigs Map of key-value configuration pairs.
|
|
101
|
+
*/
|
|
102
|
+
setConfigs(viewerConfigs: any): void;
|
|
103
|
+
/**
|
|
104
|
+
* Sets a viewer configuration.
|
|
105
|
+
*
|
|
106
|
+
* See [Viewer Configurations] for the list of available configurations.
|
|
107
|
+
*
|
|
108
|
+
* @param {String} name Configuration name.
|
|
109
|
+
* @param {*} value Configuration value.
|
|
110
|
+
*/
|
|
111
|
+
setConfig(name: string, value: any): void;
|
|
112
|
+
/**
|
|
113
|
+
* Gets the value of a viewer configuration.
|
|
114
|
+
*
|
|
115
|
+
* These are set with {@link BIMViewer#setConfig} and {@link BIMViewer#setConfigs}.
|
|
116
|
+
*
|
|
117
|
+
* @param {String} name Configuration name.
|
|
118
|
+
* @ereturns {*} Configuration value.
|
|
119
|
+
*/
|
|
120
|
+
getConfig(name: string): any;
|
|
121
|
+
getConfigs(): any;
|
|
122
|
+
/**
|
|
123
|
+
* Returns the IDs of the models in the currently loaded project.
|
|
124
|
+
*
|
|
125
|
+
* @returns {String[]} The IDs of the models in the currently loaded project.
|
|
126
|
+
*/
|
|
127
|
+
modelId(): string;
|
|
128
|
+
/**
|
|
129
|
+
* Loads a model into the viewer.
|
|
130
|
+
*
|
|
131
|
+
* Assumes that the project containing the model is currently loaded.
|
|
132
|
+
*
|
|
133
|
+
* @param {String} modelId ID of the model to load. Must be the ID of one of the models in the currently loaded project.
|
|
134
|
+
* @param {Function} done Callback invoked on success.
|
|
135
|
+
* @param {Function} error Callback invoked on failure, into which the error message string is passed.
|
|
136
|
+
*/
|
|
137
|
+
loadModel(done?: Function, error?: Function): void;
|
|
138
|
+
/**
|
|
139
|
+
* 单独加载元数据
|
|
140
|
+
* @param deflatedMetadata
|
|
141
|
+
*/
|
|
142
|
+
loadMetadata(deflatedMetadata: Buffer, force?: boolean, done?: Function): void;
|
|
143
|
+
/**
|
|
144
|
+
* Sets where the colors for model objects will be loaded from.
|
|
145
|
+
*
|
|
146
|
+
* Options are:
|
|
147
|
+
*
|
|
148
|
+
* * "model" - (default) load colors from models, and
|
|
149
|
+
* * "viewer" - load colors from the viewer's inbuilt table of colors for IFC types.
|
|
150
|
+
*
|
|
151
|
+
* This is "model" by default.
|
|
152
|
+
*
|
|
153
|
+
* @param {String} source Where colors will be loaded from - "model" or "viewer".
|
|
154
|
+
*/
|
|
155
|
+
setObjectColorSource(source: string): void;
|
|
156
|
+
/**
|
|
157
|
+
* 获取构件属性
|
|
158
|
+
* @param objectId
|
|
159
|
+
* @returns
|
|
160
|
+
*/
|
|
161
|
+
getObjectProperties(objectId: string): {
|
|
162
|
+
id: string;
|
|
163
|
+
name: string;
|
|
164
|
+
type: string;
|
|
165
|
+
propertySets: any;
|
|
166
|
+
} | null;
|
|
167
|
+
/**
|
|
168
|
+
* 获取模型信息
|
|
169
|
+
* @returns
|
|
170
|
+
*/
|
|
171
|
+
getModelInfo(): {
|
|
172
|
+
id: string | number;
|
|
173
|
+
createDate: string;
|
|
174
|
+
author: string;
|
|
175
|
+
objectCount: string | number;
|
|
176
|
+
propertySetCount: string | number;
|
|
177
|
+
};
|
|
178
|
+
/**
|
|
179
|
+
* Sets whether or not the given objects are visible.
|
|
180
|
+
*
|
|
181
|
+
* @param {String[]} objectIds IDs of objects.
|
|
182
|
+
* @param {Boolean} visible True to set objects visible, false to set them invisible.
|
|
183
|
+
*/
|
|
184
|
+
setObjectsVisible(objectIds: string[], visible: boolean): void;
|
|
185
|
+
/**
|
|
186
|
+
* Sets whether or not the given objects are selected.
|
|
187
|
+
*
|
|
188
|
+
* @param {String[]} objectIds IDs of objects.
|
|
189
|
+
* @param {Boolean} selected Whether or not to set the objects selected.
|
|
190
|
+
*/
|
|
191
|
+
setObjectsSelected(objectIds: string[], selected: boolean): void;
|
|
192
|
+
/**
|
|
193
|
+
* Sets whether or not the given objects are X-rayed.
|
|
194
|
+
*
|
|
195
|
+
* @param {String[]} objectIds IDs of objects.
|
|
196
|
+
* @param {Boolean} xrayed Whether or not to X-ray the objects.
|
|
197
|
+
*/
|
|
198
|
+
setObjectsXRayed(objectIds: string[], xrayed: boolean): void;
|
|
199
|
+
protected _withObjectsInSubtree(objectIds: string[], callback: Function): void;
|
|
200
|
+
/**
|
|
201
|
+
* Flies the camera to fit the given object in view.
|
|
202
|
+
*
|
|
203
|
+
* @param {String} objectId ID of the object
|
|
204
|
+
* @param {Function} done Callback invoked on completion
|
|
205
|
+
*/
|
|
206
|
+
flyToObject(objectId: string, done: Function): void;
|
|
207
|
+
/**
|
|
208
|
+
* Flies the camera to fit the given objects in view.
|
|
209
|
+
*
|
|
210
|
+
* @param {String[]} objectIds IDs of the objects
|
|
211
|
+
* @param {Function} done Callback invoked on completion
|
|
212
|
+
*/
|
|
213
|
+
viewFitObjects(objectIds: string[], done: Function): void;
|
|
214
|
+
/**
|
|
215
|
+
* 相机立刻聚焦到指定构建id的对象,没有转移视角动画
|
|
216
|
+
* @param {String} objectId
|
|
217
|
+
*/
|
|
218
|
+
jumpToObjects(objectIds: string): void;
|
|
219
|
+
/**
|
|
220
|
+
* 设置相机位置
|
|
221
|
+
* @param {Number[]} [params.eye] Eye position.
|
|
222
|
+
* @param {Number[]} [params.look] Point of interest.
|
|
223
|
+
* @param {Number[]} [params.up] Direction of "up".
|
|
224
|
+
*/
|
|
225
|
+
setCamera(params: any): void;
|
|
226
|
+
/**
|
|
227
|
+
* 相机移动到指定视角
|
|
228
|
+
* @param {Number[]} [params.eye] 相机位置.
|
|
229
|
+
* @param {Number[]} [params.look] 相机视点
|
|
230
|
+
* @param {Number[]} [params.up] 上方方向
|
|
231
|
+
*/
|
|
232
|
+
flyToNewView(params: any): void;
|
|
233
|
+
/**
|
|
234
|
+
* Fits the given models in view.
|
|
235
|
+
*
|
|
236
|
+
* @param {String[]} modelIds ID of the models.
|
|
237
|
+
* @param {Function} [done] Callback invoked on completion. Will be animated if this is given, otherwise will be instantaneous.
|
|
238
|
+
*/
|
|
239
|
+
viewFitModels(modelIds: string[], done: Function): void;
|
|
240
|
+
/**
|
|
241
|
+
* 切换模型分布 - 根据构建检测结果的模型分布情况聚焦不同分布区域
|
|
242
|
+
*
|
|
243
|
+
* 使用:
|
|
244
|
+
* bimViewer.viewFitPartial(1, (partNum:number)=>{
|
|
245
|
+
* console.log(partNum); //当前聚焦的模型分布索引
|
|
246
|
+
* })
|
|
247
|
+
*
|
|
248
|
+
* bimViewer.viewFitPartial((partNum:number)=>{
|
|
249
|
+
* console.log(partNum); //当前聚焦的模型分布索引
|
|
250
|
+
* })
|
|
251
|
+
*
|
|
252
|
+
* bimViewer.viewFitPartial(1); //无回调方法。自动切换分布视角
|
|
253
|
+
*
|
|
254
|
+
* bimViewer.viewFitPartial(); //无指定索引输入,无回调方法。自动切换分布视角
|
|
255
|
+
*
|
|
256
|
+
*
|
|
257
|
+
* @param {number} part - 模型分布索引(例如:根据检测结果,当前模型有三块模型分布,则可以输入[0-2]区间的数字)
|
|
258
|
+
* @param {Function} done -
|
|
259
|
+
*/
|
|
260
|
+
viewFitPartial(part?: number | Function, done?: Function): void;
|
|
261
|
+
/**
|
|
262
|
+
* 设置模型分布 - 根据构建检测结果设置不同分布位置的模型构建ID数组
|
|
263
|
+
* @param {string[][]} partialObjectIds
|
|
264
|
+
*/
|
|
265
|
+
setPartialObjectIds(partialObjectIds: string[][]): void;
|
|
266
|
+
/**
|
|
267
|
+
* Transitions the viewer into an isolated view of the given building storey.
|
|
268
|
+
*
|
|
269
|
+
* Does nothing and logs an error if no object of the given ID is in the viewer, or if the object is not an ````IfcBuildingStorey````.
|
|
270
|
+
*
|
|
271
|
+
* @param {String} storeyObjectId ID of an ````IfcBuildingStorey```` object.
|
|
272
|
+
* @param {Function} [done] Optional callback to invoke on completion. When provided, the transition will be animated, with the camera flying into position. Otherwise, the transition will be instant, with the camera jumping into position.
|
|
273
|
+
*/
|
|
274
|
+
selectStorey(storeyObjectId: string, done?: Function): void;
|
|
275
|
+
/**
|
|
276
|
+
* Sets whether or not keyboard camera control is enabled.
|
|
277
|
+
*
|
|
278
|
+
* This is useful when we don't want key events over the canvas to clash with other UI elements outside the canvas.
|
|
279
|
+
*
|
|
280
|
+
* Default value is ````true````.
|
|
281
|
+
*
|
|
282
|
+
* @param {Boolean} enabled Set ````true```` to enable keyboard input.
|
|
283
|
+
*/
|
|
284
|
+
setKeyboardEnabled(enabled: boolean): void;
|
|
285
|
+
/**
|
|
286
|
+
* Gets whether keyboard camera control is enabled.
|
|
287
|
+
*
|
|
288
|
+
* This is useful when we don't want key events over the canvas to clash with other UI elements outside the canvas.
|
|
289
|
+
*
|
|
290
|
+
* Default value is ````true````.
|
|
291
|
+
*
|
|
292
|
+
* @returns {Boolean} Returns ````true```` if keyboard input is enabled.
|
|
293
|
+
*/
|
|
294
|
+
getKeyboardEnabled(): boolean;
|
|
295
|
+
/**
|
|
296
|
+
* 缓冲对象spinner显隐设置
|
|
297
|
+
* @param show
|
|
298
|
+
*/
|
|
299
|
+
showSpinner(show?: boolean): void;
|
|
300
|
+
/**
|
|
301
|
+
* 更新包围盒 - 排除异常构建并更新包围盒
|
|
302
|
+
* @param exceptionIDs - 异常构建ID
|
|
303
|
+
* @param callback - 回调
|
|
304
|
+
*/
|
|
305
|
+
updateAABB(exceptionIDs: string[], callback: Function): void;
|
|
306
|
+
/**
|
|
307
|
+
* 销毁
|
|
308
|
+
*/
|
|
309
|
+
destroy(callback?: Function): void;
|
|
310
|
+
/**
|
|
311
|
+
* 设置对象被选中与否
|
|
312
|
+
* @param entity
|
|
313
|
+
* @param selected
|
|
314
|
+
*/
|
|
315
|
+
setEntitySelected(entity: any, selected?: boolean): void;
|
|
316
|
+
/**
|
|
317
|
+
* 选中其他对象
|
|
318
|
+
* @param entity
|
|
319
|
+
*/
|
|
320
|
+
setOthersSelected(entity: any): void;
|
|
321
|
+
/**
|
|
322
|
+
* 设置全部选中与否
|
|
323
|
+
* @param {Boolean} selected
|
|
324
|
+
*/
|
|
325
|
+
setAllObjectsSelected(selected: boolean): void;
|
|
326
|
+
/**
|
|
327
|
+
* 设置相机适应选中对象
|
|
328
|
+
* @param entity
|
|
329
|
+
*/
|
|
330
|
+
viewFitEntity(entity: any): void;
|
|
331
|
+
/**
|
|
332
|
+
* 相机适应所有选中对象
|
|
333
|
+
*/
|
|
334
|
+
viewFitSelectedObjects(): void;
|
|
335
|
+
/**
|
|
336
|
+
* Flies the camera to fit all objects in view.
|
|
337
|
+
*
|
|
338
|
+
* @param {Function} done Callback invoked on completion
|
|
339
|
+
*/
|
|
340
|
+
viewFitAll(done?: Function): void;
|
|
341
|
+
/**
|
|
342
|
+
* 设置选中对象隐藏与否
|
|
343
|
+
* @param entity
|
|
344
|
+
*/
|
|
345
|
+
setEntityHide(entity: any, visible?: boolean): void;
|
|
346
|
+
/**
|
|
347
|
+
* 隐藏选中对象以外的其他模型对象
|
|
348
|
+
* @param entity
|
|
349
|
+
* @returns
|
|
350
|
+
*/
|
|
351
|
+
setOthersHide(entity: any): void;
|
|
352
|
+
/**
|
|
353
|
+
* 显示所有对象
|
|
354
|
+
* @param {Boolean} visible True to set objects visible, false to set them invisible.
|
|
355
|
+
*/
|
|
356
|
+
setAllObjectsVisible(visible: boolean): void;
|
|
357
|
+
/**
|
|
358
|
+
* 设置选中对象透视与否
|
|
359
|
+
* @param entity
|
|
360
|
+
* @param xrayed
|
|
361
|
+
*/
|
|
362
|
+
setEntityXRayed(entity: any, xrayed?: boolean): void;
|
|
363
|
+
/**
|
|
364
|
+
* 设置其他对象透视
|
|
365
|
+
* @param entity
|
|
366
|
+
* @returns
|
|
367
|
+
*/
|
|
368
|
+
setOthersXRayed(entity: any): void;
|
|
369
|
+
/**
|
|
370
|
+
* 设置所有对象透视与否
|
|
371
|
+
* @param {Boolean} xrayed Whether or not to set all objects X-rayed.
|
|
372
|
+
*/
|
|
373
|
+
setAllObjectsXRayed(xrayed: boolean): void;
|
|
374
|
+
entityVisble(entity: any): any;
|
|
375
|
+
entityXRayed(entity: any): any;
|
|
376
|
+
entityChosed(entity: any): any;
|
|
377
|
+
/**
|
|
378
|
+
* 判断是否有被隐藏的
|
|
379
|
+
* @returns
|
|
380
|
+
*/
|
|
381
|
+
hiddenMoreThanOne(): boolean;
|
|
382
|
+
/**
|
|
383
|
+
* 判断是否有被透视的
|
|
384
|
+
* @returns
|
|
385
|
+
*/
|
|
386
|
+
xRayedMoreThanOne(): boolean;
|
|
387
|
+
/**
|
|
388
|
+
* 判断是否有被选中的
|
|
389
|
+
* @returns
|
|
390
|
+
*/
|
|
391
|
+
SelectedMoreThanOne(): boolean;
|
|
392
|
+
/**
|
|
393
|
+
* Sets the viewer's background color.
|
|
394
|
+
*
|
|
395
|
+
* @param {boolean}
|
|
396
|
+
*/
|
|
397
|
+
setBackgroundTransparent(trans?: boolean): void;
|
|
398
|
+
/**
|
|
399
|
+
* Sets the viewer's background color.
|
|
400
|
+
*
|
|
401
|
+
* @param {Number[]} rgbColor Three-element array of RGB values, each in range ````[0..1]````.
|
|
402
|
+
*/
|
|
403
|
+
setBackgroundColor(rgbColor: []): void;
|
|
404
|
+
/**
|
|
405
|
+
* 设置导航盒尺寸
|
|
406
|
+
* @param {number} size 默认是200
|
|
407
|
+
*/
|
|
408
|
+
setNavCubeSize(size: number): void;
|
|
409
|
+
/**
|
|
410
|
+
* 设置导航盒的位置
|
|
411
|
+
* @param {string} direction e.g."left","right","top","bottom"
|
|
412
|
+
* @param {number} pos
|
|
413
|
+
*/
|
|
414
|
+
setNavCubePosition(direction: string, pos: number): void;
|
|
415
|
+
/**
|
|
416
|
+
* 更新canvas
|
|
417
|
+
*/
|
|
418
|
+
updateCanvas(): void;
|
|
419
|
+
/**
|
|
420
|
+
* 设置测量鼠标偏移量
|
|
421
|
+
* @param offsetX
|
|
422
|
+
* @param offsetY
|
|
423
|
+
*/
|
|
424
|
+
setMeasureOffSet(offsetX: number, offsetY: number): void;
|
|
425
|
+
/**
|
|
426
|
+
* 设置批注鼠标偏移量
|
|
427
|
+
* @param offsetX
|
|
428
|
+
* @param offsetY
|
|
429
|
+
*/
|
|
430
|
+
setCommentsOffset(offsetX: number, offsetY: number): void;
|
|
431
|
+
/**
|
|
432
|
+
* 设置测量鼠标吸附点灵敏度
|
|
433
|
+
* @param radius
|
|
434
|
+
*/
|
|
435
|
+
setSnapRadius(radius: number): void;
|
|
436
|
+
/**
|
|
437
|
+
* 设置是否是触屏模式
|
|
438
|
+
* @param {boolean} isTouch
|
|
439
|
+
*/
|
|
440
|
+
setIsTouch(isTouch: boolean): void;
|
|
441
|
+
/**
|
|
442
|
+
* 调整光照强度 0-100
|
|
443
|
+
* @param num
|
|
444
|
+
*/
|
|
445
|
+
setLightIntensity(num: number): void;
|
|
446
|
+
/**
|
|
447
|
+
* 设置空间构建的颜色模式;默认 1
|
|
448
|
+
* @param {number} colorState
|
|
449
|
+
*/
|
|
450
|
+
setSpaceMaterialColor(colorState: number): void;
|
|
451
|
+
/**
|
|
452
|
+
* set edges Enable
|
|
453
|
+
* @param {boolean} edgesEnabled
|
|
454
|
+
*/
|
|
455
|
+
setEdgesEnabled(edgesEnabled?: boolean): void;
|
|
456
|
+
/**
|
|
457
|
+
* 是否开启环境光
|
|
458
|
+
* @param {boolean} saoEnabled
|
|
459
|
+
*/
|
|
460
|
+
setSAOEnabled(saoEnabled?: boolean): void;
|
|
461
|
+
setDTXEnabled(dtxEnabled?: boolean): void;
|
|
462
|
+
setPBREnabled(pbrEnabled?: boolean): void;
|
|
463
|
+
/**
|
|
464
|
+
* 视图复位 - 恢复默认视图
|
|
465
|
+
*/
|
|
466
|
+
resetView(callback?: Function): void;
|
|
467
|
+
/**
|
|
468
|
+
* 自适应 - 在当前相机视角适应视图填充画面
|
|
469
|
+
*/
|
|
470
|
+
fitView(callback?: Function): void;
|
|
471
|
+
/**
|
|
472
|
+
* 标注开关
|
|
473
|
+
* @param active
|
|
474
|
+
* @param callback
|
|
475
|
+
*/
|
|
476
|
+
SetAnnotationToolActive(active?: boolean, callback?: Function): void;
|
|
477
|
+
/**
|
|
478
|
+
* 批注开关
|
|
479
|
+
* @param active
|
|
480
|
+
* @param callback
|
|
481
|
+
*/
|
|
482
|
+
SetCommentsToolActive(active?: boolean, callback?: Function): void;
|
|
483
|
+
/**
|
|
484
|
+
* 第一人称视角
|
|
485
|
+
* @param active
|
|
486
|
+
* @param callback
|
|
487
|
+
*/
|
|
488
|
+
SetFirstPersonModeActive(active?: boolean, callback?: Function): void;
|
|
489
|
+
/**
|
|
490
|
+
* 测量工具统一开关
|
|
491
|
+
* @param active
|
|
492
|
+
* @param callback
|
|
493
|
+
*/
|
|
494
|
+
SetMeasureToolActive(active?: boolean, callback?: Function): void;
|
|
495
|
+
/**
|
|
496
|
+
* 角度测量开关
|
|
497
|
+
* @param active
|
|
498
|
+
* @param callback
|
|
499
|
+
*/
|
|
500
|
+
SetMeasureAngleActive(active?: boolean, callback?: Function): void;
|
|
501
|
+
/**
|
|
502
|
+
* 距离测量开关
|
|
503
|
+
* @param active
|
|
504
|
+
* @param callback
|
|
505
|
+
*/
|
|
506
|
+
SetMeasureDistanceActive(active?: boolean, callback?: Function): void;
|
|
507
|
+
/**
|
|
508
|
+
* 剖切工具开关
|
|
509
|
+
* @param active
|
|
510
|
+
* @param callback
|
|
511
|
+
*/
|
|
512
|
+
SetSectionToolActive(active?: boolean, callback?: Function): void;
|
|
513
|
+
/**
|
|
514
|
+
* 隐藏工具开关
|
|
515
|
+
* @param active
|
|
516
|
+
* @param callback
|
|
517
|
+
*/
|
|
518
|
+
SetHideToolActive(active: boolean, callback?: Function): void;
|
|
519
|
+
/**
|
|
520
|
+
* 框选开关
|
|
521
|
+
* @param active
|
|
522
|
+
* @param callback
|
|
523
|
+
*/
|
|
524
|
+
SetMarqueeSelectionActive(active: boolean, callback?: Function): void;
|
|
525
|
+
/**
|
|
526
|
+
* 相机视角开关
|
|
527
|
+
* @param active
|
|
528
|
+
* @param callback
|
|
529
|
+
*/
|
|
530
|
+
SetOrthoModeActive(active?: boolean, callback?: Function): void;
|
|
531
|
+
/**
|
|
532
|
+
* 3d/2d视角开关
|
|
533
|
+
* @param active
|
|
534
|
+
* @param callback
|
|
535
|
+
*/
|
|
536
|
+
SetThreeDModeActive(active?: boolean, callback?: Function): void;
|
|
537
|
+
/**
|
|
538
|
+
* 显示空间功能开关
|
|
539
|
+
* @param active
|
|
540
|
+
* @param callback
|
|
541
|
+
*/
|
|
542
|
+
SetShowSpaceModeActive(active?: boolean, callback?: Function): void;
|
|
543
|
+
/**
|
|
544
|
+
* 漫游
|
|
545
|
+
*/
|
|
546
|
+
get firstPersonMode(): FirstPersonMode;
|
|
547
|
+
/**
|
|
548
|
+
* 测量管理工具
|
|
549
|
+
*/
|
|
550
|
+
get measureTool(): MeasureTool;
|
|
551
|
+
/**
|
|
552
|
+
* 角度测量
|
|
553
|
+
*/
|
|
554
|
+
get measureAngleTool(): import("./toolbar/MeasureTools/MeasureAngleTool").default;
|
|
555
|
+
/**
|
|
556
|
+
* 距离测量
|
|
557
|
+
*/
|
|
558
|
+
get measureDistanceTool(): import("./toolbar/MeasureTools/MeasureDistanceTool").default;
|
|
559
|
+
/**
|
|
560
|
+
* 剖切
|
|
561
|
+
*/
|
|
562
|
+
get sectionTool(): SectionTool;
|
|
563
|
+
/**
|
|
564
|
+
* 批注
|
|
565
|
+
*/
|
|
566
|
+
get commentTool(): CommentsTool;
|
|
567
|
+
/**
|
|
568
|
+
* 标注
|
|
569
|
+
*/
|
|
570
|
+
get annotationTool(): AnnotationTool;
|
|
571
|
+
/**
|
|
572
|
+
* 结构树object(对象)
|
|
573
|
+
*/
|
|
574
|
+
get objectsExplorer(): ObjectsExplorer;
|
|
575
|
+
/**
|
|
576
|
+
* 结构树class(类别)
|
|
577
|
+
*/
|
|
578
|
+
get classesExplorer(): ClassesExplorer;
|
|
579
|
+
/**
|
|
580
|
+
* 结构树storey(楼层)
|
|
581
|
+
*/
|
|
582
|
+
get storeysExplorer(): StoreysExplorer;
|
|
583
|
+
/**
|
|
584
|
+
* 模型加载器
|
|
585
|
+
*/
|
|
586
|
+
get modelsExplorer(): ModelsExplorer;
|
|
587
|
+
/**
|
|
588
|
+
* 相机视角
|
|
589
|
+
*/
|
|
590
|
+
get orthoMode(): OrthoMode;
|
|
591
|
+
/**
|
|
592
|
+
* 2D/3D
|
|
593
|
+
*/
|
|
594
|
+
get threeDMode(): ThreeDMode;
|
|
595
|
+
/**
|
|
596
|
+
* 导航盒控制器对象
|
|
597
|
+
*/
|
|
598
|
+
get navCubeMode(): NavCubeMode;
|
|
599
|
+
/**
|
|
600
|
+
* 设置相机方向
|
|
601
|
+
* @param {number} dirNum
|
|
602
|
+
*/
|
|
603
|
+
setDirection(dirNum: number): void;
|
|
604
|
+
/**
|
|
605
|
+
* 单击模型对象
|
|
606
|
+
* @param entity
|
|
607
|
+
*/
|
|
608
|
+
singleChoseEntity(entity: any): void;
|
|
609
|
+
/**
|
|
610
|
+
* 单击点击空白
|
|
611
|
+
*/
|
|
612
|
+
singleChosedSpace(): void;
|
|
613
|
+
/**
|
|
614
|
+
* 双击模型对象
|
|
615
|
+
* @param entity
|
|
616
|
+
*/
|
|
617
|
+
doubleChoseEntity(entity: any): void;
|
|
618
|
+
/**
|
|
619
|
+
* 回到正常视图
|
|
620
|
+
*/
|
|
621
|
+
choseSpace(): void;
|
|
622
|
+
/**
|
|
623
|
+
* 按照指定角度旋转相机
|
|
624
|
+
* @param {number} angleInc
|
|
625
|
+
* @returns
|
|
626
|
+
*/
|
|
627
|
+
orbitYawCamera: (angleInc: number) => Promise<void>;
|
|
628
|
+
cameraEnable: (pointerEnabled?: boolean) => void;
|
|
629
|
+
/**
|
|
630
|
+
* 初始预览环周截图
|
|
631
|
+
* @param sizeOrCallback
|
|
632
|
+
* @param done
|
|
633
|
+
* @returns
|
|
634
|
+
*/
|
|
635
|
+
getPreShot(sizeOrCallback?: number, done?: Function): string;
|
|
636
|
+
/**
|
|
637
|
+
* 设置遮挡截图
|
|
638
|
+
* @param callback
|
|
639
|
+
*/
|
|
640
|
+
setShelterCanvas(callback?: Function): void;
|
|
641
|
+
/**
|
|
642
|
+
* 模型截图
|
|
643
|
+
* @param width
|
|
644
|
+
* @param height
|
|
645
|
+
* @param isDownload
|
|
646
|
+
* @returns
|
|
647
|
+
*/
|
|
648
|
+
shot: (width: number, height: number, isDownload: boolean) => string;
|
|
649
|
+
}
|
|
@@ -1,18 +1,6 @@
|
|
|
1
1
|
import { Annotation } from "@xtctwins/tctwins-core";
|
|
2
2
|
import Controller from "../Controller";
|
|
3
3
|
import EventTrigger from "../EventTrigger";
|
|
4
|
-
export declare type AnnotationContent = {
|
|
5
|
-
/** 当前标注所在模型ID */
|
|
6
|
-
modelId: string;
|
|
7
|
-
/** 当前标注ID */
|
|
8
|
-
entityId: string;
|
|
9
|
-
/** 当前标注类型 */
|
|
10
|
-
type: string;
|
|
11
|
-
/** 当前标注内容 */
|
|
12
|
-
content: object;
|
|
13
|
-
/** 当前标注坐标 */
|
|
14
|
-
worldPos: [];
|
|
15
|
-
};
|
|
16
4
|
/**
|
|
17
5
|
* 标注工具
|
|
18
6
|
* @class
|
|
@@ -32,7 +20,16 @@ export default class AnnotationTool extends Controller {
|
|
|
32
20
|
@param {*} cfg
|
|
33
21
|
*/
|
|
34
22
|
constructor(parent: any, cfg: any);
|
|
23
|
+
/**
|
|
24
|
+
* 设置所有标注是否可见
|
|
25
|
+
* @param visible
|
|
26
|
+
*/
|
|
35
27
|
setAllVisible(visible: boolean): void;
|
|
28
|
+
/**
|
|
29
|
+
* 点击后调用,添加新的标注
|
|
30
|
+
* @param event - 传入点击事件
|
|
31
|
+
* @returns
|
|
32
|
+
*/
|
|
36
33
|
clickToCreateAnno(event: any): void;
|
|
37
34
|
private getTime;
|
|
38
35
|
/**
|
|
@@ -47,14 +44,36 @@ export default class AnnotationTool extends Controller {
|
|
|
47
44
|
* @param {string} type
|
|
48
45
|
*/
|
|
49
46
|
setCurrentType(type: string): void;
|
|
50
|
-
|
|
47
|
+
/**
|
|
48
|
+
* 展示所有列表中的标注数据
|
|
49
|
+
*/
|
|
51
50
|
showAnnotationList(): void;
|
|
51
|
+
/**
|
|
52
|
+
* 手动添加标注
|
|
53
|
+
* @param id
|
|
54
|
+
* @param worldPos
|
|
55
|
+
* @param type
|
|
56
|
+
*/
|
|
52
57
|
addAnnotation(id: string, worldPos: number[], type: string): void;
|
|
53
58
|
private clear;
|
|
59
|
+
/**
|
|
60
|
+
* 获取标注列表
|
|
61
|
+
*/
|
|
54
62
|
get AnnotationList(): any;
|
|
63
|
+
/**
|
|
64
|
+
* 设置标注列表
|
|
65
|
+
*/
|
|
55
66
|
set AnnotationList(value: any);
|
|
56
67
|
private getTypeImage;
|
|
68
|
+
/**
|
|
69
|
+
* 设置标注图片
|
|
70
|
+
* @param urls
|
|
71
|
+
*/
|
|
57
72
|
setTypeImage(urls: any): void;
|
|
73
|
+
/**
|
|
74
|
+
* 删除指定id标注
|
|
75
|
+
* @param entityid
|
|
76
|
+
*/
|
|
58
77
|
destroyAnnotationById(entityid: string): void;
|
|
59
78
|
/**
|
|
60
79
|
* 获取指定id的标注对象
|