From 50d083505fb539df01049f321de55b323433b56a Mon Sep 17 00:00:00 2001
From: Florian Kotthoff <74312290+FlorianK13@users.noreply.github.com>
Date: Sat, 21 Sep 2024 08:10:47 +0200
Subject: [PATCH 01/21] Refactor handleInteraction #291
---
.../ThreeViewer/Controls/CustomMapControl.jsx | 20 +++++++++++--------
1 file changed, 12 insertions(+), 8 deletions(-)
diff --git a/src/components/ThreeViewer/Controls/CustomMapControl.jsx b/src/components/ThreeViewer/Controls/CustomMapControl.jsx
index 740f7794..b210f338 100644
--- a/src/components/ThreeViewer/Controls/CustomMapControl.jsx
+++ b/src/components/ThreeViewer/Controls/CustomMapControl.jsx
@@ -14,16 +14,20 @@ function CustomMapControl(props) {
const handleInteraction = (event) => {
event.preventDefault()
- const isTouch = event.type.startsWith("touch")
- const clientX = isTouch ? event.touches[0].clientX : event.clientX
- const clientY = isTouch ? event.touches[0].clientY : event.clientY
+ const getIntersects = () => {
+ const isTouch = window.isTouchDevice
+ const clientX = isTouch ? event.touches[0].clientX : event.clientX
+ const clientY = isTouch ? event.touches[0].clientY : event.clientY
- const rect = event.target.getBoundingClientRect()
- mouse.current.x = ((clientX - rect.left) / rect.width) * 2 - 1
- mouse.current.y = (-(clientY - rect.top) / rect.height) * 2 + 1
+ const rect = event.target.getBoundingClientRect()
+ mouse.current.x = ((clientX - rect.left) / rect.width) * 2 - 1
+ mouse.current.y = (-(clientY - rect.top) / rect.height) * 2 + 1
- raycaster.current.setFromCamera(mouse.current, camera)
- const intersects = raycaster.current.intersectObjects(scene.children, true)
+ raycaster.current.setFromCamera(mouse.current, camera)
+
+ return raycaster.current.intersectObjects(scene.children, true)
+ }
+ const intersects = getIntersects()
if (intersects.length > 0) {
const intersectedMesh = intersects[0].object
From f0e680b05f20147d626f8111e26d86e67f21ca7f Mon Sep 17 00:00:00 2001
From: Florian Kotthoff <74312290+FlorianK13@users.noreply.github.com>
Date: Sat, 21 Sep 2024 08:15:45 +0200
Subject: [PATCH 02/21] Get rid of one if layer #291
---
.../ThreeViewer/Controls/CustomMapControl.jsx | 66 ++++++++++---------
1 file changed, 35 insertions(+), 31 deletions(-)
diff --git a/src/components/ThreeViewer/Controls/CustomMapControl.jsx b/src/components/ThreeViewer/Controls/CustomMapControl.jsx
index b210f338..e74f524a 100644
--- a/src/components/ThreeViewer/Controls/CustomMapControl.jsx
+++ b/src/components/ThreeViewer/Controls/CustomMapControl.jsx
@@ -14,6 +14,10 @@ function CustomMapControl(props) {
const handleInteraction = (event) => {
event.preventDefault()
+ /**
+ * Returns the list of intersected objects. An intersected object is an object
+ * that lies directly below the mouse cursor.
+ */
const getIntersects = () => {
const isTouch = window.isTouchDevice
const clientX = isTouch ? event.touches[0].clientX : event.clientX
@@ -29,38 +33,38 @@ function CustomMapControl(props) {
}
const intersects = getIntersects()
- if (intersects.length > 0) {
- const intersectedMesh = intersects[0].object
- console.log("Intersected Mesh", intersectedMesh)
-
- if (!intersectedMesh) return
-
- if (
- intersectedMesh.geometry.name &&
- (intersectedMesh.geometry.name.includes("surrounding") ||
- intersectedMesh.geometry.name.includes("background"))
- ) {
- const existingIndex = props.selectedMesh.findIndex(
- (mesh) => mesh.geometry.name === intersectedMesh.geometry.name
- )
-
- if (existingIndex > -1) {
- props.setSelectedMesh([
- ...props.selectedMesh.slice(0, existingIndex),
- ...props.selectedMesh.slice(existingIndex + 1),
- ])
- } else {
- props.setSelectedMesh([
- ...props.selectedMesh,
- {
- geometry: intersectedMesh.geometry,
- material: intersectedMesh.material,
- },
- ])
- }
- }
- } else {
+ if (intersects.length === 0) {
console.log("No children in the intersected mesh.")
+ return
+ }
+ const intersectedMesh = intersects[0].object
+ console.log("Intersected Mesh", intersectedMesh)
+
+ if (!intersectedMesh) return
+
+ if (
+ intersectedMesh.geometry.name &&
+ (intersectedMesh.geometry.name.includes("surrounding") ||
+ intersectedMesh.geometry.name.includes("background"))
+ ) {
+ const existingIndex = props.selectedMesh.findIndex(
+ (mesh) => mesh.geometry.name === intersectedMesh.geometry.name
+ )
+
+ if (existingIndex > -1) {
+ props.setSelectedMesh([
+ ...props.selectedMesh.slice(0, existingIndex),
+ ...props.selectedMesh.slice(existingIndex + 1),
+ ])
+ } else {
+ props.setSelectedMesh([
+ ...props.selectedMesh,
+ {
+ geometry: intersectedMesh.geometry,
+ material: intersectedMesh.material,
+ },
+ ])
+ }
}
}
From f62d01dd2928fd559bdeef34a781dad3f5241055 Mon Sep 17 00:00:00 2001
From: Florian Kotthoff <74312290+FlorianK13@users.noreply.github.com>
Date: Sat, 21 Sep 2024 08:25:43 +0200
Subject: [PATCH 03/21] Get rid of chatgpt gibberish #291
No idea what chatgpt did there,
but the old code had no effect at all (I think)
---
.../ThreeViewer/Controls/CustomMapControl.jsx | 19 +------------------
1 file changed, 1 insertion(+), 18 deletions(-)
diff --git a/src/components/ThreeViewer/Controls/CustomMapControl.jsx b/src/components/ThreeViewer/Controls/CustomMapControl.jsx
index e74f524a..8511f8a6 100644
--- a/src/components/ThreeViewer/Controls/CustomMapControl.jsx
+++ b/src/components/ThreeViewer/Controls/CustomMapControl.jsx
@@ -47,24 +47,7 @@ function CustomMapControl(props) {
(intersectedMesh.geometry.name.includes("surrounding") ||
intersectedMesh.geometry.name.includes("background"))
) {
- const existingIndex = props.selectedMesh.findIndex(
- (mesh) => mesh.geometry.name === intersectedMesh.geometry.name
- )
-
- if (existingIndex > -1) {
- props.setSelectedMesh([
- ...props.selectedMesh.slice(0, existingIndex),
- ...props.selectedMesh.slice(existingIndex + 1),
- ])
- } else {
- props.setSelectedMesh([
- ...props.selectedMesh,
- {
- geometry: intersectedMesh.geometry,
- material: intersectedMesh.material,
- },
- ])
- }
+ props.setSelectedMesh([intersectedMesh])
}
}
From 4ea12c7e9a72f3d647586fda606eff0bd6cd30d3 Mon Sep 17 00:00:00 2001
From: Florian Kotthoff <74312290+FlorianK13@users.noreply.github.com>
Date: Sat, 21 Sep 2024 08:30:47 +0200
Subject: [PATCH 04/21] Add name to pvSystemGeometries #291
---
src/components/ThreeViewer/Meshes/PVSystems.jsx | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/components/ThreeViewer/Meshes/PVSystems.jsx b/src/components/ThreeViewer/Meshes/PVSystems.jsx
index 5ea49337..01f477ff 100644
--- a/src/components/ThreeViewer/Meshes/PVSystems.jsx
+++ b/src/components/ThreeViewer/Meshes/PVSystems.jsx
@@ -73,6 +73,7 @@ export function createPVSystem({
"position",
new THREE.Float32BufferAttribute(bufferTriangles, 3)
)
+ geometry.name = "pvSystem"
let subdividedTriangles = []
const triangleSubdivisionThreshold = 0.8
From cc39e4ab75ff7f2c484c124f3e617b57a3df57a7 Mon Sep 17 00:00:00 2001
From: Florian Kotthoff <74312290+FlorianK13@users.noreply.github.com>
Date: Sat, 21 Sep 2024 08:31:46 +0200
Subject: [PATCH 05/21] Catch meshes without names early #291
---
.../ThreeViewer/Controls/CustomMapControl.jsx | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/src/components/ThreeViewer/Controls/CustomMapControl.jsx b/src/components/ThreeViewer/Controls/CustomMapControl.jsx
index 8511f8a6..1760ec76 100644
--- a/src/components/ThreeViewer/Controls/CustomMapControl.jsx
+++ b/src/components/ThreeViewer/Controls/CustomMapControl.jsx
@@ -41,11 +41,15 @@ function CustomMapControl(props) {
console.log("Intersected Mesh", intersectedMesh)
if (!intersectedMesh) return
-
+ if (!intersectedMesh.geometry.name) {
+ console.log(
+ "There is a mesh, but it has no name so I don't know what to do."
+ )
+ return
+ }
if (
- intersectedMesh.geometry.name &&
- (intersectedMesh.geometry.name.includes("surrounding") ||
- intersectedMesh.geometry.name.includes("background"))
+ intersectedMesh.geometry.name.includes("surrounding") ||
+ intersectedMesh.geometry.name.includes("background")
) {
props.setSelectedMesh([intersectedMesh])
}
From a096c1d2d212b02961c7112697fef8ba930e9e57 Mon Sep 17 00:00:00 2001
From: Florian Kotthoff <74312290+FlorianK13@users.noreply.github.com>
Date: Sat, 21 Sep 2024 08:41:25 +0200
Subject: [PATCH 06/21] Add selector for pv systems #291
---
.../ThreeViewer/Controls/CustomMapControl.jsx | 3 +++
.../ThreeViewer/Meshes/HighlitedPVSystem.jsx | 21 +++++++++++++++++++
src/components/ThreeViewer/Scene.jsx | 8 +++++--
src/pages/Simulation.jsx | 4 ++++
4 files changed, 34 insertions(+), 2 deletions(-)
create mode 100644 src/components/ThreeViewer/Meshes/HighlitedPVSystem.jsx
diff --git a/src/components/ThreeViewer/Controls/CustomMapControl.jsx b/src/components/ThreeViewer/Controls/CustomMapControl.jsx
index 1760ec76..19543f4e 100644
--- a/src/components/ThreeViewer/Controls/CustomMapControl.jsx
+++ b/src/components/ThreeViewer/Controls/CustomMapControl.jsx
@@ -53,6 +53,9 @@ function CustomMapControl(props) {
) {
props.setSelectedMesh([intersectedMesh])
}
+ if (intersectedMesh.geometry.name.includes("pvSystem")) {
+ props.setselectedPVSystem([intersectedMesh])
+ }
}
const handleDoubleClick = (event) => {
diff --git a/src/components/ThreeViewer/Meshes/HighlitedPVSystem.jsx b/src/components/ThreeViewer/Meshes/HighlitedPVSystem.jsx
new file mode 100644
index 00000000..2786e6fb
--- /dev/null
+++ b/src/components/ThreeViewer/Meshes/HighlitedPVSystem.jsx
@@ -0,0 +1,21 @@
+import React from "react"
+import * as THREE from "three"
+
+export function HighlightedPVSystem({ meshes }) {
+ return (
+ <>
+ {meshes.map((mesh, index) => (
+
+ ))}
+ >
+ )
+}
diff --git a/src/components/ThreeViewer/Scene.jsx b/src/components/ThreeViewer/Scene.jsx
index e9a30209..70e50b23 100644
--- a/src/components/ThreeViewer/Scene.jsx
+++ b/src/components/ThreeViewer/Scene.jsx
@@ -1,8 +1,9 @@
-import React, { useRef, useState } from "react"
+import React, { useRef } from "react"
import { Canvas } from "react-three-fiber"
import CustomMapControl from "./Controls/CustomMapControl"
import DrawPVControl from "./Controls/DrawPVControl"
+import { HighlightedPVSystem } from "./Meshes/HighlitedPVSystem"
import { HighlightedMesh } from "./Meshes/HiglightedMesh"
import { PVSystems } from "./Meshes/PVSystems"
import SimulationMesh from "./Meshes/SimulationMesh"
@@ -19,6 +20,8 @@ const Scene = ({
pvSystems,
selectedMesh,
setSelectedMesh,
+ selectedPVSystem,
+ setselectedPVSystem,
pvPoints,
setPVPoints,
vegetationGeometries,
@@ -57,11 +60,12 @@ const Scene = ({
)}
{selectedMesh && }
+ {selectedPVSystem && }
{simulationMeshes.length > 0 && frontendState == "Results" && (
)}
{frontendState == "DrawPV" && (
diff --git a/src/pages/Simulation.jsx b/src/pages/Simulation.jsx
index 9fd1b118..3fb84951 100644
--- a/src/pages/Simulation.jsx
+++ b/src/pages/Simulation.jsx
@@ -35,6 +35,8 @@ function Index() {
})
// highlighted meshes for resimulation
const [selectedMesh, setSelectedMesh] = useState([])
+ // highlighted PVSystems for deletion or calculation
+ const [selectedPVSystem, setselectedPVSystem] = useState([])
// meshes that were simulated
const [simulationMeshes, setSimulationMeshes] = useState([])
@@ -90,6 +92,8 @@ function Index() {
setPVSystems={setPVSystems}
selectedMesh={selectedMesh}
setSelectedMesh={setSelectedMesh}
+ selectedPVSystem={selectedPVSystem}
+ setselectedPVSystem={setselectedPVSystem}
pvPoints={pvPoints}
setPVPoints={setPVPoints}
vegetationGeometries={vegetationGeometries}
From 2b2763c0838aecd17570075e797522486f91c650 Mon Sep 17 00:00:00 2001
From: Florian Kotthoff <74312290+FlorianK13@users.noreply.github.com>
Date: Sat, 21 Sep 2024 08:44:30 +0200
Subject: [PATCH 07/21] Ignore Sprite on double click #291
---
src/components/ThreeViewer/Controls/CustomMapControl.jsx | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/src/components/ThreeViewer/Controls/CustomMapControl.jsx b/src/components/ThreeViewer/Controls/CustomMapControl.jsx
index 19543f4e..2374a1dd 100644
--- a/src/components/ThreeViewer/Controls/CustomMapControl.jsx
+++ b/src/components/ThreeViewer/Controls/CustomMapControl.jsx
@@ -37,7 +37,11 @@ function CustomMapControl(props) {
console.log("No children in the intersected mesh.")
return
}
- const intersectedMesh = intersects[0].object
+ let intersectedMesh = intersects[0].object
+ if (intersectedMesh.type === "Sprite") {
+ //ignore Sprites (the label of pvsystems), use the underlying object
+ intersectedMesh = intersects[1].object
+ }
console.log("Intersected Mesh", intersectedMesh)
if (!intersectedMesh) return
From 387135b768eaa16bed62d3cd1d50df6e46648db1 Mon Sep 17 00:00:00 2001
From: Florian Kotthoff <74312290+FlorianK13@users.noreply.github.com>
Date: Sat, 21 Sep 2024 17:45:24 +0200
Subject: [PATCH 08/21] Properly name set method #291
---
src/components/ThreeViewer/Controls/CustomMapControl.jsx | 2 +-
src/components/ThreeViewer/Scene.jsx | 4 ++--
src/pages/Simulation.jsx | 6 ++++--
3 files changed, 7 insertions(+), 5 deletions(-)
diff --git a/src/components/ThreeViewer/Controls/CustomMapControl.jsx b/src/components/ThreeViewer/Controls/CustomMapControl.jsx
index 2374a1dd..10e1036c 100644
--- a/src/components/ThreeViewer/Controls/CustomMapControl.jsx
+++ b/src/components/ThreeViewer/Controls/CustomMapControl.jsx
@@ -58,7 +58,7 @@ function CustomMapControl(props) {
props.setSelectedMesh([intersectedMesh])
}
if (intersectedMesh.geometry.name.includes("pvSystem")) {
- props.setselectedPVSystem([intersectedMesh])
+ props.setSelectedPVSystem([intersectedMesh])
}
}
diff --git a/src/components/ThreeViewer/Scene.jsx b/src/components/ThreeViewer/Scene.jsx
index 70e50b23..775a3817 100644
--- a/src/components/ThreeViewer/Scene.jsx
+++ b/src/components/ThreeViewer/Scene.jsx
@@ -21,7 +21,7 @@ const Scene = ({
selectedMesh,
setSelectedMesh,
selectedPVSystem,
- setselectedPVSystem,
+ setSelectedPVSystem,
pvPoints,
setPVPoints,
vegetationGeometries,
@@ -65,7 +65,7 @@ const Scene = ({
)}
{frontendState == "DrawPV" && (
diff --git a/src/pages/Simulation.jsx b/src/pages/Simulation.jsx
index 3fb84951..48b8f09a 100644
--- a/src/pages/Simulation.jsx
+++ b/src/pages/Simulation.jsx
@@ -36,7 +36,7 @@ function Index() {
// highlighted meshes for resimulation
const [selectedMesh, setSelectedMesh] = useState([])
// highlighted PVSystems for deletion or calculation
- const [selectedPVSystem, setselectedPVSystem] = useState([])
+ const [selectedPVSystem, setSelectedPVSystem] = useState([])
// meshes that were simulated
const [simulationMeshes, setSimulationMeshes] = useState([])
@@ -74,6 +74,8 @@ function Index() {
geoLocation={location}
setPVSystems={setPVSystems}
pvSystems={pvSystems}
+ selectedPVSystem={selectedPVSystem}
+ setSelectedPVSystem={setSelectedPVSystem}
pvPoints={pvPoints}
setPVPoints={setPVPoints}
simulationMeshes={simulationMeshes}
@@ -93,7 +95,7 @@ function Index() {
selectedMesh={selectedMesh}
setSelectedMesh={setSelectedMesh}
selectedPVSystem={selectedPVSystem}
- setselectedPVSystem={setselectedPVSystem}
+ setSelectedPVSystem={setSelectedPVSystem}
pvPoints={pvPoints}
setPVPoints={setPVPoints}
vegetationGeometries={vegetationGeometries}
From 15d7c500c0588795473ae7498baa1605abf36acf Mon Sep 17 00:00:00 2001
From: Florian Kotthoff <74312290+FlorianK13@users.noreply.github.com>
Date: Sat, 21 Sep 2024 17:45:42 +0200
Subject: [PATCH 09/21] Add a template for the select notification #291
---
src/components/ThreeViewer/Overlay.jsx | 14 +++-
.../ThreeViewer/SelectionNotification.jsx | 78 +++++++++++++++++++
2 files changed, 91 insertions(+), 1 deletion(-)
create mode 100644 src/components/ThreeViewer/SelectionNotification.jsx
diff --git a/src/components/ThreeViewer/Overlay.jsx b/src/components/ThreeViewer/Overlay.jsx
index e046f909..acc117c0 100644
--- a/src/components/ThreeViewer/Overlay.jsx
+++ b/src/components/ThreeViewer/Overlay.jsx
@@ -21,13 +21,14 @@ import {
UnorderedList,
useDisclosure,
} from "@chakra-ui/react"
-import React from "react"
+import React, { useEffect, useRef } from "react"
import { useTranslation } from "react-i18next"
import { simulationForNewBuilding } from "../../simulation/main"
import SavingCalculation from "../PVSimulation/SavingsCalculation"
import ButtonWithHoverHelp from "../Template/ButtonWithHoverHelp"
import SliderWithLabel from "../Template/SliderWithLabel"
import { createPVSystem } from "./Meshes/PVSystems"
+import SelectionNotification from "./SelectionNotification"
function Overlay({
frontendState,
@@ -36,6 +37,8 @@ function Overlay({
setShowTerrain,
selectedMesh,
setSelectedMesh,
+ selectedPVSystem,
+ setSelectedPVSystem,
geometries,
geoLocation,
pvSystems,
@@ -70,10 +73,19 @@ function Overlay({
const handleAbortButtonClick = () => {
setFrontendState("Results")
}
+ const buttons = [
+ { label: "View Account", action: () => console.log("Viewing account") },
+ { label: "Edit Profile", action: () => console.log("Editing profile") },
+ ]
return (
<>
+
{frontendState == "Results" && (
<>