UNPKG

19.9 kBJavaScriptView Raw
1import { unpack, cross, applyMatrix, expand, distance } from './helpers'
2
3//let request = 0
4
5self.addEventListener(
6 'message',
7 message => {
8
9 //request++
10
11 message = message.data
12 if (typeof message !== 'object') message = JSON.parse(message)
13
14 if (message.command === 'Materials') {
15 console.log('received materials')
16 return
17 }
18
19 //console.time(`${message.parent}_${request}_parse`)
20 if (message.command === 'Blob' && (message.type === 'Binary' || message.type === 'Base64')) {
21 delete message.type
22 unpack(message)
23 if (Array.isArray(message.data)) message.data = message.data[0]
24 }
25
26 let { data, task, options } = message
27 for (let container of data.containers) {
28 let { id, owner, properties, meshes = [], lines = [], arcs = [], edges = [] } = container
29 let material = properties.material,
30 transfer = [],
31 group,
32 points,
33 x,
34 y,
35 z,
36 color,
37 opacity
38
39 if (lines.length > 0 || arcs.length > 0 || edges.length > 0) {
40 let line,
41 count = 0,
42 segments = 64
43 let result = (container.line = {
44 groups: [],
45 })
46
47 let mergedLines = lines.reduce((prev, next) => prev + next.points.length, 0)
48 let mergedEdges = edges.reduce((prev, next) => prev + (next.points.length / 3 - 1) * 6, 0)
49 let mergedArcs = arcs.reduce((prev, next) => prev + segments * 6, 0)
50 result.vertices = new Float32Array(mergedLines + mergedEdges + mergedArcs)
51 transfer.push(result.vertices.buffer)
52 result.distances = new Float32Array((mergedLines + mergedEdges + mergedArcs) / 3)
53 transfer.push(result.distances.buffer)
54
55 let firstVec, lastVec
56 mergedLines = 0
57 for (let index = 0, length = lines.length; index < length; index++) {
58 line = lines[index]
59 points = line.points
60
61 if (options.materials.multi) {
62 line.properties = {
63 material: {},
64 ...line.properties,
65 }
66 color = line.properties.material.color || material.color || [0, 0, 0]
67 color = [color[0] / 255, color[1] / 255, color[2] / 255]
68 opacity = line.properties.material.opacity ? line.properties.material.opacity : material.opacity
69 opacity = typeof opacity !== 'undefined' ? opacity : 0
70
71 group = {
72 start: mergedLines,
73 count: points.length,
74 index: result.groups.length,
75 meta: {
76 id: line.id,
77 container: id,
78 owner: owner,
79 layer: line.properties.layer || properties.layer,
80 ...line.meta,
81 type: 'line',
82 start: [points[0], points[1], points[2]],
83 end: [points[points.length - 3], points[points.length - 2], points[points.length - 1]],
84 min: [+Infinity, +Infinity, +Infinity],
85 max: [-Infinity, -Infinity, -Infinity],
86 material: { color, opacity },
87 },
88 }
89
90 if (typeof material.type !== 'undefined') group.meta.material.type = material.type
91 if (typeof material.linetype !== 'undefined') group.meta.material.linetype = material.linetype
92 result.groups.push(group)
93 }
94
95 for (let i = 0, l = points.length / 6; i < l; i++) {
96 mergedLines += 6
97
98 firstVec = [points[i * 6 + 0], points[i * 6 + 1], points[i * 6 + 2]]
99 result.vertices[count++] = firstVec[0]
100 result.vertices[count++] = firstVec[1]
101 result.vertices[count++] = firstVec[2]
102 options.materials.multi && expand(group.meta.min, group.meta.max, firstVec)
103
104 lastVec = [points[i * 6 + 3], points[i * 6 + 4], points[i * 6 + 5]]
105 result.vertices[count++] = lastVec[0]
106 result.vertices[count++] = lastVec[1]
107 result.vertices[count++] = lastVec[2]
108 options.materials.multi && expand(group.meta.min, group.meta.max, lastVec)
109 }
110 }
111
112 for (let index = 0, length = edges.length; index < length; index++) {
113 line = edges[index]
114 points = line.points
115
116 if (options.materials.multi) {
117 line.properties = {
118 material: {},
119 ...line.properties,
120 }
121 color = line.properties.material.color || material.color || [0, 0, 0]
122 color = [color[0] / 255, color[1] / 255, color[2] / 255]
123 opacity = line.properties.material.opacity ? line.properties.material.opacity : material.opacity
124 opacity = typeof opacity !== 'undefined' ? opacity : 0
125
126 group = {
127 start: mergedLines,
128 count: (points.length / 3 - 1) * 6,
129 index: result.groups.length,
130 meta: {
131 id: line.id,
132 container: id,
133 owner: owner,
134 layer: line.properties.layer || properties.layer,
135 ...line.meta,
136 type: 'line',
137 start: [points[0], points[1], points[2]],
138 end: [points[points.length - 3], points[points.length - 2], points[points.length - 1]],
139 min: [+Infinity, +Infinity, +Infinity],
140 max: [-Infinity, -Infinity, -Infinity],
141 material: { color, opacity },
142 },
143 }
144 if (typeof material.type !== 'undefined') group.meta.material.type = material.type
145 if (typeof material.linetype !== 'undefined') group.meta.material.linetype = material.linetype
146 result.groups.push(group)
147 }
148
149 // Edges are line-strips, a list of points consisting of 3 floats each, [x, y, z]
150 // In order to convert them to regular lines each endpoint will act as the next start-point
151 for (let i = 1, l = points.length / 3; i < l; i++) {
152 mergedLines += 6
153
154 firstVec = [points[i * 3 - 3], points[i * 3 - 2], points[i * 3 - 1]]
155 result.vertices[count++] = firstVec[0]
156 result.vertices[count++] = firstVec[1]
157 result.vertices[count++] = firstVec[2]
158 options.materials.multi && expand(group.meta.min, group.meta.max, firstVec)
159
160 lastVec = [points[i * 3 + 0], points[i * 3 + 1], points[i * 3 + 2]]
161 result.vertices[count++] = lastVec[0]
162 result.vertices[count++] = lastVec[1]
163 result.vertices[count++] = lastVec[2]
164 options.materials.multi && expand(group.meta.min, group.meta.max, lastVec)
165 }
166 }
167
168 let radius, thetaStart, thetaLength, center, zAxis, xAxis, yAxis, scalar, invScalar, segment, start
169 for (let index = 0, length = arcs.length; index < length; index++) {
170 line = arcs[index]
171 radius = line.radius
172 thetaStart = 0
173 thetaLength = Math.abs(Math.abs(line.angle) - Math.PI) < 0.000001 ? Math.PI * 2 : line.angle
174 center = line.center
175 zAxis = line.zAxis
176 xAxis = line.xAxis
177 yAxis = line.zAxis
178 ;[x, y, z] = yAxis
179 yAxis[0] = y * xAxis[2] - z * xAxis[1]
180 yAxis[1] = z * xAxis[0] - x * xAxis[2]
181 yAxis[2] = x * xAxis[1] - y * xAxis[0]
182 scalar = Math.sqrt(yAxis[0] * yAxis[0] + yAxis[1] * yAxis[1] + yAxis[2] * yAxis[2])
183
184 if (scalar !== 0) {
185 invScalar = 1 / scalar
186 yAxis[0] *= invScalar
187 yAxis[1] *= invScalar
188 yAxis[2] *= invScalar
189 } else {
190 yAxis[0] = yAxis[1] = yAxis[2] = 0
191 }
192
193 let matrix = [
194 xAxis[0],
195 xAxis[1],
196 xAxis[2],
197 0,
198 yAxis[0],
199 yAxis[1],
200 yAxis[2],
201 0,
202 zAxis[0],
203 zAxis[1],
204 zAxis[2],
205 0,
206 center[0],
207 center[1],
208 center[2],
209 1,
210 ]
211
212 segment = thetaStart / segments * thetaLength
213 lastVec = [radius * Math.cos(segment), radius * Math.sin(segment), 0]
214 applyMatrix(lastVec, matrix)
215
216 if (options.materials.multi) {
217 line.properties = {
218 material: {},
219 ...line.properties,
220 }
221 color = line.properties.material.color || material.color || [0, 0, 0]
222 color = [color[0] / 255, color[1] / 255, color[2] / 255]
223 opacity = line.properties.material.opacity ? line.properties.material.opacity : material.opacity
224 opacity = typeof opacity !== 'undefined' ? opacity : 0
225
226 group = {
227 start: mergedLines,
228 count: segments * 6,
229 index: result.groups.length,
230 meta: {
231 ...line.meta,
232 id: line.id,
233 container: id,
234 owner: owner,
235 layer: line.properties.layer || properties.layer,
236 type: 'arc',
237 circle: line.isCircle,
238 angle: line.angle,
239 start: lastVec,
240 radius,
241 thetaStart,
242 thetaLength,
243 center,
244 zAxis,
245 xAxis,
246 yAxis,
247 min: [+Infinity, +Infinity, +Infinity],
248 max: [-Infinity, -Infinity, -Infinity],
249 material: { color, opacity },
250 },
251 }
252 if (typeof material.type !== 'undefined') group.meta.material.type = material.type
253 if (typeof material.linetype !== 'undefined') group.meta.material.linetype = material.linetype
254 result.groups.push(group)
255 expand(group.meta.min, group.meta.max, lastVec)
256 }
257
258 for (let i = 1; i <= segments; i++) {
259 mergedLines += 6
260
261 firstVec = [lastVec[0], lastVec[1], lastVec[2]]
262 result.vertices[count++] = firstVec[0]
263 result.vertices[count++] = firstVec[1]
264 result.vertices[count++] = firstVec[2]
265 options.materials.multi && expand(group.meta.min, group.meta.max, firstVec)
266
267 segment = thetaStart + i / segments * thetaLength
268 lastVec = [radius * Math.cos(segment), radius * Math.sin(segment), 0]
269 applyMatrix(lastVec, matrix)
270 result.vertices[count++] = lastVec[0]
271 result.vertices[count++] = lastVec[1]
272 result.vertices[count++] = lastVec[2]
273 options.materials.multi && expand(group.meta.min, group.meta.max, lastVec)
274 }
275 }
276
277 let d = 0,
278 c = 0
279 let vertices = result.vertices
280 for (var i = 0, il = vertices.length / 3; i < il; i++) {
281 if (i > 0) {
282 d += distance(
283 [result.vertices[i * 3 + 0], result.vertices[i * 3 + 1], result.vertices[i * 3 + 2]],
284 [
285 result.vertices[(i - 1) * 3 + 0],
286 result.vertices[(i - 1) * 3 + 1],
287 result.vertices[(i - 1) * 3 + 2],
288 ],
289 )
290 }
291 result.distances[c++] = d
292 }
293
294 delete container.lines
295 }
296
297 if (meshes.length > 0) {
298 let mesh,
299 mergedVertices = 0,
300 mergedIndices = 0,
301 mergedUvs = 0,
302 mergedNormals = 0
303 let result = (container.mesh = {
304 groups: [],
305 })
306
307 for (let index = 0, l = meshes.length; index < l; index++) {
308 mesh = meshes[index]
309 mergedVertices += mesh.vertices.length
310 mergedIndices += mesh.indices.length
311 if (!!mesh.uvs) mergedUvs += mesh.uvs.length
312 if (!!mesh.normals) mergedNormals += mesh.normals.length
313 }
314
315 // Merge meshes that aren't individual
316 if (mergedVertices > 0) {
317 result.vertices = new Float32Array(mergedVertices)
318 transfer.push(result.vertices.buffer)
319
320 result.indices = new Uint32Array(mergedIndices)
321 transfer.push(result.indices.buffer)
322
323 if (mergedUvs > 0) {
324 result.uvs = new Float32Array(mergedUvs)
325 transfer.push(result.uvs.buffer)
326 }
327
328 if (mergedNormals > 0) {
329 result.normals = new Float32Array(mergedNormals)
330 transfer.push(result.normals.buffer)
331 }
332
333 mergedVertices = 0
334 mergedIndices = 0
335 mergedUvs = 0
336 mergedNormals = 0
337 let offset = 0,
338 indexCount = 0
339 for (let i = 0; i < meshes.length; i++) {
340 mesh = meshes[i]
341 if (options.materials.multi) {
342 mesh.properties = {
343 material: {},
344 surface: {},
345 ...mesh.properties,
346 }
347 color = mesh.properties.material.color || material.color || [0, 0, 0]
348 color = [color[0] / 255, color[1] / 255, color[2] / 255]
349 opacity = mesh.properties.material.opacity
350 ? mesh.properties.material.opacity
351 : material.opacity
352 opacity = typeof opacity !== 'undefined' ? opacity : 0
353
354 group = {
355 start: indexCount,
356 count: mesh.indices.length,
357 index: result.groups.length,
358 meta: {
359 ...mesh.meta,
360 id: mesh.id,
361 container: id,
362 owner: owner,
363 operationId: mesh.properties.operationId,
364 layer: mesh.properties.layer || properties.layer,
365 type: mesh.properties.surface.type,
366 ...mesh.properties.surface,
367 min: [+Infinity, +Infinity, +Infinity],
368 max: [-Infinity, -Infinity, -Infinity],
369 material: { color, opacity },
370 },
371 }
372 result.groups.push(group)
373 indexCount += mesh.indices.length
374 }
375
376 for (let vindex = 0, vlen = mesh.vertices.length / 3; vindex < vlen; vindex++) {
377 x = mesh.vertices[vindex * 3 + 0]
378 y = mesh.vertices[vindex * 3 + 1]
379 z = mesh.vertices[vindex * 3 + 2]
380 options.materials.multi && expand(group.meta.min, group.meta.max, [x, y, z])
381 result.vertices[mergedVertices++] = x
382 result.vertices[mergedVertices++] = y
383 result.vertices[mergedVertices++] = z
384 }
385
386 for (let findex = 0, flen = mesh.indices.length; findex < flen; findex++) {
387 result.indices[mergedIndices++] = mesh.indices[findex] + offset
388 }
389
390 if (!!mesh.uvs) {
391 for (let uvindex = 0, uvlen = mesh.uvs.length; uvindex < uvlen; uvindex++) {
392 result.uvs[mergedUvs++] = mesh.uvs[uvindex]
393 }
394 }
395
396 if (!!mesh.normals) {
397 for (let nindex = 0, nlen = mesh.normals.length; nindex < nlen; nindex++) {
398 result.normals[mergedNormals++] = mesh.normals[nindex]
399 }
400 }
401
402 offset += mesh.vertices.length / 3
403 }
404 }
405
406 delete container.meshes
407 }
408
409 self.postMessage(
410 {
411 action: 'Result',
412 result: container,
413 task: task,
414 },
415 transfer,
416 )
417 }
418
419 //console.timeEnd(`${message.parent}_${request}_parse`)
420
421 self.postMessage({
422 action: 'Finished',
423 task: task,
424 })
425 },
426 false,
427)