@eturnity/eturnity_3d 7.8.0 → 7.10.0-EPDM-10188.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@eturnity/eturnity_3d",
3
3
  "private": false,
4
- "version": "7.8.0",
4
+ "version": "7.10.0-EPDM-10188.0",
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.4.0",
13
+ "@eturnity/eturnity_maths": "7.10.0",
14
14
  "core-js": "^2.6.12",
15
15
  "cors": "^2.8.5",
16
16
  "earcut": "^2.2.4",
package/src/config.js CHANGED
@@ -4,7 +4,8 @@ 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 = 5
8
+ export const mmTolerance3dNode = 50
8
9
  export const earthRadius = 6371008
9
10
  export const marginAroundBuildingForCameraViewInMeter = 5
10
11
  export const layerColors = {
@@ -35,7 +35,7 @@ export function UpdateRoofModuleFieldRelations(state) {
35
35
  const intersection = intersectOutlines(moduleField.outline, roof.outline)
36
36
  if (intersection.length == 0) return false
37
37
  const intersectionArea = calculateArea(intersection[0])
38
- return intersectionArea > 100 && moduleField.area <= roof.area
38
+ return intersectionArea > 100 && moduleField.area <= roof.area + 0.1
39
39
  })
40
40
  //roofs on roof can lead to multiple roof under a point. moduleField is on the smallest
41
41
  let smallestRoof = null
@@ -315,6 +315,38 @@ export default {
315
315
  y
316
316
  })
317
317
  },
318
+ setCameraInitialPosition() {
319
+ if (this.roofs.length == 0) return
320
+ let newFov = 50
321
+ let bounds = this.roofsBounds
322
+ let targetVector = {
323
+ x: (bounds.xMax + bounds.xMin) / 2000,
324
+ y: (bounds.yMax + bounds.yMin) / 2000,
325
+ z: 0
326
+ }
327
+ let objectRadius_m = Math.max(
328
+ (bounds.xMax - bounds.xMin) / 2000,
329
+ (bounds.yMax - bounds.yMin) / 2000
330
+ )
331
+ let distance =
332
+ 5 + objectRadius_m / Math.sin(((newFov / 2) * Math.PI) / 180)
333
+ let cameraMoveVector = { x: 0, y: 0, z: distance }
334
+ const positionVector = addVector(targetVector, cameraMoveVector)
335
+ const position = [
336
+ positionVector.x,
337
+ positionVector.y - distance,
338
+ positionVector.z
339
+ ]
340
+ let target = [targetVector.x, targetVector.y, targetVector.z]
341
+
342
+ this.camera.position.set(position[0], position[1], position[2])
343
+ this.camera.updateProjectionMatrix()
344
+
345
+ this.orbitControl.target.set(target[0], target[1], target[2])
346
+ if (this.orbitControl && this.orbitControl.update) {
347
+ this.orbitControl.update()
348
+ }
349
+ },
318
350
  setCameraGlobalPosition() {
319
351
  if (this.roofs.length == 0) return
320
352
  if (this.camera.isOrthographicCamera) {
@@ -35,18 +35,18 @@ export default {
35
35
  let meshTop = this.meshes.panelsMeshes[panel.id + '_top']
36
36
  let meshSide = this.meshes.panelsMeshes[panel.id + '_side']
37
37
  if (meshTop || meshSide) {
38
- this.clearMesh(meshTop)
39
- this.clearMesh(meshSide)
38
+ this.clearMeshFromScene(meshTop, this.scene)
39
+ this.clearMeshFromScene(meshSide, this.scene)
40
40
  }
41
41
  })
42
42
  )
43
43
  )
44
44
  },
