@eturnity/eturnity_3d 0.0.4

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.
Files changed (78) hide show
  1. package/.babelrc +3 -0
  2. package/.env +0 -0
  3. package/.eslintrc +18 -0
  4. package/.eslintrc.json +18 -0
  5. package/.prettierrc +7 -0
  6. package/Dockerfile +17 -0
  7. package/README.md +18 -0
  8. package/bitbucket-pipelines.yml +681 -0
  9. package/dist/assets/images/panels/longiSolarLR4_60HPH_350M.png +0 -0
  10. package/dist/assets/images/panels/longiSolarLR4_60HPH_370M.png +0 -0
  11. package/dist/assets/images/panels/reneSola_Virtus_2_JC320S_24_Bbw copy.png +0 -0
  12. package/dist/assets/images/panels/reneSola_Virtus_2_JC320S_24_Bbw.png +0 -0
  13. package/dist/assets/images/panels/uv.png +0 -0
  14. package/dist/assets/panels/longiSolarLR4_60HPH_350M.png +0 -0
  15. package/dist/assets/panels/longiSolarLR4_60HPH_370M.png +0 -0
  16. package/dist/assets/panels/reneSola_Virtus_2_JC320S_24_Bbw.png +0 -0
  17. package/dist/assets/panels/uv.png +0 -0
  18. package/dist/assets/theme.js +43 -0
  19. package/dist/assets/vue.svg +1 -0
  20. package/dist/css/main.1f8fe45d.css +1 -0
  21. package/dist/img/longiSolarLR4_60HPH_350M.85a84b2e.png +0 -0
  22. package/dist/img/longiSolarLR4_60HPH_370M.bf6b1f4e.png +0 -0
  23. package/dist/img/reneSola_Virtus_2_JC320S_24_Bbw.8b1892e0.png +0 -0
  24. package/dist/index.html +26 -0
  25. package/dist/main.js +60230 -0
  26. package/dist/main.js.map +1 -0
  27. package/dist/vite.svg +1 -0
  28. package/docker_conf/nginx/nginx.conf +16 -0
  29. package/index.html +26 -0
  30. package/package.json +71 -0
  31. package/postcss.config.js +1 -0
  32. package/preview.html +55 -0
  33. package/public/assets/images/panels/longiSolarLR4_60HPH_350M.png +0 -0
  34. package/public/assets/images/panels/longiSolarLR4_60HPH_370M.png +0 -0
  35. package/public/assets/images/panels/reneSola_Virtus_2_JC320S_24_Bbw copy.png +0 -0
  36. package/public/assets/images/panels/reneSola_Virtus_2_JC320S_24_Bbw.png +0 -0
  37. package/public/assets/images/panels/uv.png +0 -0
  38. package/public/assets/panels/longiSolarLR4_60HPH_350M.png +0 -0
  39. package/public/assets/panels/longiSolarLR4_60HPH_370M.png +0 -0
  40. package/public/assets/panels/reneSola_Virtus_2_JC320S_24_Bbw.png +0 -0
  41. package/public/assets/panels/uv.png +0 -0
  42. package/public/assets/theme.js +43 -0
  43. package/public/assets/vue.svg +1 -0
  44. package/public/vite.svg +1 -0
  45. package/server.js +17 -0
  46. package/src/App.vue +28 -0
  47. package/src/assets/images/panels/longiSolarLR4_60HPH_350M.png +0 -0
  48. package/src/assets/images/panels/longiSolarLR4_60HPH_370M.png +0 -0
  49. package/src/assets/images/panels/reneSola_Virtus_2_JC320S_24_Bbw copy.png +0 -0
  50. package/src/assets/images/panels/reneSola_Virtus_2_JC320S_24_Bbw.png +0 -0
  51. package/src/assets/images/panels/uv.png +0 -0
  52. package/src/assets/images/white_tile.png +0 -0
  53. package/src/assets/theme.js +43 -0
  54. package/src/components/ThreeCanvasViewer.vue +247 -0
  55. package/src/config.js +104 -0
  56. package/src/functions.js +2 -0
  57. package/src/helper/DFS.js +80 -0
  58. package/src/helper/MapView.js +253 -0
  59. package/src/helper/UpdateRoofModuleFieldRelations.js +119 -0
  60. package/src/helper/UpdateRoofObstacleRelations.js +86 -0
  61. package/src/helper/clearThreeObjects.js +21 -0
  62. package/src/helper/customProvider.js +57 -0
  63. package/src/helper/geometryHandler.js +606 -0
  64. package/src/helper/graphCreation.js +43 -0
  65. package/src/helper/materials.js +55 -0
  66. package/src/helper/projectedMaterial.js +502 -0
  67. package/src/helper/renderMixin.js +1132 -0
  68. package/src/helper/threeMixin.js +171 -0
  69. package/src/main.js +28 -0
  70. package/src/store/AddMargin.js +107 -0
  71. package/src/store/hydrateData.js +209 -0
  72. package/src/store/nodesEdgesCreation.js +216 -0
  73. package/src/store/store.js +10 -0
  74. package/src/store/three-d-module.js +142 -0
  75. package/src/style.css +96 -0
  76. package/src/utils/layers.js +265 -0
  77. package/src/utils/leaflet-config.service.js +67 -0
  78. package/vue.config.js +46 -0
