@eturnity/eturnity_3d 7.8.0 → 7.10.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",
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
 
@@ -186,7 +186,7 @@ export default {
186
186
  )
187
187
  //if no panels, no materialIds,
188
188
  for (let materialId of materialIdsToRemove) {
189
- this.clearMesh(this.mergedPanelTopMeshes[materialId])
189
+ this.clearMeshFromScene(this.mergedPanelTopMeshes[materialId], this.scene)
190
190
  delete this.mergedPanelTopMeshes[materialId]
191
191
  }
192
192
  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) => {