45
- clearMesh(mesh) {
46
- if (!mesh || !this.scene) {
45
+ clearMeshFromScene(mesh, scene) {
46
+ if (!mesh || !scene) {
47
47
  return
48
48
  }
49
- this.scene.remove(mesh)
49
+ scene.remove(mesh)
50
50
  if (mesh.geometry && mesh.geometry.dispose) {
51
51
  mesh.geometry.dispose()
52
52
  mesh.geometry = null
@@ -72,14 +72,14 @@ export default {
72
72
  clearEdgesRemovedOnes() {
73
73
  Object.values(this.meshes['edgeMeshes']).forEach((mesh) => {
74
74
  if (!this.edgeIds.includes(mesh.userData.edgeId)) {
75
- this.clearMesh(mesh)
75
+ this.clearMeshFromScene(mesh, this.scene)
76
76
  }
77
77
  })
78
78
  },
79
79
  clearRemovedOnes(type) {
80
80
  Object.values(this.meshes[type]).forEach((mesh) => {
81
81
  if (!this.polygonIds.includes(mesh.userData.polygonId)) {
82
- this.clearMesh(mesh)
82
+ this.clearMeshFromScene(mesh, this.scene)
83
83
  }
84
84
  })
85
85
  },
@@ -88,6 +88,8 @@ export default {
88
88
  cylinder.userData.type = 'edgeMeshes'
89
89
  cylinder.userData.layer = edge.layer
90
90
 
91
+ cylinder.frustumCulled = false
92
+ cylinder.renderOrder = 10
91
93
  this.meshes.edgeMeshes[edge.id] = cylinder
92
94
  this.scene.add(cylinder)
93
95
  }
@@ -34,7 +34,7 @@ export default {
34
34
  methods: {
35
35
  renderImageOverlayOnBackground() {
36
36
  if (!this.imageOverlay || !this.imageOverlayMaterial) {
37
- this.clearMesh(this.meshes.backgroundMesh)
37
+ this.clearMeshFromScene(this.meshes.backgroundMesh, this.scene)
38
38
  this.meshes.backgroundMesh = null
39
39
  return
40
40
  }
@@ -48,14 +48,14 @@ export default {
48
48
  poly.layer == 'user_deactivated_panel'
49
49
  )
50
50
  ) {
51
- this.clearMesh(mesh)
51
+ this.clearMeshFromScene(mesh, this.scene)
52
52
  }
53
53
  //clear panel on moduleField with overriden number of panel
54
54
  let panel = this.polygons.find(
55
55
  (poly) => mesh.userData.polygonId == poly.id
56
56
  )
57
57
  if (!panel || panel.moduleField.data.number_of_panels_override) {
58
- this.clearMesh(mesh)
58
+ this.clearMeshFromScene(mesh, this.scene)
59
59
  }
60
60
  })
61
61
 
@@ -73,6 +73,7 @@ export default {
73
73
  //2. create or update individual meshes
74
74
  // 2a. Fill in panelTopGeometries & panelSideGeometries
75
75
  if (!panelPolygon.visible) {
76
+ console.log('panelPolygon hidden', panelPolygon)
76
77
  return
77
78
  }
78
79
  if (panelPolygon.moduleField.data.number_of_panels_override) {
@@ -95,7 +96,7 @@ export default {
95
96
 
96
97
  materialId = 'default_' + moduleTextureId
97
98
  material = this.material.panel[materialId]
98
-
99
+
99
100
  if (panelPolygon.moduleField.data) {
100
101
  if (
101
102
  this.material.panel[
@@ -115,67 +116,74 @@ export default {
115
116
  material.opacity = this.panelOpacity
116
117
  }
117
118
  //2. create or update individual meshes
118
- if (
119
- !this.meshes.panelsMeshes[panelPolygon.id + '_top'] ||
120
- !this.meshes.panelsMeshes[panelPolygon.id + '_side']
121
- ) {
122
- //mesh creation
123
- const geometry = getBufferPanelGeometry(panelPolygon)
124
- const geometrySide = getBufferPanelSideGeometry(panelPolygon)
125
- //2a.Fill in panelTopGeometries & panelSideGeometries
119
+ //update existing geometry
120
+ if (this.meshes.panelsMeshes[panelPolygon.id + '_top']) {
121
+ const topMesh = this.meshes.panelsMeshes[panelPolygon.id + '_top']
122
+ if (panelPolygon.version > topMesh.userData.version) {
123
+ let topGeometry = updateBufferPanelGeometry(
124
+ panelPolygon,
125
+ topMesh.geometry
126
+ )
127
+ topMesh.geometry = topGeometry
128
+ }
129
+
130
+ if (!panelTopGeometries[materialId]) {
131
+ panelTopGeometries[materialId] = []
132
+ }
133
+ panelTopGeometries[materialId].push(topMesh.geometry)
134
+ topMesh.material = material
135
+ }
136
+ if (this.meshes.panelsMeshes[panelPolygon.id + '_side']) {
137
+ const sideMesh = this.meshes.panelsMeshes[panelPolygon.id + '_side']
138
+ if (panelPolygon.version > sideMesh.userData.version) {
139
+ let sideGeometry = updateBufferPanelSideGeometry(
140
+ panelPolygon,
141
+ sideMesh.geometry
142
+ )
143
+ sideMesh.geometry = sideGeometry
144
+ }
145
+ if (panelPolygon.layer != 'user_deactivated_panel') {
146
+ panelSideGeometries.push(sideMesh.geometry)
147
+ }
148
+ }
149
+ //2a.Fill in panelTopGeometries & panelSideGeometries
150
+ //mesh creation
151
+ if (!this.meshes.panelsMeshes[panelPolygon.id + '_top']) {
126
152
  //gather all geometry with similar material together to merge them for faster rendering
153
+ const geometry = getBufferPanelGeometry(panelPolygon)
127
154
  if (!panelTopGeometries[materialId]) {
128
155
  panelTopGeometries[materialId] = []
129
156
  }
130
157
  panelTopGeometries[materialId].push(geometry)
158
+ if (geometry) {
159
+ const mesh = new THREE.Mesh(geometry, this.material.hidden)
160
+ mesh.userData.version = panelPolygon.version
161
+ mesh.userData.type = 'panelsMeshes'
162
+ mesh.userData.meshId = panelPolygon.id + '_top'
163
+ mesh.userData.polygonId = panelPolygon.id
164
+ this.scene.add(mesh)
165
+ mesh.matrixAutoUpdate = false
166
+ this.meshes.panelsMeshes[panelPolygon.id + '_top'] = mesh
167
+ }
168
+ }
169
+ if (!this.meshes.panelsMeshes[panelPolygon.id + 'side']) {
170
+ //sidemesh creation
171
+ const geometrySide = getBufferPanelSideGeometry(panelPolygon)
131
172
  if (panelPolygon.layer != 'user_deactivated_panel') {
132
173
  panelSideGeometries.push(geometrySide)
133
174
  }
134
- if (geometry && geometrySide) {
135
- const mesh = new THREE.Mesh(geometry, this.material.hidden)
175
+ if (geometrySide) {
136
176
  const meshSide = new THREE.Mesh(
137
177
  geometrySide,
138
178
  this.material.panelSide
139
179
  )
140
- mesh.userData.version = panelPolygon.version
141
- mesh.userData.type = 'panelsMeshes'
142
- mesh.userData.meshId = panelPolygon.id + '_top'
143
- mesh.userData.polygonId = panelPolygon.id
144
- this.scene.add(mesh)
145
180
  meshSide.userData.version = panelPolygon.version
146
181
  meshSide.userData.type = 'panelsMeshes'
147
182
  meshSide.userData.meshId = panelPolygon.id + '_side'
148
183
  meshSide.userData.polygonId = panelPolygon.id
149
- mesh.matrixAutoUpdate = false
150
184
  meshSide.matrixAutoUpdate = false
151
- this.meshes.panelsMeshes[panelPolygon.id + '_top'] = mesh
152
185
  this.meshes.panelsMeshes[panelPolygon.id + '_side'] = meshSide
153
186
  }
154
- } else {
155
- //update existing geometry
156
- const topMesh = this.meshes.panelsMeshes[panelPolygon.id + '_top']
157
- const sideMesh = this.meshes.panelsMeshes[panelPolygon.id + '_side']
158
- if (panelPolygon.version > topMesh.userData.version) {
159
- let topGeometry = updateBufferPanelGeometry(
160
- panelPolygon,
161
- topMesh.geometry
162
- )
163
- let sideGeometry = updateBufferPanelSideGeometry(
164
- panelPolygon,
165
- sideMesh.geometry
166
- )
167
-
168
- topMesh.geometry = topGeometry
169
- sideMesh.geometry = sideGeometry
170
- }
171
- if (panelPolygon.layer != 'user_deactivated_panel') {
172
- panelSideGeometries.push(sideMesh.geometry)
173
- }
174
- if (!panelTopGeometries[materialId]) {
175
- panelTopGeometries[materialId] = []
176
- }
177
- panelTopGeometries[materialId].push(topMesh.geometry)
178
- topMesh.material = material
179
187
  }
180
188
  })
181
189
 
@@ -186,7 +194,10 @@ export default {
186
194
  )
187
195
  //if no panels, no materialIds,
188
196
  for (let materialId of materialIdsToRemove) {
189
- this.clearMesh(this.mergedPanelTopMeshes[materialId])
197
+ this.clearMeshFromScene(
198
+ this.mergedPanelTopMeshes[materialId],
199
+ this.scene
200
+ )
190
201
  delete this.mergedPanelTopMeshes[materialId]
191
202
  }
192
203
  this.mergedPanelSideMesh = this.updateOrCreateMergedMesh(
@@ -56,7 +56,7 @@ export default {
56
56
  return !tileToRenderIds.includes(id)
57
57
  })
58
58
  for (let id of idsToRemove) {
59
- this.clearMesh(this.meshes.tileMeshes[id])
59
+ this.clearMeshFromScene(this.meshes.tileMeshes[id], this.scene)
60
60
  }
61
61
  },
62
62
  async renderProviderTiles() {
@@ -65,6 +65,13 @@ export default {
65
65
  e.name == 'setCameraGlobalPosition'
66
66
  )
67
67
  },
68
+ setInitialPositionRenderNeeded() {
69
+ return !!this.geometryEvents.find(
70
+ (e) =>
71
+ e.id > this.lastGeometryEventIdDone &&
72
+ e.name == 'setInitialPositionRenderNeeded'
73
+ )
74
+ },
68
75
  fullRenderNeeded() {
69
76
  return !!this.geometryEvents.find(
70
77
  (e) => e.id > this.lastGeometryEventIdDone && e.name == 'full'
@@ -74,6 +81,9 @@ export default {
74
81
  return this.geometryEvents.filter(
75
82
  (e) => e.id > this.lastGeometryEventIdDone
76
83
  )
84
+ },
85
+ geometryEventsToDoWithoutFull() {
86
+ return this.geometryEventsToDo.filter((e) => e.name != 'full')
77
87
  }
78
88
  },
79
89
  methods: {
@@ -81,22 +91,17 @@ export default {
81
91
  let methodList = []
82
92
  if (this.fullRenderNeeded) {
83
93
  methodList = this.renderingMethodsByEvent({ name: 'full' })
84
- if (this.setGlobalPositionRenderNeeded) {
85
- methodList.push(
86
- ...this.renderingMethodsByEvent({ name: 'setCameraGlobalPosition' })
87
- )
88
- }
89
- } else {
90
- for (let geometryEvent of this.geometryEventsToDo) {
91
- for (let renderingMethod of this.renderingMethodsByEvent(
92
- geometryEvent
93
- )) {
94
- if (!methodList.map((m) => m.name).includes(renderingMethod.name)) {
95
- methodList.push(renderingMethod)
96
- }
94
+ }
95
+ for (let geometryEvent of this.geometryEventsToDoWithoutFull) {
96
+ for (let renderingMethod of this.renderingMethodsByEvent(
97
+ geometryEvent
98
+ )) {
99
+ if (!methodList.map((m) => m.name).includes(renderingMethod.name)) {
100
+ methodList.push(renderingMethod)
97
101
  }
98
102
  }
99
103
  }
104
+
100
105
  if (methodList.length) {
101
106
  this.renderMethods(methodList)
102
107
  this.render()
@@ -131,6 +136,13 @@ export default {
131
136
  arg: []
132
137
  })
133
138
  break
139
+ case 'setCameraInitialPosition':
140
+ methodList.push({
141
+ name: 'setCameraInitialPosition',
142
+ method: this.setCameraInitialPosition,
143
+ arg: []
144
+ })
145
+ break
134
146
  case 'toolChange': //params.toolName
135
147
  methodList.push({
136
148
  name: 'renderEdges',
@@ -213,6 +225,11 @@ export default {
213
225
  method: this.renderObstacles,
214
226
  arg: []
215
227
  })
228
+ methodList.push({
229
+ name: 'renderNodes',
230
+ method: this.renderNodes,
231
+ arg: []
232
+ })
216
233
  } else if (params.layer == 'obstacle') {
217
234
  methodList.push({
218
235
  name: 'renderBase',
@@ -257,6 +274,11 @@ export default {
257
274
  case 'newRoofs':
258
275
  case 'moveNodesZ': //params.nodes
259
276
  case 'solveFlatness': //params.roof
277
+ methodList.push({
278
+ name: 'renderEdges',
279
+ method: this.renderEdges,
280
+ arg: []
281
+ })
260
282
  methodList.push({
261
283
  name: 'renderBuilding',
262
284
  method: this.renderBuilding,
@@ -66,12 +66,14 @@ export default {
66
66
  },
67
67
  initialiseRenderer() {
68
68
  this.resizeRenderer(this.DOMElement)
69
- this.renderer.setPixelRatio(window.devicePixelRatio)
70
- this.renderer.toneMappingExposure = 0.01
71
- this.DOMElement.appendChild(this.renderer.domElement)
69
+ if (this.renderer) {
70
+ this.renderer.setPixelRatio(window.devicePixelRatio)
71
+ this.renderer.toneMappingExposure = 0.01
72
+ this.DOMElement.appendChild(this.renderer.domElement)
73
+ }
72
74
  },
73
75
  resizeRenderer() {
74
- if(this.DOMElement){
76
+ if (this.DOMElement) {
75
77
  const width = this.DOMElement.clientWidth
76
78
  const height = this.DOMElement.clientHeight
77
79
  this.renderer.domElement.style.width = width + 'px'
@@ -1,5 +1,5 @@
1
1
  import { Point, Line } from '@eturnity/eturnity_maths'
2
- import { mmTolerance } from '../config'
2
+ import { mmTolerance, mmTolerance3dNode } from '../config'
3
3
  import {
4
4
  isAlmostSamePoint3D,
5
5
  isAlmostSameSegment2D,
@@ -54,20 +54,17 @@ export function generateNodes2D(polygons) {
54
54
  //all nodes has been created. now lets update open/selected field
55
55
  nodes2D.forEach((node2D) => {
56
56
  if (node2D.masterHandle) {
57
- node2D.masterHandle.open =
58
- node2D.belongsTo.filter(
59
- (item) =>
60
- item.polygon.outline[item.index].open ||
61
- item.polygon.outline[item.index].hasWarning
62
- ).length > 0
63
- node2D.masterHandle.hasWarning =
64
- node2D.belongsTo.filter(
65
- (item) => item.polygon.outline[item.index].hasWarning
66
- ).length > 0
67
- node2D.masterHandle.selected =
68
- node2D.belongsTo.filter(
69
- (item) => item.polygon.outline[item.index].selected
70
- ).length == node2D.belongsTo.length
57
+ node2D.masterHandle.open = node2D.belongsTo.some(
58
+ (item) =>
59
+ item.polygon.outline[item.index].open ||
60
+ item.polygon.outline[item.index].hasWarning
61
+ )
62
+ node2D.masterHandle.hasWarning = node2D.belongsTo.some(
63
+ (item) => item.polygon.outline[item.index].hasWarning
64
+ )
65
+ node2D.masterHandle.selected = node2D.belongsTo.every(
66
+ (item) => item.polygon.outline[item.index].selected
67
+ )
71
68
  }
72
69
  })
73
70
  return nodes2D
@@ -84,7 +81,7 @@ export function generateNodes3D(polygons) {
84
81
  outline.forEach((point, i) => {
85
82
  //check if nodes2D already exist
86
83
  let node3D = nodes3D.find((node) =>
87
- isAlmostSamePoint3D(node, point, mmTolerance)
84
+ isAlmostSamePoint3D(node, point, mmTolerance3dNode)
88
85
  )
89
86
  if (!node3D) {
90
87
  node3D = new Point(point.x, point.y, point.z, polygon.layer)
@@ -111,9 +108,9 @@ export function generateNodes3D(polygons) {
111
108
  //all nodes has been created. now lets update open/selected field
112
109
  nodes3D.forEach((node3D) => {
113
110
  if (node3D.masterHandle) {
114
- node3D.masterHandle.open =
115
- node3D.belongsTo.filter((item) => item.polygon.outline[item.index].open)
116
- .length > 0
111
+ node3D.masterHandle.open = node3D.belongsTo.some(
112
+ (item) => item.polygon.outline[item.index].open
113
+ )
117
114
  node3D.masterHandle.selected = node3D.belongsTo.every(
118
115
  (item) => item.polygon.outline[item.index].selected
119
116
  )
@@ -131,7 +128,8 @@ export function generateEdges2D(polygons) {
131
128
  .forEach((polygon) => {
132
129
  const outline = polygon.outline
133
130
  outline.forEach((point, i) => {
134
- if (!polygon.isClosed && i == outline.length - 1) {
131
+ const isLastPointOfPolygon = i == outline.length - 1
132
+ if (!polygon.isClosed && isLastPointOfPolygon) {
135
133
  return
136
134
  }
137
135
  //check if edge2D already exist
@@ -176,6 +174,10 @@ export function generateEdges3D(polygons) {
176
174
  .forEach((polygon) => {
177
175
  const outline = polygon.outline
178
176
  outline.forEach((point, i) => {
177
+ const isLastPointOfPolygon = i == outline.length - 1
178
+ if (!polygon.isClosed && isLastPointOfPolygon) {
179
+ return
180
+ }
179
181
  //check if edge2D already exist
180
182
  const nextPoint = outline[(i + 1) % outline.length]
181
183
  let edge3D = edges3D.find((edge) => {