@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 +2 -2
- package/src/config.js +2 -1
- package/src/helper/UpdateRoofModuleFieldRelations.js +1 -1
- package/src/helper/cameraMixin.js +32 -0
- package/src/helper/render/clear.js +7 -7
- package/src/helper/render/edge.js +2 -0
- package/src/helper/render/imageOverlay.js +1 -1
- package/src/helper/render/panel.js +3 -3
- package/src/helper/render/tile.js +1 -1
- package/src/helper/renderMixin.js +35 -13
- package/src/helper/threeMixin.js +6 -4
- package/src/store/nodesEdgesCreation.js +22 -20
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eturnity/eturnity_3d",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "7.
|
|
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.
|
|
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 =
|
|
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.
|
|
39
|
-
this.
|
|
38
|
+
this.clearMeshFromScene(meshTop, this.scene)
|
|
39
|
+
this.clearMeshFromScene(meshSide, this.scene)
|
|
40
40
|
}
|
|
41
41
|
})
|
|
42
42
|
)
|
|
43
43
|
)
|
|
44
44
|
},
|
|
45
|
-
|
|
46
|
-
if (!mesh || !
|
|
45
|
+
clearMeshFromScene(mesh, scene) {
|
|
46
|
+
if (!mesh || !scene) {
|
|
47
47
|
return
|
|
48
48
|
}
|
|
49
|
-
|
|
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.
|
|
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.
|
|
82
|
+
this.clearMeshFromScene(mesh, this.scene)
|
|
83
83
|
}
|
|
84
84
|
})
|
|
85
85
|
},
|
|
@@ -34,7 +34,7 @@ export default {
|
|
|
34
34
|
methods: {
|
|
35
35
|
renderImageOverlayOnBackground() {
|
|
36
36
|
if (!this.imageOverlay || !this.imageOverlayMaterial) {
|
|
37
|
-
this.
|
|
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.
|
|
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.
|
|
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.
|
|
189
|
+
this.clearMeshFromScene(this.mergedPanelTopMeshes[materialId], this.scene)
|
|
190
190
|
delete this.mergedPanelTopMeshes[materialId]
|
|
191
191
|
}
|
|
192
192
|
this.mergedPanelSideMesh = this.updateOrCreateMergedMesh(
|
|
@@ -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
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
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,
|
package/src/helper/threeMixin.js
CHANGED
|
@@ -66,12 +66,14 @@ export default {
|
|
|
66
66
|
},
|
|
67
67
|
initialiseRenderer() {
|
|
68
68
|
this.resizeRenderer(this.DOMElement)
|
|
69
|
-
this.renderer
|
|
70
|
-
|
|
71
|
-
|
|
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
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
)
|
|
67
|
-
|
|
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,
|
|
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
|
-
|
|
116
|
-
|
|
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
|
-
|
|
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) => {
|