@eturnity/eturnity_3d 8.16.1 → 8.16.2-EPDM-14200.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 +1 -1
- package/src/components/ThreeCanvasViewer.vue +0 -1
- package/src/config.js +11 -0
- package/src/helper/UpdateRoofModuleFieldRelations.js +169 -0
- package/src/helper/render/clear.js +16 -20
- package/src/helper/render/edge.js +1 -2
- package/src/helper/render/geometryHandler.js +53 -1
- package/src/helper/render/moduleField.js +75 -20
- package/src/helper/render/overlay.js +1 -0
- package/src/store/hydrateData.js +15 -3
package/package.json
CHANGED
package/src/config.js
CHANGED
|
@@ -282,3 +282,14 @@ export const hitOptionStroke = {
|
|
|
282
282
|
|
|
283
283
|
export const dragHeightSensitivity = 20
|
|
284
284
|
export const snapLimit = 100
|
|
285
|
+
|
|
286
|
+
export const fittingPanelsColorMap = {
|
|
287
|
+
black: '#000000',
|
|
288
|
+
blue: '#0068DE',
|
|
289
|
+
brown: '#5C4033',
|
|
290
|
+
'rustic red': '#8B0000',
|
|
291
|
+
terracotta: '#E35336',
|
|
292
|
+
transparent: 'transparent',
|
|
293
|
+
white: '#ffffff',
|
|
294
|
+
default: '#0068DE',
|
|
295
|
+
}
|
|
@@ -3,7 +3,11 @@ import {
|
|
|
3
3
|
verticalProjectionOnPlane,
|
|
4
4
|
intersectOutlines,
|
|
5
5
|
calculateArea,
|
|
6
|
+
isSelfIntersecting,
|
|
7
|
+
isPolygonInsidePolygon,
|
|
8
|
+
getConcaveOutlines,
|
|
6
9
|
} from '@eturnity/eturnity_maths'
|
|
10
|
+
import { fittingPanelsColorMap } from '../config'
|
|
7
11
|
//this function just update the "roof" and "moduleField(s)" properties of panels,moduleFields and roofs
|
|
8
12
|
export function UpdateRoofModuleFieldRelations(state) {
|
|
9
13
|
let moduleFields = state.polygons.filter(
|
|
@@ -78,3 +82,168 @@ export function removeModuleFieldAndPanelsOnNoOrMultipleRoofs(state) {
|
|
|
78
82
|
]
|
|
79
83
|
return state
|
|
80
84
|
}
|
|
85
|
+
|
|
86
|
+
export function updateModuleFieldFittingPanels({
|
|
87
|
+
moduleField,
|
|
88
|
+
state,
|
|
89
|
+
preComputed = false,
|
|
90
|
+
outline = [],
|
|
91
|
+
holes = [],
|
|
92
|
+
}) {
|
|
93
|
+
delete moduleField.fittingPanels
|
|
94
|
+
const { has_fitting_panels, fitting_panel_area_m2 } = moduleField.data
|
|
95
|
+
const hasFittingPanels = has_fitting_panels && fitting_panel_area_m2 > 0
|
|
96
|
+
if (!hasFittingPanels) return
|
|
97
|
+
|
|
98
|
+
const computedOutline = preComputed
|
|
99
|
+
? outline
|
|
100
|
+
: getModuleFieldRoofIntersection(
|
|
101
|
+
moduleField,
|
|
102
|
+
getRoofInnerMarginOutline(moduleField.roof, moduleField, state).outline
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
const computedHoles = preComputed
|
|
106
|
+
? holes
|
|
107
|
+
: getModuleFieldHoleOutlines(moduleField)
|
|
108
|
+
|
|
109
|
+
// Clean up holes outside of the outline
|
|
110
|
+
const holesClean = computedHoles
|
|
111
|
+
.map((hole) => intersectOutlines(hole, computedOutline)[0])
|
|
112
|
+
.filter(Boolean)
|
|
113
|
+
|
|
114
|
+
// map backsheet color to hex color
|
|
115
|
+
const backSheetColor = moduleField.pvData?.backsheet_color || 'default'
|
|
116
|
+
const mappedColor = fittingPanelsColorMap[backSheetColor]
|
|
117
|
+
|
|
118
|
+
moduleField.fittingPanels = {
|
|
119
|
+
outline: computedOutline,
|
|
120
|
+
holes: holesClean,
|
|
121
|
+
visible: true,
|
|
122
|
+
color: mappedColor,
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export function getRoofInnerMarginOutline(roof, moduleField, state) {
|
|
127
|
+
let roofInnerMarginOutline = roof.margins.innerOutline
|
|
128
|
+
let isOutlineSelfIntersecting = false
|
|
129
|
+
let sumAllArea = 0
|
|
130
|
+
if (isSelfIntersecting(roofInnerMarginOutline)) {
|
|
131
|
+
let selfIntersections = intersectOutlines(
|
|
132
|
+
roof.margins.innerOutline,
|
|
133
|
+
roof.margins.innerOutline
|
|
134
|
+
)
|
|
135
|
+
let sumAllArea = selfIntersections.reduce((acc, cur) => {
|
|
136
|
+
acc += calculateArea(cur)
|
|
137
|
+
return acc
|
|
138
|
+
}, 0)
|
|
139
|
+
if (moduleField) {
|
|
140
|
+
selfIntersections = selfIntersections.filter((i) => {
|
|
141
|
+
if (calculateArea(i) < 0.05 * sumAllArea) {
|
|
142
|
+
return false
|
|
143
|
+
}
|
|
144
|
+
let MFintersections = intersectOutlines(moduleField.outline, i)
|
|
145
|
+
if (MFintersections.length > 0) {
|
|
146
|
+
return true
|
|
147
|
+
}
|
|
148
|
+
})
|
|
149
|
+
} else {
|
|
150
|
+
if (state.pointer && state.pointer.reality_x && state.pointer.reality_y) {
|
|
151
|
+
let P = {
|
|
152
|
+
x: state.pointer.reality_x,
|
|
153
|
+
y: state.pointer.reality_y,
|
|
154
|
+
z: 0,
|
|
155
|
+
}
|
|
156
|
+
let pointerIntersections = selfIntersections.filter((outline) =>
|
|
157
|
+
isInsidePolygon(P, outline)
|
|
158
|
+
)
|
|
159
|
+
if (pointerIntersections.length) {
|
|
160
|
+
selfIntersections = pointerIntersections
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
let sortedSelfIntersections = selfIntersections.sort(
|
|
165
|
+
(a, b) => calculateArea(b) - calculateArea(a)
|
|
166
|
+
)
|
|
167
|
+
if (sortedSelfIntersections.length) {
|
|
168
|
+
roofInnerMarginOutline = sortedSelfIntersections[0]
|
|
169
|
+
isOutlineSelfIntersecting = true
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
return {
|
|
173
|
+
isSelfIntersecting: isOutlineSelfIntersecting,
|
|
174
|
+
outline: roofInnerMarginOutline,
|
|
175
|
+
totalArea: sumAllArea,
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
export function getModuleFieldRoofIntersection(
|
|
180
|
+
moduleField,
|
|
181
|
+
roofInnerMarginOutline
|
|
182
|
+
) {
|
|
183
|
+
const roof = moduleField.roof
|
|
184
|
+
let intersection = intersectOutlines(
|
|
185
|
+
roofInnerMarginOutline,
|
|
186
|
+
moduleField.outline
|
|
187
|
+
)[0]
|
|
188
|
+
|
|
189
|
+
intersection = intersection?.map((v) => {
|
|
190
|
+
return {
|
|
191
|
+
...v,
|
|
192
|
+
z: verticalProjectionOnPlane(v, roof.normalVector, roof.flatOutline[0]).z,
|
|
193
|
+
}
|
|
194
|
+
})
|
|
195
|
+
return intersection
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
export function getModuleFieldHoleOutlines(moduleField) {
|
|
199
|
+
const obstacles = []
|
|
200
|
+
const roof = moduleField.roof
|
|
201
|
+
if (roof.moduleFields && roof.moduleFields.length > 0) {
|
|
202
|
+
obstacles.push(
|
|
203
|
+
...roof.moduleFields.filter((obstacle) => {
|
|
204
|
+
return (
|
|
205
|
+
obstacle.id != moduleField.id && //obstacle cannot be MF itself
|
|
206
|
+
obstacle.panels &&
|
|
207
|
+
obstacle.panels.length > 0 && //obstacle cannot be a moduleField without panels on
|
|
208
|
+
!isPolygonInsidePolygon(moduleField.outline, obstacle.outline) && //obstacle cannot be a container of the polygon we try to compute
|
|
209
|
+
(obstacle.priority >= moduleField.priority ||
|
|
210
|
+
isPolygonInsidePolygon(obstacle.outline, moduleField.outline)) //obstacle cannot be a MF with lower prio level (except if fully inside)
|
|
211
|
+
)
|
|
212
|
+
})
|
|
213
|
+
)
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
let groupedConcavePanelOutlines = []
|
|
217
|
+
obstacles.forEach((moduleField) => {
|
|
218
|
+
if (moduleField.panels.length) {
|
|
219
|
+
let groupedConcavePanelData = getConcaveOutlines(
|
|
220
|
+
moduleField.panels,
|
|
221
|
+
moduleField.panels[0].outline
|
|
222
|
+
)
|
|
223
|
+
groupedConcavePanelOutlines.push(...groupedConcavePanelData.outlines)
|
|
224
|
+
}
|
|
225
|
+
})
|
|
226
|
+
|
|
227
|
+
function verticalProjectionOnRoofFlatFace(v) {
|
|
228
|
+
const projectedZ = verticalProjectionOnPlane(
|
|
229
|
+
v,
|
|
230
|
+
roof.normalVector,
|
|
231
|
+
roof.flatOutline[0]
|
|
232
|
+
).z
|
|
233
|
+
return { ...v, z: projectedZ }
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
groupedConcavePanelOutlines = groupedConcavePanelOutlines.map((outline) =>
|
|
237
|
+
outline.map((v) => verticalProjectionOnRoofFlatFace(v)).reverse()
|
|
238
|
+
)
|
|
239
|
+
|
|
240
|
+
const roofObstacleOutlines = roof.holes.map((hole) =>
|
|
241
|
+
hole.margins.outterOutline.map((v) => verticalProjectionOnRoofFlatFace(v))
|
|
242
|
+
)
|
|
243
|
+
const obstacleOutLine = [
|
|
244
|
+
...roofObstacleOutlines,
|
|
245
|
+
...groupedConcavePanelOutlines,
|
|
246
|
+
]
|
|
247
|
+
|
|
248
|
+
return obstacleOutLine
|
|
249
|
+
}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import * as THREE from 'three'
|
|
2
|
+
|
|
1
3
|
export default {
|
|
2
4
|
methods: {
|
|
3
5
|
clearThreeObjects(obj) {
|
|
@@ -31,18 +33,7 @@ export default {
|
|
|
31
33
|
return
|
|
32
34
|
}
|
|
33
35
|
scene.remove(mesh)
|
|
34
|
-
|
|
35
|
-
mesh.geometry.dispose()
|
|
36
|
-
mesh.geometry = null
|
|
37
|
-
}
|
|
38
|
-
if (mesh.texture && mesh.texture.dispose) {
|
|
39
|
-
mesh.texture.dispose()
|
|
40
|
-
mesh.texture = null
|
|
41
|
-
}
|
|
42
|
-
if (mesh.material && mesh.material.dispose) {
|
|
43
|
-
mesh.material.dispose()
|
|
44
|
-
mesh.material = null
|
|
45
|
-
}
|
|
36
|
+
this.disposeMesh(mesh)
|
|
46
37
|
if (
|
|
47
38
|
mesh.userData.meshId &&
|
|
48
39
|
this.meshes[mesh.userData.type][mesh.userData.meshId]
|
|
@@ -68,19 +59,24 @@ export default {
|
|
|
68
59
|
})
|
|
69
60
|
},
|
|
70
61
|
clearByType(type) {
|
|
71
|
-
Object.values(this.meshes[type]).forEach((
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
}
|
|
77
|
-
mesh.material = null
|
|
78
|
-
this.scene.remove(mesh)
|
|
62
|
+
Object.values(this.meshes[type]).forEach((object) => {
|
|
63
|
+
object instanceof THREE.Group
|
|
64
|
+
? object.children.forEach((c) => this.disposeMesh(c))
|
|
65
|
+
: this.disposeMesh(object)
|
|
66
|
+
this.scene.remove(object)
|
|
79
67
|
})
|
|
80
68
|
this.meshes[type] = {}
|
|
81
69
|
if (this.renderer) {
|
|
82
70
|
this.renderer.renderLists.dispose()
|
|
83
71
|
}
|
|
84
72
|
},
|
|
73
|
+
disposeMesh(mesh) {
|
|
74
|
+
if (mesh.geometry && mesh.geometry.dispose) mesh.geometry.dispose()
|
|
75
|
+
if (mesh.material && mesh.material.dispose) mesh.material.dispose()
|
|
76
|
+
if (mesh.texture && mesh.texture.dispose) mesh.texture.dispose()
|
|
77
|
+
mesh.geometry = null
|
|
78
|
+
mesh.material = null
|
|
79
|
+
mesh.texture = null
|
|
80
|
+
},
|
|
85
81
|
},
|
|
86
82
|
}
|
|
@@ -88,10 +88,9 @@ export default {
|
|
|
88
88
|
cylinder.userData.type = 'edgeMeshes'
|
|
89
89
|
cylinder.userData.layer = edge.layer
|
|
90
90
|
cylinder.frustumCulled = false
|
|
91
|
-
cylinder.renderOrder = 10
|
|
92
91
|
|
|
93
92
|
cylinder.frustumCulled = false
|
|
94
|
-
cylinder.renderOrder =
|
|
93
|
+
cylinder.renderOrder = 15
|
|
95
94
|
this.meshes.edgeMeshes[edge.id] = cylinder
|
|
96
95
|
this.scene.add(cylinder)
|
|
97
96
|
}
|
|
@@ -410,7 +410,7 @@ export function getBufferObstacleSideGeometry(obstaclePolygon, roofPolygon) {
|
|
|
410
410
|
|
|
411
411
|
export function getBufferModuleFieldGeometry(moduleFieldPolygon) {
|
|
412
412
|
const roofPolygon = moduleFieldPolygon.roof
|
|
413
|
-
const moduleHeight =
|
|
413
|
+
const moduleHeight = 20
|
|
414
414
|
//get lowest verticalProjection
|
|
415
415
|
const normalVector = roofPolygon.normalVector
|
|
416
416
|
|
|
@@ -747,3 +747,55 @@ export function getExtrusionGeometry(
|
|
|
747
747
|
const geometry = new THREE.ExtrudeGeometry(shapes, settings)
|
|
748
748
|
return geometry
|
|
749
749
|
}
|
|
750
|
+
|
|
751
|
+
export function getFittingPanelsBufferGeometry(
|
|
752
|
+
outline,
|
|
753
|
+
holes = [],
|
|
754
|
+
moduleFieldPolygon
|
|
755
|
+
) {
|
|
756
|
+
const croppedHolesOutline = holes
|
|
757
|
+
.map((hole) => {
|
|
758
|
+
const cropedHoleOutline = intersectOutlines(hole, outline)[0] || []
|
|
759
|
+
return cropedHoleOutline.map((p) => {
|
|
760
|
+
return {
|
|
761
|
+
x: p.x,
|
|
762
|
+
y: p.y,
|
|
763
|
+
z: verticalProjectionOnPlane(
|
|
764
|
+
p,
|
|
765
|
+
moduleFieldPolygon.normalVector,
|
|
766
|
+
moduleFieldPolygon.flatOutline[0]
|
|
767
|
+
).z,
|
|
768
|
+
}
|
|
769
|
+
})
|
|
770
|
+
})
|
|
771
|
+
.filter((outline) => !!outline)
|
|
772
|
+
|
|
773
|
+
// add offset to vertices for rendering
|
|
774
|
+
const FITTING_PANELS_OFFSET = 2
|
|
775
|
+
const vectorOffset = multiplyVector(
|
|
776
|
+
FITTING_PANELS_OFFSET,
|
|
777
|
+
moduleFieldPolygon.normalVector
|
|
778
|
+
)
|
|
779
|
+
const vertexList = [outline, ...croppedHolesOutline].flat()
|
|
780
|
+
vertexList.forEach((point) => {
|
|
781
|
+
const offset = addVector(point, vectorOffset)
|
|
782
|
+
Object.assign(point, offset)
|
|
783
|
+
})
|
|
784
|
+
|
|
785
|
+
const geometry = new THREE.BufferGeometry()
|
|
786
|
+
const triangleVertices = getTriangleVerticesFromOutline(
|
|
787
|
+
outline,
|
|
788
|
+
croppedHolesOutline
|
|
789
|
+
)
|
|
790
|
+
if (hasNaN(triangleVertices)) {
|
|
791
|
+
return null
|
|
792
|
+
}
|
|
793
|
+
const vertices = new Float32Array(triangleVertices)
|
|
794
|
+
|
|
795
|
+
const uvs = new Float32Array([1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0])
|
|
796
|
+
geometry.setAttribute('position', new THREE.BufferAttribute(vertices, 3))
|
|
797
|
+
geometry.setAttribute('uv', new THREE.BufferAttribute(uvs, 2))
|
|
798
|
+
geometry.computeVertexNormals()
|
|
799
|
+
geometry.userData.version = 0
|
|
800
|
+
return geometry
|
|
801
|
+
}
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import * as THREE from 'three'
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
getBufferModuleFieldGeometry,
|
|
4
|
+
getFittingPanelsBufferGeometry,
|
|
5
|
+
} from './geometryHandler'
|
|
6
|
+
|
|
3
7
|
export default {
|
|
4
8
|
methods: {
|
|
5
9
|
data() {
|
|
@@ -13,27 +17,78 @@ export default {
|
|
|
13
17
|
['moduleField', 'tmpModuleField'].includes(p.layer)
|
|
14
18
|
)
|
|
15
19
|
moduleFieldPolygons.forEach((moduleFieldPolygon) => {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
mesh
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
20
|
+
const panelOverrideMesh =
|
|
21
|
+
this.renderModuleFieldPanelOverride(moduleFieldPolygon)
|
|
22
|
+
const fittingPanelsMesh =
|
|
23
|
+
this.renderModuleFieldFittingPanels(moduleFieldPolygon)
|
|
24
|
+
|
|
25
|
+
if (!panelOverrideMesh && !fittingPanelsMesh) return
|
|
26
|
+
|
|
27
|
+
const meshList = [panelOverrideMesh, fittingPanelsMesh]
|
|
28
|
+
const group = new THREE.Group()
|
|
29
|
+
meshList.forEach((mesh) => {
|
|
30
|
+
if (mesh) group.add(mesh)
|
|
31
|
+
})
|
|
32
|
+
group.matrixAutoUpdate = false
|
|
33
|
+
group.userData.version = moduleFieldPolygon.version
|
|
34
|
+
group.userData.type = 'moduleFieldsMeshes'
|
|
35
|
+
group.userData.layer = moduleFieldPolygon.layer
|
|
36
|
+
group.userData.meshId = moduleFieldPolygon.id
|
|
37
|
+
group.userData.polygonId = moduleFieldPolygon.id
|
|
38
|
+
group.visible = this.areModuleFieldsVisible
|
|
39
|
+
this.scene.add(group)
|
|
40
|
+
this.meshes.moduleFieldsMeshes[moduleFieldPolygon.id] = group
|
|
41
|
+
return
|
|
35
42
|
})
|
|
36
43
|
},
|
|
44
|
+
renderModuleFieldPanelOverride(moduleFieldPolygon) {
|
|
45
|
+
if (!moduleFieldPolygon?.data?.number_of_panels_override) return
|
|
46
|
+
const geometry = getBufferModuleFieldGeometry(moduleFieldPolygon)
|
|
47
|
+
const material = this.material.moduleFieldWithPanelOveride
|
|
48
|
+
if (geometry) {
|
|
49
|
+
const mesh = new THREE.Mesh(geometry, material)
|
|
50
|
+
mesh.matrixAutoUpdate = false
|
|
51
|
+
mesh.userData.version = moduleFieldPolygon.version
|
|
52
|
+
mesh.userData.type = 'moduleFieldsMeshes_panelOverride'
|
|
53
|
+
mesh.userData.layer = moduleFieldPolygon.layer
|
|
54
|
+
mesh.userData.meshId = moduleFieldPolygon.id
|
|
55
|
+
mesh.userData.polygonId = moduleFieldPolygon.id
|
|
56
|
+
mesh.renderOrder = 5
|
|
57
|
+
return mesh
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
renderModuleFieldFittingPanels(moduleFieldPolygon) {
|
|
61
|
+
if (!moduleFieldPolygon?.fittingPanels?.outline) return
|
|
62
|
+
const { outline, holes, visible, color } =
|
|
63
|
+
moduleFieldPolygon.fittingPanels
|
|
64
|
+
|
|
65
|
+
const geometry = getFittingPanelsBufferGeometry(
|
|
66
|
+
outline,
|
|
67
|
+
holes,
|
|
68
|
+
moduleFieldPolygon
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
const isTransparent = color === 'transparent'
|
|
72
|
+
const material = new THREE.MeshBasicMaterial({
|
|
73
|
+
color: isTransparent ? '#ffffff' : color,
|
|
74
|
+
side: THREE.DoubleSide,
|
|
75
|
+
transparent: true,
|
|
76
|
+
opacity: isTransparent ? 0.2 : 0.8,
|
|
77
|
+
})
|
|
78
|
+
|
|
79
|
+
if (geometry) {
|
|
80
|
+
const mesh = new THREE.Mesh(geometry, material)
|
|
81
|
+
mesh.visible = visible
|
|
82
|
+
mesh.matrixAutoUpdate = false
|
|
83
|
+
mesh.userData.version = moduleFieldPolygon.version
|
|
84
|
+
mesh.userData.type = 'moduleFieldsMeshes_fittingPanels'
|
|
85
|
+
mesh.userData.layer = moduleFieldPolygon.layer
|
|
86
|
+
mesh.userData.meshId = moduleFieldPolygon.id
|
|
87
|
+
mesh.userData.polygonId = moduleFieldPolygon.id
|
|
88
|
+
mesh.renderOrder = 5
|
|
89
|
+
return mesh
|
|
90
|
+
}
|
|
91
|
+
},
|
|
37
92
|
setModuleFieldsVisibility(isVisible) {
|
|
38
93
|
this.areModuleFieldsVisible = isVisible
|
|
39
94
|
Object.values(this.meshes['moduleFieldsMeshes']).forEach(
|
package/src/store/hydrateData.js
CHANGED
|
@@ -2,13 +2,15 @@
|
|
|
2
2
|
import {
|
|
3
3
|
Polygon,
|
|
4
4
|
updateComputedGeometryPolygon,
|
|
5
|
-
getRoofMarginOutline,
|
|
6
5
|
getObstacleMarginOutline,
|
|
7
|
-
midPoint,
|
|
8
6
|
} from '@eturnity/eturnity_maths'
|
|
9
7
|
import OverlayLayer from '../Overlay/OverlayLayer'
|
|
10
8
|
import getLayers from '../utils/layers'
|
|
11
9
|
import { UpdateRoofObstacleRelations } from '../helper/UpdateRoofObstacleRelations'
|
|
10
|
+
import {
|
|
11
|
+
updateModuleFieldFittingPanels,
|
|
12
|
+
UpdateRoofModuleFieldRelations,
|
|
13
|
+
} from '../helper/UpdateRoofModuleFieldRelations'
|
|
12
14
|
function sanitizedOutline(outline) {
|
|
13
15
|
return outline.reduce((accumulator, currentValue) => {
|
|
14
16
|
if (
|
|
@@ -138,7 +140,8 @@ export async function hydratePolygons({
|
|
|
138
140
|
moduleField.data.row_spacing_valley_mm =
|
|
139
141
|
moduleFieldResp.row_spacing_valley_mm
|
|
140
142
|
moduleField.data.offset_percent = moduleFieldResp.offset_percent
|
|
141
|
-
moduleField.data.fitting_panel_area_m2 =
|
|
143
|
+
moduleField.data.fitting_panel_area_m2 =
|
|
144
|
+
moduleFieldResp.fitting_panel_area_m2
|
|
142
145
|
moduleField.data.has_fitting_panels = moduleFieldResp.has_fitting_panels
|
|
143
146
|
moduleField.data.panel_orientation = moduleFieldResp.panel_orientation
|
|
144
147
|
moduleField.data.panel_direction_degrees =
|
|
@@ -295,4 +298,13 @@ export async function hydrateData({ state, commit }, data) {
|
|
|
295
298
|
state.polygons = hydratationResult.polygons
|
|
296
299
|
|
|
297
300
|
state = UpdateRoofObstacleRelations(state)
|
|
301
|
+
state = UpdateRoofModuleFieldRelations(state)
|
|
302
|
+
state.polygons
|
|
303
|
+
.filter((poly) => poly.layer == 'moduleField')
|
|
304
|
+
.forEach((moduleField) => {
|
|
305
|
+
updateModuleFieldFittingPanels({
|
|
306
|
+
moduleField,
|
|
307
|
+
state,
|
|
308
|
+
})
|
|
309
|
+
})
|
|
298
310
|
}
|