fl-web-component 1.2.12 → 1.2.13

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.
Files changed (52) hide show
  1. package/README.md +2 -0
  2. package/dist/fl-web-component.common.1.js.map +1 -1
  3. package/dist/fl-web-component.common.2.js.map +1 -1
  4. package/dist/fl-web-component.common.3.js.map +1 -1
  5. package/dist/fl-web-component.common.js +129 -86
  6. package/dist/fl-web-component.common.js.map +1 -1
  7. package/dist/fl-web-component.css +1 -1
  8. package/package.json +1 -1
  9. package/packages/components/com-graphics/index.vue +31 -6
  10. package/src/utils/flgltf-parser.js +68 -50
  11. package/src/utils/instance-parser.js +39 -30
  12. package/packages/components/button/index.vue +0 -26
  13. package/packages/components/model/api/index.js +0 -421
  14. package/packages/components/model/api/mock/detecttree.js +0 -58
  15. package/packages/components/model/api/mock/getmodel-line.js +0 -15834
  16. package/packages/components/model/api/mock/init.js +0 -1
  17. package/packages/components/model/api/mock/pbstree.js +0 -826
  18. package/packages/components/model/api/mock/topology.json +0 -3238
  19. package/packages/components/model/components/TextOverTooltip/index.vue +0 -84
  20. package/packages/components/model/components/annotation-toolbar.vue +0 -410
  21. package/packages/components/model/components/check-proofing-model.vue +0 -39
  22. package/packages/components/model/components/clipping-type.vue +0 -59
  23. package/packages/components/model/components/com-dialogWrapper/Readme.md +0 -53
  24. package/packages/components/model/components/com-dialogWrapper/index.vue +0 -114
  25. package/packages/components/model/components/detect-panel.vue +0 -339
  26. package/packages/components/model/components/detect-tree.vue +0 -445
  27. package/packages/components/model/components/firstPer-panel.vue +0 -109
  28. package/packages/components/model/components/header-button.vue +0 -470
  29. package/packages/components/model/components/imageViewer/index.vue +0 -126
  30. package/packages/components/model/components/import-model.vue +0 -127
  31. package/packages/components/model/components/location-panel.vue +0 -91
  32. package/packages/components/model/components/measure-type.vue +0 -59
  33. package/packages/components/model/components/pbs-tree.vue +0 -497
  34. package/packages/components/model/components/proof-config.vue +0 -72
  35. package/packages/components/model/components/proof-for-pc.vue +0 -126
  36. package/packages/components/model/components/proof-history.vue +0 -300
  37. package/packages/components/model/components/proof-panel-detail.vue +0 -568
  38. package/packages/components/model/components/proof-panel.vue +0 -846
  39. package/packages/components/model/components/proof-project-user.vue +0 -445
  40. package/packages/components/model/components/proof-publish.vue +0 -130
  41. package/packages/components/model/components/proof-role.vue +0 -504
  42. package/packages/components/model/components/props-panel.vue +0 -258
  43. package/packages/components/model/index.vue +0 -3425
  44. package/packages/components/model/readme.md +0 -31
  45. package/packages/components/model/utils/annotation-tool.js +0 -333
  46. package/packages/components/model/utils/cursor.js +0 -23
  47. package/packages/components/model/utils/detect-v1.js +0 -329
  48. package/packages/components/model/utils/index.js +0 -48
  49. package/packages/components/model/utils/threejs/measure-angle.js +0 -258
  50. package/packages/components/model/utils/threejs/measure-area.js +0 -281
  51. package/packages/components/model/utils/threejs/measure-distance.js +0 -209
  52. package/packages/components/model/utils/threejs/measure-volume.js +0 -97
