@inweb/viewer-three 26.9.7 → 26.9.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/viewer-three.js +347 -125
- package/dist/viewer-three.js.map +1 -1
- package/dist/viewer-three.min.js +3 -3
- package/dist/viewer-three.module.js +329 -110
- package/dist/viewer-three.module.js.map +1 -1
- package/package.json +5 -5
- package/src/Viewer/commands/ZoomTo.ts +1 -1
- package/src/Viewer/components/SelectionComponent.ts +4 -4
- package/src/Viewer/draggers/MeasureLineDragger.ts +175 -17
- package/src/Viewer/loaders/DynamicGltfLoader/DynamicGltfLoader.js +272 -105
|
@@ -26,6 +26,9 @@ import {
|
|
|
26
26
|
import { GL_CONSTANTS } from "./GltfStructure.js";
|
|
27
27
|
import { mergeGeometries } from "three/examples/jsm/utils/BufferGeometryUtils.js";
|
|
28
28
|
|
|
29
|
+
//#AI-GENERATED using Gemini 2.5 Pro, Claude-4-sonnet
|
|
30
|
+
//#Reviewed and adapted by dborysov@opendesign.com
|
|
31
|
+
|
|
29
32
|
export class DynamicGltfLoader {
|
|
30
33
|
constructor(camera, scene, renderer) {
|
|
31
34
|
this.camera = camera;
|
|
@@ -98,6 +101,18 @@ export class DynamicGltfLoader {
|
|
|
98
101
|
this.maxConcurrentChunks = 8;
|
|
99
102
|
this.activeChunkLoads = 0;
|
|
100
103
|
this.chunkQueue = [];
|
|
104
|
+
|
|
105
|
+
// GPU-accelerated visibility system
|
|
106
|
+
this.objectIdToIndex = new Map(); // objectId -> index
|
|
107
|
+
this.maxObjectId = 0; // Maximum object ID
|
|
108
|
+
this.objectVisibility = new Float32Array(); // Array of visibility flags for each object
|
|
109
|
+
|
|
110
|
+
// Chunk loading configuration
|
|
111
|
+
this.maxConcurrentChunks = 6; // Default limit
|
|
112
|
+
|
|
113
|
+
// Merged geometry tracking
|
|
114
|
+
this.mergedObjectMap = new Map(); // objectId -> {mergedObject, startIndex, endIndex, vertexCount}
|
|
115
|
+
this.mergedGeometryVisibility = new Map(); // mergedObject -> visibility array
|
|
101
116
|
}
|
|
102
117
|
|
|
103
118
|
setVisibleEdges(visible) {
|
|
@@ -929,6 +944,59 @@ export class DynamicGltfLoader {
|
|
|
929
944
|
this.originalObjectsToSelection.clear();
|
|
930
945
|
}
|
|
931
946
|
|
|
947
|
+
initializeObjectVisibility() {
|
|
948
|
+
if (this.maxObjectId > 0) {
|
|
949
|
+
this.objectVisibility = new Float32Array(this.maxObjectId);
|
|
950
|
+
for (let i = 0; i < this.maxObjectId; i++) {
|
|
951
|
+
this.objectVisibility[i] = 1.0;
|
|
952
|
+
}
|
|
953
|
+
console.log(`Initialized object visibility array: ${this.maxObjectId} objects`);
|
|
954
|
+
}
|
|
955
|
+
}
|
|
956
|
+
|
|
957
|
+
createVisibilityMaterial(material) {
|
|
958
|
+
// Применяем шейдер напрямую к оригинальному материалу
|
|
959
|
+
material.onBeforeCompile = (shader) => {
|
|
960
|
+
shader.vertexShader = shader.vertexShader.replace(
|
|
961
|
+
"#include <common>",
|
|
962
|
+
`
|
|
963
|
+
#include <common>
|
|
964
|
+
attribute float visibility;
|
|
965
|
+
varying float vVisibility;
|
|
966
|
+
`
|
|
967
|
+
);
|
|
968
|
+
|
|
969
|
+
shader.fragmentShader = shader.fragmentShader.replace(
|
|
970
|
+
"#include <common>",
|
|
971
|
+
`
|
|
972
|
+
#include <common>
|
|
973
|
+
varying float vVisibility;
|
|
974
|
+
`
|
|
975
|
+
);
|
|
976
|
+
|
|
977
|
+
shader.vertexShader = shader.vertexShader.replace(
|
|
978
|
+
"void main() {",
|
|
979
|
+
`
|
|
980
|
+
void main() {
|
|
981
|
+
vVisibility = visibility;
|
|
982
|
+
`
|
|
983
|
+
);
|
|
984
|
+
|
|
985
|
+
shader.fragmentShader = shader.fragmentShader.replace(
|
|
986
|
+
"void main() {",
|
|
987
|
+
`
|
|
988
|
+
void main() {
|
|
989
|
+
if (vVisibility < 0.5) discard;
|
|
990
|
+
`
|
|
991
|
+
);
|
|
992
|
+
};
|
|
993
|
+
|
|
994
|
+
// Принудительная перекомпиляция материала
|
|
995
|
+
material.needsUpdate = true;
|
|
996
|
+
|
|
997
|
+
return material;
|
|
998
|
+
}
|
|
999
|
+
|
|
932
1000
|
clear() {
|
|
933
1001
|
this.chunkQueue = [];
|
|
934
1002
|
|
|
@@ -939,7 +1007,6 @@ export class DynamicGltfLoader {
|
|
|
939
1007
|
});
|
|
940
1008
|
this.structures = [];
|
|
941
1009
|
|
|
942
|
-
// Clear all nodes and unload their objects
|
|
943
1010
|
this.nodes.forEach((node) => {
|
|
944
1011
|
if (node.object) {
|
|
945
1012
|
if (node.object.parent) {
|
|
@@ -1025,13 +1092,11 @@ export class DynamicGltfLoader {
|
|
|
1025
1092
|
});
|
|
1026
1093
|
this.mergedPoints.clear();
|
|
1027
1094
|
|
|
1028
|
-
// Clear all caches
|
|
1029
1095
|
this.geometryCache.clear();
|
|
1030
1096
|
this.materialCache.clear();
|
|
1031
1097
|
this.textureCache.clear();
|
|
1032
1098
|
this.loadedMaterials.clear();
|
|
1033
1099
|
|
|
1034
|
-
// Clear all maps and sets
|
|
1035
1100
|
this.nodesToLoad = [];
|
|
1036
1101
|
this.handleToObjects.clear();
|
|
1037
1102
|
this.originalObjects.clear();
|
|
@@ -1043,7 +1108,6 @@ export class DynamicGltfLoader {
|
|
|
1043
1108
|
this.oldOptimizeObjects.clear();
|
|
1044
1109
|
this.isolatedObjects = [];
|
|
1045
1110
|
|
|
1046
|
-
// Reset counters and state
|
|
1047
1111
|
this.totalLoadedObjects = 0;
|
|
1048
1112
|
this.lastUpdateTime = 0;
|
|
1049
1113
|
this.currentMemoryUsage = 0;
|
|
@@ -1051,6 +1115,10 @@ export class DynamicGltfLoader {
|
|
|
1051
1115
|
|
|
1052
1116
|
this.abortController = new AbortController();
|
|
1053
1117
|
this.updateMemoryIndicator();
|
|
1118
|
+
|
|
1119
|
+
this.objectIdToIndex.clear();
|
|
1120
|
+
this.maxObjectId = 0;
|
|
1121
|
+
this.objectVisibility = new Float32Array();
|
|
1054
1122
|
}
|
|
1055
1123
|
|
|
1056
1124
|
setStructureTransform(structureId, matrix) {
|
|
@@ -1224,21 +1292,52 @@ export class DynamicGltfLoader {
|
|
|
1224
1292
|
this.originalObjectsToSelection.add(obj);
|
|
1225
1293
|
}
|
|
1226
1294
|
});
|
|
1295
|
+
this.initializeObjectVisibility();
|
|
1296
|
+
|
|
1297
|
+
console.log(`Optimization complete. Total objects: ${this.maxObjectId}`);
|
|
1227
1298
|
|
|
1228
1299
|
this.dispatchEvent("update");
|
|
1229
1300
|
}
|
|
1230
1301
|
|
|
1231
1302
|
mergeMeshGroups(materialGroups, rootGroup) {
|
|
1232
1303
|
for (const group of materialGroups) {
|
|
1304
|
+
if (!group.material) {
|
|
1305
|
+
console.warn("Skipping mesh group with null material");
|
|
1306
|
+
continue;
|
|
1307
|
+
}
|
|
1308
|
+
|
|
1233
1309
|
try {
|
|
1234
1310
|
const geometries = [];
|
|
1235
1311
|
const handles = new Set();
|
|
1236
1312
|
const optimizedObjects = [];
|
|
1313
|
+
const objectMapping = new Map();
|
|
1314
|
+
let currentVertexOffset = 0;
|
|
1237
1315
|
|
|
1238
1316
|
for (const mesh of group.objects) {
|
|
1239
1317
|
const geometry = mesh.geometry.clone();
|
|
1240
1318
|
mesh.updateWorldMatrix(true, false);
|
|
1241
1319
|
geometry.applyMatrix4(mesh.matrixWorld);
|
|
1320
|
+
|
|
1321
|
+
const handle = mesh.userData.handle;
|
|
1322
|
+
if (!this.objectIdToIndex.has(handle)) {
|
|
1323
|
+
this.objectIdToIndex.set(handle, this.maxObjectId++);
|
|
1324
|
+
}
|
|
1325
|
+
const objectId = this.objectIdToIndex.get(handle);
|
|
1326
|
+
|
|
1327
|
+
const vertexCount = geometry.attributes.position.count;
|
|
1328
|
+
const objectIds = new Float32Array(vertexCount);
|
|
1329
|
+
for (let i = 0; i < vertexCount; i++) {
|
|
1330
|
+
objectIds[i] = objectId;
|
|
1331
|
+
}
|
|
1332
|
+
geometry.setAttribute("objectId", new BufferAttribute(objectIds, 1));
|
|
1333
|
+
|
|
1334
|
+
objectMapping.set(mesh, {
|
|
1335
|
+
geometry,
|
|
1336
|
+
startVertexIndex: currentVertexOffset,
|
|
1337
|
+
vertexCount: geometry.attributes.position.count,
|
|
1338
|
+
});
|
|
1339
|
+
|
|
1340
|
+
currentVertexOffset += geometry.attributes.position.count;
|
|
1242
1341
|
geometries.push(geometry);
|
|
1243
1342
|
|
|
1244
1343
|
optimizedObjects.push(mesh);
|
|
@@ -1249,16 +1348,41 @@ export class DynamicGltfLoader {
|
|
|
1249
1348
|
|
|
1250
1349
|
if (geometries.length > 0) {
|
|
1251
1350
|
const mergedGeometry = mergeGeometries(geometries);
|
|
1351
|
+
|
|
1352
|
+
// Create visibility attribute
|
|
1353
|
+
const totalVertices = mergedGeometry.attributes.position.count;
|
|
1354
|
+
const visibilityArray = new Float32Array(totalVertices);
|
|
1355
|
+
|
|
1356
|
+
// Initialize all vertices as visible (1.0)
|
|
1357
|
+
for (let i = 0; i < totalVertices; i++) {
|
|
1358
|
+
visibilityArray[i] = 1.0;
|
|
1359
|
+
}
|
|
1360
|
+
|
|
1361
|
+
// Add visibility attribute to geometry
|
|
1362
|
+
mergedGeometry.setAttribute("visibility", new BufferAttribute(visibilityArray, 1));
|
|
1363
|
+
|
|
1252
1364
|
if (this.useVAO) {
|
|
1253
1365
|
this.createVAO(mergedGeometry);
|
|
1254
1366
|
}
|
|
1255
1367
|
|
|
1256
|
-
|
|
1368
|
+
// Create visibility material
|
|
1369
|
+
const visibilityMaterial = this.createVisibilityMaterial(group.material);
|
|
1370
|
+
|
|
1371
|
+
const mergedMesh = new Mesh(mergedGeometry, visibilityMaterial);
|
|
1257
1372
|
rootGroup.add(mergedMesh);
|
|
1258
1373
|
|
|
1259
1374
|
this.mergedMesh.add(mergedMesh);
|
|
1260
1375
|
this.optimizedOriginalMap.set(mergedMesh, optimizedObjects);
|
|
1261
1376
|
|
|
1377
|
+
// Store object mappings with visibility tracking
|
|
1378
|
+
this.mergedObjectMap.set(mergedMesh.uuid, {
|
|
1379
|
+
objectMapping,
|
|
1380
|
+
visibilityArray,
|
|
1381
|
+
totalVertices,
|
|
1382
|
+
});
|
|
1383
|
+
|
|
1384
|
+
this.mergedGeometryVisibility.set(mergedMesh, visibilityArray);
|
|
1385
|
+
|
|
1262
1386
|
mergedObjects.push(mergedMesh);
|
|
1263
1387
|
|
|
1264
1388
|
geometries.forEach((geometry) => {
|
|
@@ -1288,8 +1412,16 @@ export class DynamicGltfLoader {
|
|
|
1288
1412
|
for (const group of materialGroups) {
|
|
1289
1413
|
if (group.objects.length === 0) continue;
|
|
1290
1414
|
|
|
1415
|
+
if (!group.material) {
|
|
1416
|
+
console.warn("Skipping line group with null material");
|
|
1417
|
+
continue;
|
|
1418
|
+
}
|
|
1419
|
+
|
|
1291
1420
|
const handles = new Set();
|
|
1292
1421
|
let totalVertices = 0;
|
|
1422
|
+
const objectMapping = new Map();
|
|
1423
|
+
let currentVertexOffset = 0;
|
|
1424
|
+
|
|
1293
1425
|
group.objects.map((line) => {
|
|
1294
1426
|
handles.add(line.userData.handle);
|
|
1295
1427
|
totalVertices += line.geometry.attributes.position.count;
|
|
@@ -1306,6 +1438,18 @@ export class DynamicGltfLoader {
|
|
|
1306
1438
|
const positionAttr = geometry.attributes.position;
|
|
1307
1439
|
const vertexCount = positionAttr.count;
|
|
1308
1440
|
|
|
1441
|
+
const handle = line.userData.handle;
|
|
1442
|
+
if (!this.objectIdToIndex.has(handle)) {
|
|
1443
|
+
this.objectIdToIndex.set(handle, this.maxObjectId++);
|
|
1444
|
+
}
|
|
1445
|
+
// const objectId = this.objectIdToIndex.get(handle);
|
|
1446
|
+
|
|
1447
|
+
objectMapping.set(line, {
|
|
1448
|
+
startVertexIndex: currentVertexOffset,
|
|
1449
|
+
vertexCount,
|
|
1450
|
+
});
|
|
1451
|
+
currentVertexOffset += vertexCount;
|
|
1452
|
+
|
|
1309
1453
|
line.updateWorldMatrix(true, false);
|
|
1310
1454
|
const matrix = line.matrixWorld;
|
|
1311
1455
|
const vector = new Vector3();
|
|
@@ -1331,7 +1475,28 @@ export class DynamicGltfLoader {
|
|
|
1331
1475
|
geometry.computeBoundingSphere();
|
|
1332
1476
|
geometry.computeBoundingBox();
|
|
1333
1477
|
|
|
1334
|
-
const
|
|
1478
|
+
const objectIds = new Float32Array(totalVertices);
|
|
1479
|
+
let vertexIndex = 0;
|
|
1480
|
+
group.objects.forEach((line) => {
|
|
1481
|
+
const vertexCount = line.geometry.attributes.position.count;
|
|
1482
|
+
const handle = line.userData.handle;
|
|
1483
|
+
const objectId = this.objectIdToIndex.get(handle);
|
|
1484
|
+
|
|
1485
|
+
for (let i = 0; i < vertexCount; i++) {
|
|
1486
|
+
objectIds[vertexIndex++] = objectId;
|
|
1487
|
+
}
|
|
1488
|
+
});
|
|
1489
|
+
geometry.setAttribute("objectId", new BufferAttribute(objectIds, 1));
|
|
1490
|
+
|
|
1491
|
+
const visibilityArray = new Float32Array(totalVertices);
|
|
1492
|
+
for (let i = 0; i < totalVertices; i++) {
|
|
1493
|
+
visibilityArray[i] = 1.0;
|
|
1494
|
+
}
|
|
1495
|
+
geometry.setAttribute("visibility", new BufferAttribute(visibilityArray, 1));
|
|
1496
|
+
|
|
1497
|
+
const visibilityMaterial = this.createVisibilityMaterial(group.material);
|
|
1498
|
+
|
|
1499
|
+
const mergedLine = new LineSegments(geometry, visibilityMaterial);
|
|
1335
1500
|
const mergedObjects = [mergedLine];
|
|
1336
1501
|
if (this.useVAO) {
|
|
1337
1502
|
this.createVAO(mergedLine);
|
|
@@ -1340,6 +1505,14 @@ export class DynamicGltfLoader {
|
|
|
1340
1505
|
this.mergedLines.add(mergedLine);
|
|
1341
1506
|
this.optimizedOriginalMap.set(mergedLine, group.objects);
|
|
1342
1507
|
|
|
1508
|
+
this.mergedObjectMap.set(mergedLine.uuid, {
|
|
1509
|
+
objectMapping,
|
|
1510
|
+
visibilityArray,
|
|
1511
|
+
totalVertices,
|
|
1512
|
+
});
|
|
1513
|
+
|
|
1514
|
+
this.mergedGeometryVisibility.set(mergedLine, visibilityArray);
|
|
1515
|
+
|
|
1343
1516
|
handles.forEach((handle) => {
|
|
1344
1517
|
if (this.handleToOptimizedObjects.has(handle)) {
|
|
1345
1518
|
const existingObjects = this.handleToOptimizedObjects.get(handle);
|
|
@@ -1354,15 +1527,42 @@ export class DynamicGltfLoader {
|
|
|
1354
1527
|
|
|
1355
1528
|
mergeLineSegmentGroups(materialGroups, rootGroup) {
|
|
1356
1529
|
for (const group of materialGroups) {
|
|
1530
|
+
if (!group.material) {
|
|
1531
|
+
console.warn("Skipping line segment group with null material");
|
|
1532
|
+
continue;
|
|
1533
|
+
}
|
|
1534
|
+
|
|
1357
1535
|
try {
|
|
1358
1536
|
const geometries = [];
|
|
1359
1537
|
const optimizedObjects = [];
|
|
1360
1538
|
const handles = new Set();
|
|
1539
|
+
const objectMapping = new Map();
|
|
1540
|
+
let currentVertexOffset = 0;
|
|
1361
1541
|
|
|
1362
1542
|
for (const line of group.objects) {
|
|
1363
1543
|
const geometry = line.geometry.clone();
|
|
1364
1544
|
line.updateWorldMatrix(true, false);
|
|
1365
1545
|
geometry.applyMatrix4(line.matrixWorld);
|
|
1546
|
+
|
|
1547
|
+
const handle = line.userData.handle;
|
|
1548
|
+
if (!this.objectIdToIndex.has(handle)) {
|
|
1549
|
+
this.objectIdToIndex.set(handle, this.maxObjectId++);
|
|
1550
|
+
}
|
|
1551
|
+
const objectId = this.objectIdToIndex.get(handle);
|
|
1552
|
+
const vertexCount = geometry.attributes.position.count;
|
|
1553
|
+
const objectIds = new Float32Array(vertexCount);
|
|
1554
|
+
for (let i = 0; i < vertexCount; i++) {
|
|
1555
|
+
objectIds[i] = objectId;
|
|
1556
|
+
}
|
|
1557
|
+
geometry.setAttribute("objectId", new BufferAttribute(objectIds, 1));
|
|
1558
|
+
|
|
1559
|
+
objectMapping.set(line, {
|
|
1560
|
+
geometry,
|
|
1561
|
+
startVertexIndex: currentVertexOffset,
|
|
1562
|
+
vertexCount: geometry.attributes.position.count,
|
|
1563
|
+
});
|
|
1564
|
+
|
|
1565
|
+
currentVertexOffset += geometry.attributes.position.count;
|
|
1366
1566
|
geometries.push(geometry);
|
|
1367
1567
|
optimizedObjects.push(line);
|
|
1368
1568
|
handles.add(line.userData.handle);
|
|
@@ -1372,7 +1572,19 @@ export class DynamicGltfLoader {
|
|
|
1372
1572
|
|
|
1373
1573
|
if (geometries.length > 0) {
|
|
1374
1574
|
const mergedGeometry = mergeGeometries(geometries, false);
|
|
1375
|
-
|
|
1575
|
+
|
|
1576
|
+
const totalVertices = mergedGeometry.attributes.position.count;
|
|
1577
|
+
const visibilityArray = new Float32Array(totalVertices);
|
|
1578
|
+
|
|
1579
|
+
for (let i = 0; i < totalVertices; i++) {
|
|
1580
|
+
visibilityArray[i] = 1.0;
|
|
1581
|
+
}
|
|
1582
|
+
|
|
1583
|
+
mergedGeometry.setAttribute("visibility", new BufferAttribute(visibilityArray, 1));
|
|
1584
|
+
|
|
1585
|
+
const visibilityMaterial = this.createVisibilityMaterial(group.material);
|
|
1586
|
+
|
|
1587
|
+
const mergedLine = new LineSegments(mergedGeometry, visibilityMaterial);
|
|
1376
1588
|
|
|
1377
1589
|
if (this.useVAO) {
|
|
1378
1590
|
this.createVAO(mergedLine);
|
|
@@ -1381,6 +1593,15 @@ export class DynamicGltfLoader {
|
|
|
1381
1593
|
rootGroup.add(mergedLine);
|
|
1382
1594
|
this.mergedLineSegments.add(mergedLine);
|
|
1383
1595
|
this.optimizedOriginalMap.set(mergedLine, optimizedObjects);
|
|
1596
|
+
|
|
1597
|
+
this.mergedObjectMap.set(mergedLine.uuid, {
|
|
1598
|
+
objectMapping,
|
|
1599
|
+
visibilityArray,
|
|
1600
|
+
totalVertices,
|
|
1601
|
+
});
|
|
1602
|
+
|
|
1603
|
+
this.mergedGeometryVisibility.set(mergedLine, visibilityArray);
|
|
1604
|
+
|
|
1384
1605
|
mergedObjects.push(mergedLine);
|
|
1385
1606
|
|
|
1386
1607
|
geometries.forEach((geometry) => {
|
|
@@ -1408,6 +1629,11 @@ export class DynamicGltfLoader {
|
|
|
1408
1629
|
|
|
1409
1630
|
mergePointsGroups(materialGroups, rootGroup) {
|
|
1410
1631
|
for (const group of materialGroups) {
|
|
1632
|
+
if (!group.material) {
|
|
1633
|
+
console.warn("Skipping points group with null material");
|
|
1634
|
+
continue;
|
|
1635
|
+
}
|
|
1636
|
+
|
|
1411
1637
|
try {
|
|
1412
1638
|
const geometries = [];
|
|
1413
1639
|
const optimizedObjects = [];
|
|
@@ -1631,116 +1857,57 @@ export class DynamicGltfLoader {
|
|
|
1631
1857
|
this.syncHiddenObjects();
|
|
1632
1858
|
}
|
|
1633
1859
|
|
|
1634
|
-
|
|
1635
|
-
if (
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1860
|
+
_updateVisibilityAttribute(mergedObject) {
|
|
1861
|
+
if (
|
|
1862
|
+
mergedObject.geometry &&
|
|
1863
|
+
mergedObject.geometry.attributes.visibility &&
|
|
1864
|
+
mergedObject.geometry.attributes.objectId
|
|
1865
|
+
) {
|
|
1866
|
+
const visibilityArray = mergedObject.geometry.attributes.visibility.array;
|
|
1867
|
+
const objectIdArray = mergedObject.geometry.attributes.objectId.array;
|
|
1641
1868
|
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1869
|
+
for (let i = 0; i < visibilityArray.length; i++) {
|
|
1870
|
+
const objectId = objectIdArray[i];
|
|
1871
|
+
if (objectId < this.objectVisibility.length) {
|
|
1872
|
+
visibilityArray[i] = this.objectVisibility[objectId];
|
|
1873
|
+
}
|
|
1647
1874
|
}
|
|
1648
|
-
|
|
1875
|
+
|
|
1876
|
+
mergedObject.geometry.attributes.visibility.needsUpdate = true;
|
|
1649
1877
|
}
|
|
1878
|
+
}
|
|
1650
1879
|
|
|
1651
|
-
|
|
1880
|
+
syncHiddenObjects() {
|
|
1881
|
+
if (this.mergedObjectMap.size === 0) {
|
|
1882
|
+
console.log("No merged objects to sync");
|
|
1652
1883
|
return;
|
|
1653
1884
|
}
|
|
1654
1885
|
|
|
1655
|
-
this.
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
objects.forEach((x) => this.oldOptimizeObjects.add(x));
|
|
1886
|
+
if (this.objectVisibility.length > 0) {
|
|
1887
|
+
for (let i = 0; i < this.objectVisibility.length; i++) {
|
|
1888
|
+
this.objectVisibility[i] = 1.0;
|
|
1659
1889
|
}
|
|
1660
|
-
});
|
|
1661
1890
|
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
const updateListToOptimize = [];
|
|
1667
|
-
originObjects.forEach((obj) => {
|
|
1668
|
-
if (!this.hiddenHandles.has(obj.userData.handle)) {
|
|
1669
|
-
updateListToOptimize.push(obj);
|
|
1891
|
+
this.hiddenHandles.forEach((handle) => {
|
|
1892
|
+
const index = this.objectIdToIndex.get(handle);
|
|
1893
|
+
if (index !== undefined && index < this.objectVisibility.length) {
|
|
1894
|
+
this.objectVisibility[index] = 0.0;
|
|
1670
1895
|
}
|
|
1671
1896
|
});
|
|
1897
|
+
}
|
|
1672
1898
|
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
firstObject instanceof Mesh
|
|
1686
|
-
? new Mesh(newMergedGeometry, optimizedObject.material)
|
|
1687
|
-
: new LineSegments(newMergedGeometry, optimizedObject.material);
|
|
1688
|
-
|
|
1689
|
-
mergedObject.visible = true;
|
|
1690
|
-
optimizedObject.parent.add(mergedObject);
|
|
1691
|
-
this.newOptimizedObjects.add(mergedObject);
|
|
1692
|
-
|
|
1693
|
-
geometries.forEach((geometry) => {
|
|
1694
|
-
geometry.dispose();
|
|
1695
|
-
});
|
|
1696
|
-
} else if (firstObject instanceof Line) {
|
|
1697
|
-
let totalVertices = 0;
|
|
1698
|
-
updateListToOptimize.map((line) => {
|
|
1699
|
-
totalVertices += line.geometry.attributes.position.count;
|
|
1700
|
-
});
|
|
1701
|
-
|
|
1702
|
-
const positions = new Float32Array(totalVertices * 3);
|
|
1703
|
-
let posOffset = 0;
|
|
1704
|
-
|
|
1705
|
-
const indices = [];
|
|
1706
|
-
let vertexOffset = 0;
|
|
1707
|
-
|
|
1708
|
-
updateListToOptimize.forEach((line) => {
|
|
1709
|
-
const geometry = line.geometry;
|
|
1710
|
-
const positionAttr = geometry.attributes.position;
|
|
1711
|
-
const vertexCount = positionAttr.count;
|
|
1712
|
-
|
|
1713
|
-
line.updateWorldMatrix(true, false);
|
|
1714
|
-
const matrix = line.matrixWorld;
|
|
1715
|
-
const vector = new Vector3();
|
|
1716
|
-
|
|
1717
|
-
for (let i = 0; i < vertexCount; i++) {
|
|
1718
|
-
vector.fromBufferAttribute(positionAttr, i);
|
|
1719
|
-
vector.applyMatrix4(matrix);
|
|
1720
|
-
positions[posOffset++] = vector.x;
|
|
1721
|
-
positions[posOffset++] = vector.y;
|
|
1722
|
-
positions[posOffset++] = vector.z;
|
|
1723
|
-
}
|
|
1724
|
-
|
|
1725
|
-
for (let i = 0; i < vertexCount - 1; i++) {
|
|
1726
|
-
indices.push(vertexOffset + i, vertexOffset + i + 1);
|
|
1727
|
-
}
|
|
1728
|
-
|
|
1729
|
-
vertexOffset += vertexCount;
|
|
1730
|
-
});
|
|
1731
|
-
|
|
1732
|
-
const geometry = new BufferGeometry();
|
|
1733
|
-
geometry.setAttribute("position", new BufferAttribute(positions, 3));
|
|
1734
|
-
geometry.setIndex(indices);
|
|
1735
|
-
geometry.computeBoundingSphere();
|
|
1736
|
-
geometry.computeBoundingBox();
|
|
1737
|
-
|
|
1738
|
-
const mergedLine = new LineSegments(geometry, optimizedObject.material);
|
|
1739
|
-
mergedLine.visible = true;
|
|
1740
|
-
optimizedObject.parent.add(mergedLine);
|
|
1741
|
-
this.newOptimizedObjects.add(mergedLine);
|
|
1742
|
-
}
|
|
1743
|
-
});
|
|
1899
|
+
for (const mesh of this.mergedMesh) {
|
|
1900
|
+
this._updateVisibilityAttribute(mesh);
|
|
1901
|
+
}
|
|
1902
|
+
for (const line of this.mergedLines) {
|
|
1903
|
+
this._updateVisibilityAttribute(line);
|
|
1904
|
+
}
|
|
1905
|
+
for (const lineSegment of this.mergedLineSegments) {
|
|
1906
|
+
this._updateVisibilityAttribute(lineSegment);
|
|
1907
|
+
}
|
|
1908
|
+
for (const point of this.mergedPoints) {
|
|
1909
|
+
this._updateVisibilityAttribute(point);
|
|
1910
|
+
}
|
|
1744
1911
|
}
|
|
1745
1912
|
|
|
1746
1913
|
getStructureGeometryExtent(structureId) {
|