From d3f5c5e506f74fbb494f5bc93ad03fa7ef8f92f7 Mon Sep 17 00:00:00 2001 From: Jerald-Golden-B Date: Fri, 2 May 2025 11:35:03 +0530 Subject: [PATCH] Enhance TriggerConnector and useProductStore: add removeTrigger return value and improve event handling in TriggerConnector --- .../triggers/connector/triggerConnector.tsx | 105 ++++++++++++++++-- app/src/store/simulation/useProductStore.ts | 7 +- 2 files changed, 104 insertions(+), 8 deletions(-) diff --git a/app/src/modules/simulation/triggers/connector/triggerConnector.tsx b/app/src/modules/simulation/triggers/connector/triggerConnector.tsx index 5c4c602..7eb0e81 100644 --- a/app/src/modules/simulation/triggers/connector/triggerConnector.tsx +++ b/app/src/modules/simulation/triggers/connector/triggerConnector.tsx @@ -1,5 +1,5 @@ import { useEffect, useRef, useState } from "react"; -import { useThree } from "@react-three/fiber"; +import { useFrame, useThree } from "@react-three/fiber"; import * as THREE from "three"; import { useSubModuleStore } from "../../../../store/useModuleStore"; import { useSelectedAsset } from "../../../../store/simulation/useSimulationStore"; @@ -9,6 +9,7 @@ import { useSelectedProduct } from "../../../../store/simulation/useSimulationSt import { handleAddEventToProduct } from "../../events/points/functions/handleAddEventToProduct"; import { QuadraticBezierLine } from "@react-three/drei"; import { upsertProductOrEventApi } from "../../../../services/simulation/UpsertProductOrEventApi"; +import { useDeleteTool } from "../../../../store/store"; interface ConnectionLine { id: string; @@ -18,13 +19,16 @@ interface ConnectionLine { } function TriggerConnector() { - const { gl, raycaster, scene } = useThree(); + const { gl, raycaster, scene, pointer, camera } = useThree(); const { subModule } = useSubModuleStore(); - const { products, getPointByUuid, getIsEventInProduct, getActionByUuid, addTrigger, addEvent, getEventByModelUuid, getProductById } = useProductStore(); + const { products, getPointByUuid, getIsEventInProduct, getActionByUuid, addTrigger, removeTrigger, addEvent, getEventByModelUuid, getProductById } = useProductStore(); const { selectedAsset, clearSelectedAsset } = useSelectedAsset(); const { selectedProduct } = useSelectedProduct(); const [hoveredLineKey, setHoveredLineKey] = useState(null); const groupRefs = useRef>({}); + const [helperlineColor, setHelperLineColor] = useState("red"); + const [currentLine, setCurrentLine] = useState<{ start: THREE.Vector3; end: THREE.Vector3; mid: THREE.Vector3; } | null>(null); + const { deleteTool } = useDeleteTool(); const [firstSelectedPoint, setFirstSelectedPoint] = useState<{ productId: string; @@ -303,6 +307,61 @@ function TriggerConnector() { }, [gl, subModule, selectedProduct, firstSelectedPoint]); + + useFrame(() => { + if (firstSelectedPoint) { + raycaster.setFromCamera(pointer, camera); + const intersects = raycaster.intersectObjects(scene.children, true).filter( + (intersect) => + !intersect.object.name.includes("Roof") && + !intersect.object.name.includes("agv-collider") && + !intersect.object.name.includes("MeasurementReference") && + !intersect.object.userData.isPathObject && + !(intersect.object.type === "GridHelper") + ); + + let point: THREE.Vector3 | null = null; + + if (intersects.length > 0) { + point = intersects[0].point; + if (point.y < 0.05) { + point = new THREE.Vector3(point.x, 0.05, point.z); + } + } + + const sphereIntersects = raycaster.intersectObjects(scene.children, true).filter((intersect) => intersect.object.name === ('Event-Sphere')); + const startPoint = getWorldPositionFromScene(firstSelectedPoint.pointUuid); + + if (point && startPoint) { + + const distance = startPoint.distanceTo(point); + const heightFactor = Math.max(0.5, distance * 0.2); + const midPoint = new THREE.Vector3( + (startPoint.x + point.x) / 2, + Math.max(startPoint.y, point.y) + heightFactor, + (startPoint.z + point.z) / 2 + ); + + setCurrentLine({ + start: startPoint, + mid: midPoint, + end: point, + }); + + if (sphereIntersects.length > 0) { + setHelperLineColor("#6cf542"); + } else { + setHelperLineColor("red"); + } + } else { + setCurrentLine(null); + } + } else { + setCurrentLine(null); + } + + }) + const getWorldPositionFromScene = (pointUuid: string): THREE.Vector3 | null => { const pointObj = scene.getObjectByProperty("uuid", pointUuid); if (!pointObj) return null; @@ -312,8 +371,23 @@ function TriggerConnector() { return worldPosition; }; + const removeConnection = (connection: ConnectionLine) => { + if (connection.trigger.triggerUuid) { + const event = removeTrigger(connection.trigger.triggerUuid); + if (event) { + console.log('event: ', event); + updateBackend( + selectedProduct.productName, + selectedProduct.productId, + organization, + event + ); + } + } + }; + return ( - + {connections.map((connection) => { const startPoint = getWorldPositionFromScene(connection.startPointUuid); const endPoint = getWorldPositionFromScene(connection.endPointUuid); @@ -335,20 +409,37 @@ function TriggerConnector() { start={startPoint.toArray()} end={endPoint.toArray()} mid={midPoint.toArray()} - color={hoveredLineKey === connection.id ? "red" : "#42a5f5"} + color={deleteTool && hoveredLineKey === connection.id ? "red" : "#42a5f5"} lineWidth={4} - dashed={hoveredLineKey !== connection.id} + dashed={deleteTool && hoveredLineKey === connection.id ? false : true} dashSize={0.75} dashScale={20} onPointerOver={() => setHoveredLineKey(connection.id)} onPointerOut={() => setHoveredLineKey(null)} onClick={() => { - console.log("Connection clicked:", connection); + if (deleteTool) { + setHoveredLineKey(null); + setCurrentLine(null); + removeConnection(connection); + } }} userData={connection.trigger} /> ); })} + + {currentLine && ( + + )} ); } diff --git a/app/src/store/simulation/useProductStore.ts b/app/src/store/simulation/useProductStore.ts index 0918128..a47bcdb 100644 --- a/app/src/store/simulation/useProductStore.ts +++ b/app/src/store/simulation/useProductStore.ts @@ -44,7 +44,7 @@ type ProductsStore = { actionUuid: string, trigger: TriggerSchema ) => EventsSchema | undefined; - removeTrigger: (triggerUuid: string) => void; + removeTrigger: (triggerUuid: string) => EventsSchema | undefined; updateTrigger: ( triggerUuid: string, updates: Partial @@ -318,6 +318,7 @@ export const useProductStore = create()( }, removeTrigger: (triggerUuid) => { + let updatedEvent: EventsSchema | undefined; set((state) => { for (const product of state.products) { for (const event of product.eventDatas) { @@ -325,16 +326,19 @@ export const useProductStore = create()( for (const point of (event as ConveyorEventSchema).points) { if (point.action && 'triggers' in point.action) { point.action.triggers = point.action.triggers.filter(t => t.triggerUuid !== triggerUuid); + updatedEvent = JSON.parse(JSON.stringify(event)); } } } else if ('point' in event) { const point = (event as any).point; if ('action' in point && 'triggers' in point.action) { point.action.triggers = point.action.triggers.filter((t: any) => t.triggerUuid !== triggerUuid); + updatedEvent = JSON.parse(JSON.stringify(event)); } else if ('actions' in point) { for (const action of point.actions) { if ('triggers' in action) { action.triggers = action.triggers.filter((t: any) => t.triggerUuid !== triggerUuid); + updatedEvent = JSON.parse(JSON.stringify(event)); } } } @@ -342,6 +346,7 @@ export const useProductStore = create()( } } }); + return updatedEvent; }, updateTrigger: (triggerUuid, updates) => {