1 | import { unpack, cross, applyMatrix, expand, distance } from './helpers'
|
2 |
|
3 |
|
4 |
|
5 | self.addEventListener(
|
6 | 'message',
|
7 | message => {
|
8 |
|
9 |
|
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 |
|
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 |
|
150 |
|
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 |
|
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 |
|
420 |
|
421 | self.postMessage({
|
422 | action: 'Finished',
|
423 | task: task,
|
424 | })
|
425 | },
|
426 | false,
|
427 | )
|