fl-web-component 1.3.18 → 1.3.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -0
- package/dist/fl-web-component.common.js +126 -82
- package/dist/fl-web-component.common.js.map +1 -1
- package/dist/fl-web-component.css +1 -1
- package/package.json +1 -1
- package/packages/components/com-flcanvas/index.vue +3 -2
- package/packages/components/com-graphics/index.vue +51 -14
- package/src/utils/instance-parser.js +10 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
@charset "UTF-8";#fl-model[data-v-
|
|
1
|
+
@charset "UTF-8";#fl-model[data-v-1bdd1986]{width:100%;height:100%;cursor:pointer}[data-v-1bdd1986] .tips-label{width:60px;color:#000;font:12px Helvetica;margin-top:-3em;padding:5px;text-align:center;vertical-align:middle;background-color:khaki}[data-v-1bdd1986] .measure-label{max-width:100px;margin-top:-1em;border:10px;border-radius:5px;padding:3px 10px;cursor:pointer;color:#009bea;background-color:#f4f4f4;box-shadow:0 1px 3px 1px rgba(0,0,0,.25)}[data-v-1bdd1986] .circle-tag{width:10px;height:10px;margin-top:5px;border-radius:50%;background-color:#ff5000}[data-v-1bdd1986] .measure-label-font{word-break:break-all}[data-v-1bdd1986] .mark-label-img{padding-top:5px;width:20px;height:20px}.lil-gui{background:hsla(0,0%,100%,.95)!important;border:1px solid #e0e0e0!important;border-radius:8px!important;box-shadow:0 4px 12px rgba(0,0,0,.15)!important;backdrop-filter:blur(10px)!important;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif!important}.lil-gui .title{background:linear-gradient(135deg,#f8f9fa,#e9ecef)!important;color:#495057!important;border-bottom:1px solid #dee2e6!important;font-weight:600!important;padding:0 12px!important;border-radius:8px 8px 0 0!important}.lil-gui .controller{border-bottom:1px solid #f1f3f4!important;background:transparent!important}.lil-gui .controller:last-child{border-bottom:none!important}.lil-gui .controller .name{color:#495057!important;font-weight:500!important;font-size:12px!important}.lil-gui .controller .widget{background:#f8f9fa!important;border:1px solid #ced4da!important;border-radius:4px!important;color:#495057!important}.lil-gui .controller .widget:focus,.lil-gui .controller .widget:hover{border-color:#80bdff!important;box-shadow:0 0 0 2px rgba(0,123,255,.25)!important}.lil-gui .controller .widget:focus{outline:none!important}.lil-gui .controller input[type=range]{background:#e9ecef!important;height:4px!important;-webkit-appearance:none!important;-moz-appearance:none!important;appearance:none!important;border-radius:2px!important}.lil-gui .controller.number .fill{border-right:solid #008de9}.lil-gui .controller input[type=range]::-webkit-slider-thumb{background:#007bff!important;border:2px solid #fff!important;box-shadow:0 2px 4px rgba(0,0,0,.2)!important;width:16px!important;height:16px!important;border-radius:50%!important;-webkit-appearance:none!important;appearance:none!important;cursor:pointer!important}.lil-gui .controller input[type=range]::-moz-range-thumb{background:#007bff!important;border:2px solid #fff!important;box-shadow:0 2px 4px rgba(0,0,0,.2)!important;width:16px!important;height:16px!important;border-radius:50%!important;cursor:pointer!important}.lil-gui .controller .option{background:#fff!important;color:#495057!important;border-bottom:1px solid #f1f3f4!important}.lil-gui .controller .option:hover{background:#f8f9fa!important}.lil-gui .controller .option:last-child{border-bottom:none!important}.lil-gui input:active{background:#e6eff4}.lil-gui .controller button{background:linear-gradient(135deg,#007bff,#0056b3)!important;color:#fff!important;border:none!important;border-radius:4px!important;font-weight:500!important;transition:all .2s ease!important}.lil-gui .controller button:hover{background:linear-gradient(135deg,#0056b3,#004085)!important;transform:translateY(-1px)!important;box-shadow:0 4px 8px rgba(0,123,255,.3)!important}.lil-gui .controller .color{border:2px solid #fff!important;border-radius:4px!important;box-shadow:0 2px 4px rgba(0,0,0,.1)!important}.lil-gui .controller.number .slider,.lil-gui .controller.number .slider:hover{background-color:#e6eff4}.lil-gui input,.lil-gui input:hover,.lil-gui input[type=number]:focus,.lil-gui input[type=text]:focus{background:#e6eff4}.lil-gui .controller>.name{min-width:25px}.lil-gui .controller.number input{color:#2e3136}.lil-gui .controller.number .slider:active{background-color:#e6eff4}.lil-gui .folder>.title{background:linear-gradient(135deg,#f1f3f4,#e9ecef)!important;color:#495057!important;border-bottom:1px solid #dee2e6!important}.lil-gui .folder>.title:before{color:#6c757d!important}.lil-gui .folder.closed>.children{display:none!important}#konva-container[data-v-1a4705f8]{z-index:3;width:100%;height:100%;cursor:pointer;overflow:hidden}span[data-v-f547d5c6]{font-weight:bolder}.text[data-v-f547d5c6]{margin-top:20px}.line[data-v-f547d5c6]{border-bottom:1px solid #dcdfe6;margin:20px 0}.center[data-v-f547d5c6]{display:flex;flex-direction:column;align-items:center}.center .cen span[data-v-f547d5c6],.center .top span[data-v-f547d5c6]{color:"#53a8ff";display:inline-block;width:30px;height:30px;text-align:center;line-height:30px;border:1px solid;padding:5px;margin-bottom:10px;background-color:#e9f3ff}.center .cen span[data-v-f547d5c6]{margin:10px}.button[data-v-f547d5c6]{display:flex;justify-content:end;margin-top:20px}@font-face{font-family:iconfont;src:url(//at.alicdn.com/t/font_3226805_qqvo3ag3r8.woff2?t=1646635700216) format("woff2"),url(//at.alicdn.com/t/font_3226805_qqvo3ag3r8.woff?t=1646635700216) format("woff"),url(//at.alicdn.com/t/font_3226805_qqvo3ag3r8.ttf?t=1646635700216) format("truetype")}.iconfont[data-v-f547d5c6]{font-family:iconfont!important;font-size:50px;font-style:normal;color:"#53a8ff";-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.icon-shubiao[data-v-f547d5c6]:before{content:""}#svg-tigger[data-v-0ec35ee4]{cursor:pointer;height:100%;width:100%}
|
package/package.json
CHANGED
|
@@ -147,7 +147,8 @@
|
|
|
147
147
|
|
|
148
148
|
let layers = dxf.tables.layer.layers;
|
|
149
149
|
//加载图纸
|
|
150
|
-
console.log(
|
|
150
|
+
console.log(dxf);
|
|
151
|
+
console.log(entities);
|
|
151
152
|
|
|
152
153
|
for (let key in entities) {
|
|
153
154
|
|
|
@@ -179,7 +180,7 @@
|
|
|
179
180
|
strokeWidth: 0.2,
|
|
180
181
|
name: key.replace(/\s*/g, ""),
|
|
181
182
|
entityId: key,
|
|
182
|
-
stroke:
|
|
183
|
+
stroke: group[0].stroke,
|
|
183
184
|
customColor: configParams ? configParams.color : "",
|
|
184
185
|
//visible: configParams ? configParams.visible :true,
|
|
185
186
|
sceneFunc (context, shape) {
|
|
@@ -346,6 +346,7 @@
|
|
|
346
346
|
},
|
|
347
347
|
};
|
|
348
348
|
if (intersects.length > 0) {
|
|
349
|
+
intersects[0].object.userData.currentInstanceIndex = intersects[0].instanceId;
|
|
349
350
|
params = {
|
|
350
351
|
objects: [intersects[0].object],
|
|
351
352
|
mousePosition: { x: event.clientX, y: event.clientY },
|
|
@@ -445,9 +446,10 @@
|
|
|
445
446
|
switch (key) {
|
|
446
447
|
case 'color':
|
|
447
448
|
targetObj.forEach(children => {
|
|
449
|
+
const instanceIndex = children.userData.instanceMaps[ele.name]['instanceIndex'];
|
|
448
450
|
if (children.isMesh) {
|
|
449
451
|
children.setColorAt(
|
|
450
|
-
|
|
452
|
+
instanceIndex,
|
|
451
453
|
new this.THREE.Color(ele.attr[key])
|
|
452
454
|
);
|
|
453
455
|
children.instanceColor.needsUpdate = true;
|
|
@@ -456,26 +458,28 @@
|
|
|
456
458
|
break;
|
|
457
459
|
case 'visible':
|
|
458
460
|
targetObj.forEach(children => {
|
|
459
|
-
const
|
|
461
|
+
const instanceIndex = children.userData.instanceMaps[ele.name]['instanceIndex'];
|
|
462
|
+
const copyMatrix = children.userData.instanceMaps[ele.name]['copyMatrix'];
|
|
460
463
|
if (ele.attr[key]) {
|
|
461
464
|
const restoreMatrix = new this.THREE.Matrix4().copy(
|
|
462
|
-
|
|
465
|
+
copyMatrix
|
|
463
466
|
);
|
|
464
|
-
children.setMatrixAt(
|
|
467
|
+
children.setMatrixAt(instanceIndex, restoreMatrix);
|
|
465
468
|
} else {
|
|
466
469
|
const offsetMatrix = new this.THREE.Matrix4()
|
|
467
|
-
.copy(
|
|
470
|
+
.copy(copyMatrix)
|
|
468
471
|
.makeTranslation(9999999, 9999999, 9999999);
|
|
469
|
-
children.setMatrixAt(
|
|
472
|
+
children.setMatrixAt(instanceIndex, offsetMatrix);
|
|
470
473
|
}
|
|
471
474
|
children.instanceMatrix.needsUpdate = true;
|
|
472
475
|
});
|
|
473
476
|
break;
|
|
474
477
|
case 'opacity':
|
|
478
|
+
const instanceIndex = children.userData.instanceMaps[ele.name]['instanceIndex'];
|
|
475
479
|
targetObj.forEach(children => {
|
|
476
480
|
if (children.isMesh) {
|
|
477
481
|
const opacity = children.geometry.attributes.opacity.array;
|
|
478
|
-
opacity[
|
|
482
|
+
opacity[instanceIndex] = ele.attr[key];
|
|
479
483
|
children.geometry.attributes.opacity.needsUpdate = true;
|
|
480
484
|
}
|
|
481
485
|
});
|
|
@@ -552,14 +556,25 @@
|
|
|
552
556
|
},
|
|
553
557
|
// 定位到模型
|
|
554
558
|
locateModel(name) {
|
|
555
|
-
let obj = scene.getObjectByName(name);
|
|
559
|
+
let obj = scene.getObjectByName(name) || this.getObjectByName(name)?.[0];
|
|
556
560
|
if (obj) {
|
|
557
561
|
// cameraControls.fitToSphere(obj.parent, true); // TODO 待处理,先用 setModelCenter 进行定位
|
|
558
562
|
if (obj.isGroup) {
|
|
559
563
|
this.setModelCenter(obj);
|
|
560
564
|
} else if (obj.isMesh) {
|
|
561
|
-
|
|
562
|
-
|
|
565
|
+
const instanceIndex = obj.userData.instanceMaps[name]['instanceIndex'];
|
|
566
|
+
const tempMatrix = new this.THREE.Matrix4();
|
|
567
|
+
// const instancePos = new this.THREE.Vector3();
|
|
568
|
+
obj.getMatrixAt(instanceIndex, tempMatrix);
|
|
569
|
+
|
|
570
|
+
let center = this.getCenter(obj, tempMatrix);
|
|
571
|
+
// const instanceLocalCenter = center.applyMatrix4(tempMatrix);
|
|
572
|
+
// center.applyMatrix4(tempMatrix); // 先应用实例矩阵
|
|
573
|
+
// obj.localToWorld(center);
|
|
574
|
+
// instancePos.setFromMatrixPosition(tempMatrix); // 提取局部位置
|
|
575
|
+
// obj.localToWorld(instancePos);
|
|
576
|
+
|
|
577
|
+
let size = this.getSize(obj, tempMatrix);
|
|
563
578
|
this.locateByCenterBox(center, size);
|
|
564
579
|
}
|
|
565
580
|
}
|
|
@@ -634,7 +649,8 @@
|
|
|
634
649
|
);
|
|
635
650
|
let direction = new this.THREE.Vector3(1, 1, 1).normalize();
|
|
636
651
|
let p = new this.THREE.Vector3().copy(center).add(direction.multiplyScalar(distance));
|
|
637
|
-
let cameraCenter = new this.THREE.Vector3(p.x, p.y, p.z)
|
|
652
|
+
let cameraCenter = new this.THREE.Vector3(p.x, p.y, p.z)
|
|
653
|
+
.addScalar(
|
|
638
654
|
Math.max(size.x, size.y, size.z)
|
|
639
655
|
);
|
|
640
656
|
cameraControls.setLookAt(
|
|
@@ -667,7 +683,9 @@
|
|
|
667
683
|
getObjectByName(name) {
|
|
668
684
|
let object = [];
|
|
669
685
|
scene.traverse(item => {
|
|
670
|
-
if (item.name === name
|
|
686
|
+
if (item.name === name
|
|
687
|
+
|| (item.userData?.instanceMaps?.[name] !== undefined) // 或者找出对应的实例对象
|
|
688
|
+
) {
|
|
671
689
|
object.push(item);
|
|
672
690
|
}
|
|
673
691
|
});
|
|
@@ -1506,15 +1524,34 @@
|
|
|
1506
1524
|
scenePass = null;
|
|
1507
1525
|
},
|
|
1508
1526
|
// 获取中心点
|
|
1509
|
-
getCenter(
|
|
1527
|
+
getCenter(instancedMesh, tempMatrix) {
|
|
1528
|
+
// 1. 获取原始几何体的中心(局部坐标,相对于单个 mesh 原点)
|
|
1529
|
+
const geometry = instancedMesh.geometry;
|
|
1530
|
+
if (!geometry.boundingBox) {
|
|
1531
|
+
geometry.computeBoundingBox();
|
|
1532
|
+
}
|
|
1533
|
+
const localCenter = geometry.boundingBox.getCenter(new this.THREE.Vector3());
|
|
1534
|
+
|
|
1535
|
+
// 2. 将中心应用实例的局部变换(tempMatrix)
|
|
1536
|
+
const instanceLocalCenter = localCenter.clone().applyMatrix4(tempMatrix);
|
|
1537
|
+
|
|
1538
|
+
// 3. 转换到世界坐标
|
|
1539
|
+
const worldCenter = instancedMesh.localToWorld(instanceLocalCenter.clone());
|
|
1540
|
+
|
|
1541
|
+
return worldCenter;
|
|
1510
1542
|
let center = new this.THREE.Vector3();
|
|
1543
|
+
if(tempMatrix){
|
|
1544
|
+
obj.applyMatrix4(tempMatrix)
|
|
1545
|
+
obj.updateMatrixWorld();
|
|
1546
|
+
}
|
|
1511
1547
|
obj.boundingBox.getCenter(center);
|
|
1512
1548
|
if (obj.userData.is3D) {
|
|
1513
1549
|
center.applyMatrix4(mat4);
|
|
1550
|
+
obj.updateMatrixWorld();
|
|
1514
1551
|
}
|
|
1515
1552
|
return center;
|
|
1516
1553
|
},
|
|
1517
|
-
getSize(obj) {
|
|
1554
|
+
getSize(obj, tempMatrix) {
|
|
1518
1555
|
let size = new this.THREE.Vector3();
|
|
1519
1556
|
obj.boundingBox.getSize(size);
|
|
1520
1557
|
if (obj.userData.is3D) {
|
|
@@ -106,6 +106,9 @@ function handleInstancedMeshModel(
|
|
|
106
106
|
model.userData[key] = meshNameConfig[key];
|
|
107
107
|
meshName += ':' + meshNameConfig[key];
|
|
108
108
|
}
|
|
109
|
+
|
|
110
|
+
// 初始化实例映射表
|
|
111
|
+
model.userData.instanceMaps = {}
|
|
109
112
|
// 一次性为该 drawObject 的所有实例设置矩阵与颜色
|
|
110
113
|
drawObj.MapInstance.forEach((item, index) => {
|
|
111
114
|
model.userData.instanceIndex = index;
|
|
@@ -113,6 +116,11 @@ function handleInstancedMeshModel(
|
|
|
113
116
|
model.userData.primId = mesh.prmid;
|
|
114
117
|
model.name = meshName !== '' ? item.instanceId + meshName : item.instanceId;
|
|
115
118
|
|
|
119
|
+
model.userData.instanceMaps[item.instanceId] = {};
|
|
120
|
+
model.userData.instanceMaps[item.instanceId]['instanceIndex'] = index;
|
|
121
|
+
model.userData.instanceMaps[item.instanceId]['primId'] = mesh.prmid;
|
|
122
|
+
model.userData.instanceMaps[item.instanceId]['name'] = model.name;
|
|
123
|
+
|
|
116
124
|
const matrixVal = item.matrix?.val;
|
|
117
125
|
if (matrixVal) {
|
|
118
126
|
const m4 = new THREE.Matrix4();
|
|
@@ -137,6 +145,8 @@ function handleInstancedMeshModel(
|
|
|
137
145
|
model.setMatrixAt(index, m4);
|
|
138
146
|
const copyMatrix = new THREE.Matrix4().copy(m4);
|
|
139
147
|
model.userData.copyMatrix = copyMatrix;
|
|
148
|
+
|
|
149
|
+
model.userData.instanceMaps[item.instanceId]['copyMatrix'] = copyMatrix;
|
|
140
150
|
}
|
|
141
151
|
// 需要先设置全部实例颜色,否则后续设置颜色无效
|
|
142
152
|
const { color } = mesh.prop;
|