fl-web-component 2.0.18 → 2.0.19-beta.0

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.
@@ -88,8 +88,11 @@ function createStreamState(prefixIdKey) {
88
88
  return {
89
89
  prefixIdKey: prefixIdKey || '',
90
90
  buffer: new Uint8Array(),
91
- pendingPrimitives: new Map(),
92
- expectingPrimitive: true,
91
+ pendingMesh: null,
92
+ pendingPrimitiveIds: new Set(),
93
+ pendingPrimitiveGroups: [],
94
+ pendingMatchedPrimitiveIds: new Set(),
95
+ expectingMesh: true,
93
96
  isFullProps: true,
94
97
  };
95
98
  }
@@ -105,101 +108,179 @@ function parseStreamChunk(state, chunkView, flushing = false) {
105
108
  const meshes = [];
106
109
  const primitives = [];
107
110
 
108
- while (state.buffer.length > 0) {
109
- if (state.expectingPrimitive) {
110
- if (state.buffer.length < 12) break;
111
+ const commitPendingMesh = () => {
112
+ if (!state.pendingMesh) return;
111
113
 
112
- try {
113
- const dataView = new DataView(
114
- state.buffer.buffer,
115
- state.buffer.byteOffset,
116
- state.buffer.byteLength
117
- );
118
- const primitiveResult = parsePrimitive(dataView, state.buffer, 0, state.isFullProps);
119
- const primitiveData = primitiveResult.primitive;
120
-
121
- _applyPrefixId(primitiveData, 'id', null, state.prefixIdKey);
122
- _applyPrefixId(primitiveData, 'material', null, state.prefixIdKey);
123
-
124
- if (state.isFullProps) {
125
- const { position, normal, posindex, nolindex, indices } =
126
- parsePrimitiveData(primitiveData);
127
- const formatted = formatPrimitiveData({ position, normal, posindex, nolindex });
128
- delete primitiveData.nolindex;
129
- delete primitiveData.posindex;
130
- primitiveData.position = formatted.position;
131
- primitiveData.normal = formatted.normal;
132
- primitiveData.indices = indices;
133
- }
114
+ const meshList = Array.isArray(state.pendingMesh) ? state.pendingMesh : [state.pendingMesh];
115
+ meshList.forEach(mesh => {
116
+ meshes.push(mesh);
117
+ primitives.push(state.pendingPrimitiveGroups);
118
+ });
134
119
 
135
- state.pendingPrimitives.set(primitiveData.id, primitiveData);
136
- state.expectingPrimitive = false;
137
- state.buffer = state.buffer.slice(primitiveResult.offset);
138
- } catch (e) {
120
+ state.pendingMesh = null;
121
+ state.pendingPrimitiveIds = new Set();
122
+ state.pendingPrimitiveGroups = [];
123
+ state.pendingMatchedPrimitiveIds = new Set();
124
+ };
125
+
126
+ while (state.buffer.length > 0) {
127
+ if (state.expectingMesh) {
128
+ const meshResult = tryParseMeshFromState(state);
129
+ if (meshResult.status === 'incomplete') break;
130
+ if (meshResult.status === 'invalid') {
139
131
  break;
140
132
  }
141
- } else {
142
- if (state.buffer.length < 4) break;
143
133
 
144
- const length = new DataView(state.buffer.buffer, state.buffer.byteOffset).getUint32(0, false);
145
- if (length > 10 * 1024 * 1024) {
146
- state.expectingPrimitive = true;
134
+ commitPendingMesh();
135
+ state.pendingMesh = meshResult.mesh;
136
+ state.pendingPrimitiveIds = new Set(collectMeshPrimitiveIds(meshResult.mesh));
137
+ state.pendingPrimitiveGroups = [];
138
+ state.pendingMatchedPrimitiveIds = new Set();
139
+ state.expectingMesh = false;
140
+ state.buffer = state.buffer.slice(meshResult.totalLen);
141
+ } else {
142
+ const nextMeshResult = tryParseMeshFromState(state);
143
+ if (nextMeshResult.status === 'success') {
144
+ commitPendingMesh();
145
+ state.pendingMesh = nextMeshResult.mesh;
146
+ state.pendingPrimitiveIds = new Set(collectMeshPrimitiveIds(nextMeshResult.mesh));
147
+ state.pendingPrimitiveGroups = [];
148
+ state.pendingMatchedPrimitiveIds = new Set();
149
+ state.expectingMesh = false;
150
+ state.buffer = state.buffer.slice(nextMeshResult.totalLen);
147
151
  continue;
148
152
  }
149
153
 
150
- const totalLen = 4 + length;
151
- if (state.buffer.length < totalLen) break;
152
-
153
- const data = state.buffer.slice(4, totalLen);
154
- let mesh = null;
154
+ if (state.buffer.length < 12) break;
155
155
 
156
+ let primitiveResult = null;
156
157
  try {
157
- const jsonStr = utf8Decoder.decode(data);
158
- mesh = JSON.parse(jsonStr);
158
+ primitiveResult = parsePrimitiveFromState(state);
159
159
  } catch (e) {
160
- state.expectingPrimitive = true;
161
- continue;
160
+ break;
162
161
  }
163
162
 
164
- if (mesh) {
165
- state.isFullProps = true;
163
+ const primitiveData = primitiveResult.primitive;
166
164
 
167
- _applyPrefixId(mesh, 'id', null, state.prefixIdKey);
168
- if (Array.isArray(mesh)) {
169
- mesh.forEach(item => {
170
- _applyPrefixId(item.primitives, 'prmid', item.documentId, state.prefixIdKey);
171
- });
172
- } else {
173
- _applyPrefixId(mesh.primitives, 'prmid', mesh.documentId, state.prefixIdKey);
174
- }
165
+ if (state.pendingPrimitiveIds.has(primitiveData.id)) {
166
+ state.pendingPrimitiveGroups.push(primitiveData);
167
+ state.pendingMatchedPrimitiveIds.add(primitiveData.id);
168
+ }
175
169
 
176
- const docId = mesh.id;
177
- const meshToPrimId = mesh.primitives.map(item => item.prmid);
178
- const hasPendingPrimitive = meshToPrimId.some(item => state.pendingPrimitives.has(item));
179
- const hasPendingMesh = state.pendingPrimitives.has(docId);
180
-
181
- if (hasPendingMesh || hasPendingPrimitive) {
182
- let primitiveData = state.pendingPrimitives.get(docId);
183
- if (!hasPendingMesh && hasPendingPrimitive) {
184
- primitiveData = state.pendingPrimitives.get(meshToPrimId[0]);
185
- }
186
- meshes.push(mesh);
187
- primitives.push(primitiveData);
188
- }
170
+ state.buffer = state.buffer.slice(primitiveResult.consumedBytes);
189
171
 
190
- state.expectingPrimitive = false;
191
- state.buffer = state.buffer.slice(totalLen);
172
+ if (
173
+ state.pendingPrimitiveIds.size > 0 &&
174
+ state.pendingMatchedPrimitiveIds.size >= state.pendingPrimitiveIds.size
175
+ ) {
176
+ commitPendingMesh();
177
+ state.expectingMesh = true;
192
178
  }
193
179
  }
194
180
  }
195
181
 
196
182
  if (flushing) {
183
+ commitPendingMesh();
197
184
  state.buffer = new Uint8Array();
198
185
  }
199
186
 
200
187
  return { meshes, primitives };
201
188
  }
202
189
 
190
+ function normalizeStreamMesh(mesh, prefixIdKey) {
191
+ _applyPrefixId(mesh, 'id', null, prefixIdKey);
192
+ const meshList = Array.isArray(mesh) ? mesh : [mesh];
193
+
194
+ meshList.forEach(item => {
195
+ if (!item) return;
196
+ if (!Array.isArray(item.primitives)) {
197
+ item.primitives = [];
198
+ }
199
+ _applyPrefixId(item.primitives, 'prmid', item.documentId, prefixIdKey);
200
+ });
201
+
202
+ return mesh;
203
+ }
204
+
205
+ function collectMeshPrimitiveIds(mesh) {
206
+ const ids = [];
207
+ const meshList = Array.isArray(mesh) ? mesh : [mesh];
208
+
209
+ meshList.forEach(item => {
210
+ if (!item || !Array.isArray(item.primitives)) return;
211
+ item.primitives.forEach(primitive => {
212
+ if (primitive && primitive.prmid != null) {
213
+ ids.push(primitive.prmid);
214
+ }
215
+ });
216
+ });
217
+
218
+ return ids;
219
+ }
220
+
221
+ function isValidStreamMesh(mesh) {
222
+ const meshList = Array.isArray(mesh) ? mesh : [mesh];
223
+ if (meshList.length === 0) return false;
224
+ return meshList.every(item => item && typeof item === 'object' && Array.isArray(item.primitives));
225
+ }
226
+
227
+ function tryParseMeshFromState(state) {
228
+ if (state.buffer.length < 4) {
229
+ return { status: 'incomplete' };
230
+ }
231
+
232
+ const length = new DataView(state.buffer.buffer, state.buffer.byteOffset).getUint32(0, false);
233
+ if (length <= 0 || length > 10 * 1024 * 1024) {
234
+ return { status: 'invalid' };
235
+ }
236
+
237
+ const totalLen = 4 + length;
238
+ if (state.buffer.length < totalLen) {
239
+ return { status: 'incomplete' };
240
+ }
241
+
242
+ try {
243
+ const data = state.buffer.slice(4, totalLen);
244
+ const parsedMesh = JSON.parse(utf8Decoder.decode(data));
245
+ if (!isValidStreamMesh(parsedMesh)) {
246
+ return { status: 'invalid' };
247
+ }
248
+ const mesh = normalizeStreamMesh(parsedMesh, state.prefixIdKey);
249
+ return { status: 'success', mesh, totalLen };
250
+ } catch (e) {
251
+ return { status: 'invalid' };
252
+ }
253
+ }
254
+
255
+ function parsePrimitiveFromState(state) {
256
+ const dataView = new DataView(
257
+ state.buffer.buffer,
258
+ state.buffer.byteOffset,
259
+ state.buffer.byteLength
260
+ );
261
+ const primitiveResult = parsePrimitive(dataView, state.buffer, 0, state.isFullProps);
262
+ const primitiveData = primitiveResult.primitive;
263
+
264
+ _applyPrefixId(primitiveData, 'id', null, state.prefixIdKey);
265
+ _applyPrefixId(primitiveData, 'material', null, state.prefixIdKey);
266
+
267
+ if (state.isFullProps) {
268
+ const { position, normal, posindex, nolindex, indices } =
269
+ parsePrimitiveData(primitiveData);
270
+ const formatted = formatPrimitiveData({ position, normal, posindex, nolindex });
271
+ delete primitiveData.nolindex;
272
+ delete primitiveData.posindex;
273
+ primitiveData.position = formatted.position;
274
+ primitiveData.normal = formatted.normal;
275
+ primitiveData.indices = indices;
276
+ }
277
+
278
+ return {
279
+ primitive: primitiveData,
280
+ consumedBytes: primitiveResult.offset,
281
+ };
282
+ }
283
+
203
284
  function parseBufferData(buffer, prefixIdKey) {
204
285
  let uint8Array = null;
205
286
  let dataView = null;
@@ -288,8 +369,20 @@ function parsePrimitive(dataView, uint8Array, offset, isFullProps = true) {
288
369
  if (dataView.byteLength < offset + 12) {
289
370
  throw new Error('Insufficient data for primitive header');
290
371
  }
291
- primitive.id = dataView.getInt32(offset, false);
372
+ const primitiveIdTextLen = dataView.getUint32(offset, false);
292
373
  offset += 4;
374
+ if (primitiveIdTextLen === 0xffffffff) {
375
+ primitive.id = null;
376
+ } else if (primitiveIdTextLen > 0) {
377
+ if (dataView.byteLength < offset + primitiveIdTextLen) {
378
+ throw new Error('Insufficient data for primitive id content');
379
+ }
380
+ const textBytes = uint8Array.subarray(offset, offset + primitiveIdTextLen);
381
+ primitive.id = utf8Decoder.decode(textBytes);
382
+ offset += primitiveIdTextLen;
383
+ } else {
384
+ primitive.id = '';
385
+ }
293
386
 
294
387
  if (dataView.byteLength < offset + 4) {
295
388
  throw new Error('Insufficient data for GeomText length');
@@ -309,11 +402,26 @@ function parsePrimitive(dataView, uint8Array, offset, isFullProps = true) {
309
402
  primitive.documentId = '';
310
403
  }
311
404
 
312
- primitive.material = dataView.getInt32(offset, false);
313
- offset += 4;
314
-
315
- if (dataView.byteLength < offset + 4) {
316
- throw new Error('Insufficient data for GeomText length');
405
+ if (dataView.byteLength < offset + 4) {
406
+ throw new Error('Insufficient data for Material length');
407
+ }
408
+ const materialTextLen = dataView.getUint32(offset, false);
409
+ offset += 4;
410
+ if (materialTextLen === 0xffffffff) {
411
+ primitive.material = null;
412
+ } else if (materialTextLen > 0) {
413
+ if (dataView.byteLength < offset + materialTextLen) {
414
+ throw new Error('Insufficient data for Material content');
415
+ }
416
+ const textBytes = uint8Array.subarray(offset, offset + materialTextLen);
417
+ primitive.material = utf8Decoder.decode(textBytes);
418
+ offset += materialTextLen;
419
+ } else {
420
+ primitive.material = '';
421
+ }
422
+
423
+ if (dataView.byteLength < offset + 4) {
424
+ throw new Error('Insufficient data for GeomText length');
317
425
  }
318
426
  const geomTextLen = dataView.getUint32(offset, false);
319
427
  offset += 4;
@@ -24,8 +24,12 @@ function processMeshData(input, options) {
24
24
  }
25
25
  }
26
26
 
27
+ const identity = new THREE.Matrix4().identity();
28
+ const identityElements = identity.elements;
29
+
27
30
  input.mesh.forEach(meshItem => {
28
31
  const geomList = [];
32
+ const meshMatrix = meshItem.matrix?.length ? meshItem.matrix : identityElements;
29
33
  meshItem.primitives.forEach(primitive => {
30
34
  const primitiveData = input.primitive.find(g => g.id === primitive.prmid);
31
35
  if (primitiveData) {
@@ -34,26 +38,27 @@ function processMeshData(input, options) {
34
38
  const material = mergedMaterial || baseMaterial;
35
39
  const sourceVisible =
36
40
  mergedMaterial?.visible === false || baseMaterial?.visible === false ? false : true;
41
+ const baseColor = [255, 255, 255, 1];
37
42
  const prop = {
38
- color: material?.color || [255, 255, 255, 1],
43
+ color: material?.color
44
+ ? material?.color.length
45
+ ? material.color
46
+ : baseColor
47
+ : baseColor,
39
48
  fontsize: material?.fontsize !== undefined ? material?.fontsize : 20,
40
49
  frontname: material?.frontname !== undefined ? material?.frontname : '',
41
50
  italic: material?.italic,
42
51
  linepacing: 1, // 默认值
43
- linewidth: material?.linewidth !== undefined ? material?.linewidth : 1, // 默认值
52
+ linewidth: material?.linewidth !== undefined ? material?.linewidth : 10, // 默认值
44
53
  visible: sourceVisible,
45
54
  sourceVisible,
46
55
  transparent: material?.transp !== undefined ? material?.transp : 0,
47
56
  };
48
57
 
49
- const identity = new THREE.Matrix4().identity();
50
-
51
58
  geomList.push({
52
59
  matrix: {
53
- val: primitive.matrix?.length ? primitive.matrix : identity.elements,
54
- // val: identity.elements,
60
+ val: primitive.matrix?.length ? primitive.matrix : identityElements,
55
61
  },
56
- // originMatrix: meshItem.id == primitive.prmid ? [] : identity.elements,
57
62
  prmid: primitive.prmid,
58
63
  geomId: primitiveData.id,
59
64
  type: primitiveData.geomType,
@@ -71,6 +76,9 @@ function processMeshData(input, options) {
71
76
 
72
77
  drawObjMap.set(meshItem.id, {
73
78
  drawObjId: meshItem.id,
79
+ matrix: {
80
+ val: meshMatrix,
81
+ },
74
82
  geoms: geomList,
75
83
  // lodLevel: meshItem.type || 2,
76
84
  });
@@ -146,7 +154,7 @@ function processOnePrimtiveToMultiMesh(primitive) {
146
154
  return {
147
155
  instanceId: primitive.drawObjId, // 实例与drawObj一对多关系
148
156
  drawObject: primitive.geoms[0]?.prmid || '',
149
- matrix: primitive.geoms[0]?.matrix || [],
157
+ matrix: primitive.matrix || {},
150
158
  };
151
159
  }
152
160
 
@@ -240,6 +248,8 @@ function parseNode(node, isFlatNode) {
240
248
  // 生成默认node节点
241
249
  function generateNode(mesh) {
242
250
  let nodes = [];
251
+ const identity = new THREE.Matrix4().identity();
252
+ const identityElements = identity.elements;
243
253
  mesh.forEach(item => {
244
254
  if (item.primitives.length) {
245
255
  let tempNode = {
@@ -247,7 +257,9 @@ function generateNode(mesh) {
247
257
  _batchId: item.id,
248
258
  name: item.id,
249
259
  mesh: item.id,
250
- matrix: {},
260
+ matrix: {
261
+ val: item.matrix?.length ? item.matrix : identityElements,
262
+ },
251
263
  nodeType: 3,
252
264
  };
253
265
  nodes.push(tempNode);
@@ -5,7 +5,7 @@ import helvetikerFont from 'three/examples/fonts/helvetiker_regular.typeface.jso
5
5
  import { MeshLineGeometry, MeshLineMaterial } from 'meshline';
6
6
  import StreamLoaderParserWorker from '../../packages/utils/StreamLoaderParser.worker.js';
7
7
 
8
- const GEOM_TYPES = {
8
+ export const GEOM_TYPES = {
9
9
  geom_3d: 53248,
10
10
  geom_3d_text: 53249,
11
11
  geom_3d_mtext: 53250,
@@ -91,15 +91,46 @@ function requestInstancedMapping(instances, drawObjs) {
91
91
  });
92
92
  }
93
93
 
94
- function getInstanceNormalSign(matrix) {
95
- if (!matrix || typeof matrix.determinant !== 'function') return 1;
96
- return matrix.determinant() < 0 ? -1 : 1;
97
- }
98
-
99
- /**
100
- * 重置处理状态,用于新的批量加载会话
101
- */
102
- function resetProcessingState() {
94
+ function getInstanceNormalSign(matrix) {
95
+ if (!matrix || typeof matrix.determinant !== 'function') return 1;
96
+ return matrix.determinant() < 0 ? -1 : 1;
97
+ }
98
+
99
+ function getMatrixVal(matrix) {
100
+ const val = matrix && matrix.val ? matrix.val : matrix;
101
+ return val && val.length >= 16 ? val : null;
102
+ }
103
+
104
+ function composeInstanceMatrix(instance, mesh, geometry) {
105
+ const resultMatrix = new THREE.Matrix4();
106
+ const meshMatrix = new THREE.Matrix4();
107
+ const primitiveMatrix = new THREE.Matrix4();
108
+ const meshMatrixVal = getMatrixVal(instance && instance.matrix);
109
+ const primitiveMatrixVal = getMatrixVal(mesh && mesh.matrix);
110
+
111
+ if (meshMatrixVal) {
112
+ meshMatrix.fromArray(meshMatrixVal);
113
+ }
114
+ if (primitiveMatrixVal) {
115
+ primitiveMatrix.fromArray(primitiveMatrixVal);
116
+ }
117
+
118
+ const { points, alignType } = mesh || {};
119
+ if (mesh && isTextType(mesh.type) && points && points.length >= 3) {
120
+ const positionMatrix = new THREE.Matrix4();
121
+ const alignMatrix = createAlignedText(alignType, geometry);
122
+ positionMatrix.identity().makeTranslation(points[0], points[1], points[2]);
123
+ primitiveMatrix.multiply(alignMatrix).multiply(positionMatrix);
124
+ }
125
+
126
+ resultMatrix.multiplyMatrices(meshMatrix, primitiveMatrix);
127
+ return resultMatrix;
128
+ }
129
+
130
+ /**
131
+ * 重置处理状态,用于新的批量加载会话
132
+ */
133
+ function resetProcessingState() {
103
134
  drawObjMapInstance = {};
104
135
  // instanceToInstancedMeshMap.clear();
105
136
  // processedDrawObjects.clear();
@@ -434,47 +465,27 @@ function setInstanceMatricesAndColors(model, drawObj, mesh, meshName, customColo
434
465
 
435
466
  // const instancedMesh = instanceToInstancedMeshMap.get(item.instanceId);
436
467
 
437
- // 处理矩阵变换
438
- const matrixVal = item.matrix?.val;
439
- if (matrixVal) {
440
- const m4 = new THREE.Matrix4();
441
- const meshMatrix = new THREE.Matrix4();
442
- const geomMatrix = new THREE.Matrix4();
443
-
444
- meshMatrix.fromArray(matrixVal);
445
- geomMatrix.fromArray(new THREE.Matrix4().identity().elements);
446
-
447
- // 处理文本居中对齐
448
- const { points, alignType } = mesh;
449
- if (isTextType(mesh.type)) {
450
- const positionMatrix = new THREE.Matrix4();
451
- const alignMatrix = createAlignedText(alignType, model.geometry);
452
- positionMatrix.identity().makeTranslation(points[0], points[1], points[2]);
453
- geomMatrix.multiply(alignMatrix).multiply(positionMatrix);
454
- }
455
-
456
- m4.multiplyMatrices(meshMatrix, geomMatrix);
457
- model.setMatrixAt(index, m4);
458
-
459
- const normalSignAttr = model.geometry && model.geometry.getAttribute('instanceNormalSign');
460
- if (normalSignAttr && normalSignAttr.array && index < normalSignAttr.array.length) {
461
- normalSignAttr.array[index] = getInstanceNormalSign(m4);
462
- }
463
-
464
- const copyMatrix = new THREE.Matrix4().copy(m4);
465
- model.userData.copyMatrix = copyMatrix;
466
-
467
- const temp = model.userData.instancesMap.get(item.instanceId);
468
- temp.copyMatrix = copyMatrix;
469
- if (sourceVisible === false) {
470
- const offsetMatrix = new THREE.Matrix4()
471
- .copy(copyMatrix)
472
- .makeTranslation(9999999, 9999999, 9999999);
473
- model.setMatrixAt(index, offsetMatrix);
474
- }
475
- }
476
-
477
- // 设置颜色
468
+ const m4 = composeInstanceMatrix(item, mesh, model.geometry);
469
+ model.setMatrixAt(index, m4);
470
+
471
+ const normalSignAttr = model.geometry && model.geometry.getAttribute('instanceNormalSign');
472
+ if (normalSignAttr && normalSignAttr.array && index < normalSignAttr.array.length) {
473
+ normalSignAttr.array[index] = getInstanceNormalSign(m4);
474
+ }
475
+
476
+ const copyMatrix = new THREE.Matrix4().copy(m4);
477
+ model.userData.copyMatrix = copyMatrix;
478
+
479
+ const temp = model.userData.instancesMap.get(item.instanceId);
480
+ temp.copyMatrix = copyMatrix;
481
+ if (sourceVisible === false) {
482
+ const offsetMatrix = new THREE.Matrix4()
483
+ .copy(copyMatrix)
484
+ .makeTranslation(9999999, 9999999, 9999999);
485
+ model.setMatrixAt(index, offsetMatrix);
486
+ }
487
+
488
+ // 设置颜色
478
489
  model.setColorAt(index, meshColor);
479
490
  });
480
491
 
@@ -549,25 +560,9 @@ function appendInstanceToInstancedMesh(model, drawObj, mesh, instance, customCol
549
560
  ? new THREE.Color(customColor)
550
561
  : new THREE.Color(`rgb(${colorArr[0]}, ${colorArr[1]}, ${colorArr[2]})`);
551
562
 
552
- const matrixVal = instance.matrix?.val;
553
- if (!matrixVal || !mesh || !mesh.matrix || !mesh.matrix.val) return;
554
-
555
- const m4 = new THREE.Matrix4();
556
- const meshMatrix = new THREE.Matrix4();
557
- const geomMatrix = new THREE.Matrix4();
558
-
559
- meshMatrix.fromArray(instance.matrix.val);
560
- geomMatrix.fromArray(new THREE.Matrix4().identity().elements);
561
-
562
- const { points, alignType } = mesh;
563
- if (isTextType(mesh.type)) {
564
- const positionMatrix = new THREE.Matrix4();
565
- const alignMatrix = createAlignedText(alignType, model.geometry);
566
- positionMatrix.identity().makeTranslation(points[0], points[1], points[2]);
567
- geomMatrix.multiply(alignMatrix).multiply(positionMatrix);
568
- }
569
-
570
- m4.multiplyMatrices(meshMatrix, geomMatrix);
563
+ if (!mesh) return;
564
+
565
+ const m4 = composeInstanceMatrix(instance, mesh, model.geometry);
571
566
  const renderMatrix =
572
567
  sourceVisible === false
573
568
  ? new THREE.Matrix4().copy(m4).makeTranslation(9999999, 9999999, 9999999)
@@ -679,7 +674,7 @@ function drawModel(geom, instanceName, instanceCount, nColor, nOpacity, options
679
674
  let model;
680
675
  // 处理二维几何体(普通2D图形和特殊2D图形)
681
676
  if (geom.type == GEOM_TYPES.geom_2d || geom.type == GEOM_TYPES.geom_2d_others) {
682
- model = draw2Dmodel(geom, instanceName, instanceCount, options); // TODO 该类型调试中
677
+ model = draw2Dmodel(geom, instanceName, instanceCount, nColor, nOpacity, options); // TODO 该类型调试中
683
678
  // 处理二维文本类型
684
679
  } else if (isTextType(geom.type)) {
685
680
  model = drawText(geom, instanceName, instanceCount, options);
@@ -690,7 +685,7 @@ function drawModel(geom, instanceName, instanceCount, nColor, nOpacity, options
690
685
  geom.type == GEOM_TYPES.geom_2d_ellipse ||
691
686
  geom.type == GEOM_TYPES.geom_2d_ellipseArc
692
687
  ) {
693
- model = drawCurves(geom, instanceName, instanceCount, options); // TODO 该类型调试中
688
+ model = drawCurves(geom, instanceName, instanceCount, nColor, nOpacity, options); // TODO 该类型调试中
694
689
  // 处理三维几何体(普通3D模型和OBJ模型)
695
690
  } else if (geom.type == GEOM_TYPES.geom_3d || geom.type == GEOM_TYPES.geom_3d_obj) {
696
691
  model = draw3Dmodel(geom, instanceName, instanceCount, nColor, nOpacity, options);
@@ -719,7 +714,7 @@ function isTextType(type) {
719
714
  * @param {String} instanceName- 曲线实例的名称
720
715
  * @return {Object}- 包含曲线模型和曲线信息的对象
721
716
  */
722
- function drawCurves(geom, instanceName, instanceCount, options = {}) {
717
+ function drawCurves(geom, instanceName, instanceCount, nColor, nOpacity, options = {}) {
723
718
  let { points, normals } = geom;
724
719
  let aX = points[0];
725
720
  let aY = points[1];
@@ -760,6 +755,8 @@ function drawCurves(geom, instanceName, instanceCount, options = {}) {
760
755
  },
761
756
  instanceName,
762
757
  instanceCount,
758
+ nColor,
759
+ nOpacity,
763
760
  options
764
761
  );
765
762
  // model.rotation.x = -Math.PI / 2;
@@ -943,7 +940,8 @@ function draw3Dmodel(
943
940
  // 处理transparent透明度
944
941
  opacity = 1 - transparent;
945
942
 
946
- const finalOpacity = nOpacity !== '' ? nOpacity : opacity;
943
+ const finalOpacity =
944
+ nOpacity !== undefined && nOpacity !== null && nOpacity !== '' ? nOpacity : opacity;
947
945
 
948
946
  // 判断是否全透明
949
947
  const isTransparent = finalOpacity < 1.0;
@@ -1070,7 +1068,7 @@ function draw3Dmodel(
1070
1068
  * @param {String} instanceName - 模型实例的名称
1071
1069
  * @returns {Object} - 包含所有 2D 模型的组对象
1072
1070
  */
1073
- function draw2Dmodel(geom, instanceName, instanceCount, options = {}) {
1071
+ function draw2Dmodel(geom, instanceName, instanceCount, nColor, nOpacity, options = {}) {
1074
1072
  const points = geom.points;
1075
1073
  const normals = geom.normals;
1076
1074
  const geometry = new THREE.BufferGeometry();
@@ -1103,6 +1101,8 @@ function draw2Dmodel(geom, instanceName, instanceCount, options = {}) {
1103
1101
  },
1104
1102
  instanceName,
1105
1103
  instanceCount,
1104
+ nColor,
1105
+ nOpacity,
1106
1106
  options
1107
1107
  );
1108
1108
  // mesh.raycast = raycast;