@@ -1,3425 +0,0 @@
1
- <template>
2
- <div id="blocker">
3
- <!-- 顶部按钮-->
4
- <!-- :currentRoute="currentRoute" -->
5
- <!-- @layerConfig="layerConfig" -->
6
- <!-- @setHandleVisiable="setHandleVisiable" -->
7
- <!-- drawName="" -->
8
- <!-- 工具栏 -->
9
- <CheckProofingModel
10
- ref="checkProofingModel"
11
- class="check-proofing-container"
12
- @click="importProofModel"
13
- :defaultParams="defaultParams"
14
- />
15
- <HeaderButton
16
- v-show="showForScreenshot"
17
- class="header-button-container"
18
- ref="headerButton"
19
- :canvasShow="true"
20
- :closeRightOperationType="closeRightOperationType"
21
- :proofingModel="proofingModel"
22
- @rightOperation="headerRightOperation"
23
- />
24
- <ProofConfig
25
- v-show="showForScreenshot"
26
- ref="proofConfig"
27
- class="proof-config-container"
28
- @viewVersion="viewVersion"
29
- @publishVersion="publishVersion"
30
- :defaultParams="defaultParams"
31
- />
32
- <!-- <el-card class="tree-container">
33
- <el-tabs v-model="activeName" :stretch="true">
34
- <el-tab-pane label="工厂树" name="pbsTree">
35
- <PbsTree
36
- class="tree-box-item-card"
37
- v-show="showForScreenshot"
38
- ref="pbsTree"
39
- @pbsNodeClick="pbsNodeClick"
40
- @checkChange="checkChange"
41
- />
42
- </el-tab-pane>
43
- <el-tab-pane label="碰撞报告" name="detectTree">
44
- <DetectTree
45
- class="tree-box-item-card"
46
- v-show="showForScreenshot"
47
- ref="detectTree"
48
- @locate="locateByDetect"
49
- @highlight="highlightByDetect"
50
- :treeData="detectTreeData"
51
- />
52
- </el-tab-pane>
53
- </el-tabs>
54
- </el-card> -->
55
- <PbsTree
56
- class="tree-container"
57
- v-show="showForScreenshot && showPbsTreePanel"
58
- ref="pbsTree"
59
- @pbsNodeClick="pbsNodeClick"
60
- @checkChange="checkChange"
61
- />
62
- <!-- 模型 -->
63
- <div id="instructions"></div>
64
- <!-- 批注画板 -->
65
- <div id="konva-drawing-board" v-show="showDrawingBoard"></div>
66
-
67
- <!-- 工具栏 -->
68
- <!-- <ToolBtn
69
- v-if="toolBtnSetting.toolBtn.all"
70
- :setting="toolBtnSetting.toolBtn"
71
- ref="toolBtn"
72
- @handleBtnEvent="handleBtnEvent"
73
- @home="home"
74
- @firstPer="firstPer"
75
- /> -->
76
- <!-- 测量 -->
77
- <!-- <MeasureType v-if="ctrlPanel['measure']" @measure="handleMeasure" /> -->
78
-
79
- <!-- 属性按钮 -->
80
- <!-- <PropsBtn v-show="showForScreenshot" @lookDetails="lookPropsDetails" /> -->
81
- <!-- 校审按钮 -->
82
- <!-- <ProofBtn v-show="showForScreenshot" @lookDetails="lookProofDetails" /> -->
83
- <!-- 碰撞检测按钮 -->
84
- <!-- <DetectBtn v-show="showForScreenshot" @lookDetails="lookDetectDetails" /> -->
85
-
86
- <!-- <el-button
87
- v-show="showForScreenshot"
88
- type="primary"
89
- size="small"
90
- @click="toggleDrawToolbar"
91
- class="draw-btn"
92
- :disabled="disableDrawBtn"
93
- >批注工具栏</el-button
94
- > -->
95
- <div class="right-panel-container">
96
- <!-- 属性面板 -->
97
- <PropsPanel
98
- class="props-panel-container"
99
- ref="propsPanel"
100
- v-if="showForScreenshot && showPropsPanel"
101
- @rightOperation="rightOperation"
102
- />
103
- <!-- 校审面板 -->
104
- <ProofPanel
105
- class="proof-panel-container"
106
- ref="proofPanel"
107
- v-show="showForScreenshot && showProofPanel"
108
- :defaultParams="defaultParams"
109
- :proofData="proofData"
110
- :showProofDetail="showProofDetail"
111
- :readOnlyMode="readOnlyMode"
112
- @selectRow="handleClickProofList"
113
- @deleteRow="handleDeleteProofList"
114
- @clickEditBtn="handleProofEditBtn"
115
- @clickAddBtn="handleProofAddBtn"
116
- @clickCancelBtn="handleProofCancelBtn"
117
- @clickSaveBtn="handleProofSavelBtn"
118
- @rightOperation="rightOperation"
119
- />
120
- <!-- 碰撞检查 -->
121
- <DetectPanel
122
- class="detect-panel-container"
123
- ref="detectPanel"
124
- v-if="showForScreenshot && showDetectPanel"
125
- :defaultParams="defaultParams"
126
- :treeData="detectTreeData"
127
- @showReport="focusDetectTree"
128
- @rightOperation="rightOperation"
129
- @locate="locateByDetect"
130
- @highlight="highlightByDetect"
131
- @getDetectCheckTree="getDetectCheckTree"
132
- />
133
- </div>
134
- <!-- 定位 -->
135
- <LocationPanel
136
- v-if="locationPanelShow"
137
- :position="position"
138
- ref="locationPanel"
139
- @sureLocation="postLocation"
140
- @cancel="cancelLocation"
141
- />
142
- <!-- 裁切 -->
143
- <!-- <ClippingType v-if="ctrlPanel['clipping']" @clippingType="clippingType" /> -->
144
-
145
- <!-- 点击批注添加时触发, 画板模式 closeDrawing: 退出添加批注功能 -->
146
- <div v-if="showForScreenshot && showToolbar" class="toolbar_show toolbar-container">
147
- <!-- 批注工具栏 -->
148
- <DrawToolbar
149
- ref="drawToolbar"
150
- @closeDrawing="closeDrawing"
151
- @handleDraw="handleDrawAnnotation"
152
- @handleClear="handleClearAnnotation"
153
- @colorChange="handleColorChange"
154
- @save="preHandleProofSavelBtn"
155
- />
156
- </div>
157
- <!-- 第一人称 -->
158
- <el-dialog v-if="firstPerFlag" width="35%" :visible.sync="firstPerFlag">
159
- <FirstPerPanel @start="start" />
160
- </el-dialog>
161
- </div>
162
- </template>
163
- <script>
164
- import CameraControls from 'camera-controls';
165
- import { RoomEnvironment } from 'three/examples/jsm/environments/RoomEnvironment.js';
166
- import {
167
- proofInit,
168
- getModelByGroup,
169
- getPropertyByGroup,
170
- upload,
171
- checkProofingModel,
172
- getProjectId,
173
- getDesignIp,
174
- getOriginalPbsTree,
175
- getTopology,
176
- } from './api/index.js';
177
- import { loading, loadingClose } from './utils/index';
178
- import _ from 'lodash';
179
- import { CSS2DRenderer } from 'three/examples/jsm/renderers/CSS2DRenderer';
180
- import { FontLoader } from 'three/examples/jsm/loaders/FontLoader';
181
- import { TextGeometry } from 'three/examples/jsm/geometries/TextGeometry.js';
182
- import helvetikerFont from 'three/examples/fonts/helvetiker_regular.typeface.json';
183
- import AnnotationDraw from './utils/annotation-tool';
184
- import Konva from 'konva';
185
- import cursors from './utils/cursor';
186
- import html2canvas from 'html2canvas';
187
- import MeasureDistance from './utils/threejs/measure-distance.js';
188
- import MeasureArea from './utils/threejs/measure-area.js';
189
- import MeasureAngle from './utils/threejs/measure-angle.js';
190
- import MeasureVolume from './utils/threejs/measure-volume.js';
191
- import { GUI } from 'three/examples/jsm/libs/lil-gui.module.min.js';
192
- import { LDrawUtils } from 'three/examples/jsm/utils/LDrawUtils.js';
193
- import { PointerLockControls } from 'three/examples/jsm/controls/PointerLockControls.js';
194
- import ProofConfig from './components/proof-config.vue';
195
- import ProofPanel from './components/proof-panel.vue';
196
- import CheckProofingModel from './components/check-proofing-model.vue';
197
- import PbsTree from './components/pbs-tree.vue';
198
- import DetectTree from './components/detect-tree';
199
- import PropsPanel from './components/props-panel.vue';
200
- import CollisionSystem from './utils/detect-v1';
201
- import { MeshLineGeometry, MeshLineMaterial, raycast } from 'meshline';
202
-
203
- // 初始值都为null的变量
204
- var [animateId, recordAlphaBatch, threeMeasure, gui, cube] = (function* (v) {
205
- while (true) yield v;
206
- })(null);
207
-
208
- // 初始值都为false
209
- var [
210
- renderEnabled,
211
- roaming,
212
- moveForward,
213
- moveBackward,
214
- moveLeft,
215
- moveRight,
216
- canJump,
217
- roaming,
218
- listenerMouse,
219
- isWalking,
220
- isWalkingPaused,
221
- clickKey,
222
- addRoamingFlag,
223
- markFlag,
224
- ] = (function* (v) {
225
- while (true) yield v;
226
- })(false);
227
-
228
- // 初始值都为数组 []
229
- var [clippingMesh, bombData, globePlanes] = (function* (v) {
230
- while (true) yield v;
231
- })([]);
232
-
233
- // 初始值都为数字 0
234
- var [timeStamp, fpsClock, firstTime, lastTime] = (function* (v) {
235
- while (true) yield v;
236
- })(0);
237
-
238
- // 初始值为空{}
239
- var [batchTable] = (function* (v) {
240
- while (true) yield v;
241
- })({});
242
- var spaceUp = true; // 处理一直按着空格连续跳的问题
243
- var singleFrameTime = 1 / 30;
244
- var renderEnabled = false;
245
-
246
- var renderer,
247
- camera,
248
- scene,
249
- modelGroup,
250
- cameraControls,
251
- instructions,
252
- timeOut,
253
- labelRenderer,
254
- raycaster,
255
- mouse,
256
- intersect,
257
- clock,
258
- horizontalRaycaster,
259
- downRaycaster,
260
- velocity,
261
- direction,
262
- rotation,
263
- pointControls,
264
- previousModel;
265
- let oldCheckedNodes = [];
266
- var removeSpeed = 5000; //控制器移动速度
267
- var upSpeed = 5000; //控制跳起时的速度
268
- var modelClickEvent = '',
269
- clippingType = '';
270
- var intersectsObject = [];
271
-
272
- var targetObj = null,
273
- konvaStage = null,
274
- konvaLayer = null,
275
- annotationTool = null,
276
- inspectionRect = null;
277
-
278
- const GEOM_TYPES = {
279
- geom_3d: 53248,
280
- geom_3d_text: 53249,
281
- geom_3d_mtext: 53250,
282
- geom_3d_obj: 53251,
283
- geom_2d: 57344,
284
- geom_2d_text: 57345,
285
- geom_2d_mtext: 57346,
286
- geom_2d_circle: 57347,
287
- geom_2d_arc: 57348,
288
- geom_2d_ellipse: 57349,
289
- geom_2d_ellipseArc: 57350,
290
- geom_2d_others: 57351,
291
- };
292
- const INSTANCES_TYPES = {
293
- TEXTANNO: 'TEXTANNO',
294
- };
295
- const STAGE_MODEL_TYPE = {
296
- PID: 1,
297
- REALITY: 2,
298
- };
299
-
300
- var guiParams = {
301
- x轴: 0,
302
- y轴: 0,
303
- z轴: 0,
304
- };
305
-
306
- export default {
307
- name: 'GraphicModel',
308
- // beforeRouteUpdate(to, from, next) {
309
- // // 离开该组件所对应的特定路由时触发的事件
310
- // // window.location.reload(); // TODO 临时刷新,待优化
311
- // // console.log(to)
312
- // // console.log(from)
313
- // // this.mounted();
314
- // next();
315
- // },
316
- data() {
317
- return {
318
- proofingModel: false,
319
- showPropsPanel: false,
320
- showProofPanel: false,
321
- showDetectPanel: false,
322
- showPbsTreePanel: true,
323
- canvasLoading: false, // 批注下画板
324
- showToolbar: false,
325
- showDrawingBoard: false,
326
- checkedToolbarItem: false,
327
- drawing: false,
328
- drawingType: '',
329
- disableDrawBtn: true,
330
- showForScreenshot: true,
331
- defaultParams: {
332
- projectId: null,
333
- stageId: null,
334
- version: null,
335
- },
336
- dataServerParams: {
337
- toProjId: null,
338
- toStagId: null,
339
- toVersion: null,
340
- },
341
- activeName: 'pbsTree',
342
- maxAltitude: 0,
343
- firstPerFlag: false, // 第一视角弹框
344
- isFirstPer: false, // 不再出现弹框
345
- detectTreeData: [],
346
- roamPanelName: '漫游',
347
- roamingPath: [],
348
- locationPanelShow: false,
349
- // 操作按钮互斥, 弹出面板也要互斥, 记录控制面板的变量
350
- ctrlPanel: {
351
- view: false,
352
- mark: false,
353
- roaming: false,
354
- material: false,
355
- light: false,
356
- clipping: false,
357
- measure: false,
358
- pid: false,
359
- spotLight: false,
360
- bomb: false,
361
- alpha: false,
362
- locationUser: false,
363
- },
364
- toolBtnSetting: {
365
- property: true,
366
- rightClick: false,
367
- leftClick: true,
368
- leftBtnId: [0, 1], //左侧按钮列表的id,默认为[],为全部显示
369
- modelBrowser: false,
370
- treeShow: false,
371
- scene: false,
372
- toolBtn: {
373
- all: true,
374
- // home: false,
375
- // view: true,
376
- // mark: true,
377
- // roaming: true,
378
- // material: true,
379
- // light: true,
380
- clipping: true,
381
- measure: true,
382
- // pid: false,
383
- // spotLight: true,
384
- // bomb: true,
385
- firstPer: true,
386
- drawing: true,
387
- // alpha: true,
388
- // locationUser: true
389
- },
390
- },
391
- modelCenter: {
392
- x: 0,
393
- y: 0,
394
- z: 0,
395
- },
396
- closeRightOperationType: {
397
- type: '',
398
- close: true,
399
- },
400
- proofData: {
401
- stageId: '',
402
- version: null,
403
- position: '',
404
- projectId: '',
405
- relevant: '',
406
- previewScreenshotData: '',
407
- problemPrintscreenId: '',
408
- },
409
- showProofDetail: false,
410
- proofConfig: {
411
- viewVersion: null,
412
- },
413
- // onceRenderFlag: true, // 首次渲染标识
414
- };
415
- },
416
- computed: {
417
- activedToolBtn() {
418
- let actived = false;
419
- for (const key in this.ctrlPanel) {
420
- if (this.ctrlPanel[key] === true) {
421
- actived = true;
422
- }
423
- }
424
- return actived;
425
- },
426
- readOnlyMode() {
427
- return !!this.defaultParams.version;
428
- },
429
- },
430
- components: {
431
- ProofConfig,
432
- ProofPanel,
433
- CheckProofingModel,
434
- PbsTree,
435
- PropsPanel,
436
- // PbsTree: () => import("./components/pbs-tree"),
437
- // DetectTree: () => import("./components/detect-tree"),
438
- // PropsPanel: () => import("./components/props-panel.vue"),
439
- // ProofPanel: () => import("./components/proof-panel.vue"),
440
- DetectPanel: () => import('./components/detect-panel.vue'),
441
- DrawToolbar: () => import('./components/annotation-toolbar.vue'),
442
- // MeasureType: () => import('./components/measure-type.vue'),
443
- // ClippingType: () => import('./components/clipping-type.vue'),
444
- LocationPanel: () => import('./components/location-panel.vue'),
445
- FirstPerPanel: () => import('./components/firstPer-panel.vue'),
446
- HeaderButton: () => import('./components/header-button.vue'),
447
- // CheckProofingModel: () => import("./components/check-proofing-model.vue"),
448
- },
449
- beforeRouteEnter(to, from, next) {
450
- if (!to.query.version) {
451
- localStorage.removeItem('proofHistoryVersion');
452
- }
453
- next();
454
- },
455
- beforeRouteLeave(to, from, next) {
456
- try {
457
- this.$refs.proofPanel.clearUpdateModelInterval();
458
- this.resetData();
459
- this.$modal.closeLoading();
460
- next();
461
- } catch (err) {
462
- console.log(err);
463
- next();
464
- }
465
- },
466
- created() {
467
- this.defaultParams.projectId = this.$route.query.projectId;
468
- this.defaultParams.version = this.$route.query.version;
469
-
470
- console.log('defaultParams', this.defaultParams);
471
- CameraControls.install({ THREE: this.THREE });
472
- fpsClock = new this.THREE.Clock();
473
- raycaster = new this.THREE.Raycaster();
474
- mouse = new this.THREE.Vector2();
475
- this.initData();
476
- },
477
- mounted() {
478
- if (this.defaultParams.version) {
479
- this.init();
480
- this.proofingModel = true;
481
- } else {
482
- // 检测模型是否正在校对中
483
- this.$modal.loading('加载中...');
484
- checkProofingModel(this.defaultParams)
485
- .then((proofingModel) => {
486
- if (proofingModel) {
487
- this.proofingModel = true;
488
- this.init();
489
- // this.$refs.proofPanel.IfUpdateModel(this.defaultParams);
490
- this.$refs.proofConfig.abledProofPublishBtn();
491
- } else {
492
- this.$refs.proofConfig.ableImportModelBtn();
493
- this.$refs.checkProofingModel.showCheckProofingModel();
494
- this.$modal.closeLoading();
495
- }
496
- })
497
- .catch((err) => {
498
- console.log(err);
499
- this.$modal.closeLoading();
500
- });
501
- }
502
- },
503
- watch: {
504
- showToolbar(val) {
505
- if (val === false && konvaStage) {
506
- this.$nextTick(() => {
507
- // this.clearPreViewAnn();
508
- konvaStage.container().style.cursor = 'default';
509
- });
510
- }
511
- },
512
- checkedToolbarItem(val) {
513
- const div = document.getElementById('konva-drawing-board');
514
-
515
- if (val) {
516
- div.style.pointerEvents = 'auto';
517
- } else {
518
- this.drawingType = '';
519
- div.style.pointerEvents = 'none';
520
- }
521
- },
522
- },
523
- methods: {
524
- // 初始化模型服务
525
- proofInit() {
526
- loading('加载中...');
527
-
528
- proofInit(this.defaultParams)
529
- .then((res) => {
530
- console.log(this.$refs);
531
- // this.$refs.pbsTree.getPbsTree(this.defaultParams);
532
- // this.$refs.detectTree.getPbsTree(this.defaultParams);
533
-
534
- // 同时请求 ip 和 projectid
535
- // const requests = [getDesignIp(), getProjectId({
536
- // projectId: this.defaultParams.projectId
537
- // })];
538
-
539
- // console.log(requests)
540
-
541
- // return Promise.all(requests)
542
-
543
- return getProjectId({
544
- projectId: this.defaultParams.projectId,
545
- version: this.defaultParams.version,
546
- });
547
- })
548
- .catch((err) => {
549
- console.error(err);
550
- })
551
- .finally(() => {
552
- loadingClose();
553
- })
554
- .then((res) => {
555
- try {
556
- // const ip = res[0];
557
- const { data } = res;
558
- this.dataServerParams.toProjId = data.toProjId; // 此处是校审项目 id 映射的业务项目 id;
559
- this.dataServerParams.toStagId = data.toStagId;
560
- this.dataServerParams.toVersion = data.toVersion;
561
-
562
- this.$refs.pbsTree.getPbsTree({
563
- // ip,
564
- toProjId: this.dataServerParams.toProjId,
565
- toStagId: this.dataServerParams.toStagId,
566
- toVersion: this.dataServerParams.toVersion,
567
- });
568
- } catch (err) {
569
- console.error(err);
570
- }
571
- });
572
- },
573
- // 初始化操作
574
- init() {
575
- instructions = document.getElementById('instructions');
576
- this.proofInit();
577
- this.$nextTick(() => {
578
- this.initAnnotation('konva-drawing-board');
579
- this.loadDrawData();
580
- });
581
- this.draw();
582
- setTimeout(() => {
583
- this.timeRender();
584
- }, 100);
585
- },
586
- // 绘制
587
- draw() {
588
- modelGroup = new this.THREE.Group();
589
- this.initLabelRender();
590
- this.initRender();
591
- this.initScene();
592
- this.initCamera({ type: 'orthographic' });
593
- this.initLight();
594
- const _this = this;
595
-
596
- window.onresize = this.onWindowResize;
597
- renderer.domElement.addEventListener('mouseup', this.mouseClick, false);
598
- renderer.domElement.addEventListener('mousedown', this.setOrbitPoint, false);
599
-
600
- renderer.domElement.addEventListener('wheel', (e) => {
601
- // canvas 禁止事件穿透
602
- if (annotationTool) {
603
- annotationTool.destroy();
604
- annotationTool = null;
605
- }
606
- this.showDrawingBoard = false;
607
- });
608
- cameraControls.addEventListener('wake', (e) => {
609
- renderEnabled = true;
610
- listenerMouse = true;
611
- });
612
- cameraControls.addEventListener('sleep', (e) => {
613
- renderEnabled = false;
614
- });
615
- cameraControls.addEventListener('controlstart', (res) => {
616
- // this.resetOrbitPoint();
617
- // window.controlstart = res;
618
- // canvas 禁止事件穿透
619
- this.clearPreViewAnn();
620
- this.showDrawingBoard = false;
621
- renderEnabled = true;
622
- listenerMouse = true;
623
- });
624
- this.animate();
625
- },
626
- // 初始化无需视图绑定的内部变量
627
- initData() {
628
- this.propertyGroup = {};
629
-
630
- // 缓存模型源数据
631
- this.groupCache = {};
632
-
633
- // 缓存属性源数据
634
- this.groupPropsCache = {};
635
-
636
- // 首次渲染标识
637
- this.onceRenderFlag = true;
638
- this.pickedModel = {
639
- last: null,
640
- current: null,
641
- };
642
- },
643
- initHelper() {
644
- const { stageId, version } = this.defaultParams;
645
- if (stageId == STAGE_MODEL_TYPE.PID) {
646
- const gridHelper = this.renderGridHelper();
647
- scene.add(gridHelper);
648
- } else {
649
- const axesHelper = new this.THREE.AxesHelper(10000);
650
- scene.add(axesHelper);
651
- }
652
- },
653
- renderGridHelper(
654
- size = 1000,
655
- divisions = 100,
656
- color1 = 0x444444,
657
- color2 = 0x888888,
658
- orient = 'z',
659
- ) {
660
- color1 = new this.THREE.Color(color1);
661
- color2 = new this.THREE.Color(color2);
662
-
663
- const center = divisions / 2;
664
- const step = size / divisions;
665
- const halfSize = size / 2;
666
-
667
- const vertices = [],
668
- colors = [];
669
-
670
- for (let i = 0, j = 0, k = -halfSize; i <= divisions; i++, k += step) {
671
- if (orient === 'x') {
672
- vertices.push(0, -halfSize, k, 0, halfSize, k);
673
- vertices.push(0, k, -halfSize, 0, k, halfSize);
674
- } else if (orient === 'y') {
675
- vertices.push(-halfSize, 0, k, halfSize, 0, k);
676
- vertices.push(k, 0, -halfSize, k, 0, halfSize);
677
- } else if (orient === 'z') {
678
- vertices.push(-halfSize, k, 0, halfSize, k, 0);
679
- vertices.push(k, -halfSize, 0, k, halfSize, 0);
680
- }
681
-
682
- const color = i === center ? color1 : color2;
683
-
684
- color.toArray(colors, j);
685
- j += 3;
686
- color.toArray(colors, j);
687
- j += 3;
688
- color.toArray(colors, j);
689
- j += 3;
690
- color.toArray(colors, j);
691
- j += 3;
692
- }
693
-
694
- const geometry = new this.THREE.BufferGeometry();
695
- geometry.setAttribute('position', new this.THREE.Float32BufferAttribute(vertices, 3));
696
- geometry.setAttribute('color', new this.THREE.Float32BufferAttribute(colors, 3));
697
-
698
- const material = new this.THREE.LineBasicMaterial({
699
- vertexColors: true,
700
- toneMapped: false,
701
- });
702
-
703
- return new this.THREE.LineSegments(geometry, material);
704
- },
705
- /* 属性区域 */
706
- // 查看属性
707
- lookPropsDetails(val) {
708
- this.$set(this, 'showPropsPanel', val);
709
- if (!val) {
710
- this.$set(this, 'detailsData', {});
711
- }
712
- },
713
- // 查看属性
714
- lookProofDetails(val) {
715
- this.$set(this, 'showProofPanel', val);
716
- if (!val) {
717
- this.$set(this, 'proofDetailsData', {});
718
- }
719
- },
720
-
721
- // 点击碰撞检查
722
- lookDetectDetails(val) {
723
- this.$refs.detectPanel.init(
724
- { queryParams: { ...this.defaultParams, rebuild: 0 } },
725
- { contentType: 'application/x-www-form-urlencoded' },
726
- );
727
- },
728
-
729
- // 初始化渲染器
730
- initRender() {
731
- renderer = new this.THREE.WebGLRenderer({
732
- antialias: true,
733
- powerPreference: 'high-performance',
734
- alpha: true,
735
- logarithmicDepthBuffer: true,
736
- preserveDrawingBuffer: true, //保留图形缓冲区 TODO 临时截图使用
737
- });
738
- renderer.setPixelRatio(window.devicePixelRatio * 2);
739
- renderer.setSize(window.innerWidth, window.innerHeight);
740
- renderer.sortObjects = false;
741
- renderer.domElement.id = 'three-model';
742
- //告诉渲染器需要阴影效果
743
- renderer.shadowMap.enabled = true;
744
- renderer.toneMapping = this.THREE.ACESFilmicToneMapping;
745
- renderer.toneMappingExposure = 1.0;
746
- renderer.outputEncoding = this.THREE.sRGBEncoding;
747
- instructions.appendChild(renderer.domElement);
748
- },
749
- // 初始化文字画布
750
- initLabelRender() {
751
- labelRenderer = new CSS2DRenderer();
752
- labelRenderer.setSize(window.innerWidth, window.innerHeight);
753
- labelRenderer.domElement.style.position = 'absolute';
754
- labelRenderer.domElement.style.top = '0px';
755
- labelRenderer.domElement.style.pointerEvents = 'none';
756
- instructions.appendChild(labelRenderer.domElement);
757
- },
758
- // 初始化相机
759
- initCamera(options = {}) {
760
- const { stageId } = this.defaultParams;
761
- if (stageId == STAGE_MODEL_TYPE.PID) {
762
- // 正投影相机
763
- const width = window.innerWidth; //canvas画布宽度
764
- const height = window.innerHeight; //canvas画布高度
765
- const k = width / height; //canvas画布宽高比
766
- const s = 200; //控制left, right, top, bottom范围大小
767
- camera = new this.THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 8000);
768
- // camera.position.set(300, 300, 300);
769
- // camera.lookAt(new this.THREE.Vector3(300, 300, 0));
770
- } else {
771
- camera = new this.THREE.PerspectiveCamera(
772
- 45,
773
- window.innerWidth / window.innerHeight,
774
- 0.1,
775
- 10000,
776
- );
777
- }
778
-
779
- this.initCameraControls();
780
- },
781
-
782
- // 初始化场景
783
- initScene() {
784
- scene = new this.THREE.Scene();
785
-
786
- // const mat4 = new this.THREE.Matrix4();
787
- // //生成绕x轴旋转90度的矩阵
788
- // mat4.makeRotationX(-Math.PI/2);
789
- // scene.applyMatrix4(mat4);
790
- // window.scene = scene; // TODO delete
791
- // window.three = this.THREE;
792
- },
793
-
794
- // 初始化控件
795
- initCameraControls() {
796
- cameraControls = new CameraControls(camera, renderer.domElement);
797
- cameraControls.dollyToCursor = true;
798
- cameraControls.smoothTime = 0.1;
799
- cameraControls.draggingSmoothTime = 0.05;
800
- cameraControls.truckSpeed = 2.0;
801
- cameraControls.infinityDolly = true;
802
- cameraControls.minDistance = 10;
803
- cameraControls.dollySpeed = 0.15; // 鼠标滚轮每次移动速度倍率
804
- // window.cameraControls = cameraControls; // TODO delete
805
- },
806
- // 初始化光源
807
- initLight() {
808
- const pmremGenerator = new this.THREE.PMREMGenerator(renderer);
809
- scene.environment = pmremGenerator.fromScene(new RoomEnvironment(), 0.06).texture;
810
- },
811
- // resetOrbitPoint() {
812
- // return; // todo
813
- // const _v3A = new this.THREE.Vector3();
814
- // _v3A.set( 0, 0, -1 ).applyQuaternion( cameraControls._camera.quaternion );
815
- // _v3A.multiplyScalar( cameraControls._spherical.radius );
816
- // _v3A.add( cameraControls._camera.position );
817
-
818
- // cameraControls.setFocalOffset( 0, 0, 0, false );
819
- // cameraControls.moveTo( _v3A.x, _v3A.y, _v3A.z, false );
820
-
821
- // cameraControls.reset(false);
822
- // cameraControls.normalizeRotations();
823
- // cameraControls.truck(0, 0)
824
- // cameraControls.setFocalOffset(0, 0, 0, false);
825
- // camera.position.set(0, 0, 0)
826
- // camera.lookAt(new this.THREE.Vector3(0, 0, 0))
827
- // camera.updateProjectionMatrix()
828
-
829
- // cameraControls.setOrbitPoint(0, 0, 0, true)
830
- // cameraControls.update();
831
- // },
832
- // 动画
833
- animate() {
834
- const delta = fpsClock.getDelta();
835
- timeStamp += delta;
836
- animateId = requestAnimationFrame(this.animate);
837
- if (timeStamp > singleFrameTime) {
838
- cameraControls.enabled && cameraControls.update(timeStamp);
839
- this.firstPerspective();
840
- renderEnabled = true;
841
- labelRenderer.render(scene, camera);
842
-
843
- if (renderEnabled) {
844
- renderer.render(scene, camera);
845
- }
846
- timeStamp = timeStamp % singleFrameTime;
847
- }
848
- },
849
- // 延迟渲染
850
- timeRender() {
851
- // 设置为可渲染
852
- renderEnabled = true;
853
- if (timeOut) {
854
- clearTimeout(timeOut);
855
- }
856
- timeOut = setTimeout(() => {
857
- renderEnabled = false;
858
- }, 1500);
859
- },
860
- // details面板创建
861
- detailsMounted() {
862
- if (this.entityId) {
863
- this.$refs.propsPanel.getModelProperty(
864
- this.entityId,
865
- this.projectId,
866
- intersect.object.userData.pbsId,
867
- intersect.object.userData.version,
868
- ); // intersect.object.userData.pbsId
869
- }
870
- },
871
-
872
- // 左击事件
873
- mouseClick(event) {
874
- // this.resetOrbitPoint();
875
- lastTime = new Date().getTime();
876
- if (event.button === 0) {
877
- if (lastTime - firstTime < 300) {
878
- clickKey = true;
879
- listenerMouse = false;
880
- }
881
- if (clickKey) {
882
- if (roaming || listenerMouse) {
883
- listenerMouse = false;
884
- return;
885
- }
886
- this.modelClick(event, 'left', modelClickEvent);
887
- clickKey = false;
888
- }
889
- } else if (event.button === 2) {
890
- if (lastTime - firstTime < 300) {
891
- // this.rightClick(event)
892
- }
893
- }
894
- },
895
- // 鼠标按下事件
896
- setOrbitPoint(event) {
897
- // this.resetOrbitPoint();
898
- firstTime = new Date().getTime();
899
- renderer.domElement.onmouseup = () => {
900
- lastTime = new Date().getTime();
901
- if (lastTime - firstTime < 300) {
902
- clickKey = true;
903
- listenerMouse = false;
904
- }
905
- };
906
-
907
- if (event.button === 0) {
908
- const elRect = renderer.domElement.getBoundingClientRect();
909
- const canvasX = event.clientX - elRect.left;
910
- const canvasY = event.clientY - elRect.top;
911
- const mousePoint = new this.THREE.Vector2();
912
- mousePoint.set(
913
- (canvasX / elRect.width) * 2.0 - 1.0,
914
- ((elRect.height - canvasY) / elRect.height) * 2.0 - 1.0,
915
- );
916
- // camera.updateMatrixWorld()
917
- raycaster.setFromCamera(mousePoint, camera);
918
- const intersects = raycaster.intersectObjects(scene.children, true);
919
- const obj = intersects && intersects.length > 0 ? intersects[0] : null;
920
- if (obj) {
921
- cameraControls.setOrbitPoint(obj.point.x, obj.point.y, obj.point.z, false);
922
- cameraControls.update();
923
- }
924
- }
925
- },
926
- highlightModel(model) {
927
- if (typeof model == 'string' && model == 'reset') {
928
- model = null;
929
- }
930
- // 非首次
931
- if (this.pickedModel.last) {
932
- // 同一模型
933
- if (model && this.pickedModel.last.name == model.name) {
934
- return;
935
- } else {
936
- // 恢复上个模型颜色
937
- this.changeModelColor({
938
- groupModel: this.pickedModel.last,
939
- type: 'reset',
940
- });
941
- }
942
- }
943
- this.pickedModel.last = model;
944
-
945
- // 保存颜色
946
- if (model) {
947
- this.changeModelColor({
948
- groupModel: model,
949
- color: new this.THREE.Color(0x53a8ff),
950
- });
951
- }
952
- },
953
- changeModelColor({ groupModel, color, type = 'highlight' }) {
954
- groupModel.children.forEach((item) => {
955
- if (item.type === 'Mesh') {
956
- if (type == 'toggleHighlight') {
957
- // 碰撞报告 - 节点高亮的开关,点击高亮,再次点击取消高亮(此高亮与下面的模型点击高亮是两种高亮,且只显示最后一次处理的高亮)
958
- if (item.material.userData.toggleColor) {
959
- // 恢复颜色:恢复原来的颜色
960
- if (item.material.userData.highlightColor) {
961
- // 如果原色是模型点击高亮
962
- item.material.color = item.material.userData.highlightColor;
963
- } else {
964
- // 否则恢复原来的颜色
965
- item.material.color = item.material.userData.originalColor;
966
- }
967
- item.material.userData.toggleColor = null;
968
- } else if (item.material.userData.highlightColor) {
969
- // 更新颜色:若存在模型点击高亮,则覆盖
970
- item.material.userData.toggleColor = color;
971
- item.material.color = color;
972
- } else {
973
- // 更新颜色:若为原色,则正常高亮
974
- item.material.userData.originalColor = item.material.color;
975
- item.material.userData.toggleColor = color;
976
- item.material.color = color;
977
- }
978
- } else if (type == 'reset') {
979
- // 模型点击 - 恢复颜色:恢复原来的颜色
980
- if (item.material.userData.toggleColor) {
981
- item.material.color = item.material.userData.toggleColor;
982
- } else {
983
- item.material.color = item.material.userData.originalColor;
984
- }
985
- item.material.userData.highlightColor = null;
986
- } else if (type == 'highlight') {
987
- // 模型点击 - 更新颜色:高亮当前颜色
988
- if (!item.material.userData.toggleColor) {
989
- // 如果没有碰撞报告高亮,则保存原来的颜色
990
- item.material.userData.originalColor = item.material.color;
991
- }
992
- item.material.userData.highlightColor = color;
993
- item.material.color = color;
994
- }
995
- }
996
- });
997
-
998
- this.timeRender();
999
- },
1000
- // 模型点击事件
1001
- modelClick(event, type, eventType) {
1002
- if (recordAlphaBatch !== null) {
1003
- this.editAlpha(recordAlphaBatch, 'alpha', 1.0, true);
1004
- recordAlphaBatch = null;
1005
- }
1006
- //通过鼠标点击的位置计算出raycaster所需要的点的位置,以屏幕中心为原点,值的范围为-1到1.
1007
- mouse.x = (event.clientX / instructions.offsetWidth) * 2 - 1;
1008
- mouse.y = -(event.clientY / instructions.offsetHeight) * 2 + 1;
1009
- // 通过鼠标点的位置和当前相机的矩阵计算出raycaster
1010
- raycaster.setFromCamera(mouse, camera);
1011
- // 获取raycaster直线和所有模型相交的数组集合
1012
- const intersects = raycaster.intersectObjects(scene.children, true);
1013
- console.log('当前点击模型', intersects[0]);
1014
- if (intersects.length > 0) {
1015
- // 判断点击的是不是上一次选中的
1016
- intersect = intersects[0];
1017
- // 为了兼容之前的模型数据, 更换模型解析后 模型浏览树数据的entityId与batchId相等
1018
- switch (eventType) {
1019
- //根据entityId获取相关的属性信息
1020
- case 'showPropsPanel':
1021
- this.$refs.propsPanel.getPropertiesByEntity(this.entityId, this.projectId, this.pbsId);
1022
- break;
1023
- // 点击事件
1024
- default:
1025
- const modelId = intersect.object.userData.instanceName;
1026
- const params = {
1027
- modelId,
1028
- propertyGroup: this.propertyGroup,
1029
- };
1030
-
1031
- this.pickedModel.current = intersect.object.parent;
1032
-
1033
- if (!this.activedToolBtn) {
1034
- this.highlightModel(this.pickedModel.current);
1035
- this.$refs.pbsTree.scrollTo(this.pickedModel.current.name);
1036
- if (type === 'left' && this.showPropsPanel) {
1037
- this.$refs.propsPanel.getModelProperty(params);
1038
- }
1039
- }
1040
-
1041
- // 剖切
1042
- if (this.ctrlPanel.clipping && clippingType === 'local') {
1043
- // for(let i = 0; i < this.pickedModel.current.children.length; i++){
1044
- console.log(this.pickedModel.current);
1045
- console.log(LDrawUtils.mergeObject(this.pickedModel.current));
1046
- this.controlModel(LDrawUtils.mergeObject(this.pickedModel.current).children[0]);
1047
- // }
1048
- }
1049
- // this.getDataByEntityId(event, type, intersect.object)
1050
- break;
1051
- }
1052
- } else {
1053
- this.highlightModel('reset');
1054
- this.$refs.propsPanel?.resetProperties();
1055
- // renderer.autoClear = true
1056
- //点击区域未获取模型对象
1057
- this.entityId = '';
1058
- intersect = undefined;
1059
- // this.recoverColor()
1060
- // this.clearCopyMesh()
1061
- // this.clearEntites()
1062
- switch (eventType) {
1063
- default:
1064
- if (type === 'left') {
1065
- this.leftClickDown && iframe.postMessage('leftClick', {});
1066
- }
1067
- break;
1068
- }
1069
- }
1070
- },
1071
- /**
1072
- * 根据几何体的类型绘制对应的模型
1073
- * @param {Object} geom- 几何体对象,包含类型和其他属性
1074
- * @param {String} instanceName- 实例名称,用于标记模型
1075
- * @return {Object}- 绘制的模型对象
1076
- */
1077
- drawModel(geom, instanceName) {
1078
- let model;
1079
-
1080
- if (geom.type == GEOM_TYPES.geom_2d || geom.type == GEOM_TYPES.geom_2d_others) {
1081
- model = this.draw2Dmodel(geom, instanceName);
1082
- // model = new this.THREE.Object(geom, this.material);
1083
- } else if (geom.type == GEOM_TYPES.geom_2d_text) {
1084
- model = this.drawText(geom, instanceName);
1085
- } else if (
1086
- geom.type == GEOM_TYPES.geom_2d_circle ||
1087
- geom.type == GEOM_TYPES.geom_2d_arc ||
1088
- geom.type == GEOM_TYPES.geom_2d_ellipse ||
1089
- geom.type == GEOM_TYPES.geom_2d_ellipseArc
1090
- ) {
1091
- model = this.drawCurve(geom, instanceName);
1092
- } else {
1093
- model = this.draw3Dmodel(geom, instanceName);
1094
- }
1095
- return model;
1096
- },
1097
- /**
1098
- * 绘制曲线
1099
- *
1100
- * @param {Object} geom- 包含曲线信息的几何体对象
1101
- * @param {String} instanceName- 曲线实例的名称
1102
- * @return {Object}- 包含曲线模型和曲线信息的对象
1103
- */
1104
- drawCurve(geom, instanceName) {
1105
- let { points, normals } = geom;
1106
- let aX = points[0];
1107
- let aY = points[1];
1108
- let aZ = points[2];
1109
- let xrad = points[3];
1110
- let yrad = points[4];
1111
- let startAngle = points[5];
1112
- let endAngle = points[6];
1113
-
1114
- let curve = new this.THREE.EllipseCurve(
1115
- 0,
1116
- 0,
1117
- xrad,
1118
- yrad,
1119
- startAngle,
1120
- endAngle,
1121
- false, // 曲线方向为逆时针
1122
- );
1123
- let curvePoints = curve.getPoints(50);
1124
- let list = [];
1125
- for (let i = 0; i < curvePoints.length; i++) {
1126
- const { x, y } = curvePoints[i];
1127
- list.push(x);
1128
- list.push(parseFloat(y));
1129
-
1130
- // // 根据角度计算动态 Z 值(例如正弦波动)
1131
- // const angle = Math.atan2(y, x); // 当前点的极角
1132
- // const z = Math.sin(angle * 2) * 2; // Z轴动态变化
1133
- // list.push(z); // 将原始的 z 坐标添加到列表中
1134
- list.push(parseFloat(0)); // 将原始的 z 坐标添加到列表中
1135
- }
1136
-
1137
- const model = this.build2Dmodel(geom, { points: list, normals });
1138
- model.rotation.x = -Math.PI / 2;
1139
- model.position.set(aX, aY, aZ);
1140
- model.userData.instanceName = instanceName;
1141
- return model;
1142
- },
1143
- // 绘制 3D 模型
1144
- draw3Dmodel(geom, instanceName) {
1145
- const geometry = new this.THREE.BufferGeometry();
1146
-
1147
- geometry.setIndex(geom.triangles);
1148
- const position = new Float32Array(geom.points);
1149
- const normal = new Float32Array(geom.normals);
1150
- geometry.setAttribute('position', new this.THREE.BufferAttribute(position, 3));
1151
- geometry.setAttribute('normal', new this.THREE.BufferAttribute(normal, 3));
1152
-
1153
- const { color } = geom.prop;
1154
- const material = new this.THREE.MeshStandardMaterial({
1155
- color: new this.THREE.Color(`rgb(${color[0]}, ${color[1]}, ${color[2]})`),
1156
- side: this.THREE.DoubleSide,
1157
- transparent: false, // 确保透明属性关闭
1158
- opacity: 1, // 确保不透明
1159
- metalness: 0.8,
1160
- roughness: 0.5,
1161
- // lightMapIntensity: 0.7,
1162
- envMapIntensity: 0.5, // 调低环境贴图的强度
1163
- });
1164
- const mesh = new this.THREE.Mesh(geometry, material);
1165
- // mesh.geometry.computeBoundingBox();
1166
- mesh.userData.instanceName = instanceName;
1167
-
1168
- return mesh;
1169
- },
1170
- // 根据 triangles 分割 points, 生成线
1171
- getPointsForLine(points, triangles) {
1172
- let result = [];
1173
-
1174
- // 数组顶部添加 0 标志位应对索引
1175
- triangles.unshift(0);
1176
-
1177
- // 遍历三角形索引数组
1178
- for (let i = 0; i < triangles.length; i++) {
1179
- const sliceStartFlag = triangles[i];
1180
- const sliceEndFlag = triangles[i + 1];
1181
-
1182
- // 如果有下一个切片索引,则将当前切片的点坐标添加到结果数组中
1183
- if (sliceEndFlag) {
1184
- result.push(points.slice(sliceStartFlag * 3, sliceEndFlag * 3));
1185
- }
1186
- }
1187
-
1188
- // 返回提取出的线条点坐标数组
1189
- return result;
1190
- },
1191
- /**
1192
- * 绘制 2D 模型的方法
1193
- *
1194
- * @param {Object} geom - 包含几何体信息的对象
1195
- * @param {String} instanceName - 模型实例的名称
1196
- * @returns {Object} - 包含所有 2D 模型的组对象
1197
- */
1198
- draw2Dmodel(geom, instanceName) {
1199
- const points = this.getPointsForLine(geom.points, geom.triangles);
1200
- const normals = this.getPointsForLine(geom.normals, geom.triangles);
1201
- const group = new this.THREE.Group();
1202
-
1203
- for (let i = 0; i < points.length; i++) {
1204
- const line = this.build2Dmodel(geom, {
1205
- points: points[i],
1206
- normals: normals[i],
1207
- });
1208
- line.userData.instanceName = instanceName;
1209
- group.add(line);
1210
- }
1211
- return group;
1212
- },
1213
- // 绘制 2D 模型
1214
- build2Dmodel(geom, lineInfo) {
1215
- const { points, normals } = lineInfo;
1216
-
1217
- // const geometry = new LineGeometry()
1218
- const geometry = new this.THREE.BufferGeometry();
1219
-
1220
- const position = new Float32Array(points);
1221
- const normal = new Float32Array(normals);
1222
-
1223
- geometry.setAttribute('position', new this.THREE.BufferAttribute(position, 3));
1224
- geometry.setAttribute('normal', new this.THREE.BufferAttribute(normal, 3));
1225
-
1226
- const { color, linewidth } = geom.prop;
1227
-
1228
- const material = new MeshLineMaterial({
1229
- color: new this.THREE.Color(`rgb(${color[0]}, ${color[1]}, ${color[2]})`),
1230
- lineWidth: 0.2 * linewidth,
1231
- });
1232
- // const line = new Line2( geometry, material );
1233
- // line.computeLineDistances();
1234
- const lineGeometry = new MeshLineGeometry();
1235
- lineGeometry.setPoints(geometry);
1236
-
1237
- const mesh = new this.THREE.Mesh(lineGeometry, material);
1238
- mesh.raycast = raycast;
1239
-
1240
- return mesh;
1241
-
1242
- // // const material = new LineMaterial({
1243
- // // color: new this.THREE.Color(`rgb(${color[0]}, ${color[1]}, ${color[2]})`),
1244
- // // linewidth: linewidth,
1245
- // // // dashed: false,
1246
- // // })
1247
- // const material = new this.THREE.LineBasicMaterial({
1248
- // color: new this.THREE.Color(
1249
- // `rgb(${color[0]}, ${color[1]}, ${color[2]})`
1250
- // ),
1251
- // linewidth: linewidth,
1252
- // });
1253
- // // const line = new Line2( geometry, material );
1254
- // // line.computeLineDistances();
1255
- // const line = new this.THREE.Line(geometry, material);
1256
-
1257
- return line;
1258
- },
1259
- // drawText 方法,用于渲染 2D 或 3D 文字
1260
- drawText(geom, instanceName) {
1261
- const { prop, text, points, normals } = geom;
1262
- const { color, linewidth, fontsize, fontname, rotate, italic, widthscale } = prop;
1263
-
1264
- var loader = new FontLoader();
1265
- var font = loader.parse(helvetikerFont);
1266
- var geometry = new TextGeometry(`${text}`, {
1267
- font: font, // 字体格式
1268
- size: fontsize, // 字体大小
1269
- height: 1, // 字体深度
1270
- curveSegments: 11, // 曲线控制点数
1271
- bevelEnabled: true, // 斜角
1272
- bevelThickness: 0.1, // 斜角的深度
1273
- bevelSize: 1, // 斜角的大小
1274
- bevelSegments: 1, // 斜角段数
1275
- });
1276
- // const { stageId } = this.defaultParams;
1277
-
1278
- const normal = new Float32Array(normals);
1279
- // 设置几何体的顶点法线属性.attributes.normal
1280
- geometry.setAttribute('normal', new this.THREE.BufferAttribute(normal, 3));
1281
-
1282
- const colors = color.split(',');
1283
- var mat = new this.THREE.MeshBasicMaterial({
1284
- color: new this.THREE.Color(`rgb(${colors[0]}, ${colors[1]}, ${colors[2]})`),
1285
- // opacity: 1,
1286
- // shininess: 1,
1287
- });
1288
-
1289
- const mesh = new this.THREE.Mesh(geometry, mat);
1290
-
1291
- // if (stageId == STAGE_MODEL_TYPE.PID) {
1292
- // mesh.translateX(-(fontsize / 2));
1293
- // mesh.translateY(-(fontsize / 2));
1294
- // }
1295
-
1296
- mesh.position.set(points[0], points[1], points[2]);
1297
- if (rotate) {
1298
- console.log('rotate', rotate, mesh);
1299
- mesh.rotateY(rotate);
1300
- }
1301
- mesh.rotateX(-Math.PI / 2);
1302
- mesh.translateX(-(fontsize / 2));
1303
- mesh.translateY(-(fontsize / 2));
1304
-
1305
- mesh.userData.instanceName = instanceName;
1306
-
1307
- return mesh;
1308
- },
1309
- /**
1310
- * 根据组 ID 获取模型信息
1311
- *
1312
- * @param {string} groupId - 要获取模型信息的组 ID
1313
- * @returns {Promise}
1314
- */
1315
- getModelsByGroup(groupId) {
1316
- return new Promise((resolve) => {
1317
- const param = {
1318
- groupId: groupId,
1319
- // ...this.defaultParams,
1320
- ...this.dataServerParams,
1321
- };
1322
-
1323
- if (!this.groupCache[groupId]) {
1324
- getModelByGroup(param)
1325
- .then((res) => {
1326
- const modelsInfo = (this.groupCache[groupId] = res);
1327
- console.log(modelsInfo);
1328
- resolve(modelsInfo);
1329
- })
1330
- .catch((err) => {
1331
- resolve(err);
1332
- });
1333
- } else {
1334
- resolve(this.groupCache[groupId]);
1335
- }
1336
-
1337
- console.log('groupCache', this.groupCache);
1338
-
1339
- // getModelByGroup(param).then((res) => {
1340
- // const modelsInfo = res;
1341
- // console.log(modelsInfo);
1342
- // resolve(modelsInfo);
1343
- // }).catch((err) => {
1344
- // resolve(err);
1345
- // });
1346
- });
1347
- },
1348
-
1349
- getPropertyByGroup(groupId) {
1350
- const param = {
1351
- groupId: groupId,
1352
- // ...this.defaultParams,
1353
- ...this.dataServerParams,
1354
- };
1355
- if (!this.groupPropsCache[groupId]) {
1356
- getPropertyByGroup(param)
1357
- .then((res) => {
1358
- const propInfo = (this.groupPropsCache[groupId] = res);
1359
- console.log(propInfo);
1360
- Object.assign(this.propertyGroup, propInfo);
1361
- })
1362
- .catch((err) => {
1363
- console.log(err);
1364
- });
1365
- } else {
1366
- Object.assign(this.propertyGroup, this.groupPropsCache[groupId]);
1367
- }
1368
- },
1369
- /**
1370
- * 比较新选中节点与旧选中节点,获取新增和移除的节点
1371
- * @param {Array} newCheckedNodes - 新选中的节点数组
1372
- * @returns {Object} - 包含新增和移除节点的对象
1373
- */
1374
- diffCheckedNodes(newCheckedNodes) {
1375
- // 找出新增的元素
1376
- const addNodes = _.difference(newCheckedNodes, oldCheckedNodes);
1377
- // 找出删除的元素
1378
- const removedNodes = _.difference(oldCheckedNodes, newCheckedNodes);
1379
-
1380
- console.log('oldCheckedNodes', oldCheckedNodes);
1381
- oldCheckedNodes = newCheckedNodes;
1382
- console.log('newCheckedNodes', newCheckedNodes);
1383
- console.log('add:', addNodes); // 输出新增的元素
1384
- console.log('Removed:', removedNodes); // 输出删除的元素
1385
- return {
1386
- addNodes,
1387
- removedNodes,
1388
- };
1389
- },
1390
- resetData() {
1391
- oldCheckedNodes = [];
1392
- },
1393
- // 勾选 pbs 树渲染对应模型
1394
- checkChange(nodes) {
1395
- console.log('nodes', nodes);
1396
- const { addNodes, removedNodes } = this.diffCheckedNodes(nodes);
1397
-
1398
- const handleNodes = addNodes.length ? addNodes : removedNodes;
1399
- const nodeState = addNodes.length ? 'add' : 'removed';
1400
- this.getModelByNode(handleNodes, nodeState);
1401
- },
1402
- /**
1403
- * 根据节点获取模型
1404
- * @param {Array} nodes - 节点数组
1405
- * @param {String} type - 操作类型,可能是 "add" 或 "remove"
1406
- */
1407
- async getModelByNode(nodes, type) {
1408
- loading('加载中...');
1409
- // nodes = ['1274011493561532418']
1410
- for (let i = 0; i < nodes.length; i++) {
1411
- const models = await this.getModelsByGroup(nodes[i]);
1412
- models && this.handleModel(models, type);
1413
-
1414
- type == 'add' && this.getPropertyByGroup(nodes[i]);
1415
- }
1416
-
1417
- console.log(this.onceRenderFlag);
1418
- console.log(this.groupPropsCache);
1419
- if (this.onceRenderFlag && scene.children.length) {
1420
- // this.initHelper();
1421
- let box3 = new this.THREE.Box3().setFromObject(scene);
1422
- this.setModelCenter(box3);
1423
- this.setCameraConfig();
1424
-
1425
- this.onceRenderFlag = false;
1426
- }
1427
- // 关闭加载提示
1428
- loadingClose();
1429
- },
1430
- // async getModelByNode(nodes, type) {
1431
- // loading("加载中...");
1432
- // const promiseGroup = [];
1433
- // for (let i = 0; i < nodes.length; i++) {
1434
- // // const models = await this.getModelsByGroup(nodes[i]);
1435
- // // models && this.handleModel(models, type);
1436
- // const models = this.getModelsByGroup(nodes[i])
1437
- // promiseGroup.push(models);
1438
-
1439
- // models.then((models) => {
1440
- // this.handleModel(models, type);
1441
- // });
1442
- // }
1443
- // Promise.all(promiseGroup).then(() => {
1444
- // // 关闭加载提示
1445
- // loadingClose();
1446
- // }).catch((error) => {
1447
- // this.$message({
1448
- // type: "error",
1449
- // message: err.msg,
1450
- // });
1451
- // // 关闭加载提示
1452
- // loadingClose();
1453
- // })
1454
- // },
1455
-
1456
- // 点击 pbs 节点定位模型`
1457
- // 这里应该是有问题的 因为给的是groupId groupName等信息,并没有具体能找到模型实体的id,所以要不就再新增一个接口
1458
- // 还有一个问题是 定位应该是定位到某一个实体上 所以 tree的信息还得重新获取一下 因为这里写的是模拟的数据 现在接口服务关闭了
1459
- pbsNodeClick(node) {
1460
- const obj = scene.getObjectByName(node);
1461
- console.log(obj);
1462
-
1463
- if (obj) {
1464
- this.clearPreViewAnn();
1465
- this.showDrawingBoard = true;
1466
- this.disableDrawBtn = true;
1467
- this.showToolbar = false;
1468
- if (annotationTool) {
1469
- annotationTool.destroy();
1470
- annotationTool = null;
1471
- }
1472
-
1473
- if (this.showPropsPanel) {
1474
- const params = {
1475
- modelId: obj.name,
1476
- propertyGroup: this.propertyGroup,
1477
- // ...this.defaultParams,
1478
- };
1479
-
1480
- this.$refs.propsPanel.getModelProperty(params);
1481
- }
1482
-
1483
- if (obj.children.length) {
1484
- cameraControls.fitToBox(obj, true);
1485
- }
1486
-
1487
- this.highlightModel(obj);
1488
- }
1489
- },
1490
- locateModel(node) {
1491
- const obj = scene.getObjectByName(node);
1492
-
1493
- if (obj) {
1494
- cameraControls.fitToBox(obj, true);
1495
- }
1496
- },
1497
- // 相机定位
1498
- animateCamera(
1499
- cameraTargetX,
1500
- cameraTargetY,
1501
- cameraTargetZ,
1502
- controlsTargetX,
1503
- controlsTargetY,
1504
- controlsTargetZ,
1505
- moveSmooth = false,
1506
- offset,
1507
- ) {
1508
- // this.resetOrbitPoint(); // 还原轨道中心点
1509
-
1510
- // offset && cameraControls.setOrbitPoint( 0, 0, 0, false )
1511
-
1512
- cameraControls.setLookAt(
1513
- cameraTargetX,
1514
- cameraTargetY,
1515
- cameraTargetZ,
1516
- controlsTargetX,
1517
- controlsTargetY,
1518
- controlsTargetZ,
1519
- moveSmooth,
1520
- );
1521
-
1522
- offset && cameraControls.setFocalOffset(offset.x, offset.y, offset.z, false);
1523
- cameraControls.update(0);
1524
- },
1525
- // 根据 pbs 信息绘制 pbs 模型树
1526
- handleModel(modelInfo, type) {
1527
- const instances = modelInfo.instances;
1528
- const isInstanceChildren = modelInfo.type && modelInfo.type === 'instanceChildren';
1529
-
1530
- const drawObjs = isInstanceChildren
1531
- ? modelInfo.drawObjs
1532
- : this.formatDrawObjs(modelInfo.drawObjs);
1533
-
1534
- for (let i = 0; i < instances.length; i++) {
1535
- // if(_.isEmpty(instances[i])){
1536
- // continue;
1537
- // }
1538
- const drawId = instances[i].drawObject;
1539
- const instanceName = instances[i].instanceId;
1540
- const targetGroup = scene.getObjectByProperty('name', instanceName);
1541
- // 如果找不到目标组(即首次勾选PBS树节点),则加载模型
1542
- if (!targetGroup) {
1543
- const group = new this.THREE.Group();
1544
- group.name = instances[i].instanceId;
1545
- group.userData.tags = instances[i].tags?.toUpperCase();
1546
- group.userData.category = instances[i].category;
1547
- group.userData.bounding = instances[i].bounding;
1548
-
1549
- const matrix4 = instances[i].matrix.val;
1550
-
1551
- if (instances[i].children && instances[i].children.length) {
1552
- const childrenModelInfo = {
1553
- instances: instances[i].children,
1554
- drawObjs,
1555
- type: 'instanceChildren',
1556
- parentGroup: group,
1557
- };
1558
-
1559
- this.handleModel(childrenModelInfo, type);
1560
- }
1561
-
1562
- if (drawObjs[drawId]) {
1563
- drawObjs[drawId]['geoms'].forEach((item) => {
1564
- const model = this.drawModel(item, instanceName);
1565
- // intersectsObject.push(model);
1566
-
1567
- group.add(model);
1568
- });
1569
- const m4 = new this.THREE.Matrix4();
1570
- m4.elements = matrix4;
1571
- group.applyMatrix4(m4);
1572
-
1573
- if (isInstanceChildren) {
1574
- // modelGroup.add(group);
1575
- modelInfo.parentGroup.add(group);
1576
- } else {
1577
- modelGroup.add(group);
1578
- }
1579
- }
1580
-
1581
- // 如果是列表中的最后一个实例,则将模型组添加到场景中
1582
- // 子实例不需要执行
1583
- if (i == instances.length - 1 && !isInstanceChildren) {
1584
- scene.add(modelGroup);
1585
- }
1586
- // 如果找到了目标组,并且是新增操作,则显示模型
1587
- } else if (targetGroup && type == 'add') {
1588
- targetGroup.visible = true;
1589
- targetGroup.layers.set(0);
1590
- // 如果找到了目标组,并且是移除操作,则隐藏模型
1591
- } else if (targetGroup && type == 'removed') {
1592
- targetGroup.visible = false;
1593
- targetGroup.layers.set(1);
1594
- }
1595
- }
1596
- this.timeRender();
1597
- },
1598
- /**
1599
- * 将数组数据转换为键值对形式的 JSON 对象
1600
- * @param {Array} data - 包含对象的数组,每个对象都有一个 drawObjId 属性
1601
- * @returns {Object}
1602
- */
1603
- formatDrawObjs(data) {
1604
- const obj = {};
1605
- data.forEach((item) => {
1606
- obj[item.drawObjId] = item;
1607
- });
1608
- return obj;
1609
- },
1610
- initAnnotation(domId) {
1611
- // canvas 禁止事件穿透
1612
- const div = document.getElementById('konva-drawing-board');
1613
- div.style.pointerEvents = 'none';
1614
-
1615
- const app = document.getElementById('app');
1616
- konvaStage = new Konva.Stage({
1617
- className: 'stage',
1618
- container: domId,
1619
- width: app.clientWidth,
1620
- height: app.clientHeight,
1621
- draggable: false,
1622
- });
1623
- // window.konvaStage = konvaStage; // TODO delete
1624
-
1625
- // konvaStage.container().style.background = "rgb(33,40,48)";
1626
- konvaLayer = new Konva.Layer({
1627
- name: 'konva-layer',
1628
- });
1629
- konvaStage.add(konvaLayer);
1630
- konvaLayer.draw();
1631
- var scaleBy = 1.5;
1632
- // konvaStage.on("wheel", (e) => {
1633
- // e.evt.preventDefault();
1634
- // var oldScale = konvaStage.scaleX();
1635
- // var pointer = konvaStage.getPointerPosition();
1636
- // var mousePointTo = {
1637
- // x: (pointer.x - konvaStage.x()) / oldScale,
1638
- // y: (pointer.y - konvaStage.y()) / oldScale,
1639
- // };
1640
- // // how to scale? Zoom in? Or zoom out?
1641
- // let direction = e.evt.deltaY > 0 ? -1 : 1;
1642
- // if (e.evt.ctrlKey) {
1643
- // direction = -direction;
1644
- // }
1645
- // var newScale = direction > 0 ? oldScale * scaleBy : oldScale / scaleBy;
1646
- // konvaStage.scale({ x: newScale, y: newScale });
1647
- // var newPos = {
1648
- // x: pointer.x - mousePointTo.x * newScale,
1649
- // y: pointer.y - mousePointTo.y * newScale,
1650
- // };
1651
- // konvaStage.position(newPos);
1652
- // });
1653
- konvaStage.on('click', (e) => {
1654
- const position = konvaStage.getPointerPosition();
1655
- const x = (position.x - konvaStage.getX()) / konvaStage.scaleX();
1656
- const y = (position.y - konvaStage.getY()) / konvaStage.scaleY();
1657
- inspectionRect.setX(x);
1658
- inspectionRect.setY(y);
1659
- if (e.target.attrs.hasOwnProperty('className') && e.target.attrs.className === 'stage') {
1660
- const obj = this.getIntersects(inspectionRect.getClientRect());
1661
- targetObj = obj.length > 0 ? obj[obj.length - 1] : null;
1662
- } else {
1663
- targetObj = e.target;
1664
- }
1665
- // console.log(targetObj)
1666
- if (targetObj === null || targetObj.attrs.name === 'annotation-shape') return;
1667
- this.entityId = targetObj.attrs.entityId;
1668
- if (e.evt.button === 0) {
1669
- this.svgClick(targetObj);
1670
- } else if (e.evt.button === 2) {
1671
- // 为2是右击
1672
- this.rightClick(targetObj);
1673
- }
1674
- });
1675
- konvaStage.on('contextmenu', (e) => {
1676
- e.evt.preventDefault();
1677
- });
1678
- },
1679
- // 碰撞检测
1680
- getIntersects(rect) {
1681
- let l = konvaLayer.children.length;
1682
- let intersects = [];
1683
- for (let index = 0; index < l; index++) {
1684
- const ele = konvaLayer.children[index];
1685
- if (ele.attrs.name !== 'intersect-rect') {
1686
- const boundingRect = ele.getClientRect();
1687
- if (
1688
- !(
1689
- rect.x + rect.width < boundingRect.x ||
1690
- boundingRect.x + boundingRect.width < rect.x ||
1691
- rect.y + rect.height < boundingRect.y ||
1692
- boundingRect.y + boundingRect.height < rect.y
1693
- )
1694
- ) {
1695
- intersects.push(ele);
1696
- }
1697
- }
1698
- }
1699
- return intersects;
1700
- },
1701
-
1702
- handleDrawAnnotation(parmas = {}) {
1703
- this.showDrawingBoard = true;
1704
- this.checkedToolbarItem = true;
1705
- parmas.type = parmas.type || '';
1706
- this.drawingType = parmas.type;
1707
- this.drawingStrokeWidth = parmas.strokeWidth;
1708
- // 需要开启禁止拖动
1709
- switch (parmas.type) {
1710
- case 'Rect':
1711
- konvaStage.container().style.cursor = 'crosshair'; // `url('${cursors.eraser}') 15 15, auto`
1712
- break;
1713
- case 'Line':
1714
- konvaStage.container().style.cursor = `url('${cursors.pen}') 15 15, auto`;
1715
- break;
1716
- case 'Circle':
1717
- konvaStage.container().style.cursor = 'crosshair';
1718
- break;
1719
- case 'Rubber':
1720
- konvaStage.container().style.cursor = `url('${cursors.eraser}') 10 28, auto`;
1721
- break;
1722
- case 'Text':
1723
- konvaStage.container().style.cursor = `url('${cursors.text}') 15 15, auto`;
1724
- break;
1725
- }
1726
- // konvaStage.draggable(false);
1727
- if (annotationTool) {
1728
- annotationTool.updateType({
1729
- type: parmas.type,
1730
- strokeWidth: parmas.strokeWidth,
1731
- });
1732
- } else {
1733
- annotationTool = new AnnotationDraw.AnnotationTool(
1734
- konvaStage,
1735
- konvaLayer,
1736
- parmas.type,
1737
- parmas.strokeWidth,
1738
- );
1739
- annotationTool.start();
1740
- // window.annotationTool = annotationTool; // TODO delete
1741
- }
1742
- },
1743
- handleClearAnnotation() {
1744
- this.handleDrawAnnotation();
1745
- if (annotationTool) {
1746
- annotationTool.clearLayer();
1747
- }
1748
- },
1749
- handleColorChange(val) {
1750
- if (annotationTool) {
1751
- annotationTool.updateColor(val);
1752
- }
1753
- },
1754
-
1755
- locationAnnotation(id) {
1756
- // this.leftAllDrawings = false
1757
- // this.leftDrawingStructure = false
1758
- // this.avatarImage = item.path
1759
- // this.proxyImageShow = true
1760
- // 获取标注的列表添加到图纸中并且定位
1761
- // 清除上一次查看的标注
1762
- this.clearPreViewAnn();
1763
- getMarkOne(id)
1764
- .then((res) => {
1765
- console.log(res);
1766
- if (res.code === 200 && res.data) {
1767
- const x = Number(res.data.x);
1768
- const y = Number(res.data.y);
1769
- const z = Number(res.data.z);
1770
- konvaStage.setX(x);
1771
- konvaStage.setY(y);
1772
- konvaStage.scale({
1773
- x: z,
1774
- y: z,
1775
- });
1776
- // this.drawCallbackData(res.data.relevant);
1777
- }
1778
- })
1779
- .catch();
1780
- },
1781
- viewingDraw() {
1782
- konvaStage.draggable(false); // 不可移动
1783
- },
1784
- editingDraw() {
1785
- konvaStage.draggable(false); // 不可移动
1786
- },
1787
- // 保存标记后的图片
1788
- handleSaveAnnotation() {
1789
- this.handleDrawAnnotation();
1790
- if (!annotationTool.layer?.children?.length) {
1791
- return;
1792
- }
1793
- // this.$refs.drawToolbar.showToolbar = false; // 关闭画板工具条
1794
- this.showToolbar = false; // 关闭画板工具条
1795
- this.canvasLoading = true;
1796
- const annotationArr = [];
1797
- annotationTool.layer.children.forEach((item) => {
1798
- annotationArr.push(item.attrs);
1799
- });
1800
-
1801
- return annotationArr;
1802
- console.log(JSON.stringify(annotationArr));
1803
- // this.screenshot(JSON.stringify(annotationArr));
1804
- },
1805
- /* 保存批注
1806
- 将当前可视窗口使用html2canvas插件的照相机功能,保存为图片
1807
- 将图片及该批注图片相对于svg的位置及大小发给后端
1808
- 下次点击批注图片时,将SVG位置及大小实时更新 */
1809
- async screenshot() {
1810
- this.showForScreenshot = false;
1811
- let canvasID = document.getElementById('app'); // this.$refs.drawingDisplay
1812
-
1813
- let canvas;
1814
- await new Promise((resolve) => {
1815
- this.$nextTick(async () => {
1816
- canvas = await html2canvas(canvasID, {
1817
- allowTaint: true,
1818
- useCORS: true,
1819
- });
1820
- resolve();
1821
- });
1822
- });
1823
-
1824
- let urlData = canvas.toDataURL('image/jpeg', 1.0);
1825
- this.showForScreenshot = true;
1826
- return urlData;
1827
- // this.uploadScreenshot(urlData)
1828
- // if (res.code === 200) {
1829
- // await this.uploadByUrl(res.data.link, file);
1830
- // const obj = {
1831
- // documentId: this.presentDrawing,
1832
- // path: res.data.path,
1833
- // projectId: this.projectId,
1834
- // name: dataNow,
1835
- // x: konvaStage.x().toString(),
1836
- // y: konvaStage.y().toString(),
1837
- // z: konvaStage.scaleX().toString(),
1838
- // relevant: annotationArr,
1839
- // };
1840
- // const data2 = await addMark(obj);
1841
- // if (data2.code === 200) {
1842
- // this.$message.success("保存成功");
1843
- // this.closeDrawing();
1844
- // } else {
1845
- // this.canvasLoading = false;
1846
- // }
1847
- // } else {
1848
- // this.canvasLoading = false;
1849
- // }
1850
- },
1851
- uploadScreenshot(urlData) {
1852
- // 上传文件
1853
- const arr = urlData.split(',');
1854
- const mime = arr[0].match(/:(.*?);/)[1]; // 此处得到的为文件类型
1855
- const bstr = window.atob(arr[1]); // 此处将base64解码
1856
- let n = bstr.length;
1857
- const u8arr = new Uint8Array(n);
1858
- while (n--) {
1859
- u8arr[n] = bstr.charCodeAt(n);
1860
- }
1861
- const dataNow = Date.now();
1862
- const file = new File([u8arr], `newCanvas${dataNow}.jpeg`, {
1863
- type: mime,
1864
- });
1865
- const fileData = new FormData();
1866
- fileData.append('file', file);
1867
- return upload(fileData);
1868
- },
1869
- /* 解决跨域 */
1870
- uploadByUrl(url, data) {
1871
- return fetch(url, {
1872
- mode: 'cors',
1873
- headers: { 'Content-Type': 'application/octet-stream' },
1874
- method: 'PUT',
1875
- body: data,
1876
- });
1877
- },
1878
- /* 添加批注触发,打开画板模式 */
1879
- toggleDrawToolbar(status) {
1880
- // this.canvasShow = false
1881
- // 打开工具栏
1882
- const _setOpenToolbarState = () => {
1883
- this.leftAllDrawings = false;
1884
- this.leftDrawingStructure = false;
1885
- this.showToolbar = true;
1886
- };
1887
- // 关闭工具栏
1888
- const _setCloseToolbarState = () => {
1889
- this.leftAllDrawings = false;
1890
- this.leftDrawingStructure = false;
1891
- this.showToolbar = false;
1892
- this.checkedToolbarItem = false;
1893
- };
1894
-
1895
- if (typeof status == 'boolean') {
1896
- // 明确设置工具栏状态
1897
- if (status === false) {
1898
- _setCloseToolbarState();
1899
- } else {
1900
- _setOpenToolbarState();
1901
- }
1902
- } else {
1903
- // toggle工具栏
1904
- if (this.showToolbar) {
1905
- _setCloseToolbarState();
1906
- } else {
1907
- _setOpenToolbarState();
1908
- }
1909
- }
1910
-
1911
- // if (status != undefined ? status === false : this.showToolbar) {
1912
- // // 关闭工具栏
1913
- // this.leftAllDrawings = false;
1914
- // this.leftDrawingStructure = false;
1915
- // this.showToolbar = false;
1916
- // this.checkedToolbarItem = false;
1917
- // // this.checkedToolbarItem = this.clearPreViewAnn();
1918
- // // this.$set(this, "rightType", "");
1919
- // } else if (
1920
- // status != undefined ? status === true : this.showToolbar === false
1921
- // ) {
1922
- // // this.checkedToolbarItem = this.clearPreViewAnn();
1923
- // // this.$set(this, "rightType", "");
1924
- // }
1925
- },
1926
- // 获取图纸数据并加载
1927
- loadDrawData(id, parmas, callback) {
1928
- if (this.$route.path.indexOf('DrawingDisplay') > 0) {
1929
- this.$modal.loading('正在加载,请稍后...');
1930
- }
1931
- // recordDocumentId = this.presentDrawing;
1932
- this.$set(this, 'presentDrawing', id);
1933
- konvaLayer.destroyChildren();
1934
- konvaStage.scale({
1935
- x: 1,
1936
- y: 1,
1937
- });
1938
- konvaStage.setX(0);
1939
- konvaStage.setY(0);
1940
- inspectionRect = new Konva.Rect({
1941
- width: 1,
1942
- height: 1,
1943
- x: 0,
1944
- y: 0,
1945
- stroke: '#000',
1946
- strokeWidth: 0.2,
1947
- name: 'intersect-rect',
1948
- visible: false,
1949
- });
1950
- konvaLayer.add(inspectionRect);
1951
- return;
1952
- getDocPreview(id)
1953
- .then((res) => {
1954
- let dxf = null;
1955
- if (res.type == 0) {
1956
- const parser = new DxfParser();
1957
- dxf = parser.parse(res.dxf);
1958
- let json = JSON.stringify(dxf);
1959
- let pat = {};
1960
- pat.json = json;
1961
- pat.docId = id;
1962
- addDrawingJson(pat);
1963
- }
1964
- if (res.type == 1) {
1965
- dxf = JSON.parse(res.dxf);
1966
- }
1967
- let entities = formatEntity(dxf.entities); // dxf.entities;
1968
- let layers = dxf.tables.layer.layers;
1969
- for (let key in layers) {
1970
- let color = getColors()[layers[key].colorIndex];
1971
- color = 'rgb(' + color + ')';
1972
- if (entities[key]) {
1973
- let group = new Konva.Group({
1974
- x: 0,
1975
- y: 0,
1976
- name: key,
1977
- entityId: key,
1978
- isGroup: true,
1979
- visible: true,
1980
- });
1981
- let l = entities[key].length;
1982
- for (let i = 0; i < l; i++) {
1983
- let type = entities[key][i].type;
1984
-
1985
- handleFn(type, dxf, entities[key][i], group, key, color, konvaLayer);
1986
- }
1987
- konvaLayer.add(group);
1988
- }
1989
- }
1990
- const newScale = 1;
1991
- konvaStage.scale({
1992
- x: newScale,
1993
- y: newScale,
1994
- });
1995
- const boundingRect = konvaLayer.getClientRect();
1996
- const x = this.$refs.svgDraw.clientWidth / 2 - Math.ceil(boundingRect.width) / 2;
1997
- const y =
1998
- this.$refs.svgDraw.clientHeight / 2 -
1999
- (Math.ceil(boundingRect.height) / 2 + boundingRect.y);
2000
- konvaStage.setX(x);
2001
- konvaStage.setY(y);
2002
- activedSvgPan.zoom.x = newScale;
2003
- activedSvgPan.zoom.y = newScale;
2004
- activedSvgPan.x = x;
2005
- activedSvgPan.y = y;
2006
- setTimeout(() => {
2007
- if (this.entityId) {
2008
- this.rightOpenType(this.rightType, this.entityId, true); // 右侧窗口打开时数据更新
2009
- this.getOnlyId(this.entityId);
2010
- this.svgCenteredMagnification(this.entityId);
2011
- }
2012
- callback && callback(parmas);
2013
- }, 300);
2014
- this.$modal.closeLoading();
2015
- })
2016
- .catch((err) => {
2017
- console.log(err);
2018
- this.$modal.closeLoading();
2019
- this.$message({
2020
- type: 'error',
2021
- message: err.msg,
2022
- });
2023
- konvaLayer.removeChildren();
2024
- });
2025
- },
2026
- /* 批注退出添加 */
2027
- closeDrawing() {
2028
- this.entityId = ''; // 添加批注时,清空entityId
2029
- // if (this.oldTargetNode.length !== 0) this.resetHightLight([]); // 添加批注时,清空高亮
2030
- this.showToolbar = false;
2031
- this.proxyImageShow = false;
2032
- this.canvasLoading = false;
2033
- this.showDrawingBoard = false;
2034
- this.checkedToolbarItem = false;
2035
-
2036
- if (annotationTool) {
2037
- annotationTool.destroy();
2038
- annotationTool = null;
2039
- }
2040
- // konvaStage.draggable(true);
2041
- konvaStage.container().style.cursor = 'pointer';
2042
- this.$set(this, 'rightType', 'annotation');
2043
- },
2044
- clearPreViewAnn() {
2045
- const lists = konvaStage.find('.annotation-shape');
2046
- lists.forEach((item) => {
2047
- item.destroy();
2048
- });
2049
- },
2050
- handleDeleteProofList() {
2051
- this.clearPreViewAnn();
2052
- this.closeDrawing();
2053
- },
2054
- preHandleProofSavelBtn() {
2055
- setTimeout(() => {
2056
- this.handleProofSavelBtn();
2057
- });
2058
- },
2059
- async handleProofSavelBtn() {
2060
- const cameraViewTag = this.getViewTag();
2061
- const viewAnnotation = this.handleSaveAnnotation();
2062
-
2063
- this.proofData.version = this.defaultParams.version;
2064
- this.proofData.position = JSON.stringify(cameraViewTag);
2065
-
2066
- // if (_.isEmpty(data.id)) {
2067
- this.proofData.projectId = this.defaultParams.projectId;
2068
- // }
2069
- this.proofData.relevant = viewAnnotation
2070
- ? JSON.stringify(viewAnnotation)
2071
- : JSON.stringify('');
2072
-
2073
- loading('视点截图中...');
2074
- const previewScreenshotData = await this.screenshot()
2075
- .catch((err) => {
2076
- this.$message({
2077
- type: 'error',
2078
- message: err.msg,
2079
- });
2080
- })
2081
- .finally(() => {
2082
- loadingClose();
2083
- });
2084
-
2085
- this.$refs.proofPanel.openAnnotationDetailDialog();
2086
-
2087
- this.$set(this.proofData, 'previewScreenshotData', previewScreenshotData);
2088
- // this.proofData.previewScreenshotData = previewScreenshotData;
2089
-
2090
- const screenshotMsg = await this.uploadScreenshot(previewScreenshotData);
2091
-
2092
- if (screenshotMsg.code == 200) {
2093
- this.proofData.problemPrintscreenId = screenshotMsg.msg;
2094
- }
2095
- console.log(this.proofData);
2096
-
2097
- // console.log(this.proofData.previewScreenshotData)
2098
-
2099
- // this.$set(this, "proofData", this.proofData);
2100
-
2101
- // this.$refs.proofPanel.saveForm(
2102
- // proofData,
2103
- // () => {
2104
- // this.toggleDrawToolbar(false);
2105
- // this.disableDrawBtn = false;
2106
- // },
2107
- // () => {
2108
- // this.disableDrawBtn = true;
2109
- // }
2110
- // );
2111
-
2112
- this.checkedToolbarItem = false;
2113
- },
2114
-
2115
- handleClickProofList(data) {
2116
- const { position, relevant } = data;
2117
- const { cameraPosition, cameraTarget, offset } = JSON.parse(position);
2118
-
2119
- console.log('跳转视点', cameraPosition, cameraTarget, offset);
2120
-
2121
- // 视点
2122
- this.animateCamera(
2123
- cameraPosition.x,
2124
- cameraPosition.y,
2125
- cameraPosition.z,
2126
- cameraTarget.x,
2127
- cameraTarget.y,
2128
- cameraTarget.z,
2129
- true,
2130
- offset,
2131
- );
2132
- this.clearPreViewAnn();
2133
- this.highlightModel('reset');
2134
-
2135
- if (relevant) {
2136
- // this.showToolbar = true;
2137
-
2138
- // TODO 暂用 setTimeout
2139
- setTimeout(() => {
2140
- this.showDrawingBoard = true;
2141
- this.disableDrawBtn = true;
2142
- this.showToolbar = false;
2143
- if (annotationTool) {
2144
- annotationTool.destroy();
2145
- annotationTool = null;
2146
- }
2147
-
2148
- const formatRelevant = JSON.parse(relevant);
2149
- formatRelevant && this.handleLoadAnnotation(formatRelevant);
2150
- }, 300);
2151
- }
2152
- },
2153
- // 将标注添加到图纸中
2154
- handleLoadAnnotation(lists) {
2155
- lists.forEach((item) => {
2156
- switch (item.type) {
2157
- case 'Rect':
2158
- const rect = new Konva.Rect({
2159
- name: item.name,
2160
- x: item.x,
2161
- y: item.y,
2162
- width: item.width,
2163
- height: item.height,
2164
- stroke: item.stroke,
2165
- strokeWidth: item.strokeWidth,
2166
- visible: true,
2167
- draggable: true,
2168
- type: item.type,
2169
- });
2170
- rect.on('mousedown', (e) => {
2171
- e.cancelBubble = true;
2172
- });
2173
-
2174
- rect.on('click', (e) => {
2175
- e.cancelBubble = true;
2176
- if (this.drawingType === 'Rubber') {
2177
- rect.destroy();
2178
- }
2179
- });
2180
-
2181
- konvaLayer.add(rect);
2182
- break;
2183
- case 'Circle':
2184
- const circle = new Konva.Circle({
2185
- name: item.name,
2186
- x: item.x,
2187
- y: item.y,
2188
- radius: item.radius < 0 ? 0 : item.radius,
2189
- stroke: item.stroke,
2190
- strokeWidth: item.strokeWidth,
2191
- visible: true,
2192
- draggable: true,
2193
- type: item.type,
2194
- });
2195
- circle.on('mousedown', (e) => {
2196
- e.cancelBubble = true;
2197
- });
2198
-
2199
- circle.on('click', (e) => {
2200
- e.cancelBubble = true;
2201
- if (this.drawingType === 'Rubber') {
2202
- circle.destroy();
2203
- }
2204
- });
2205
-
2206
- konvaLayer.add(circle);
2207
- break;
2208
- case 'Line':
2209
- const line = new Konva.Line({
2210
- name: item.name,
2211
- points: item.points,
2212
- stroke: item.stroke,
2213
- strokeWidth: item.strokeWidth,
2214
- lineCap: item.lineCap,
2215
- lineJoin: item.lineJoin,
2216
- visible: true,
2217
- draggable: true,
2218
- type: item.type,
2219
- });
2220
- line.on('mousedown', (e) => {
2221
- e.cancelBubble = true;
2222
- });
2223
-
2224
- line.on('click', (e) => {
2225
- e.cancelBubble = true;
2226
- if (this.drawingType === 'Rubber') {
2227
- line.destroy();
2228
- }
2229
- });
2230
-
2231
- konvaLayer.add(line);
2232
- break;
2233
- case 'Text':
2234
- const textNode = new Konva.Text({
2235
- name: item.name,
2236
- x: item.x,
2237
- y: item.y,
2238
- width: item.width,
2239
- text: item.text,
2240
- fontSize: item.fontSize,
2241
- fill: item.fill,
2242
- visible: true,
2243
- draggable: true,
2244
- type: item.type,
2245
- });
2246
- textNode.on('mousedown', (e) => {
2247
- e.cancelBubble = true;
2248
- });
2249
-
2250
- textNode.on('click', (e) => {
2251
- e.cancelBubble = true;
2252
- if (this.drawingType === 'Rubber') {
2253
- textNode.destroy();
2254
- }
2255
- });
2256
-
2257
- konvaLayer.add(textNode);
2258
- break;
2259
- }
2260
- });
2261
- console.log(konvaLayer);
2262
- },
2263
- handleProofEditBtn(detailData) {
2264
- this.toggleDrawToolbar(true);
2265
- this.disableDrawBtn = false;
2266
-
2267
- this.proofData = Object.assign(this.proofData, detailData);
2268
- },
2269
- handleProofAddBtn() {
2270
- this.toggleDrawToolbar(true);
2271
- this.clearPreViewAnn();
2272
- this.disableDrawBtn = false;
2273
-
2274
- this.resetProofData();
2275
- },
2276
- resetProofData() {
2277
- this.proofData.stageId = '';
2278
- this.proofData.version = null;
2279
- this.proofData.position = '';
2280
- this.proofData.projectId = '';
2281
- this.proofData.relevant = '';
2282
- this.proofData.previewScreenshotData = '';
2283
- this.proofData.problemPrintscreenId = '';
2284
- this.proofData.description = '';
2285
- this.proofData.remark = '';
2286
- this.proofData.status = '';
2287
- this.proofData.createTime = '';
2288
- this.proofData.replyTime = '';
2289
- this.proofData.postId = '';
2290
- this.proofData.solveBy = '';
2291
- delete this.proofData.id;
2292
- },
2293
- handleProofCancelBtn() {
2294
- this.toggleDrawToolbar(false);
2295
- this.clearPreViewAnn();
2296
- this.disableDrawBtn = true;
2297
- },
2298
- // 添加视点
2299
- getViewTag() {
2300
- // todo
2301
- const delta = fpsClock.getDelta();
2302
- timeStamp += delta;
2303
- // cameraControls.update(timeStamp);
2304
-
2305
- const cameraPosition = cameraControls.getPosition();
2306
- const cameraTarget = cameraControls.getTarget();
2307
- const offset = cameraControls.getFocalOffset();
2308
-
2309
- const element = cameraControls.camera.matrix.elements;
2310
-
2311
- console.log('获取视点', cameraPosition, cameraTarget);
2312
-
2313
- const vector = {
2314
- x: [element[0], element[1], element[2], element[3]],
2315
- y: [element[4], element[5], element[6], element[7]],
2316
- z: [element[8], element[9], element[10], element[11]],
2317
- };
2318
-
2319
- const up = cameraControls.camera.up;
2320
- return { cameraPosition, cameraTarget, vector, up, offset };
2321
- },
2322
- locateByDetect(data, node) {
2323
- console.log('locateByDetect', data, node);
2324
- this.pbsNodeClick(node.objectid);
2325
- },
2326
- highlightByDetect(data, node) {
2327
- console.log('highlightByDetect', data, node);
2328
-
2329
- const obj = scene.getObjectByName(node.objectid);
2330
- this.changeModelColor({
2331
- groupModel: obj,
2332
- color: new this.THREE.Color(0xff0000),
2333
- type: 'toggleHighlight',
2334
- });
2335
- },
2336
- focusDetectTree() {
2337
- this.activeName = 'detectTree';
2338
- },
2339
- getDetectCheckTree() {
2340
- const param = this.dataServerParams;
2341
- getTopology(param).then((topologyData) => {
2342
- const collisionSystem = new CollisionSystem({ scene, topologyData });
2343
- this.detectTreeData = collisionSystem.run();
2344
- });
2345
- },
2346
- // 工具按钮互斥操作
2347
- handleBtnEvent(val) {
2348
- if (previousModel) {
2349
- this.recoverColor();
2350
- }
2351
- // 新增功能互斥
2352
- addRoamingFlag = false;
2353
- markFlag = false;
2354
- // 关闭新增标注弹框
2355
- this.$set(this, 'markPanelShow', false);
2356
- this.$set(this, 'locationPanelShow', false);
2357
- // 清除漫游点
2358
- if (this.roamingPath.length > 0) {
2359
- this.delTipsLabel();
2360
- this.roamingPath = [];
2361
- this.removeMesh(points);
2362
- this.removeMesh(line);
2363
- }
2364
- for (let key in this.ctrlPanel) {
2365
- modelClickEvent = '';
2366
- if (key !== 'pid' && val.event !== 'pid') {
2367
- const flag = val.flag === key ? !this.ctrlPanel[key] : false;
2368
- this.$set(this.ctrlPanel, key, flag);
2369
- } else if (val.event === 'pid') {
2370
- const flag = val.flag ? true : false;
2371
- this.$set(this.ctrlPanel, 'pid', flag);
2372
- }
2373
- }
2374
- if (val.event === 'drawing' && !this.disableDrawBtn) {
2375
- this.toggleDrawToolbar();
2376
- }
2377
- this.btnOperate(val.event, this.ctrlPanel[val.event]);
2378
- },
2379
- // 不同按钮的操作事项
2380
- btnOperate(e, flag) {
2381
- // 打开pid 不参与互斥
2382
- if (e !== 'pid') {
2383
- // 清空标注
2384
- this.clearEntites();
2385
- // this.cancelLocation()
2386
- // this.removeMoveMark()
2387
- // // 清空漫游
2388
- // this.viewRoaming(false)
2389
- // 关闭剖切
2390
- if (clippingType) {
2391
- clippingType === 'all' ? this.clearAllClipping() : this.clearLocalClipping();
2392
- clippingType = '';
2393
- }
2394
- // 关闭测量
2395
- if (threeMeasure) this.measure(false);
2396
- // 关闭聚光灯
2397
- // if (spotLight) {
2398
- // this.clearSpotLight()
2399
- // this.initLight()
2400
- // }
2401
- // 恢复爆炸
2402
- // this.bomb(0, 'all')
2403
- }
2404
- modelClickEvent = '';
2405
- switch (e) {
2406
- case 'view':
2407
- modelClickEvent = flag ? 'view' : '';
2408
- break;
2409
- case 'mark':
2410
- if (!flag) {
2411
- this.handleAddMark(false);
2412
- this.clearEntites();
2413
- }
2414
- modelClickEvent = flag ? 'mark' : '';
2415
- break;
2416
- // case 'locationUser':
2417
- // if (!flag) {
2418
- // this.cancelLocation()
2419
- // }
2420
- // break;
2421
- case 'roaming':
2422
- this.viewRoaming(flag);
2423
- modelClickEvent = flag ? 'roaming' : '';
2424
- break;
2425
- case 'material':
2426
- break;
2427
- case 'light':
2428
- flag ? this.clearMeasure() : '';
2429
- modelClickEvent = flag ? 'light' : '';
2430
- break;
2431
- case 'measure':
2432
- modelClickEvent = !flag ? '' : 'measure';
2433
- this.measure(flag);
2434
- break;
2435
- case 'bomb':
2436
- modelClickEvent = !flag ? '' : 'bomb';
2437
- break;
2438
- case 'spotLight':
2439
- if (flag) {
2440
- this.initSpotLight();
2441
- modelClickEvent = 'spotLight';
2442
- } else {
2443
- this.clearSpotLight();
2444
- modelClickEvent = '';
2445
- }
2446
- break;
2447
- case 'pid':
2448
- if (flag) {
2449
- modelClickEvent = 'pid';
2450
- } else {
2451
- modelClickEvent = '';
2452
- }
2453
- this.$nextTick(() => {
2454
- this.onContainerResize();
2455
- });
2456
- break;
2457
- case 'clipping':
2458
- if (!flag) {
2459
- modelClickEvent = '';
2460
- clippingType === 'all' ? this.clearAllClipping() : this.clearLocalClipping();
2461
- clippingType = '';
2462
- } else {
2463
- modelClickEvent = 'clipping';
2464
- }
2465
- break;
2466
- case 'alpha':
2467
- if (flag) {
2468
- modelClickEvent = 'alphaControl';
2469
- } else {
2470
- modelClickEvent = '';
2471
- this.alphaReset();
2472
- }
2473
- }
2474
- },
2475
- // 测量类型
2476
- handleMeasure(type) {
2477
- if (threeMeasure) {
2478
- threeMeasure.close();
2479
- threeMeasure = null;
2480
- }
2481
- renderEnabled = true;
2482
- switch (type) {
2483
- case 'distance':
2484
- threeMeasure = new MeasureDistance.MeasureDistance(
2485
- renderer,
2486
- scene,
2487
- camera,
2488
- instructions.offsetWidth,
2489
- instructions.offsetHeight,
2490
- );
2491
- threeMeasure.start();
2492
- break;
2493
- case 'area':
2494
- threeMeasure = new MeasureArea.MeasureArea(
2495
- renderer,
2496
- scene,
2497
- camera,
2498
- instructions.offsetWidth,
2499
- instructions.offsetHeight,
2500
- );
2501
- threeMeasure.start();
2502
- break;
2503
- case 'angle':
2504
- threeMeasure = new MeasureAngle.MeasureAngle(
2505
- renderer,
2506
- scene,
2507
- camera,
2508
- instructions.offsetWidth,
2509
- instructions.offsetHeight,
2510
- );
2511
- threeMeasure.start();
2512
- break;
2513
- case 'volume':
2514
- threeMeasure = new MeasureVolume.MeasureVolume(
2515
- renderer,
2516
- scene,
2517
- camera,
2518
- instructions.offsetWidth,
2519
- instructions.offsetHeight,
2520
- );
2521
- threeMeasure.start();
2522
- break;
2523
- }
2524
- },
2525
- // 测量
2526
- measure(val) {
2527
- if (!val && threeMeasure) {
2528
- threeMeasure.close();
2529
- threeMeasure = null;
2530
- this.timeRender();
2531
- }
2532
- },
2533
- /**
2534
- * 主视角
2535
- */
2536
- home() {
2537
- if (roaming) {
2538
- this.disposeRoaming();
2539
- }
2540
- const obj = scene.getObjectByName('rootModel');
2541
- if (obj) {
2542
- this.setModelCenter(obj.userData.boundingBox, true);
2543
- }
2544
- // this.animateCamera(cameraControls._position0.x, cameraControls._position0.y, cameraControls._position0.z, cameraControls._target0.x, cameraControls._target0.y, cameraControls._target0.z)
2545
- // this.timeRender()
2546
- },
2547
- setModelCenter(boundingBox, flag) {
2548
- // this.resetOrbitPoint();
2549
- const box3 = new this.THREE.Box3(boundingBox.min, boundingBox.max);
2550
- const center = new this.THREE.Vector3();
2551
- box3.getCenter(center);
2552
- const size = box3.getSize(new this.THREE.Vector3());
2553
-
2554
- // cameraControls.setOrbitPoint(
2555
- // center.x, center.y, center.z, false
2556
- // )
2557
- // cameraControls.update()
2558
-
2559
- camera.position.set(center.x, center.y + size.y, center.z + size.z / 2);
2560
- camera.lookAt(new this.THREE.Vector3(center.x, center.y, center.z));
2561
- this.animateCamera(
2562
- center.x,
2563
- center.y + size.y,
2564
- center.z + size.z / 2,
2565
- center.x,
2566
- center.y,
2567
- center.z,
2568
- flag,
2569
- );
2570
- camera.updateProjectionMatrix();
2571
- },
2572
- /* 第一视角区域 */
2573
- // 出现弹框
2574
- firstPer() {
2575
- if (this.ctrlPanel['pid']) {
2576
- this.$confirm('确定关闭pid?', '提示', {
2577
- confirmButtonText: '确定',
2578
- cancelButtonText: '取消',
2579
- type: 'warning',
2580
- })
2581
- .then(() => {
2582
- // 关闭其余面板
2583
- for (let key in this.ctrlPanel) {
2584
- this.$set(this.ctrlPanel, key, false);
2585
- }
2586
- this.onWindowResize();
2587
- this.isFirstPer = sessionStorage.getItem('isFirstPer');
2588
- // 判断是否出现弹框
2589
- if (this.isFirstPer === 'true') {
2590
- this.start(true);
2591
- } else {
2592
- this.firstPerFlag = true;
2593
- }
2594
- })
2595
- .catch(() => {
2596
- return false;
2597
- });
2598
- } else {
2599
- // 关闭其余面板
2600
- for (let key in this.ctrlPanel) {
2601
- this.$set(this.ctrlPanel, key, false);
2602
- }
2603
- this.isFirstPer = sessionStorage.getItem('isFirstPer');
2604
- // 判断是否出现弹框
2605
- if (this.isFirstPer === 'true') {
2606
- this.start(true);
2607
- } else {
2608
- this.firstPerFlag = true;
2609
- }
2610
- }
2611
- },
2612
- // 开始第一视角
2613
- start(val) {
2614
- // this.timeRender()
2615
- // 记录是否不再出现弹框
2616
- this.isFirstPer = val;
2617
- sessionStorage.setItem('isFirstPer', val);
2618
- clock = new this.THREE.Clock();
2619
- horizontalRaycaster = new this.THREE.Raycaster(
2620
- new this.THREE.Vector3(),
2621
- new this.THREE.Vector3(),
2622
- 0,
2623
- 10,
2624
- );
2625
- downRaycaster = new this.THREE.Raycaster(
2626
- new this.THREE.Vector3(),
2627
- new this.THREE.Vector3(0, -1, 0),
2628
- 0,
2629
- 10,
2630
- );
2631
- // downRaycaster.params = {
2632
- // Mesh: { threshold: 5000 },
2633
- // Line: { threshold: 15000 },
2634
- // Points: { threshold: 5000 },
2635
- // LOD: { threshold: 5000 },
2636
- // Sprite: { threshold: 5000 }
2637
- // }
2638
- // downRaycaster.params = {
2639
- // Mesh: { threshold: 200 },
2640
- // Line: { threshold: 200 },
2641
- // Points: { threshold: 200 },
2642
- // LOD: { threshold: 200 },
2643
- // Sprite: { threshold: 200 }
2644
- // }
2645
-
2646
- velocity = new this.THREE.Vector3(); //移动速度变量
2647
- direction = new this.THREE.Vector3(); //移动的方向变量
2648
- rotation = new this.THREE.Vector3(); //当前的相机朝向
2649
- this.firstPerFlag = false;
2650
- this.initPointerLock();
2651
- },
2652
- // 键盘监听事件
2653
- onKeyDown(event) {
2654
- if (!event.keyCode) return;
2655
- // this.timeRender()
2656
- switch (event.keyCode) {
2657
- // 向左
2658
- case 37:
2659
- case 65:
2660
- moveLeft = true;
2661
- break;
2662
- // 向右
2663
- case 39:
2664
- case 68:
2665
- moveRight = true;
2666
- break;
2667
- // 向前
2668
- case 38:
2669
- case 87:
2670
- moveForward = true;
2671
- break;
2672
- // 向后
2673
- case 40:
2674
- case 83:
2675
- moveBackward = true;
2676
- break;
2677
- // 跳跃
2678
- case 32:
2679
- if (canJump && spaceUp) velocity.y += upSpeed;
2680
- canJump = false;
2681
- spaceUp = false;
2682
- break;
2683
- }
2684
- },
2685
- onKeyUp(event) {
2686
- if (!event.keyCode) return;
2687
- // this.timeRender()
2688
- switch (event.keyCode) {
2689
- // 前进
2690
- case 38:
2691
- case 87:
2692
- moveForward = false;
2693
- break;
2694
- // 向左
2695
- case 37:
2696
- case 65:
2697
- moveLeft = false;
2698
- break;
2699
- // 后退
2700
- case 40:
2701
- case 83:
2702
- moveBackward = false;
2703
- break;
2704
- // 向右
2705
- case 39:
2706
- case 68:
2707
- moveRight = false;
2708
- break;
2709
- // 跳跃
2710
- case 32:
2711
- spaceUp = true;
2712
- break;
2713
- }
2714
- },
2715
- // 页面是否锁定
2716
- initPointerLock() {
2717
- pointControls = new PointerLockControls(camera, renderer.domElement);
2718
- // 相机位置
2719
- // pointControls.getObject().position.set(camera.position.x, camera.position.y, camera.position.z)
2720
- pointControls.getObject().position.set(0, 3 - this.maxAltitude / 10, 0);
2721
- // pointControls.getObject().position.set(camera.position.x, 3 - this.maxAltitude / 10, camera.position.y)
2722
- pointControls.lock();
2723
- // 锁定
2724
- pointControls.addEventListener('lock', () => {
2725
- cameraControls.enabled = false;
2726
- this.toolBtnSetting.toolBtn.all = false;
2727
- window.addEventListener('keydown', this.onKeyDown, false);
2728
- window.addEventListener('keyup', this.onKeyUp, false);
2729
- renderer.domElement.removeEventListener('mouseup', this.mouseClick, false);
2730
- renderer.domElement.removeEventListener('mousedown', this.setOrbitPoint, false);
2731
- // renderer.domElement.removeEventListener('contextmenu', this.rightClick)
2732
- });
2733
- // 解锁
2734
- pointControls.addEventListener('unlock', () => {
2735
- cameraControls.enabled = true;
2736
- // 返回初始视角
2737
- this.home();
2738
- this.toolBtnSetting.toolBtn.all = true;
2739
- window.removeEventListener('keydown', this.onKeyDown);
2740
- window.removeEventListener('keyup', this.onKeyUp);
2741
- renderer.domElement.addEventListener('mouseup', this.mouseClick, false);
2742
- renderer.domElement.addEventListener('mousedown', this.setOrbitPoint, false);
2743
- // renderer.domElement.addEventListener('contextmenu', this.rightClick, false)
2744
- });
2745
- // 鼠标转动
2746
- pointControls.addEventListener('change', () => {
2747
- // this.timeRender()
2748
- });
2749
- scene.add(pointControls.getObject());
2750
- },
2751
- // 第一视角运动
2752
- firstPerspective() {
2753
- if (!cameraControls.enabled && pointControls) {
2754
- // 获取到控制器对象
2755
- var control = pointControls.getObject();
2756
- // 获取刷新时间
2757
- var delta = clock.getDelta();
2758
- // velocity每次的速度,为了保证有过渡
2759
- velocity.x -= velocity.x * 10.0 * delta;
2760
- velocity.z -= velocity.z * 10.0 * delta;
2761
- velocity.y -= 9.8 * 100.0 * delta; // 默认下降的速度
2762
- // 获取当前按键的方向并获取朝哪个方向移动
2763
- direction.z = Number(moveForward) - Number(moveBackward);
2764
- direction.x = Number(moveRight) - Number(moveLeft);
2765
- // 将法向量的值归一化
2766
- direction.normalize();
2767
- // 碰撞检测
2768
- // rotation.copy(control.getWorldDirection(rotation))
2769
- // var m = new this.THREE.Matrix4()
2770
- // if (direction.z > 0) {
2771
- // if (direction.x > 0) {
2772
- // m.makeRotationY(Math.PI / 4)
2773
- // } else if (direction.x < 0) {
2774
- // m.makeRotationY(-Math.PI / 4)
2775
- // } else {
2776
- // m.makeRotationY(0)
2777
- // }
2778
- // } else if (direction.z < 0) {
2779
- // if (direction.x > 0) {
2780
- // m.makeRotationY((Math.PI / 4) * 3)
2781
- // } else if (direction.x < 0) {
2782
- // m.makeRotationY((-Math.PI / 4) * 3)
2783
- // } else {
2784
- // m.makeRotationY(Math.PI)
2785
- // }
2786
- // } else {
2787
- // if (direction.x > 0) {
2788
- // m.makeRotationY(Math.PI / 2)
2789
- // } else if (direction.x < 0) {
2790
- // m.makeRotationY(-Math.PI / 2)
2791
- // }
2792
- // }
2793
- // rotation.applyMatrix4(m)
2794
- // horizontalRaycaster.set(control.position, rotation)
2795
- // var horizontalIntersections = horizontalRaycaster.intersectObjects(
2796
- // scene.children,
2797
- // true
2798
- // )
2799
- // var horOnObject = horizontalIntersections.length > 0
2800
- // 判断移动方向修改速度方向
2801
- // if (!horOnObject) {
2802
- if (moveForward || moveBackward) velocity.z -= direction.z * removeSpeed * delta;
2803
- if (moveLeft || moveRight) velocity.x -= direction.x * removeSpeed * delta;
2804
- // }
2805
- // 复制相机的位置
2806
- downRaycaster.ray.origin.copy(control.position);
2807
- // 获取相机靠下5的位置
2808
- downRaycaster.ray.origin.y += 10;
2809
-
2810
- // const foundMeshes = this.findMeshByName(scene.children[0], '2.655.2-MODELELEM-o.160.80.66ee82db-160');
2811
- // const foundMeshes = this.findMeshByName(scene.children[0], '2.667.2-MODELELEM-o.160.a.1923d213481-160');
2812
-
2813
- // console.log(foundMeshes[0].children)
2814
- // 判断是否停留在了立方体上面
2815
- // var intersections = downRaycaster.intersectObjects(foundMeshes[0].children, true)
2816
- var intersections = downRaycaster.intersectObjects(scene.children, true);
2817
-
2818
- // var intersections = downRaycaster.intersectObjects(intersectsObject, false)
2819
- // const intersected = intersectsObject.find((item) => {
2820
- // return item.userData.instanceName === '2.655.2-MODELELEM-o.160.80.66ee82db-160'
2821
- // }
2822
- // )
2823
- // console.log(intersected)
2824
- // console.log('downRaycaster.ray.origin', downRaycaster.ray.origin.x, downRaycaster.ray.origin.y, downRaycaster.ray.origin.z)
2825
- // console.log('downRaycaster.ray', JSON.stringify(downRaycaster.ray))
2826
-
2827
- // var intersections = downRaycaster.intersectObjects(scene.children[0], true)
2828
- var onObject = intersections.length > 0;
2829
- if (onObject === true) {
2830
- // console.log('onObject', intersections)
2831
- velocity.y = Math.max(0, velocity.y);
2832
- canJump = true;
2833
- }
2834
- // 根据速度值移动控制器
2835
- pointControls.moveRight(-velocity.x * delta);
2836
- pointControls.moveForward(-velocity.z * delta);
2837
- control.position.y += velocity.y * delta;
2838
- // 保证控制器的y轴在平面上
2839
- if (control.position.y < 3 - this.maxAltitude / 10) {
2840
- velocity.y = -this.maxAltitude / 10;
2841
- control.position.y = 3 - this.maxAltitude / 10;
2842
- canJump = true;
2843
-
2844
- // console.log('control.position.y', control.position.y)
2845
- }
2846
- }
2847
- },
2848
- findMeshByName(scene, meshName) {
2849
- const foundMeshes = [];
2850
- scene.traverse((child) => {
2851
- if (child.name === meshName) {
2852
- foundMeshes.push(child);
2853
- }
2854
- });
2855
- return foundMeshes;
2856
- },
2857
- // 清除 取消标注的点
2858
- clearEntites() {
2859
- if (scene && scene.getObjectByName('mark-label')) {
2860
- let sprit = scene.getObjectByName('mark-label');
2861
- scene.remove(sprit);
2862
- this.clearEntites();
2863
- }
2864
- // 清除 取消弹框
2865
- if (scene && scene.getObjectByName('bullet-box-label')) {
2866
- let sprit = scene.getObjectByName('bullet-box-label');
2867
- scene.remove(sprit);
2868
- this.clearEntites();
2869
- }
2870
- return;
2871
- },
2872
- // 获取mesh的中心点
2873
- getMeshCenterAndVolume(mesh) {
2874
- const box = new this.THREE.Box3().setFromObject(mesh);
2875
- const center = new this.THREE.Vector3();
2876
- const volume = box.getSize(new this.THREE.Vector3());
2877
- box.getCenter(center);
2878
- return {
2879
- center: center,
2880
- box: volume,
2881
- };
2882
- },
2883
- createVirtualClippingBox(size, data, clippingPlanes) {
2884
- const center = [data.center.x, data.center.y, data.center.z];
2885
-
2886
- if (cube) {
2887
- cube.geometry.dispose();
2888
- cube.material.dispose();
2889
- scene.remove(cube);
2890
- cube = null;
2891
- // transformControl.visible = false
2892
- }
2893
- const geo = new this.THREE.BoxGeometry(Math.abs(size.x), Math.abs(size.y), Math.abs(size.z));
2894
- const m = new this.THREE.MeshStandardMaterial({
2895
- color: 0xffffff,
2896
- transparent: true,
2897
- opacity: 0.2,
2898
- side: this.THREE.DoubleSide,
2899
- clippingPlanes: clippingPlanes,
2900
- needsUpdate: true,
2901
- });
2902
- cube = new this.THREE.Mesh(geo, m);
2903
- cube.name = 'virtualClippingBox';
2904
- scene.add(cube);
2905
- const v3 = new this.THREE.Vector3(
2906
- center[0] - this.modelCenter.x,
2907
- center[1] - this.modelCenter.y,
2908
- center[2] - this.modelCenter.z,
2909
- );
2910
- cube.position.set(v3.x, v3.y, v3.z);
2911
- // cube.userData.box = new this.THREE.Vector3(size.x, size.y, size.z)
2912
- },
2913
- changeClippingVal(index, type) {
2914
- clippingMesh.forEach((item) => {
2915
- item.material.clippingPlanes[index].constant += operate[type];
2916
- });
2917
- this.timeRender();
2918
- },
2919
- clippingType(val) {
2920
- if (clippingType === val) {
2921
- // 清除全局剖切效果
2922
- this.clearAllClipping();
2923
- clippingType = '';
2924
- } else if (val === 'all') {
2925
- clippingType = val;
2926
- // 先清除局部剖切效果
2927
- this.clearLocalClipping();
2928
- // 添加全部剖切效果
2929
- const box3 = new this.THREE.Box3();
2930
- box3.expandByObject(scene.children[0]);
2931
- const size = box3.getSize(new this.THREE.Vector3());
2932
- globePlanes = [Math.ceil(size.x), Math.ceil(size.y), Math.ceil(size.z)];
2933
- renderer.clippingPlanes = [
2934
- new this.THREE.Plane(new this.THREE.Vector3(-1, 0, 0), globePlanes[0]),
2935
- new this.THREE.Plane(new this.THREE.Vector3(0, -1, 0), globePlanes[1]),
2936
- new this.THREE.Plane(new this.THREE.Vector3(0, 0, -1), globePlanes[2]),
2937
- ];
2938
- guiParams = {
2939
- x轴: globePlanes[0],
2940
- y轴: globePlanes[1],
2941
- z轴: globePlanes[2],
2942
- };
2943
- this.addClippingGui('全局剖切', renderer.clippingPlanes);
2944
- } else {
2945
- // 清除全局剖切效果
2946
- this.clearAllClipping();
2947
- }
2948
- },
2949
- // 添加剖切轴工具
2950
- addClippingGui(title, objClipp1, objClipp2) {
2951
- gui = new GUI({
2952
- title: title,
2953
- });
2954
- gui
2955
- .add(guiParams, 'x轴')
2956
- .min(-guiParams['x轴'])
2957
- .max(guiParams['x轴'])
2958
- .onChange((d) => {
2959
- objClipp1[0].constant = d;
2960
- objClipp2 && (objClipp2[0].constant = d);
2961
- });
2962
- gui
2963
- .add(guiParams, 'y轴')
2964
- .min(-guiParams['y轴'])
2965
- .max(guiParams['y轴'])
2966
- .onChange((d) => {
2967
- objClipp1[1].constant = d;
2968
- objClipp2 && (objClipp2[1].constant = d);
2969
- });
2970
- gui
2971
- .add(guiParams, 'z轴')
2972
- .min(-guiParams['z轴'])
2973
- .max(guiParams['z轴'])
2974
- .onChange((d) => {
2975
- objClipp1[2].constant = d;
2976
- objClipp2 && (objClipp2[2].constant = d);
2977
- });
2978
- },
2979
- // 在全局剖切下恢复原状
2980
- clearAllClipping() {
2981
- if (renderer) {
2982
- renderer.clippingPlanes = Object.freeze([]);
2983
- }
2984
- gui && gui.destroy();
2985
- },
2986
- // 清除上一步骤的切片
2987
- clearClipping() {
2988
- clippingMesh.forEach((item) => {
2989
- item.material.clippingPlanes = Object.freeze([]);
2990
- item.material.needsUpdate = true;
2991
- });
2992
- clippingMesh.splice(0);
2993
- },
2994
- // 清除局部剖切效果
2995
- clearLocalClipping() {
2996
- guiParams = {
2997
- x轴: 0,
2998
- y轴: 0,
2999
- z轴: 0,
3000
- };
3001
- gui && gui.destroy();
3002
- this.clearClipping();
3003
- this.clearClippingTools();
3004
- },
3005
- // 清除辅助剖切的工具
3006
- clearClippingTools() {
3007
- batchTable = {};
3008
- bombData.splice(0);
3009
- if (cube) {
3010
- cube.material.dispose();
3011
- cube.geometry.dispose();
3012
- cube.clear();
3013
- scene.remove(cube);
3014
- cube = null;
3015
- }
3016
- },
3017
- // 剖切模型
3018
- controlModel(model) {
3019
- this.clearClipping();
3020
- // 创建剖切面
3021
- const box3 = new this.THREE.Box3();
3022
- box3.expandByObject(model);
3023
- const size = box3.getSize(new this.THREE.Vector3());
3024
- const data = this.getMeshCenterAndVolume(model);
3025
- const center = [data.center.x, data.center.y, data.center.z];
3026
-
3027
- let constant = {
3028
- x: Math.abs(center[0] - this.modelCenter.x + size.x / 2),
3029
- y: Math.abs(center[1] - this.modelCenter.y + size.y / 2),
3030
- z: Math.abs(center[2] - this.modelCenter.z + size.z / 2),
3031
- };
3032
- const clippingPlanes = [
3033
- new this.THREE.Plane(new this.THREE.Vector3(-1, 0, 0), constant.x),
3034
- new this.THREE.Plane(new this.THREE.Vector3(0, -1, 0), constant.y),
3035
- new this.THREE.Plane(new this.THREE.Vector3(0, 0, -1), constant.z),
3036
- ];
3037
-
3038
- // const geometry = new this.THREE.BoxGeometry(Math.abs(size.x), Math.abs(size.y), Math.abs(size.z));
3039
- // const material = new this.THREE.MeshBasicMaterial( {
3040
- // color: 0x00ff00,
3041
- // transparent: true,
3042
- // opacity: 0.2,
3043
- // side: this.THREE.DoubleSide,
3044
- // } );
3045
- // const mesh = new this.THREE.Mesh( geometry, material );
3046
- // mesh.position.set(model.position.x, model.position.y, model.position.z)
3047
- // mesh.material.clippingPlanes = clippingPlanes
3048
- // mesh.needsUpdate = true;
3049
-
3050
- // mesh.add(model)
3051
- // scene.add(mesh)
3052
- model.material.clippingPlanes = clippingPlanes;
3053
- model.needsUpdate = true;
3054
-
3055
- // 添加虚拟盒子
3056
- this.createVirtualClippingBox(size, data, clippingPlanes);
3057
- renderer.localClippingEnabled = true;
3058
- guiParams = {
3059
- x轴: Math.ceil(constant.x),
3060
- y轴: Math.ceil(constant.y),
3061
- z轴: Math.ceil(constant.z),
3062
- };
3063
- this.addClippingGui('局部剖切', model.material.clippingPlanes, cube.material.clippingPlanes);
3064
- },
3065
- // 动态设置视角滚轮的距离
3066
- setCameraConfig() {
3067
- let box3 = new this.THREE.Box3().setFromObject(scene);
3068
- let size = new this.THREE.Vector3();
3069
- box3.getSize(size);
3070
- const maxBorder = Math.max(size.x, size.y, size.z);
3071
-
3072
- cameraControls.camera.far = maxBorder * 50; // 设置相机的远裁剪面
3073
-
3074
- cameraControls.minDistance = maxBorder * 0.05; // 动态设置视角滚轮的距离
3075
-
3076
- camera.updateProjectionMatrix();
3077
- },
3078
- /* 右侧显示窗口
3079
- type: this.rightType所记录的数据 */
3080
- rightOperation(type) {
3081
- // this.mutualExclusionPoint();
3082
- // 控制右侧显示的弹窗
3083
- // 第一步 判断type 是否与 rightType 相等 如果相等 就是关闭对应的窗口
3084
- switch (type) {
3085
- case 'proof':
3086
- if (this.showProofPanel) {
3087
- this.closeRightOperationType = {
3088
- type: type,
3089
- close: true,
3090
- };
3091
- } else {
3092
- this.closeRightOperationType = {
3093
- type: type,
3094
- close: false,
3095
- };
3096
- }
3097
- this.showProofPanel = !this.showProofPanel;
3098
- break;
3099
- case 'detect':
3100
- if (this.showDetectPanel) {
3101
- this.closeRightOperationType = {
3102
- type: type,
3103
- close: true,
3104
- };
3105
- } else {
3106
- this.closeRightOperationType = {
3107
- type: type,
3108
- close: false,
3109
- };
3110
- }
3111
- this.showDetectPanel = !this.showDetectPanel;
3112
- break;
3113
- case 'property':
3114
- if (this.showPropsPanel) {
3115
- this.closeRightOperationType = {
3116
- type: type,
3117
- close: true,
3118
- };
3119
- } else {
3120
- this.closeRightOperationType = {
3121
- type: type,
3122
- close: false,
3123
- };
3124
- }
3125
- this.showPropsPanel = !this.showPropsPanel;
3126
- break;
3127
- }
3128
- // if (this.rightType === type) {
3129
- // this.$set(this, "rightType", "");
3130
- // } else {
3131
- // // 如果不相等 就是切到其他面板 那么就要关闭上一步操作
3132
- // this.$set(this, "rightType", type);
3133
- // }
3134
- },
3135
- headerRightOperation(type) {
3136
- this.clearHeaderRightOperation();
3137
- // 第一步 判断type 是否与 rightType 相等 如果相等 就是关闭对应的窗口
3138
- switch (type) {
3139
- case 'proof':
3140
- this.showProofPanel = !this.showProofPanel;
3141
- break;
3142
- case 'detect':
3143
- if (!scene.children.length) {
3144
- this.$message({
3145
- type: 'warning',
3146
- message: '请先加载模型',
3147
- });
3148
- return;
3149
- }
3150
-
3151
- this.showDetectPanel = !this.showDetectPanel;
3152
-
3153
- if (this.showDetectPanel && this.showProofPanel) {
3154
- this.showProofPanel = false;
3155
- this.handleClearAnnotation();
3156
- this.handleDeleteProofList();
3157
-
3158
- this.closeRightOperationType = {
3159
- type: 'proof',
3160
- close: true,
3161
- };
3162
- }
3163
-
3164
- break;
3165
- case 'property':
3166
- this.showPropsPanel = !this.showPropsPanel;
3167
-
3168
- if (this.showPropsPanel) {
3169
- const modelId = this.pickedModel.current?.name;
3170
- const params = {
3171
- modelId,
3172
- propertyGroup: this.propertyGroup,
3173
- };
3174
- this.$nextTick(() => {
3175
- this.$refs.propsPanel.getModelProperty(params);
3176
- });
3177
- }
3178
-
3179
- break;
3180
- case 'clipping-all': // 剖切
3181
- this.clippingType('all');
3182
- break;
3183
- case 'distance': // 测量
3184
- case 'area':
3185
- case 'angle':
3186
- this.handleMeasure(type);
3187
- break;
3188
- case 'first-person':
3189
- this.firstPer();
3190
- break;
3191
- case 'pbsTree':
3192
- this.showPbsTreePanel = !this.showPbsTreePanel;
3193
- break;
3194
- case 'annotate':
3195
- if (this.defaultParams.version) {
3196
- this.$message({
3197
- type: 'warning',
3198
- message: '校审历史中无法使用批注功能',
3199
- });
3200
- return;
3201
- }
3202
- if (this.showProofPanel) {
3203
- this.toggleDrawToolbar();
3204
- } else {
3205
- this.$message({
3206
- type: 'warning',
3207
- message: '请在添加或编辑校审意见中使用',
3208
- });
3209
- }
3210
- break;
3211
- }
3212
- },
3213
- clearHeaderRightOperation() {
3214
- this.measure(false);
3215
- this.clearAllClipping();
3216
- },
3217
- // 清除操作
3218
- clearRight(type) {
3219
- // switch (type) {
3220
- // case "searching":
3221
- // this.resetRelationSvg2(this.$refs.searching.resetRelationDom); // 在检索状态下 关闭后 需要清除页面高亮的节点
3222
- // break;
3223
- // case "inspection":
3224
- // oldSubsidiaryNode.length > 0 &&
3225
- // this.resetHightSubsidiaryLight([]);
3226
- // recordConCharArr.length > 0 && this.resetHighLightConChar();
3227
- // break;
3228
- // case "property":
3229
- // this.getSvgRed();
3230
- // break;
3231
- // case "annotation":
3232
- // this.clearPreViewAnn();
3233
- // break;
3234
- // }
3235
- },
3236
- viewVersion(item) {
3237
- // this.$set(this.proofConfig, 'viewVersion', item)
3238
- this.proofConfig.viewVersion = item;
3239
-
3240
- // const params = {}
3241
- // if(item && item.id){
3242
- // params.version = item.id
3243
- // }
3244
-
3245
- this.redirectPage(item);
3246
- },
3247
- redirectPage(params) {
3248
- const queryParams = {
3249
- projectId: (params && params.projectId) || this.defaultParams.projectId,
3250
- };
3251
-
3252
- if (params && params.id) {
3253
- queryParams.version = params.id;
3254
- }
3255
- this.$router.replace({
3256
- path: '/proof-model',
3257
- query: queryParams,
3258
- });
3259
- window.location.reload();
3260
- },
3261
- importProofModel() {
3262
- this.$refs.proofConfig.openImportModelDialog();
3263
- },
3264
- publishVersion() {
3265
- this.redirectPage();
3266
- },
3267
- },
3268
- };
3269
- </script>
3270
- <style lang="scss" scoped>
3271
- #blocker {
3272
- // height: 100%;
3273
- // width: 100%;
3274
- box-sizing: border-box;
3275
- position: relative;
3276
- display: flex;
3277
- flex-direction: column;
3278
- // background-color: #2c375d;
3279
- // background-color: #f0f0f0;
3280
- // z-index: 2;
3281
- // display: none;
3282
- }
3283
- #instructions {
3284
- width: 100%;
3285
- height: calc(100% - 58px);
3286
- background: linear-gradient(0deg, rgba(255, 255, 255, 0.9) 0%, #b3d6ff 100%);
3287
-
3288
- // display: flex;
3289
- // flex-direction: row;
3290
- // box-sizing: border-box;
3291
- // padding: 5px;
3292
- // height: 100%;
3293
- }
3294
- #konva-drawing-board {
3295
- // z-index: 1;
3296
- width: 100%;
3297
- height: 100%;
3298
- cursor: pointer;
3299
- overflow: hidden;
3300
- position: absolute;
3301
- top: 0;
3302
- }
3303
- ::v-deep .measure-label-canvas {
3304
- // position: absolute;
3305
- // z-index: 999;
3306
- pointer-events: none !important;
3307
- }
3308
- .toolbar_show {
3309
- position: absolute;
3310
- top: 27px;
3311
- left: 50%;
3312
- transform: translateX(-50%);
3313
- z-index: 10;
3314
- }
3315
- .draw-btn {
3316
- position: absolute;
3317
- bottom: 10px;
3318
- left: 50%;
3319
- }
3320
- .right-panel-container {
3321
- display: flex;
3322
- position: fixed;
3323
- top: 60px;
3324
- right: 0;
3325
- z-index: 10;
3326
- // height: calc(100% - 35px);
3327
- }
3328
- ::v-deep .el-tabs__item {
3329
- color: #fff;
3330
-
3331
- &.is-active {
3332
- color: #409eff;
3333
- }
3334
- }
3335
- // wbs、pbs树样式
3336
- .tree-container {
3337
- position: fixed;
3338
- height: calc(100% - 58px);
3339
- width: 300px;
3340
- padding: 20px 20px 10px;
3341
- left: 0px;
3342
- top: 58px;
3343
- background: #dff0fb;
3344
- border: none;
3345
- border-radius: 10px;
3346
- box-sizing: border-box;
3347
- z-index: 10;
3348
- }
3349
- ::v-deep .el-card__body {
3350
- padding: 0;
3351
- }
3352
-
3353
- ::v-deep .tips-label {
3354
- width: 65px;
3355
- color: BLACK;
3356
- font: 12px Helvetica;
3357
- padding: 5px;
3358
- text-align: center;
3359
- vertical-align: middle;
3360
- background-color: KHAKI;
3361
- }
3362
-
3363
- ::v-deep .measure-label {
3364
- max-width: 100px;
3365
- margin-top: -1em;
3366
- border: 10px;
3367
- border-radius: 5px;
3368
- padding: 3px 10px;
3369
- cursor: pointer;
3370
- color: rgb(0, 155, 234);
3371
- background-color: rgb(244, 244, 244);
3372
- box-shadow: 0px 1px 3px 1px rgba(0, 0, 0, 0.25);
3373
- }
3374
- ::v-deep .circle-tag {
3375
- width: 10px;
3376
- height: 10px;
3377
- border-radius: 50%;
3378
- background-color: #009bea;
3379
- }
3380
- ::v-deep .measure-label-font {
3381
- word-break: break-all;
3382
- }
3383
- ::v-deep .props-panel-container,
3384
- ::v-deep .proof-panel-container,
3385
- ::v-deep .detect-panel-container {
3386
- box-shadow: 0px 2px 10px 0px rgba(0, 0, 0, 0.4);
3387
- border-radius: 10px;
3388
- margin: 0 5px;
3389
- z-index: 10;
3390
- }
3391
- ::v-deep .proof-config-container {
3392
- position: fixed;
3393
- right: 0;
3394
- z-index: 10;
3395
- top: 12px;
3396
- .history-dialog {
3397
- position: fixed;
3398
- left: 40%;
3399
- top: 5px;
3400
- }
3401
- }
3402
- ::v-deep .header-button-container {
3403
- position: fixed;
3404
- z-index: 10;
3405
- top: 0;
3406
- background: #fff;
3407
- }
3408
- ::v-deep .check-proofing-container {
3409
- width: 100vw;
3410
- height: 100vh;
3411
- position: fixed;
3412
- z-index: 10;
3413
- display: flex;
3414
- justify-content: center;
3415
- align-items: center;
3416
- }
3417
- </style>
3418
- <style>
3419
- .lil-gui:nth-child(1) {
3420
- top: 200px;
3421
- }
3422
- .lil-gui:nth-child(2) {
3423
- top: 400px;
3424
- }
3425
- </style>