@eturnity/eturnity_3d 7.2.2-qa-7.2.4 → 7.2.2

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@eturnity/eturnity_3d",
3
3
  "private": false,
4
- "version": "7.2.2-qa-7.2.4",
4
+ "version": "7.2.2",
5
5
  "main": "dist/main.js",
6
6
  "scripts": {
7
7
  "dev": "vue-cli-service serve --skip-plugins @vue/cli-plugin-eslint",
@@ -10,7 +10,7 @@
10
10
  "prettier": "prettier --write \"**/*.{js,vue}\""
11
11
  },
12
12
  "dependencies": {
13
- "@eturnity/eturnity_maths": "7.2.2-qa-7.2.3",
13
+ "@eturnity/eturnity_maths": "7.2.2",
14
14
  "core-js": "^2.6.12",
15
15
  "cors": "^2.8.5",
16
16
  "earcut": "^2.2.4",
@@ -25,6 +25,15 @@ export default {
25
25
  data() {
26
26
  return {
27
27
  scene: new THREE.Scene(),
28
+ camera: new THREE.PerspectiveCamera(50, 300 / 300, 0.1, 100000),
29
+ orthographicCamera: new THREE.OrthographicCamera(
30
+ 10 / -2,
31
+ 10 / 2,
32
+ 10 / 2,
33
+ 10 / -2,
34
+ 1,
35
+ 1000
36
+ ),
28
37
  layers: null,
29
38
  provider: null,
30
39
  cameraProjection: null,
@@ -52,14 +61,13 @@ export default {
52
61
  },
53
62
  screenshotable: false,
54
63
  areModuleFieldsVisible: false,
55
- areUserDeactivatedPanelsVisible: false,
56
- animationFrameId: null,
57
64
  intervalId: null,
65
+ requestAnimationFrameId: null,
58
66
  }
59
67
  },
60
68
  beforeDestroy() {
61
69
  clearInterval(this.intervalId)
62
- cancelAnimationFrame(this.animationFrameId)
70
+ cancelAnimationFrame(this.requestAnimationFrameId)
63
71
  },
64
72
  mixins: [renderMixin, threeMixin, materialMixin],
65
73
  async mounted() {
@@ -280,7 +288,7 @@ export default {
280
288
  },
281
289
  animate() {
282
290
  this.render()
283
- this.animationFrameId = requestAnimationFrame(this.animate)
291
+ this.requestAnimationFrameId = requestAnimationFrame(this.animate)
284
292
  },
285
293
  render() {
286
294
  this.renderer.clear()
package/src/config.js CHANGED
@@ -4,7 +4,7 @@ export const snapToPointTolerance = 15
4
4
  export const snapToIntersectionPointTolerance = 15
5
5
  export const snapToLineTolerance = 10
6
6
  export const distanceToCloseNode = 70
7
- export const mmTolerance = 1
7
+ export const mmTolerance = 50
8
8
  export const earthRadius = 6371008
9
9
 
10
10
  export const layerColors = {
@@ -139,8 +139,8 @@ export const maxMargin = 2500
139
139
  export const node3DRadius = 0.05
140
140
  export const beamColor = '#ffffff'
141
141
  export const node3DColor = 'white'
142
- export const beamOpacity = 0.1
143
- export const node3dOpacity = 0.1
142
+ export const beamOpacity = 0.4
143
+ export const node3dOpacity = 0.3
144
144
  export const dimMarginColor = '#ff000020'
145
145
  export const defaultTextureUrl = require('./assets/images/panels/reneSola_Virtus_2_JC320S_24_Bbw.png')
146
146
  const textureImageDomain = 'https://public-data.eturnity.io/'
@@ -1,136 +1,12 @@
1
1
  import TWEEN from 'tween'
2
- import * as THREE from 'three'
3
- import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
4
2
  import {
5
3
  addVector,
6
- getDistanceBetweenPoints,
7
4
  multiplyVector,
8
5
  substractVector
9
6
  } from '@eturnity/eturnity_maths'
10
7
 
11
8
  export default {
12
- data() {
13
- return {
14
- camera: null,
15
- perspectiveCamera: new THREE.PerspectiveCamera(50, 300 / 300, 1, 50000),
16
- orthographicCamera: new THREE.OrthographicCamera(10, 10, 10, 10, 1, 1000)
17
- }
18
- },
19
9
  methods: {
20
- turnPerspectiveCameraToOrthogonal() {
21
- const cameraPosition = new THREE.Vector3(
22
- this.camera.position.x,
23
- this.camera.position.y,
24
- this.camera.position.z
25
- )
26
- var halfHeightDistance =
27
- (this.camera.position.z * this.camera.fov * Math.PI) / 180
28
-
29
- // Create an orthographic camera aligned to look down
30
- this.orthographicCamera.left =
31
- (-this.camera.aspect * halfHeightDistance) / 2
32
- this.orthographicCamera.right =
33
- (this.camera.aspect * halfHeightDistance) / 2
34
- this.orthographicCamera.top = halfHeightDistance / 2
35
- this.orthographicCamera.bottom = -halfHeightDistance / 2
36
- this.orthographicCamera.near = 1
37
- this.orthographicCamera.far = 1000
38
- this.orthographicCamera.up = new THREE.Vector3(0, 1, 0)
39
- this.orthographicCamera.position.set(
40
- cameraPosition.x,
41
- cameraPosition.y,
42
- 100
43
- )
44
- this.camera = this.orthographicCamera
45
- this.camera.position.set(
46
- cameraPosition.x,
47
- cameraPosition.y,
48
- cameraPosition.z
49
- )
50
- this.camera.position.set(
51
- cameraPosition.x,
52
- cameraPosition.y,
53
- cameraPosition.z
54
- )
55
- this.camera.updateProjectionMatrix()
56
- this.renderer.camera = this.camera
57
- this.composer.renderCamera = this.camera
58
-
59
- this.renderPass.camera = this.camera
60
- this.overlayRenderPass.camera = this.camera
61
- this.outlinePassHighlight.renderCamera = this.camera
62
- this.outlinePassSelected.renderCamera = this.camera
63
-
64
- this.orbitControl.screenSpacePanning = true
65
- this.orbitControl.object = this.camera
66
- this.orbitControl.target.set(cameraPosition.x, cameraPosition.y, 0)
67
- this.orbitControl.mouseButtons = {
68
- LEFT: THREE.MOUSE.PAN,
69
- MIDDLE: THREE.MOUSE.DOLLY,
70
- RIGHT: THREE.MOUSE.ROTATE
71
- }
72
- this.orbitControl.enableRotate = false
73
- this.orbitControl.addEventListener('change', () => {
74
- this.orbitControlChange()
75
- })
76
- this.orbitControl.update()
77
- this.camera.position.set(
78
- cameraPosition.x,
79
- cameraPosition.y,
80
- cameraPosition.z
81
- )
82
- this.camera.lookAt(
83
- new THREE.Vector3(cameraPosition.x, cameraPosition.y, 0)
84
- ) // Set look at coordinate like this
85
- this.camera.updateProjectionMatrix()
86
- this.nodesVisible = true
87
- this.renderNodes()
88
- this.composer.render()
89
- },
90
- turnOrthogonalCameraToPerspective() {
91
- this.camera = this.perspectiveCamera
92
- console.log(this.orthographicCamera)
93
- let altitude =
94
- (this.orthographicCamera.right - this.orthographicCamera.left) /
95
- ((this.perspectiveCamera.fov * Math.PI) / 180) /
96
- this.perspectiveCamera.aspect
97
-
98
- this.camera.position.set(
99
- this.orthographicCamera.position.x,
100
- this.orthographicCamera.position.y,
101
- altitude
102
- )
103
-
104
- this.camera.up = new THREE.Vector3(0, 0, 1)
105
- this.camera.updateProjectionMatrix()
106
-
107
- this.renderer.camera = this.camera
108
- this.composer.renderer.camera = this.camera
109
- this.composer.renderCamera = this.camera
110
- this.renderPass.camera = this.camera
111
- this.overlayRenderPass.camera = this.camera
112
- this.outlinePassHighlight.camera = this.camera
113
- this.outlinePassHighlight.renderCamera = this.camera
114
- this.outlinePassSelected.camera = this.camera
115
- this.outlinePassSelected.renderCamera = this.camera
116
- this.orbitControl.camera = this.camera
117
- this.orbitControl.object = this.camera
118
- this.orbitControl.target.set(
119
- this.camera.position.x,
120
- this.camera.position.y,
121
- 0
122
- )
123
- this.orbitControl.screenSpacePanning = false
124
- this.orbitControl.enableRotate = true
125
- this.orbitControl.mouseButtons = {
126
- LEFT: THREE.MOUSE.ROTATE,
127
- MIDDLE: THREE.MOUSE.DOLLY,
128
- RIGHT: THREE.MOUSE.PAN
129
- }
130
- this.orbitControl.update()
131
-
132
- this.composer.render()
133
- },
134
10
  zoomIn3D() {
135
11
  let target = this.orbitControl.target
136
12
  let curentPosition = this.camera.position
@@ -163,7 +39,6 @@ export default {
163
39
  },
164
40
  setCameraGlobalPosition() {
165
41
  if (this.roofs.length == 0) return
166
- let newFov = 50
167
42
  let bounds = this.roofsBounds
168
43
  let targetVector = {
169
44
  x: (bounds.xMax + bounds.xMin) / 2000,
@@ -175,7 +50,7 @@ export default {
175
50
  (bounds.yMax - bounds.yMin) / 2000
176
51
  )
177
52
  let distance =
178
- 5 + objectRadius_m / Math.sin(((newFov / 2) * Math.PI) / 180)
53
+ 5 + objectRadius_m / Math.sin(((this.camera.fov / 2) * Math.PI) / 180)
179
54
  let cameraMoveVector = { x: 0, y: 0, z: distance }
180
55
  const positionVector = addVector(targetVector, cameraMoveVector)
181
56
  const position = [
@@ -184,39 +59,8 @@ export default {
184
59
  positionVector.z
185
60
  ]
186
61
  let target = [targetVector.x, targetVector.y, targetVector.z]
187
- this.setTweenTo(position, target, newFov)
188
- },
189
- setCameraGlobalVerticalPosition() {
190
- let position, target
191
- let newFov = 10
192
- if (this.roofs.length != 0) {
193
- let bounds = this.roofsBounds
194
- let targetVector = {
195
- x: (bounds.xMax + bounds.xMin) / 2000,
196
- y: (bounds.yMax + bounds.yMin) / 2000,
197
- z: 0
198
- }
199
- let objectRadius_m = Math.max(
200
- (bounds.xMax - bounds.xMin) / 2000,
201
- (bounds.yMax - bounds.yMin) / 2000
202
- )
203
62
 
204
- let distance =
205
- 2 * (objectRadius_m / Math.sin(((newFov / 2) * Math.PI) / 180))
206
- let cameraMoveVector = { x: 0, y: 0, z: distance }
207
- const positionVector = addVector(targetVector, cameraMoveVector)
208
- position = [positionVector.x, positionVector.y, positionVector.z]
209
- target = [targetVector.x, targetVector.y, targetVector.z]
210
- } else {
211
- position = [0, 0, 300]
212
- target = [0, 0, 0]
213
- }
214
- this.setTweenTo(
215
- position,
216
- target,
217
- newFov,
218
- this.turnPerspectiveCameraToOrthogonal
219
- )
63
+ this.setTweenTo(position, target)
220
64
  },
221
65
  setCameraOrthogonalTo(polygon) {
222
66
  if (polygon) {
@@ -265,128 +109,23 @@ export default {
265
109
  this.setTweenTo(position, target)
266
110
  }
267
111
  },
268
- setTweenTo(position, target, fov = 50, onCompleteCallback = () => {}) {
112
+ setTweenTo(position, target, speed = 2000) {
269
113
  TWEEN.removeAll()
270
- console.log('setTweenTo')
114
+ if (this.orbitControl) {
115
+ this.tweenOrbit = new TWEEN.Tween(this.orbitControl.target)
116
+ .to({ x: target[0], y: target[1], z: target[2] }, speed)
117
+ .easing(TWEEN.Easing.Sinusoidal.Out)
118
+ .start()
119
+ }
271
120
  if (this.camera) {
272
- const currentTweenVar = {
273
- t: 0
274
- }
275
- const initialTarget = {
276
- x: this.orbitControl.target.x,
277
- y: this.orbitControl.target.y,
278
- z: this.orbitControl.target.z
279
- }
280
- const initialFov = this.camera.fov
281
- const initialCameraPosition = {
282
- x: this.camera.position.x,
283
- y: this.camera.position.y,
284
- z: this.camera.position.z
285
- }
286
- const finalCameraPosition = {
287
- x: position[0],
288
- y: position[1],
289
- z: position[2]
290
- }
291
- if (position[0] == target[0] && position[1] == target[1]) {
292
- const distance2D = getDistanceBetweenPoints(
293
- finalCameraPosition,
294
- initialCameraPosition
295
- )
296
- //angle from south
297
- const angle2D = Math.atan2(
298
- initialCameraPosition.y - finalCameraPosition.y,
299
- initialCameraPosition.x - finalCameraPosition.x
300
- )
301
- console.log('setTween Camera Vertical')
302
- this.tweenCamera = new TWEEN.Tween(currentTweenVar)
303
- .to({ t: 1 }, 2000)
304
- .easing(TWEEN.Easing.Sinusoidal.Out)
305
- .onUpdate(() => {
306
- const t = currentTweenVar.t
307
- this.camera.fov = initialFov + Math.sqrt(t) * (fov - initialFov)
308
-
309
- const newDistance = distance2D * (1 - t)
310
- const newAngle = (angle2D + Math.PI / 2) * (1 - t) - Math.PI / 2
311
- const newAltitude =
312
- finalCameraPosition.z +
313
- (1 - t) * (initialCameraPosition.z - finalCameraPosition.z)
314
- const nextPosition = {
315
- x: finalCameraPosition.x + newDistance * Math.cos(newAngle),
316
- y: finalCameraPosition.y + newDistance * Math.sin(newAngle),
317
- z: newAltitude
318
- }
319
- this.camera.position.set(
320
- nextPosition.x,
321
- nextPosition.y,
322
- nextPosition.z
323
- )
324
- this.camera.up = new THREE.Vector3(
325
- 0,
326
- Math.sin((t * Math.PI) / 2),
327
- Math.cos((t * Math.PI) / 2)
328
- )
329
-
330
- this.camera.updateProjectionMatrix()
331
- const nextTarget = {
332
- x: initialTarget.x + t * (target[0] - initialTarget.x),
333
- y: initialTarget.y + t * (target[1] - initialTarget.y),
334
- z: initialTarget.z + t * (target[2] - initialTarget.z)
335
- }
336
-
337
- this.orbitControl.target.set(
338
- nextTarget.x,
339
- nextTarget.y,
340
- nextTarget.z
341
- )
342
- if (this.orbitControl && this.orbitControl.update)
343
- this.orbitControl.update()
344
- })
345
- .onComplete(() => {
346
- onCompleteCallback()
347
- })
348
- } else {
349
- console.log('setTween Camera not Vertical')
350
- this.camera.up = { x: 0, y: 0, z: 1 }
351
- this.tweenCamera = new TWEEN.Tween(currentTweenVar)
352
- .to({ t: 1 }, 2000)
353
- .easing(TWEEN.Easing.Sinusoidal.Out)
354
- .onUpdate(() => {
355
- const t = currentTweenVar.t
356
- this.camera.fov = initialFov + t * t * (fov - initialFov)
357
- this.camera.updateProjectionMatrix()
358
-
359
- const nextPosition = {
360
- x:
361
- finalCameraPosition.x +
362
- (1 - t) * (initialCameraPosition.x - finalCameraPosition.x),
363
- y:
364
- finalCameraPosition.y +
365
- (1 - t) * (initialCameraPosition.y - finalCameraPosition.y),
366
- z:
367
- finalCameraPosition.z +
368
- (1 - t) * (initialCameraPosition.z - finalCameraPosition.z)
369
- }
370
- this.camera.position.set(
371
- nextPosition.x,
372
- nextPosition.y,
373
- nextPosition.z
374
- )
375
- const nextTarget = {
376
- x: initialTarget.x + t * (target[0] - initialTarget.x),
377
- y: initialTarget.y + t * (target[1] - initialTarget.y),
378
- z: initialTarget.z + t * (target[2] - initialTarget.z)
379
- }
380
- this.orbitControl.target.set(
381
- nextTarget.x,
382
- nextTarget.y,
383
- nextTarget.z
384
- )
385
- if (this.orbitControl && this.orbitControl.update)
386
- this.orbitControl.update()
387
- })
388
- }
389
- this.tweenCamera.start()
121
+ this.tweenCamera = new TWEEN.Tween(this.camera.position)
122
+ .to({ x: position[0], y: position[1], z: position[2] }, speed)
123
+ .easing(TWEEN.Easing.Sinusoidal.Out)
124
+ .onUpdate(() => {
125
+ if (this.orbitControl && this.orbitControl.update)
126
+ this.orbitControl.update()
127
+ })
128
+ .start()
390
129
  }
391
130
  }
392
131
  },
@@ -32,32 +32,18 @@ export default {
32
32
  side: THREE.DoubleSide
33
33
  })
34
34
 
35
- this.material.edge = new THREE.MeshBasicMaterial({
35
+ this.material.edge = new THREE.MeshPhongMaterial({
36
36
  color: beamColor,
37
37
  transparent: true,
38
38
  opacity: beamOpacity
39
39
  })
40
- //Creating dot alpha texture for nodes
41
- const canvas = document.createElement('canvas'),
42
- ctx = canvas.getContext('2d');
43
- canvas.width = 64
44
- canvas.height = 64
45
- ctx.fillStyle = 'black'
46
- ctx.fillRect(0, 0, 64, 64)
47
- ctx.strokeStyle = 'white'
48
- ctx.beginPath()
49
- ctx.lineWidth = 10
50
- ctx.arc(32, 32, 16, 0, Math.PI * 2)
51
- ctx.stroke()
52
- const texture = new THREE.CanvasTexture(canvas)
53
40
 
54
41
  this.material.node = new THREE.PointsMaterial({
55
- alphaMap: texture,
56
- size: 25,
57
- sizeAttenuation: false,
58
- transparent: true,
59
- color: "0xffffff",
60
- opacity: 1,
42
+ size: 0.05,
43
+ sizeAttenuation: true,
44
+ color: node3DColor,
45
+ opacity: node3dOpacity,
46
+ transparent: true
61
47
  })
62
48
 
63
49
  this.material.panel = {}
@@ -72,13 +58,6 @@ export default {
72
58
  side: THREE.DoubleSide
73
59
  })
74
60
  }
75
- this.material.panel['userDeactivatedPanel'] = new THREE.MeshBasicMaterial({
76
- color: 0xffffff,
77
- transparent: true,
78
- alphaTest: 0,
79
- opacity: 0.2,
80
- side: THREE.DoubleSide
81
- })
82
61
  this.material.roof = [this.material.wall]
83
62
 
84
63
  this.material.flatRoof = new THREE.MeshPhongMaterial({
@@ -115,8 +94,7 @@ export default {
115
94
  color: 0xffffff,
116
95
  transparent: true,
117
96
  alphaTest: 1,
118
- opacity: 0.2,
119
- side: THREE.DoubleSide
97
+ opacity: 0
120
98
  })
121
99
  this.material.moduleField = new THREE.MeshBasicMaterial({
122
100
  color: 0xe0e0ff,
@@ -43,6 +43,7 @@ export default {
43
43
  )
44
44
  },
45
45
  clearMesh(mesh) {
46
+
46
47
  if (!mesh || !this.scene) {
47
48
  return
48
49
  }
@@ -76,6 +77,13 @@ export default {
76
77
  }
77
78
  })
78
79
  },
80
+ clearNodesRemovedOnes() {
81
+ Object.values(this.meshes['nodeMeshes']).forEach((mesh) => {
82
+ if (!this.nodeIds.includes(mesh.userData.nodeId)) {
83
+ this.clearMesh(mesh)
84
+ }
85
+ })
86
+ },
79
87
  clearRemovedOnes(type) {
80
88
  Object.values(this.meshes[type]).forEach((mesh) => {
81
89
  if (!this.polygonIds.includes(mesh.userData.polygonId)) {
@@ -36,62 +36,30 @@ export default {
36
36
  },
37
37
  renderEdges() {
38
38
  this.clearEdgesRemovedOnes('edgeMeshes')
39
- if(this.renderLineEdges){
40
- this.renderLineEdges()
41
- }
42
39
  let cylinder
40
+ //this.clearByType('edgeMeshes')
41
+ // const material = new THREE.LineBasicMaterial( { color: beamColor,transparent:true,opacity:beamOpacity ,sizeAttenuation: true} );
42
+ // material.linewidth=5
43
43
  const material = this.material.edge
44
- this.edges.forEach((edge) => {
45
- cylinder = this.meshes.edgeMeshes[edge.id]
46
- if (cylinder) {
47
- cylinder.visible = false
48
- }
49
- if (['obstacle', 'construction'].includes(edge.layer)) return
50
- if (
51
- ['selectRoof'].includes(this.selectedTool) &&
52
- edge.layer != 'roof'
53
- ) {
54
- return
55
- }
56
- if (
57
- ['selectModuleField'].includes(this.selectedTool) &&
58
- (edge.layer != 'moduleField' ||
59
- !this.selectedModuleField ||
60
- !edge.belongsTo
61
- .map((i) => i.polygonId)
62
- .includes(this.selectedModuleField.id))
63
- ) {
64
- return
65
- }
66
- cylinder = this.meshes.edgeMeshes[edge.id]
67
- if (cylinder) {
68
- //update
69
- cylinder.visible = true
70
- this.setCylinderPosition(cylinder, edge)
71
- //change cylinder length
72
- } else {
73
- const edgeRadius = this.edgeRadius || 0.1
74
- const geometry = new THREE.CylinderGeometry(
75
- edgeRadius,
76
- edgeRadius,
77
- 1,
78
- 6
79
- )
80
- if (this.edgeOpacity != undefined) {
81
- material.opacity = this.edgeOpacity
82
- }
83
- cylinder = new THREE.Mesh(geometry, material.clone())
84
- cylinder = this.setCylinderPosition(cylinder, edge)
44
+ this.edges
45
+ .filter((edge) => edge.layer == 'roof')
46
+ .forEach((edge) => {
47
+ cylinder = this.meshes.edgeMeshes[edge.id]
48
+ if (cylinder) {
49
+ //update
50
+ this.setCylinderPosition(cylinder, edge)
51
+ //change cylinder length
52
+ } else {
53
+ const geometry = new THREE.CylinderGeometry(0.1, 0.1, 1, 6)
54
+ cylinder = new THREE.Mesh(geometry, material)
55
+ cylinder = this.setCylinderPosition(cylinder, edge)
85
56
 
86
- cylinder.userData.meshId = edge.id
87
- cylinder.userData.edgeId = edge.id
88
- cylinder.userData.type = 'edgeMeshes'
89
- cylinder.userData.layer = edge.layer
57
+ cylinder.userData.edgeId = edge.id
90
58
 
91
- this.meshes.edgeMeshes[edge.id] = cylinder
92
- this.scene.add(cylinder)
93
- }
94
- })
59
+ this.meshes.edgeMeshes[edge.id] = cylinder
60
+ this.scene.add(cylinder)
61
+ }
62
+ })
95
63
  }
96
64
  }
97
65
  }
@@ -6,58 +6,13 @@ export default {
6
6
  renderRoofsMargin() {
7
7
  this.clearByType('roofMarginMeshes')
8
8
 
9
- if (
10
- ![
11
- 'selectMargin',
12
- 'selectModuleField',
13
- 'drawRoof',
14
- 'drawObstacle'
15
- ].includes(this.selectedTool)
16
- ) {
17
- return
18
- }
19
- let showableRoofs = []
20
- if (['drawRoof', 'drawObstacle'].includes(this.selectedTool)) {
21
- if (this.selectedRoof) {
22
- showableRoofs = [this.selectedRoof]
23
- }
24
- if (this.selectedObstacle) {
25
- showableRoofs = this.selectedObstacle.roofs
26
- }
27
- } else {
28
- showableRoofs = this.roofs
29
- }
30
- showableRoofs.forEach((roofPolygon) => {
31
- const geometries = getBufferRoofMarginGeometry(roofPolygon)
9
+ if (this.selectedTool == 'selectMargin') {
10
+ this.roofs.forEach((roofPolygon) => {
11
+ const geometries = getBufferRoofMarginGeometry(roofPolygon)
32
12
 
33
- geometries.forEach((geometry, index) => {
34
- if (geometry) {
35
- const marginColor = roofPolygon.margins.isSameMargin
36
- ? colorArrayBase[0]
37
- : colorArrayBase[index % colorArrayBase.length]
38
- let material = new THREE.MeshPhongMaterial({
39
- color: marginColor,
40
- specular: 0x009900,
41
- shininess: 0,
42
- flatShading: true,
43
- side: THREE.DoubleSide,
44
- transparent: true,
45
- opacity: 0.8
46
- })
47
- const mesh = new THREE.Mesh(geometry, material)
48
- geometry.dispose()
49
- this.scene.add(mesh)
50
- this.meshes.roofMarginMeshes[roofPolygon.id + '_' + index] = mesh
51
- }
52
- })
53
- roofPolygon.holes.forEach((obstaclePolygon) => {
54
- const geometries = getBufferRoofMarginGeometry(
55
- obstaclePolygon,
56
- roofPolygon
57
- )
58
13
  geometries.forEach((geometry, index) => {
59
14
  if (geometry) {
60
- const marginColor = obstaclePolygon.margins.isSameMargin
15
+ const marginColor = roofPolygon.margins.isSameMargin
61
16
  ? colorArrayBase[0]
62
17
  : colorArrayBase[index % colorArrayBase.length]
63
18
  let material = new THREE.MeshPhongMaterial({
@@ -71,17 +26,43 @@ export default {
71
26
  })
72
27
  const mesh = new THREE.Mesh(geometry, material)
73
28
  geometry.dispose()
74
- geometry = null
75
- material.dispose()
76
- material = null
77
29
  this.scene.add(mesh)
78
- this.meshes.roofMarginMeshes[
79
- obstaclePolygon.id + '_' + roofPolygon.id + '_' + index
80
- ] = mesh
30
+ this.meshes.roofMarginMeshes[roofPolygon.id + '_' + index] = mesh
81
31
  }
82
32
  })
33
+ roofPolygon.holes.forEach((obstaclePolygon) => {
34
+ const geometries = getBufferRoofMarginGeometry(
35
+ obstaclePolygon,
36
+ roofPolygon
37
+ )
38
+ geometries.forEach((geometry, index) => {
39
+ if (geometry) {
40
+ const marginColor = obstaclePolygon.margins.isSameMargin
41
+ ? colorArrayBase[0]
42
+ : colorArrayBase[index % colorArrayBase.length]
43
+ let material = new THREE.MeshPhongMaterial({
44
+ color: marginColor,
45
+ specular: 0x009900,
46
+ shininess: 0,
47
+ flatShading: true,
48
+ side: THREE.DoubleSide,
49
+ transparent: true,
50
+ opacity: 0.8
51
+ })
52
+ const mesh = new THREE.Mesh(geometry, material)
53
+ geometry.dispose()
54
+ geometry = null
55
+ material.dispose()
56
+ material = null
57
+ this.scene.add(mesh)
58
+ this.meshes.roofMarginMeshes[
59
+ obstaclePolygon.id + '_' + roofPolygon.id + '_' + index
60
+ ] = mesh
61
+ }
62
+ })
63
+ })
83
64
  })
84
- })
65
+ }
85
66
  }
86
67
  }
87
68
  }
@@ -10,9 +10,9 @@ export default {
10
10
  geometries.forEach((geometry) => {
11
11
  const positions = geometry.attributes.position.array
12
12
  const normals = geometry.attributes.normal.array
13
- mergedVertices.push(...positions.slice(0, 3 * geometry.drawRange.count))
14
- mergedNormals.push(...normals.slice(0, 3 * geometry.drawRange.count))
15
13
 
14
+ mergedVertices.push(...positions.slice(0, geometry.drawRange.count * 3))
15
+ mergedNormals.push(...normals.slice(0, geometry.drawRange.count * 3))
16
16
  if (geometry.attributes.uv) {
17
17
  const uvs = geometry.attributes.uv.array
18
18
  mergedUvs.push(...uvs)
@@ -41,12 +41,12 @@ export default {
41
41
  for (let k in mergedNormals) {
42
42
  normals[k] = mergedNormals[k]
43
43
  }
44
- mergedGeometry.setDrawRange(0, mergedVertices.length / 3)
45
44
  } else {
46
45
  mergedGeometry.dispose()
47
46
  mergedGeometry = null
48
47
  mergedGeometry = this.createMergedGeometry(geometries)
49
48
  }
49
+ mergedGeometry.setDrawRange(0, mergedVertices.length / 3)
50
50
  mergedGeometry.attributes.position.needsUpdate = true
51
51
  mergedGeometry.attributes.normal.needsUpdate = true
52
52
  mergedGeometry.needsUpdate = true
@@ -100,7 +100,6 @@ export default {
100
100
  )
101
101
  mesh.geometry = mergedGeometry
102
102
  }
103
- mesh.frustumCulled = false
104
103
  return mesh
105
104
  }
106
105
  }
@@ -7,23 +7,19 @@ export default {
7
7
  if (!this.areModuleFieldsVisible) {
8
8
  return
9
9
  }
10
- const moduleFieldPolygons = this.polygons.filter((p) =>
11
- ['moduleField', 'tmpModuleField'].includes(p.layer)
12
- )
13
- moduleFieldPolygons.forEach((moduleFieldPolygon) => {
10
+ this.moduleFields.forEach((moduleFieldPolygon) => {
14
11
  const geometry = getBufferModuleFieldGeometry(moduleFieldPolygon)
15
12
  if (geometry) {
16
13
  let material
17
- if (moduleFieldPolygon.data.number_of_panels_override) {
18
- material = this.material.moduleFieldWithPanelOveride
19
- } else {
20
- material = this.material.moduleField
14
+ if(moduleFieldPolygon.data.number_of_panels_override){
15
+ material=this.material.moduleFieldWithPanelOveride
16
+ }else{
17
+ material=this.material.moduleField
21
18
  }
22
19
  const mesh = new THREE.Mesh(geometry, this.material.moduleField)
23
20
  mesh.matrixAutoUpdate = false
24
21
  mesh.userData.version = moduleFieldPolygon.version
25
22
  mesh.userData.type = 'moduleFieldsMeshes'
26
- mesh.userData.layer = moduleFieldPolygon.layer
27
23
  mesh.userData.meshId = moduleFieldPolygon.id
28
24
  mesh.userData.polygonId = moduleFieldPolygon.id
29
25
  this.scene.add(mesh)
@@ -1,18 +1,10 @@
1
1
  import * as THREE from 'three'
2
+
2
3
  export default {
3
4
  methods: {
4
5
  renderNodes() {
5
- console.log('renderNodes', this.nodesVisible)
6
- if (!this.nodesVisible) {
7
- if (this.meshes.nodeMeshes) {
8
- this.meshes.nodeMeshes.visible = false
9
- }
10
- return
11
- }
12
-
13
6
  let geometry
14
7
  if (this.meshes.nodeMeshes) {
15
- this.meshes.nodeMeshes.visible = true
16
8
  geometry = this.meshes.nodeMeshes.geometry
17
9
  geometry.attributes.position.needsUpdate = true
18
10
  } else {
@@ -48,11 +40,8 @@ export default {
48
40
  nodeMeshes.userData.meshId = null
49
41
  nodeMeshes.userData.polygonId = null
50
42
  nodeMeshes.matrixAutoUpdate = false
51
- nodeMeshes.renderOrder = 10
52
43
  this.meshes.nodeMeshes = nodeMeshes
53
- if (this.overlayScene) {
54
- this.overlayScene.add(nodeMeshes)
55
- }
44
+ this.scene.add(nodeMeshes)
56
45
  }
57
46
  }
58
47
  }
@@ -35,10 +35,9 @@ export default {
35
35
  },
36
36
  renderPanels() {
37
37
  this.clearRemovedOnes('panelsMeshes')
38
- //clear mesh of userDeactivated panels && panels with overriden # of panels
39
38
  Object.values(this.meshes.panelsMeshes).forEach((mesh) => {
39
+ //clear UserDeactivatedModules
40
40
  if (
41
- !this.areUserDeactivatedPanelsVisible &&
42
41
  this.polygons.find(
43
42
  (poly) =>
44
43
  poly.id == mesh.userData.polygonId &&
@@ -55,80 +54,53 @@ export default {
55
54
  this.clearMesh(mesh)
56
55
  }
57
56
  })
58
-
59
57
  let panelSideGeometries = []
60
58
  let panelTopGeometries = {}
61
- let panels = this.panels
62
- if (this.areUserDeactivatedPanelsVisible) {
63
- panels = this.polygons.filter((polygon) => {
64
- return ['panel', 'user_deactivated_panel'].includes(polygon.layer)
65
- })
66
- }
67
- panels.forEach((panelPolygon) => {
68
- //for each visible panels
69
- //1. define materialId and material
70
- //2. create or update individual meshes
71
- // 2a. Fill in panelTopGeometries & panelSideGeometries
59
+ this.panels.forEach((panelPolygon) => {
72
60
  if (!panelPolygon.visible) {
73
61
  return
74
62
  }
63
+ //definition of the material
75
64
  if (panelPolygon.moduleField.data.number_of_panels_override) {
76
65
  return
77
66
  }
78
- //1.define materialId and material
79
- let material
80
- let materialId
81
- if (panelPolygon.layer == 'user_deactivated_panel') {
82
- materialId = 'userDeactivatedPanel'
83
- material = this.material.panel[materialId]
84
- material.opacity = this.panelOpacity
85
- } else {
86
- const moduleTextureId =
87
- panelPolygon.moduleField.pvData.hasOwnProperty(
88
- 'module_texture_version_id'
89
- ) && panelPolygon.moduleField.pvData.module_texture_version_id
90
- ? panelPolygon.moduleField.pvData.module_texture_version_id
91
- : 0
92
-
93
- materialId = 'default_' + moduleTextureId
94
- material = this.material.panel[materialId]
95
- material.transparent = true
96
- material.opacity = this.panelOpacity
97
- if (panelPolygon.moduleField.data) {
98
- if (
99
- this.material.panel[
100
- panelPolygon.moduleField.data.component_id_pv_module
101
- ]
102
- ) {
103
- materialId = panelPolygon.moduleField.data.component_id_pv_module
104
- material = this.material.panel[materialId]
105
- }
106
- } else if (panelPolygon.moduleField.pvData) {
107
- if (this.material.panel[panelPolygon.moduleField.pvData.id]) {
108
- materialId = panelPolygon.moduleField.pvData.id
109
- material = this.material.panel[materialId]
110
- }
67
+ const moduleTextureId = panelPolygon.moduleField.pvData.hasOwnProperty(
68
+ 'module_texture_version_id'
69
+ ) && panelPolygon.moduleField.pvData.module_texture_version_id
70
+ ? panelPolygon.moduleField.pvData.module_texture_version_id
71
+ : 0
72
+ let materialId = 'default_' + moduleTextureId
73
+ let material = this.material.panel[materialId]
74
+ material.transparent = true
75
+ material.opacity = this.panelOpacity
76
+ if (panelPolygon.moduleField.data) {
77
+ if (
78
+ this.material.panel[
79
+ panelPolygon.moduleField.data.component_id_pv_module
80
+ ]
81
+ ) {
82
+ materialId = panelPolygon.moduleField.data.component_id_pv_module
83
+ material = this.material.panel[materialId]
84
+ }
85
+ } else if (panelPolygon.moduleField.pvData) {
86
+ if (this.material.panel[panelPolygon.moduleField.pvData.id]) {
87
+ materialId = panelPolygon.moduleField.pvData.id
88
+ material = this.material.panel[materialId]
111
89
  }
112
90
  }
113
- //2. create or update individual meshes
114
91
  if (
115
92
  !this.meshes.panelsMeshes[panelPolygon.id + '_top'] ||
116
93
  !this.meshes.panelsMeshes[panelPolygon.id + '_side']
117
94
  ) {
118
- //mesh creation
119
95
  const geometry = getBufferPanelGeometry(panelPolygon)
120
96
  const geometrySide = getBufferPanelSideGeometry(panelPolygon)
121
- //2a.Fill in panelTopGeometries & panelSideGeometries
122
- //gather all geometry with similar material together to merge them for faster rendering
123
97
  if (!panelTopGeometries[materialId]) {
124
98
  panelTopGeometries[materialId] = []
125
99
  }
126
100
  panelTopGeometries[materialId].push(geometry)
127
- if (panelPolygon.layer != 'user_deactivated_panel') {
128
- panelSideGeometries.push(geometrySide)
129
- }
101
+ panelSideGeometries.push(geometrySide)
130
102
  if (geometry && geometrySide) {
131
- const mesh = new THREE.Mesh(geometry, this.material.hidden)
103
+ const mesh = new THREE.Mesh(geometry, material)
132
104
  const meshSide = new THREE.Mesh(
133
105
  geometrySide,
134
106
  this.material.panelSide
@@ -137,18 +109,18 @@ export default {
137
109
  mesh.userData.type = 'panelsMeshes'
138
110
  mesh.userData.meshId = panelPolygon.id + '_top'
139
111
  mesh.userData.polygonId = panelPolygon.id
140
- this.scene.add(mesh)
141
112
  meshSide.userData.version = panelPolygon.version
142
113
  meshSide.userData.type = 'panelsMeshes'
143
114
  meshSide.userData.meshId = panelPolygon.id + '_side'
144
115
  meshSide.userData.polygonId = panelPolygon.id
116
+ geometry.dispose()
117
+ geometrySide.dispose()
145
118
  mesh.matrixAutoUpdate = false
146
119
  meshSide.matrixAutoUpdate = false
147
120
  this.meshes.panelsMeshes[panelPolygon.id + '_top'] = mesh
148
121
  this.meshes.panelsMeshes[panelPolygon.id + '_side'] = meshSide
149
122
  }
150
123
  } else {
151
- //update existing geometry
152
124
  const topMesh = this.meshes.panelsMeshes[panelPolygon.id + '_top']
153
125
  const sideMesh = this.meshes.panelsMeshes[panelPolygon.id + '_side']
154
126
  if (panelPolygon.version > topMesh.userData.version) {
@@ -164,9 +136,7 @@ export default {
164
136
  topMesh.geometry = topGeometry
165
137
  sideMesh.geometry = sideGeometry
166
138
  }
167
- if (panelPolygon.layer != 'user_deactivated_panel') {
168
- panelSideGeometries.push(sideMesh.geometry)
169
- }
139
+ panelSideGeometries.push(sideMesh.geometry)
170
140
  if (!panelTopGeometries[materialId]) {
171
141
  panelTopGeometries[materialId] = []
172
142
  }
@@ -175,7 +145,7 @@ export default {
175
145
  }
176
146
  })
177
147
 
178
- //removing unused mergedmesh
148
+ //removing unused mesh
179
149
  const materialIds = Object.keys(panelTopGeometries)
180
150
  const materialIdsToRemove = Object.keys(this.mergedPanelTopMeshes).filter(
181
151
  (key) => !materialIds.includes(key)
@@ -130,35 +130,17 @@ export default {
130
130
  this.applyTextureOnMesh(this.material.roof, this.mergedRoofMesh)
131
131
  },
132
132
  renderFlatRoofs() {
133
- this.clearRemovedOnes('flatRoofMeshes')
134
- let geometry
133
+ this.clearByType('flatRoofMeshes')
135
134
  this.roofs.forEach((roofPolygon) => {
136
- let mesh = this.meshes.flatRoofMeshes[roofPolygon.id]
137
- if (mesh) {
138
- if (mesh.userData.version < roofPolygon.version) {
139
- geometry = updateBufferRoofGeometry(
140
- roofPolygon.flatOutline,
141
- [],
142
- mesh.geometry
143
- )
144
- mesh.geometry = geometry
145
- mesh.userData.version = roofPolygon.version
146
- }
147
- mesh.visible = roofPolygon.maximumGap > maximumGapLimit
148
- } else {
149
- geometry = getBufferRoofGeometry(roofPolygon.flatOutline)
150
- if (geometry) {
151
- const material = this.material.curvedRoof
152
- mesh = new THREE.Mesh(geometry, material)
153
- mesh.userData.polygonId = roofPolygon.id
154
- mesh.userData.version = roofPolygon.version
155
- mesh.userData.type = 'flatRoofMeshes'
156
- mesh.userData.meshId = roofPolygon.id
157
-
158
- mesh.visible = roofPolygon.maximumGap > maximumGapLimit
159
- this.scene.add(mesh)
160
- this.meshes.flatRoofMeshes[roofPolygon.id] = mesh
161
- }
135
+ if (roofPolygon.maximumGap < maximumGapLimit) return
136
+ let geometry = getBufferRoofGeometry(roofPolygon.flatOutline)
137
+ if (geometry) {
138
+ const material = this.material.curvedRoof
139
+ const mesh = new THREE.Mesh(geometry, material)
140
+ mesh.itemData = roofPolygon
141
+ mesh.frustumCulled = false
142
+ this.scene.add(mesh)
143
+ this.meshes.flatRoofMeshes[roofPolygon.id] = mesh
162
144
  }
163
145
  })
164
146
  }
@@ -56,13 +56,6 @@ export default {
56
56
  nodeIds() {
57
57
  return this.nodes.map((p) => p.id)
58
58
  },
59
- setGlobalPositionRenderNeeded() {
60
- return !!this.geometryEvents.find(
61
- (e) =>
62
- e.id > this.lastGeometryEventIdDone &&
63
- e.name == 'setCameraGlobalPosition'
64
- )
65
- },
66
59
  fullRenderNeeded() {
67
60
  return !!this.geometryEvents.find(
68
61
  (e) => e.id > this.lastGeometryEventIdDone && e.name == 'full'
@@ -79,11 +72,6 @@ export default {
79
72
  let methodList = []
80
73
  if (this.fullRenderNeeded) {
81
74
  methodList = this.renderingMethodsByEvent({ name: 'full' })
82
- if (this.setGlobalPositionRenderNeeded) {
83
- methodList.push(
84
- ...this.renderingMethodsByEvent({ name: 'setCameraGlobalPosition' })
85
- )
86
- }
87
75
  } else {
88
76
  for (let geometryEvent of this.geometryEventsToDo) {
89
77
  for (let renderingMethod of this.renderingMethodsByEvent(
@@ -130,11 +118,6 @@ export default {
130
118
  })
131
119
  break
132
120
  case 'toolChange': //params.toolName
133
- methodList.push({
134
- name: 'renderEdges',
135
- method: this.renderEdges,
136
- arg: []
137
- })
138
121
  case 'marginIsSameChange': //params.polygon
139
122
  case 'marginDifferentChange': //params.polygon,index
140
123
  case 'marginSameChange': //params.polygon
@@ -149,13 +132,6 @@ export default {
149
132
  case 'removeNodes': //params.nodes
150
133
  case 'removeEdges': //params.edges
151
134
  case 'translate': //params.edges
152
- if (this.removeConstructionPolylineMesh) {
153
- methodList.push({
154
- name: 'removeConstructionPolyline',
155
- method: this.removeConstructionPolylineMesh,
156
- arg: []
157
- })
158
- }
159
135
  methodList.push({
160
136
  name: 'renderGeometry',
161
137
  method: this.renderGeometry,
@@ -256,24 +232,11 @@ export default {
256
232
  arg: []
257
233
  })
258
234
  case 'selectedRoofChange':
259
- case 'selectedObstacleChange':
260
235
  methodList.push({
261
236
  name: 'renderFlatRoofs',
262
237
  method: this.renderFlatRoofs,
263
238
  arg: []
264
239
  })
265
- methodList.push({
266
- name: 'renderRoofsMargin',
267
- method: this.renderRoofsMargin,
268
- arg: []
269
- })
270
- break
271
- case 'selectedModuleFieldChange':
272
- methodList.push({
273
- name: 'renderEdges',
274
- method: this.renderEdges,
275
- arg: []
276
- })
277
240
  break
278
241
  case 'subHandleSelectionChange':
279
242
  case 'masterHandleSelectionChange':
@@ -358,28 +321,12 @@ export default {
358
321
  arg: [params.roofIds]
359
322
  })
360
323
  break
361
- case 'selectedPanelChange':
362
- methodList.push({
363
- name: 'renderModuleFields',
364
- method: this.renderModuleFields,
365
- arg: []
366
- })
367
- break
368
- case 'removeConstruction':
369
- methodList.push({
370
- name: 'removeConstructionPolyline',
371
- method: this.removeConstructionPolyline,
372
- arg: []
373
- })
374
- break
375
324
  }
376
325
  return methodList
377
326
  },
378
327
  async renderMethods(methodList) {
379
328
  for (let item of methodList) {
380
- if (item.method) {
381
- await item.method(...item.arg)
382
- }
329
+ await item.method(...item.arg)
383
330
  }
384
331
  },
385
332
  renderGeometry() {
@@ -464,6 +411,12 @@ export default {
464
411
  }
465
412
  },
466
413
  beforeDestroy() {
414
+ if (this.tweenOrbit) {
415
+ this.tweenOrbit = null
416
+ }
417
+ if (this.tweenCamera) {
418
+ this.tweenCamera = null
419
+ }
467
420
  this.clearThreeObjects(this.scene)
468
421
 
469
422
  if (this.three_map) {
@@ -62,7 +62,7 @@ export default {
62
62
  },
63
63
  initialiseThree(isInteractive = true) {
64
64
  this.scene.background = new THREE.Color(0xb0b0b0)
65
- this.camera = this.perspectiveCamera
65
+
66
66
  this.camera.position.set(0, -100, 50)
67
67
  this.camera.up.set(0, 0, 1)
68
68
 
@@ -80,10 +80,6 @@ export default {
80
80
 
81
81
  // const axesHelper = new THREE.AxesHelper( 20 );
82
82
  // this.scene.add( axesHelper );
83
-
84
- this.scene.add(this.perspectiveCamera)
85
- this.scene.add(this.orthographicCamera)
86
-
87
83
  //Light
88
84
  const ambientLight = new THREE.AmbientLight(0xf0f0f0, 0.5)
89
85
  this.scene.add(ambientLight)
@@ -106,12 +102,7 @@ export default {
106
102
  this.camera,
107
103
  this.renderer.domElement
108
104
  )
109
- this.orbitControl.mouseButtons = {
110
- LEFT: THREE.MOUSE.PAN,
111
- RIGHT: THREE.MOUSE.ROTATE,
112
- MIDDLE: THREE.MOUSE.DOLLY
113
- }
114
- this.orbitControl.screenSpacePanning = false
105
+ this.orbitControl.maxPolarAngle = (Math.PI / 2) * (87 / 90)
115
106
  this.orbitControl.addEventListener('change', () => {
116
107
  this.orbitControlChange()
117
108
  })
@@ -123,7 +114,16 @@ export default {
123
114
  directionalLight2.dispose()
124
115
  },
125
116
  orbitControlChange() {
126
- this.render()
117
+ if (this.orbitControl.target.z != 0) {
118
+ this.orbitControl.target.set(
119
+ this.orbitControl.target.x,
120
+ this.orbitControl.target.y,
121
+ 0
122
+ )
123
+ this.orbitControl.update()
124
+ } else {
125
+ this.render()
126
+ }
127
127
  },
128
128
  onWindowResize() {
129
129
  this.camera.aspect = window.innerWidth / window.innerHeight
@@ -47,7 +47,6 @@ export async function hydratePolygons({
47
47
  })
48
48
  let roof = new Polygon(roof_outline, 'roof')
49
49
  roof.id = roofResp.roof_uuid
50
- roof.version = roofResp.version
51
50
  roof.name = roofResp.roof_name
52
51
  roof.shadingData = roofResp.shading_data
53
52
  roof.systemSolarSizeKWp = roofResp.system_solar_size_kWp
@@ -68,7 +67,6 @@ export async function hydratePolygons({
68
67
  })
69
68
  let obstacle = new Polygon(obstacle_outline, 'obstacle')
70
69
  obstacle.id = obstacleResp.obstacle_uuid
71
- obstacle.version = obstacleResp.version
72
70
  obstacle.height = obstacleResp.obstacle_height_above_ground_mm
73
71
  obstacle.isParallel = obstacleResp.obstacle_slope_is_parallel_to_roof
74
72
  obstacle = updateComputedGeometryPolygon(obstacle)
@@ -114,9 +114,10 @@ export function generateNodes3D(polygons) {
114
114
  node3D.masterHandle.open =
115
115
  node3D.belongsTo.filter((item) => item.polygon.outline[item.index].open)
116
116
  .length > 0
117
- node3D.masterHandle.selected = node3D.belongsTo.every(
118
- (item) => item.polygon.outline[item.index].selected
119
- )
117
+ node3D.masterHandle.selected =
118
+ node3D.belongsTo.filter(
119
+ (item) => item.polygon.outline[item.index].selected
120
+ ).length > node3D.belongsTo.length
120
121
  }
121
122
  })
122
123
  return nodes3D
@@ -179,13 +180,11 @@ export function generateEdges3D(polygons) {
179
180
  //check if edge2D already exist
180
181
  const nextPoint = outline[(i + 1) % outline.length]
181
182
  let edge3D = edges3D.find((edge) => {
182
- return (
183
- isAlmostSameSegment3D(
184
- [point, nextPoint],
185
- edge.outline,
186
- mmTolerance
187
- ) && edge.layer == polygon.layer
188
- )
183
+ isAlmostSameSegment3D(
184
+ [point, nextPoint],
185
+ edge.outline,
186
+ mmTolerance
187
+ ) && edge.layer == polygon.layer
189
188
  })
190
189
  if (!edge3D) {
191
190
  //create an edge at this position
Binary file