@@ -0,0 +1,606 @@
1
+ import * as THREE from 'three'
2
+ import { defaultBaseHeight } from '../config'
3
+ import earcut from 'earcut'
4
+ import {
5
+ verticalProjectionOnPlane,
6
+ addVector,
7
+ multiplyVector,
8
+ getNormalVectorFrom3Points,
9
+ hasNaN,
10
+ getDistanceBetweenPoints,
11
+ intersectOutlines
12
+ } from '@eturnity/eturnity_maths'
13
+
14
+ export function getTriangleVerticesFromOutline(
15
+ polygonOutline,
16
+ holesOutlines = []
17
+ ) {
18
+ if(polygonOutline.length==0){
19
+ return new Float32Array([])
20
+ }
21
+ var dataVertices = polygonOutline
22
+ .map((p) => {
23
+ return [p.x / 1000, p.y / 1000, p.z / 1000]
24
+ })
25
+ .flat()
26
+ let holesStartingIndexes = []
27
+ let holesVertices=[]
28
+ //we group building and wall vertices and give the starting index of each obstacles.
29
+ if (holesOutlines.length > 0) {
30
+ const HoleIndexOffset = (dataVertices.length / 3)+1
31
+ holesStartingIndexes.push(HoleIndexOffset)
32
+ let lastIndex=HoleIndexOffset
33
+ for(let k=0;k<holesOutlines.length-1;k++){
34
+ let newIndex=lastIndex+(holesOutlines[k].length)
35
+ holesStartingIndexes.push(newIndex)
36
+ lastIndex=newIndex
37
+ }
38
+ holesStartingIndexes=[...new Set(holesStartingIndexes)]
39
+ holesVertices = holesOutlines
40
+ .map((holeOutline) => {
41
+ return holeOutline.map((p) => {
42
+ return [p.x / 1000, p.y / 1000, p.z / 1000]
43
+ })
44
+ })
45
+ .flat().flat()
46
+ }
47
+ let lastPoint = polygonOutline[polygonOutline.length - 1]
48
+ let lastVertex = [lastPoint.x / 1000, lastPoint.y / 1000, lastPoint.z / 1000]
49
+ dataVertices.push(...lastVertex)
50
+ dataVertices.push(...holesVertices)
51
+
52
+ var triangles = []
53
+ try{
54
+ triangles=earcut(dataVertices, holesStartingIndexes, 3)
55
+ }catch(err){
56
+ console.error(err)
57
+ }
58
+ const triangleVertices = []
59
+ triangles.forEach((index) => {
60
+ triangleVertices.push(
61
+ dataVertices[3 * index],
62
+ dataVertices[3 * index + 1],
63
+ dataVertices[3 * index + 2]
64
+ )
65
+ })
66
+ return triangleVertices
67
+ }
68
+ export function updateBufferRoofGeometry(polygonOutline,holesOutline=[],geometry) {
69
+ //Calcul of triangles using cutear algo
70
+ const triangleVertices = getTriangleVerticesFromOutline(polygonOutline,holesOutline)
71
+ if(hasNaN(triangleVertices)){return null}
72
+ const vertices = new Float32Array(triangleVertices)
73
+ // itemSize = 3 because there are 3 values (components) per vertex
74
+ if(geometry.attributes.position && geometry.attributes.position.array.length>=vertices.length){
75
+ let positions=geometry.attributes.position.array
76
+ for(let k in vertices){
77
+ positions[k]=vertices[k]
78
+ }
79
+
80
+ }else{
81
+ geometry.dispose()
82
+ geometry=null
83
+ geometry = new THREE.BufferGeometry()
84
+ geometry.setAttribute( 'position', new THREE.BufferAttribute( vertices, 3 ) );
85
+ }
86
+ geometry.setDrawRange( 0, vertices.length/3 );
87
+ geometry.computeVertexNormals()
88
+ geometry.attributes.position.needsUpdate = true;
89
+ return geometry
90
+ }
91
+
92
+ export function getBufferRoofGeometry(polygonOutline,holesOutline=[]) {
93
+ const geometry = new THREE.BufferGeometry()
94
+ //Calcul of triangles using cutear algo
95
+ const triangleVertices = getTriangleVerticesFromOutline(polygonOutline,holesOutline)
96
+ if(hasNaN(triangleVertices)){return null}
97
+ const vertices = new Float32Array(triangleVertices)
98
+ // itemSize = 3 because there are 3 values (components) per vertex
99
+ geometry.setAttribute('position', new THREE.BufferAttribute(vertices, 3))
100
+ geometry.computeVertexNormals()
101
+ return geometry
102
+ }
103
+
104
+
105
+
106
+ export function getWallVertices(polygon){
107
+ const length = polygon.outline.length
108
+ const trianglesVertices = []
109
+ polygon.outline.forEach((p_up_0, index) => {
110
+ const p_up_1 = polygon.outline[(index + 1) % length]
111
+ const p_bottom_0 = { ...p_up_0, z: 0 }
112
+ const p_bottom_1 = { ...p_up_1, z: 0 }
113
+
114
+ trianglesVertices.push(
115
+ ...[
116
+ p_up_0.x / 1000,
117
+ p_up_0.y / 1000,
118
+ p_up_0.z / 1000,
119
+ p_up_1.x / 1000,
120
+ p_up_1.y / 1000,
121
+ p_up_1.z / 1000,
122
+ p_bottom_0.x / 1000,
123
+ p_bottom_0.y / 1000,
124
+ p_bottom_0.z / 1000,
125
+ p_up_1.x / 1000,
126
+ p_up_1.y / 1000,
127
+ p_up_1.z / 1000,
128
+ p_bottom_0.x / 1000,
129
+ p_bottom_0.y / 1000,
130
+ p_bottom_0.z / 1000,
131
+ p_bottom_1.x / 1000,
132
+ p_bottom_1.y / 1000,
133
+ p_bottom_1.z / 1000
134
+ ]
135
+ )
136
+ })
137
+
138
+ polygon.holes.forEach((hole)=>{
139
+ let obstacleWallOutline=intersectOutlines(hole.outline, polygon.outline)[0]||[]
140
+ obstacleWallOutline=obstacleWallOutline.map(p=>{
141
+ return {
142
+ ...p,
143
+ z:verticalProjectionOnPlane(p,polygon.normalVector,polygon.flatOutline[0]).z
144
+ }
145
+ })
146
+ const lengthHole = obstacleWallOutline.length
147
+ obstacleWallOutline.forEach((p_up_0, index) => {
148
+ const p_up_1 = obstacleWallOutline[(index + 1) % lengthHole]
149
+ const p_bottom_0 = { ...p_up_0, z: 0 }
150
+ const p_bottom_1 = { ...p_up_1, z: 0 }
151
+
152
+ trianglesVertices.push(
153
+ ...[
154
+ p_up_0.x / 1000,
155
+ p_up_0.y / 1000,
156
+ p_up_0.z / 1000,
157
+ p_up_1.x / 1000,
158
+ p_up_1.y / 1000,
159
+ p_up_1.z / 1000,
160
+ p_bottom_0.x / 1000,
161
+ p_bottom_0.y / 1000,
162
+ p_bottom_0.z / 1000,
163
+ p_up_1.x / 1000,
164
+ p_up_1.y / 1000,
165
+ p_up_1.z / 1000,
166
+ p_bottom_0.x / 1000,
167
+ p_bottom_0.y / 1000,
168
+ p_bottom_0.z / 1000,
169
+ p_bottom_1.x / 1000,
170
+ p_bottom_1.y / 1000,
171
+ p_bottom_1.z / 1000
172
+ ]
173
+ )
174
+ })
175
+ })
176
+ if(hasNaN(trianglesVertices)){return null}
177
+ const vertices = new Float32Array(trianglesVertices)
178
+ return vertices
179
+ }
180
+ export function updateBufferWallGeometry(polygon,geometry) {
181
+ //geometry = new THREE.BufferGeometry()
182
+ //Calcul of triangles using cutear algo
183
+ const vertices=getWallVertices(polygon)
184
+ // itemSize = 3 because there are 3 values (components) per vertex
185
+
186
+ if(geometry.attributes.position && geometry.attributes.position.array.length>=vertices.length){
187
+ let positions=geometry.attributes.position.array
188
+ for(let k in vertices){
189
+ positions[k]=vertices[k]
190
+ }
191
+ geometry.setDrawRange( 0, vertices.length/3 );
192
+ }else{
193
+ geometry.dispose()
194
+ geometry=null
195
+ geometry = new THREE.BufferGeometry()
196
+ geometry.setAttribute( 'position', new THREE.BufferAttribute( vertices, 3 ) );
197
+ }
198
+ geometry.computeVertexNormals()
199
+ geometry.attributes.position.needsUpdate = true;
200
+ return geometry
201
+ }
202
+
203
+ export function getBufferWallGeometry(polygon) {
204
+ const geometry = new THREE.BufferGeometry()
205
+ //Calcul of triangles using cutear algo
206
+ const vertices=getWallVertices(polygon)
207
+ // itemSize = 3 because there are 3 values (components) per vertex
208
+ geometry.setAttribute('position', new THREE.BufferAttribute(vertices, 3))
209
+ geometry.computeVertexNormals()
210
+
211
+ return geometry
212
+ }
213
+
214
+ export function getBufferObstacleGeometry(obstaclePolygon, roofPolygon) {
215
+ let obstacleHeight
216
+ if(obstaclePolygon.isParallel){
217
+ obstacleHeight = parseInt(obstaclePolygon.height || 0)
218
+ }else{
219
+ obstacleHeight = parseInt(obstaclePolygon.heightReference + obstaclePolygon.height || 0)
220
+ }
221
+
222
+ //get lowest verticalProjection
223
+ const normalVector = roofPolygon.normalVector
224
+ const passByPoint = roofPolygon.flatOutline[0]
225
+
226
+ // const minHeight = Math.min(
227
+ // ...obstaclePolygon.outline.map(
228
+ // (p) => verticalProjectionOnPlane(p, normalVector, passByPoint).z
229
+ // )
230
+ // )
231
+ // const topHeight = minHeight + obstacleHeight
232
+ const topHeight = obstacleHeight
233
+
234
+ const geometry = new THREE.BufferGeometry()
235
+ const cropedHoleOutline=intersectOutlines(obstaclePolygon.outline, roofPolygon.outline)[0] || []
236
+
237
+ //Calcul of triangles using cutear algo
238
+ const trianglesVertices = []
239
+ const obstacleOutlineTop = []
240
+ cropedHoleOutline.forEach((p) => {
241
+ const p_bottom_0 = verticalProjectionOnPlane(p, normalVector, passByPoint)
242
+
243
+ let p_up_0
244
+ if (!obstaclePolygon.isParallel) {
245
+ p_up_0 = { ...p_bottom_0, z: topHeight }
246
+ } else {
247
+ const vectorFromBottomToTop = multiplyVector(obstacleHeight, {
248
+ x: 0,
249
+ y: 0,
250
+ z: 1
251
+ })
252
+ p_up_0 = addVector(p_bottom_0, vectorFromBottomToTop)
253
+ }
254
+ obstacleOutlineTop.push(p_up_0)
255
+ })
256
+ trianglesVertices.push(...getTriangleVerticesFromOutline(obstacleOutlineTop))
257
+
258
+ if(hasNaN(trianglesVertices)){return null}
259
+ const vertices = new Float32Array(trianglesVertices)
260
+ // itemSize = 3 because there are 3 values (components) per vertex
261
+ geometry.setAttribute('position', new THREE.BufferAttribute(vertices, 3))
262
+ geometry.computeVertexNormals()
263
+ return geometry
264
+ }
265
+
266
+ export function getBufferObstacleSideGeometry(obstaclePolygon, roofPolygon) {
267
+ let obstacleHeight
268
+ if(obstaclePolygon.isParallel){
269
+ obstacleHeight = parseInt(obstaclePolygon.height || 0)
270
+ }else{
271
+ obstacleHeight = parseInt(obstaclePolygon.heightReference + obstaclePolygon.height || 0)
272
+ }
273
+
274
+ const normalVector = roofPolygon.normalVector
275
+ const passByPoint = roofPolygon.flatOutline[0]
276
+
277
+ // const minHeight = Math.min(
278
+ // ...obstaclePolygon.outline.map(
279
+ // (p) => verticalProjectionOnPlane(p, normalVector, passByPoint).z
280
+ // )
281
+ // )
282
+ // const topHeight = minHeight + obstacleHeight
283
+ const topHeight = obstacleHeight
284
+
285
+ const geometry = new THREE.BufferGeometry()
286
+ const cropedHoleOutline=intersectOutlines(obstaclePolygon.outline, roofPolygon.outline)[0] || []
287
+ //Calcul of triangles using cutear algo
288
+ const obstacleLength = cropedHoleOutline.length
289
+ const trianglesVertices = []
290
+ const obstacleOutlineTop = []
291
+ cropedHoleOutline.forEach((p, index) => {
292
+ const p_bottom_0 = verticalProjectionOnPlane(p, normalVector, passByPoint)
293
+ const p_bottom_1 = verticalProjectionOnPlane(
294
+ cropedHoleOutline[(index + 1) % obstacleLength],
295
+ normalVector,
296
+ passByPoint
297
+ )
298
+ let p_up_0
299
+ let p_up_1
300
+ if (!obstaclePolygon.isParallel) {
301
+ p_up_0 = { ...p_bottom_0, z: topHeight }
302
+ p_up_1 = { ...p_bottom_1, z: topHeight }
303
+ } else {
304
+ //const vectorFromBottomToTop=multiplyVector(obstacleHeight,{normalVector})
305
+ const vectorFromBottomToTop = multiplyVector(obstacleHeight, {
306
+ x: 0,
307
+ y: 0,
308
+ z: 1
309
+ })
310
+ p_up_0 = addVector(p_bottom_0, vectorFromBottomToTop)
311
+ p_up_1 = addVector(p_bottom_1, vectorFromBottomToTop)
312
+ }
313
+ trianglesVertices.push(
314
+ ...[
315
+ p_up_0.x / 1000,
316
+ p_up_0.y / 1000,
317
+ p_up_0.z / 1000,
318
+ p_up_1.x / 1000,
319
+ p_up_1.y / 1000,
320
+ p_up_1.z / 1000,
321
+ p_bottom_0.x / 1000,
322
+ p_bottom_0.y / 1000,
323
+ p_bottom_0.z / 1000,
324
+ p_up_1.x / 1000,
325
+ p_up_1.y / 1000,
326
+ p_up_1.z / 1000,
327
+ p_bottom_0.x / 1000,
328
+ p_bottom_0.y / 1000,
329
+ p_bottom_0.z / 1000,
330
+ p_bottom_1.x / 1000,
331
+ p_bottom_1.y / 1000,
332
+ p_bottom_1.z / 1000
333
+ ]
334
+ )
335
+ })
336
+
337
+ if(hasNaN(trianglesVertices)){return null}
338
+ const vertices = new Float32Array(trianglesVertices)
339
+ // itemSize = 3 because there are 3 values (components) per vertex
340
+ geometry.setAttribute('position', new THREE.BufferAttribute(vertices, 3))
341
+ geometry.computeVertexNormals()
342
+ return geometry
343
+ }
344
+
345
+ export function getBufferModuleFieldGeometry(moduleFieldPolygon) {
346
+ const roofPolygon = moduleFieldPolygon.roof
347
+ const moduleHeight = 10
348
+ //get lowest verticalProjection
349
+ const normalVector = roofPolygon.normalVector
350
+
351
+ const moduleFieldOutlineTop = []
352
+ const geometry = new THREE.BufferGeometry()
353
+ //Calcul of triangles using cutear algo
354
+ const trianglesVertices = []
355
+ moduleFieldPolygon.outline.forEach((p) => {
356
+ const vectorFromBottomToTop = multiplyVector(moduleHeight, normalVector)
357
+ let p_up_0 = addVector(p, vectorFromBottomToTop)
358
+ moduleFieldOutlineTop.push(p_up_0)
359
+ })
360
+ trianglesVertices.push(
361
+ ...getTriangleVerticesFromOutline(moduleFieldOutlineTop)
362
+ )
363
+ if(hasNaN(trianglesVertices)){return null}
364
+ const vertices = new Float32Array(trianglesVertices)
365
+ var uvs = new Float32Array([
366
+ 1, 1, 0, 1, 0, 0,
367
+
368
+ 1, 1, 0, 0, 1, 0
369
+ ])
370
+
371
+ geometry.setAttribute('position', new THREE.BufferAttribute(vertices, 3))
372
+ geometry.setAttribute('uv', new THREE.BufferAttribute(uvs, 2))
373
+
374
+ geometry.computeVertexNormals()
375
+ return geometry
376
+ }
377
+
378
+ export function getBufferPanelGeometry(panelPolygon) {
379
+ let panelNormalVector = getNormalVectorFrom3Points(
380
+ panelPolygon.outline[0],
381
+ panelPolygon.outline[1],
382
+ panelPolygon.outline[2]
383
+ )
384
+ if (panelNormalVector.z < 0) {
385
+ panelNormalVector = multiplyVector(-1, panelNormalVector)
386
+ }
387
+ const roofPolygon = panelPolygon.roof
388
+ const panelHeight = parseInt(panelPolygon.height || 50)
389
+ //get lowest verticalProjection
390
+
391
+ const panelOutlineTop = []
392
+ const geometry = new THREE.BufferGeometry()
393
+ //Calcul of triangles using cutear algo
394
+ const trianglesVertices = []
395
+ panelPolygon.outline.forEach((p) => {
396
+ const vectorFromBottomToTop = multiplyVector(panelHeight, panelNormalVector)
397
+ let p_up_0 = addVector(p, vectorFromBottomToTop)
398
+
399
+ panelOutlineTop.push(p_up_0)
400
+ })
401
+ trianglesVertices.push(...getTriangleVerticesFromOutline(panelOutlineTop))
402
+
403
+ if(hasNaN(trianglesVertices)){return null}
404
+ const vertices = new Float32Array(trianglesVertices)
405
+ var A = panelPolygon.outline[2]
406
+ var B = panelPolygon.outline[3]
407
+ var C = panelPolygon.outline[1]
408
+ var D = panelPolygon.outline[0]
409
+ const AB = getDistanceBetweenPoints(A, B)
410
+ const AC = getDistanceBetweenPoints(A, C)
411
+ let uvs
412
+ if (AB < AC) {
413
+ uvs = new Float32Array([
414
+ 0, 1,
415
+ 0, 0,
416
+ 1, 0,
417
+
418
+ 0, 1,
419
+ 1, 0,
420
+ 1, 1
421
+ ])
422
+ }else{
423
+ uvs = new Float32Array([
424
+ 0, 0,
425
+ 1, 0,
426
+ 1, 1,
427
+
428
+ 1, 0,
429
+ 0, 1,
430
+ 1, 1
431
+ ])
432
+ }
433
+
434
+ geometry.setAttribute('position', new THREE.BufferAttribute(vertices, 3))
435
+ geometry.setAttribute('uv', new THREE.BufferAttribute(uvs, 2))
436
+
437
+ geometry.computeVertexNormals()
438
+ return geometry
439
+ }
440
+ export function updateBufferPanelGeometry(panelPolygon,geometry){
441
+ geometry=updateBufferRoofGeometry(panelPolygon.outline,[],geometry)
442
+ return geometry
443
+ }
444
+
445
+ export function updateBufferPanelSideGeometry(panelPolygon,geometry){
446
+ geometry=updateBufferRoofGeometry(panelPolygon.outline,[],geometry)
447
+ return geometry
448
+ }
449
+ export function getBufferPanelSideGeometry(panelPolygon) {
450
+ let panelNormalVector = getNormalVectorFrom3Points(
451
+ panelPolygon.outline[0],
452
+ panelPolygon.outline[1],
453
+ panelPolygon.outline[2]
454
+ )
455
+ if (panelNormalVector.z < 0) {
456
+ panelNormalVector = multiplyVector(-1, panelNormalVector)
457
+ }
458
+ const roofPolygon = panelPolygon.roof
459
+ const panelHeight = parseInt(panelPolygon.height || 50)
460
+ // const normalVector = roofPolygon.normalVector
461
+ // const passByPoint = roofPolygon.flatOutline[0]
462
+
463
+ const geometry = new THREE.BufferGeometry()
464
+ //Calcul of triangles using cutear algo
465
+ const panelLength = panelPolygon.outline.length
466
+ const trianglesVertices = []
467
+ const panelOutlineTop = []
468
+ panelPolygon.outline.forEach((p, index) => {
469
+ //const vectorFromBottomToTop=multiplyVector(obstacleHeight,{normalVector})
470
+ const p_bottom_0 = p
471
+ const p_bottom_1 = panelPolygon.outline[(index + 1) % panelLength]
472
+ const vectorFromBottomToTop = multiplyVector(panelHeight, panelNormalVector)
473
+ let p_up_0 = addVector(p_bottom_0, vectorFromBottomToTop)
474
+ let p_up_1 = addVector(p_bottom_1, vectorFromBottomToTop)
475
+ trianglesVertices.push(
476
+ ...[
477
+ p_up_0.x / 1000,
478
+ p_up_0.y / 1000,
479
+ p_up_0.z / 1000,
480
+ p_up_1.x / 1000,
481
+ p_up_1.y / 1000,
482
+ p_up_1.z / 1000,
483
+ p_bottom_0.x / 1000,
484
+ p_bottom_0.y / 1000,
485
+ p_bottom_0.z / 1000,
486
+ p_bottom_0.x / 1000,
487
+ p_bottom_0.y / 1000,
488
+ p_bottom_0.z / 1000,
489
+ p_up_1.x / 1000,
490
+ p_up_1.y / 1000,
491
+ p_up_1.z / 1000,
492
+ p_bottom_1.x / 1000,
493
+ p_bottom_1.y / 1000,
494
+ p_bottom_1.z / 1000
495
+ ]
496
+ )
497
+ })
498
+ if(hasNaN(trianglesVertices)){return null}
499
+
500
+ const vertices = new Float32Array(trianglesVertices)
501
+
502
+ // itemSize = 3 because there are 3 values (components) per vertex
503
+ geometry.setAttribute('position', new THREE.BufferAttribute(vertices, 3))
504
+ geometry.computeVertexNormals()
505
+ return geometry
506
+ }
507
+
508
+ export function getBufferRoofMarginGeometry(polygon,roofPolygon=null) {
509
+ const geometries = []
510
+ const length = polygon.margins.innerOutline.length
511
+
512
+ polygon.margins.innerOutline.forEach((K, index) => {
513
+ //check if distance ==0 then margin not displayed
514
+ let geometry
515
+ const distance=polygon.margins.isSameMargin?polygon.margins.sameMargin:polygon.margins.distances[index]
516
+ if(distance<=0){
517
+ geometry=null
518
+ }else{
519
+ const A = polygon.margins.outterOutline[index]
520
+ const B = polygon.margins.outterOutline[(index + 1) % length]
521
+ const J = polygon.margins.innerOutline[(index + 1) % length]
522
+
523
+ let marginOutline=[A,B,J,K]
524
+ if(roofPolygon){
525
+ marginOutline=intersectOutlines(marginOutline, roofPolygon.flatOutline)[0] || []
526
+ marginOutline=marginOutline.map(p=>{
527
+ return {
528
+ x:p.x,
529
+ y:p.y,
530
+ z:verticalProjectionOnPlane(p,roofPolygon.normalVector,roofPolygon.flatOutline[0]).z
531
+ }
532
+ })
533
+ }
534
+ marginOutline=marginOutline.map(p=>{return {x:p.x,y:p.y,z:p.z+10}})
535
+ geometry = new THREE.BufferGeometry()
536
+
537
+ const trianglesVertices = []
538
+
539
+ trianglesVertices.push(
540
+ ...getTriangleVerticesFromOutline(marginOutline)
541
+ )
542
+ if(hasNaN(trianglesVertices)){return null}
543
+ const vertices = new Float32Array(trianglesVertices)
544
+
545
+ geometry.setAttribute('position', new THREE.BufferAttribute(vertices, 3))
546
+ geometry.computeVertexNormals()
547
+ }
548
+ geometries.push(geometry)
549
+ })
550
+ return geometries
551
+ }
552
+
553
+ export function getExtrusionGeometry(
554
+ solidsHolesMapData,
555
+ height = (defaultBaseHeight - 100) / 1000
556
+ ) {
557
+ const shapes = []
558
+ const getBezierPath = (segments) => {
559
+ const bezierPath = new THREE.Shape()
560
+ for (let i = 0; i < segments.length; i += 1) {
561
+ const curr = segments[i]
562
+ const next = segments[(i + 1) % segments.length]
563
+ const p = []
564
+ p[0] = curr
565
+ p[1] = curr
566
+ p[2] = next
567
+ p[3] = next
568
+
569
+ if (i === 0) {
570
+ bezierPath.moveTo(p[0].x / 1000, p[0].y / 1000)
571
+ }
572
+ bezierPath.bezierCurveTo(
573
+ p[1].x / 1000,
574
+ p[1].y / 1000,
575
+ p[2].x / 1000,
576
+ p[2].y / 1000,
577
+ p[3].x / 1000,
578
+ p[3].y / 1000
579
+ )
580
+ }
581
+
582
+ bezierPath.closePath()
583
+ return bezierPath
584
+ }
585
+ for (const shape of solidsHolesMapData) {
586
+ const solidShape = getBezierPath(shape.outline)
587
+ const holes = shape.holes
588
+ const holePaths = []
589
+ for (let i = 0; i < holes.length; i += 1) {
590
+ const holePath = getBezierPath(holes[i])
591
+ holePaths.push(holePath)
592
+ }
593
+ solidShape.holes = holePaths
594
+ shapes.push(solidShape)
595
+ }
596
+ const settings = {
597
+ depth: height,
598
+ curveSegments: 10,
599
+ bevelEnabled: false,
600
+ material: 0,
601
+ extrudeMaterial: 1
602
+ }
603
+
604
+ const geometry = new THREE.ExtrudeGeometry(shapes, settings)
605
+ return geometry
606
+ }
@@ -0,0 +1,43 @@
1
+ import {Graph} from './DFS'
2
+ import {
3
+ isSameSegment2D,
4
+ } from '@eturnity/eturnity_maths'
5
+ export function generateGraph(polygons){
6
+ const edges2D=[]
7
+ const g=new Graph()
8
+ polygons
9
+ .filter((poly) => poly.layer=='roof')
10
+ .forEach((polygon,index) => {
11
+ g.dict.push(polygon.id)
12
+ const outline = polygon.outline
13
+ outline.forEach((point, i) => {
14
+ //check if edge2D already exist
15
+ const nextPoint = outline[(i + 1) % outline.length]
16
+ let edge2D = edges2D.find((edge) => {
17
+ return (
18
+ isSameSegment2D([point, nextPoint], edge.outline)
19
+ )
20
+ })
21
+ if (!edge2D) {
22
+ //create an edge at this position
23
+ edge2D = {}
24
+ edge2D.outline=[point, nextPoint]
25
+ edge2D.belongsTo = []
26
+ edges2D.push(edge2D)
27
+ }
28
+ //add BelongToPolygon
29
+ edge2D.belongsTo.push({
30
+ polygonId: polygon.id,
31
+ index: i,
32
+ polygon
33
+ })
34
+ })
35
+ })
36
+ for(let k in edges2D){
37
+ let edge=edges2D[k]
38
+ if(edge.belongsTo.length==2){
39
+ g.addEdge(edge.belongsTo[0].polygonId,edge.belongsTo[1].polygonId)
40
+ }
41
+ }
42
+ return g
43
+ }
@@ -0,0 +1,55 @@
1
+ import * as THREE from 'three'
2
+ import {beamColor,beamOpacity,node3DColor,node3dOpacity,defaultTextureUrls} from '../config'
3
+ const material=[]
4
+
5
+ material.wall = new THREE.MeshLambertMaterial({
6
+ color: 0xdddddd,
7
+ side:THREE.DoubleSide
8
+ })
9
+
10
+ // TODO get Canvas image from TwoD
11
+ material.obstacle = new THREE.MeshPhongMaterial({
12
+ color: 0xff0000,
13
+ side:THREE.DoubleSide,
14
+ })
15
+
16
+ material.edge=new THREE.MeshPhongMaterial({ color: beamColor,transparent:true,opacity:beamOpacity })
17
+ material.node=new THREE.PointsMaterial( { size: 0.05, sizeAttenuation: true,color: node3DColor, opacity:node3dOpacity, transparent: true } );
18
+ const loader = new THREE.TextureLoader()
19
+ // texture.minFilter = THREE.LinearFilter
20
+ material.panel={}
21
+
22
+ for(let k=0;k<defaultTextureUrls.length;k++){
23
+ let texture=loader.load(defaultTextureUrls[k], function (texture) {})
24
+ material.panel['default_'+k] = new THREE.MeshBasicMaterial({
25
+ map: texture,
26
+ side: THREE.DoubleSide,
27
+ })
28
+ }
29
+
30
+ material.flatRoof = new THREE.MeshPhongMaterial({
31
+ color: 0x00ff00,
32
+ specular: 0x009900,
33
+ shininess: 0,
34
+ flatShading: true,
35
+ side:THREE.DoubleSide,
36
+ transparent:true,
37
+ opacity:0.5
38
+ })
39
+
40
+ material.moduleField = new THREE.MeshLambertMaterial({
41
+ color: 0xff0000,
42
+ side:THREE.DoubleSide,
43
+ })
44
+ material.curvedRoof = new THREE.MeshPhongMaterial({
45
+ color: 0xffff00,
46
+ specular: 0x009900,
47
+ shininess: 0,
48
+ flatShading: true,
49
+ side:THREE.DoubleSide,
50
+ transparent:true,
51
+ opacity:0.5
52
+ })
53
+
54
+
55
+ export {material}