diff --git a/app/src/components/layout/sidebarLeft/Assets.tsx b/app/src/components/layout/sidebarLeft/Assets.tsx index 9e04615..1cdd9bd 100644 --- a/app/src/components/layout/sidebarLeft/Assets.tsx +++ b/app/src/components/layout/sidebarLeft/Assets.tsx @@ -133,7 +133,6 @@ const Assets: React.FC = () => { } else { try { const res = await getCategoryAsset(asset); - console.log('res: ', res); setCategoryAssets(res); setFiltereredAssets(res); } catch (error) {} diff --git a/app/src/components/layout/sidebarRight/mechanics/ArmBotMechanics.tsx b/app/src/components/layout/sidebarRight/mechanics/ArmBotMechanics.tsx index cfa7822..e157d07 100644 --- a/app/src/components/layout/sidebarRight/mechanics/ArmBotMechanics.tsx +++ b/app/src/components/layout/sidebarRight/mechanics/ArmBotMechanics.tsx @@ -2,7 +2,7 @@ import React, { useRef, useMemo, useCallback, useState } from "react"; import { InfoIcon, AddIcon, RemoveIcon, ResizeHeightIcon } from "../../../icons/ExportCommonIcons"; import InputWithDropDown from "../../../ui/inputs/InputWithDropDown"; import { useSelectedActionSphere, useSimulationStates, useSocketStore } from "../../../../store/store"; -import * as Types from '../../../../types/world/worldTypes'; +import * as SimulationTypes from '../../../../types/simulation'; import LabledDropdown from "../../../ui/inputs/LabledDropdown"; import { handleResize } from "../../../../functions/handleResizePannel"; @@ -34,7 +34,7 @@ const ArmBotMechanics: React.FC = () => { if (!selectedActionSphere?.points?.uuid) return []; const armBotPaths = simulationStates.filter( - (path): path is Types.ArmBotEventsSchema => path.type === "ArmBot" + (path): path is SimulationTypes.ArmBotEventsSchema => path.type === "ArmBot" ); const currentPoint = armBotPaths.find( @@ -54,7 +54,7 @@ const ArmBotMechanics: React.FC = () => { let points: { uuid: string; position: [number, number, number] }[] = []; if (connectedModel.type === "Conveyor") { - const conveyor = connectedModel as Types.ConveyorEventsSchema; + const conveyor = connectedModel as SimulationTypes.ConveyorEventsSchema; const connectedPointUUIDs = currentPoint?.connections?.targets .filter(t => t.modelUUID === connectedModel.modeluuid) @@ -72,7 +72,7 @@ const ArmBotMechanics: React.FC = () => { triggers = conveyor.points.flatMap(p => p.triggers?.filter(t => t.isUsed) || []); } else if (connectedModel.type === "StaticMachine") { - const staticMachine = connectedModel as Types.StaticMachineEventsSchema; + const staticMachine = connectedModel as SimulationTypes.StaticMachineEventsSchema; points = [{ uuid: staticMachine.points.uuid, @@ -128,7 +128,7 @@ const ArmBotMechanics: React.FC = () => { if (!selectedActionSphere?.points?.uuid) return { selectedPoint: null }; const armBotPaths = simulationStates.filter( - (path): path is Types.ArmBotEventsSchema => path.type === "ArmBot" + (path): path is SimulationTypes.ArmBotEventsSchema => path.type === "ArmBot" ); const points = armBotPaths.find( @@ -140,7 +140,7 @@ const ArmBotMechanics: React.FC = () => { }; }, [selectedActionSphere, simulationStates]); - const updateBackend = async (updatedPath: Types.ArmBotEventsSchema | undefined) => { + const updateBackend = async (updatedPath: SimulationTypes.ArmBotEventsSchema | undefined) => { if (!updatedPath) return; const email = localStorage.getItem("email"); const organization = email ? email.split("@")[1].split(".")[0] : ""; @@ -150,12 +150,11 @@ const ArmBotMechanics: React.FC = () => { modeluuid: updatedPath.modeluuid, eventData: { type: "ArmBot", points: updatedPath.points } } - console.log('data: ', data); socket.emit('v2:model-asset:updateEventData', data); } - const handleActionUpdate = useCallback((updatedAction: Partial) => { + const handleActionUpdate = useCallback((updatedAction: Partial) => { if (!selectedActionSphere?.points?.uuid || !selectedPoint) return; const updatedPaths = simulationStates.map((path) => { @@ -175,7 +174,7 @@ const ArmBotMechanics: React.FC = () => { }); const updatedPath = updatedPaths.find( - (path): path is Types.ArmBotEventsSchema => + (path): path is SimulationTypes.ArmBotEventsSchema => path.type === "ArmBot" && path.points.uuid === selectedActionSphere.points.uuid ); @@ -188,7 +187,7 @@ const ArmBotMechanics: React.FC = () => { handleActionUpdate({ speed }); }, [handleActionUpdate]); - const handleProcessChange = useCallback((processes: Types.ArmBotEventsSchema['points']['actions']['processes']) => { + const handleProcessChange = useCallback((processes: SimulationTypes.ArmBotEventsSchema['points']['actions']['processes']) => { handleActionUpdate({ processes }); }, [handleActionUpdate]); diff --git a/app/src/components/layout/sidebarRight/mechanics/ConveyorMechanics.tsx b/app/src/components/layout/sidebarRight/mechanics/ConveyorMechanics.tsx index 71ee9ce..080aba5 100644 --- a/app/src/components/layout/sidebarRight/mechanics/ConveyorMechanics.tsx +++ b/app/src/components/layout/sidebarRight/mechanics/ConveyorMechanics.tsx @@ -17,7 +17,7 @@ import { useSocketStore, } from "../../../../store/store"; import * as THREE from "three"; -import * as Types from "../../../../types/world/worldTypes"; +import * as SimulationTypes from "../../../../types/simulation"; import InputToggle from "../../../ui/inputs/InputToggle"; import { setFloorItemApi } from "../../../../services/factoryBuilder/assest/floorAsset/setFloorItemApi"; import { setEventApi } from "../../../../services/factoryBuilder/assest/floorAsset/setEventsApt"; @@ -36,13 +36,13 @@ const ConveyorMechanics: React.FC = () => { if (!selectedActionSphere) return null; return simulationStates .filter( - (path): path is Types.ConveyorEventsSchema => path.type === "Conveyor" + (path): path is SimulationTypes.ConveyorEventsSchema => path.type === "Conveyor" ) .flatMap((path) => path.points) .find((point) => point.uuid === selectedActionSphere.points.uuid); }, [selectedActionSphere, simulationStates]); - const updateBackend = async (updatedPath: Types.ConveyorEventsSchema | undefined) => { + const updateBackend = async (updatedPath: SimulationTypes.ConveyorEventsSchema | undefined) => { if (!updatedPath) return; const email = localStorage.getItem("email"); const organization = email ? email.split("@")[1].split(".")[0] : ""; @@ -93,7 +93,7 @@ const ConveyorMechanics: React.FC = () => { }); const updatedPath = updatedPaths.find( - (path): path is Types.ConveyorEventsSchema => + (path): path is SimulationTypes.ConveyorEventsSchema => path.type === "Conveyor" && path.points.some( (point) => point.uuid === selectedActionSphere.points.uuid @@ -126,7 +126,7 @@ const ConveyorMechanics: React.FC = () => { ); const updatedPath = updatedPaths.find( - (path): path is Types.ConveyorEventsSchema => + (path): path is SimulationTypes.ConveyorEventsSchema => path.type === "Conveyor" && path.points.some( (point) => point.uuid === selectedActionSphere.points.uuid @@ -174,7 +174,7 @@ const ConveyorMechanics: React.FC = () => { ); const updatedPath = updatedPaths.find( - (path): path is Types.ConveyorEventsSchema => + (path): path is SimulationTypes.ConveyorEventsSchema => path.type === "Conveyor" && path.points.some( (point) => point.uuid === selectedActionSphere.points.uuid @@ -188,7 +188,7 @@ const ConveyorMechanics: React.FC = () => { if (selectedItem?.type === "action" && selectedItem.item.uuid === uuid) { const updatedAction = updatedPaths .filter( - (path): path is Types.ConveyorEventsSchema => path.type === "Conveyor" + (path): path is SimulationTypes.ConveyorEventsSchema => path.type === "Conveyor" ) .flatMap((path) => path.points) .find((p) => p.uuid === selectedActionSphere.points.uuid) @@ -229,7 +229,7 @@ const ConveyorMechanics: React.FC = () => { ); const updatedPath = updatedPaths.find( - (path): path is Types.ConveyorEventsSchema => + (path): path is SimulationTypes.ConveyorEventsSchema => path.type === "Conveyor" && path.points.some( (point) => point.uuid === selectedActionSphere.points.uuid @@ -273,7 +273,7 @@ const ConveyorMechanics: React.FC = () => { ); const updatedPath = updatedPaths.find( - (path): path is Types.ConveyorEventsSchema => + (path): path is SimulationTypes.ConveyorEventsSchema => path.type === "Conveyor" && path.points.some( (point) => point.uuid === selectedActionSphere.points.uuid @@ -311,7 +311,7 @@ const ConveyorMechanics: React.FC = () => { ); const updatedPath = updatedPaths.find( - (path): path is Types.ConveyorEventsSchema => + (path): path is SimulationTypes.ConveyorEventsSchema => path.type === "Conveyor" && path.points.some( (point) => point.uuid === selectedActionSphere.points.uuid @@ -330,7 +330,7 @@ const ConveyorMechanics: React.FC = () => { ); const updatedPath = updatedPaths.find( - (path): path is Types.ConveyorEventsSchema => + (path): path is SimulationTypes.ConveyorEventsSchema => path.type === "Conveyor" && path.modeluuid === selectedPath.path.modeluuid ); @@ -367,7 +367,7 @@ const ConveyorMechanics: React.FC = () => { ); const updatedPath = updatedPaths.find( - (path): path is Types.ConveyorEventsSchema => + (path): path is SimulationTypes.ConveyorEventsSchema => path.type === "Conveyor" && path.points.some( (point) => point.uuid === selectedActionSphere.points.uuid @@ -400,7 +400,7 @@ const ConveyorMechanics: React.FC = () => { ); const updatedPath = updatedPaths.find( - (path): path is Types.ConveyorEventsSchema => + (path): path is SimulationTypes.ConveyorEventsSchema => path.type === "Conveyor" && path.points.some( (point) => point.uuid === selectedActionSphere.points.uuid @@ -435,7 +435,7 @@ const ConveyorMechanics: React.FC = () => { ); const updatedPath = updatedPaths.find( - (path): path is Types.ConveyorEventsSchema => + (path): path is SimulationTypes.ConveyorEventsSchema => path.type === "Conveyor" && path.points.some( (point) => point.uuid === selectedActionSphere.points.uuid @@ -479,7 +479,7 @@ const ConveyorMechanics: React.FC = () => { ); const updatedPath = updatedPaths.find( - (path): path is Types.ConveyorEventsSchema => + (path): path is SimulationTypes.ConveyorEventsSchema => path.type === "Conveyor" && path.points.some( (point) => point.uuid === selectedActionSphere.points.uuid @@ -525,7 +525,7 @@ const ConveyorMechanics: React.FC = () => { ); const updatedPath = updatedPaths.find( - (path): path is Types.ConveyorEventsSchema => + (path): path is SimulationTypes.ConveyorEventsSchema => path.type === "Conveyor" && path.points.some( (point) => point.uuid === selectedActionSphere.points.uuid @@ -571,7 +571,7 @@ const ConveyorMechanics: React.FC = () => { ); const updatedPath = updatedPaths.find( - (path): path is Types.ConveyorEventsSchema => + (path): path is SimulationTypes.ConveyorEventsSchema => path.type === "Conveyor" && path.points.some( (point) => point.uuid === selectedActionSphere.points.uuid diff --git a/app/src/components/layout/sidebarRight/mechanics/StaticMachineMechanics.tsx b/app/src/components/layout/sidebarRight/mechanics/StaticMachineMechanics.tsx index 564f221..812ed54 100644 --- a/app/src/components/layout/sidebarRight/mechanics/StaticMachineMechanics.tsx +++ b/app/src/components/layout/sidebarRight/mechanics/StaticMachineMechanics.tsx @@ -2,7 +2,7 @@ import React, { useRef, useMemo, useCallback } from "react"; import { InfoIcon } from "../../../icons/ExportCommonIcons"; import InputWithDropDown from "../../../ui/inputs/InputWithDropDown"; import { useSelectedActionSphere, useSimulationStates, useSocketStore } from "../../../../store/store"; -import * as Types from '../../../../types/world/worldTypes'; +import * as SimulationTypes from '../../../../types/simulation'; import LabledDropdown from "../../../ui/inputs/LabledDropdown"; import { setEventApi } from "../../../../services/factoryBuilder/assest/floorAsset/setEventsApt"; @@ -17,7 +17,7 @@ const StaticMachineMechanics: React.FC = () => { if (!selectedActionSphere?.points?.uuid) return { selectedPoint: null, connectedPointUuids: [] }; const staticMachinePaths = simulationStates.filter( - (path): path is Types.StaticMachineEventsSchema => path.type === "StaticMachine" + (path): path is SimulationTypes.StaticMachineEventsSchema => path.type === "StaticMachine" ); const points = staticMachinePaths.find( @@ -39,7 +39,7 @@ const StaticMachineMechanics: React.FC = () => { }; }, [selectedActionSphere, simulationStates]); - const updateBackend = async (updatedPath: Types.StaticMachineEventsSchema | undefined) => { + const updateBackend = async (updatedPath: SimulationTypes.StaticMachineEventsSchema | undefined) => { if (!updatedPath) return; const email = localStorage.getItem("email"); const organization = email ? email.split("@")[1].split(".")[0] : ""; @@ -59,7 +59,7 @@ const StaticMachineMechanics: React.FC = () => { socket.emit('v2:model-asset:updateEventData', data); } - const handleActionUpdate = useCallback((updatedAction: Partial) => { + const handleActionUpdate = useCallback((updatedAction: Partial) => { if (!selectedActionSphere?.points?.uuid) return; const updatedPaths = simulationStates.map((path) => { @@ -79,7 +79,7 @@ const StaticMachineMechanics: React.FC = () => { }); const updatedPath = updatedPaths.find( - (path): path is Types.StaticMachineEventsSchema => + (path): path is SimulationTypes.StaticMachineEventsSchema => path.type === "StaticMachine" && path.points.uuid === selectedActionSphere.points.uuid ); @@ -96,7 +96,7 @@ const StaticMachineMechanics: React.FC = () => { handleActionUpdate({ material }); }, [handleActionUpdate]); - const handleTriggerChange = useCallback((updatedTrigger: Partial) => { + const handleTriggerChange = useCallback((updatedTrigger: Partial) => { if (!selectedActionSphere?.points?.uuid) return; const updatedPaths = simulationStates.map((path) => { @@ -116,7 +116,7 @@ const StaticMachineMechanics: React.FC = () => { }); const updatedPath = updatedPaths.find( - (path): path is Types.StaticMachineEventsSchema => + (path): path is SimulationTypes.StaticMachineEventsSchema => path.type === "StaticMachine" && path.points.uuid === selectedActionSphere.points.uuid ); diff --git a/app/src/components/layout/sidebarRight/mechanics/VehicleMechanics.tsx b/app/src/components/layout/sidebarRight/mechanics/VehicleMechanics.tsx index 67d132f..73199c9 100644 --- a/app/src/components/layout/sidebarRight/mechanics/VehicleMechanics.tsx +++ b/app/src/components/layout/sidebarRight/mechanics/VehicleMechanics.tsx @@ -2,7 +2,7 @@ import React, { useRef, useMemo } from "react"; import { InfoIcon } from "../../../icons/ExportCommonIcons"; import InputWithDropDown from "../../../ui/inputs/InputWithDropDown"; import { useEditingPoint, useEyeDropMode, usePreviewPosition, useSelectedActionSphere, useSimulationStates, useSocketStore } from "../../../../store/store"; -import * as Types from '../../../../types/world/worldTypes'; +import * as SimulationTypes from '../../../../types/simulation'; import PositionInput from "../customInput/PositionInputs"; import { setEventApi } from "../../../../services/factoryBuilder/assest/floorAsset/setEventsApt"; import LabeledButton from "../../../ui/inputs/LabledButton"; @@ -21,7 +21,7 @@ const VehicleMechanics: React.FC = () => { if (!selectedActionSphere?.points?.uuid) return { selectedPoint: null, connectedPointUuids: [] }; const vehiclePaths = simulationStates.filter( - (path): path is Types.VehicleEventsSchema => path.type === "Vehicle" + (path): path is SimulationTypes.VehicleEventsSchema => path.type === "Vehicle" ); const points = vehiclePaths.find( @@ -43,7 +43,7 @@ const VehicleMechanics: React.FC = () => { }; }, [selectedActionSphere, simulationStates]); - const updateBackend = async (updatedPath: Types.VehicleEventsSchema | undefined) => { + const updateBackend = async (updatedPath: SimulationTypes.VehicleEventsSchema | undefined) => { if (!updatedPath) return; const email = localStorage.getItem("email"); const organization = email ? email.split("@")[1].split(".")[0] : ""; @@ -64,7 +64,7 @@ const VehicleMechanics: React.FC = () => { } - const handleActionUpdate = React.useCallback((updatedAction: Partial) => { + const handleActionUpdate = React.useCallback((updatedAction: Partial) => { if (!selectedActionSphere?.points?.uuid) return; const updatedPaths = simulationStates.map((path) => { @@ -84,7 +84,7 @@ const VehicleMechanics: React.FC = () => { }); const updatedPath = updatedPaths.find( - (path): path is Types.VehicleEventsSchema => + (path): path is SimulationTypes.VehicleEventsSchema => path.type === "Vehicle" && path.points.uuid === selectedActionSphere.points.uuid ); @@ -118,7 +118,7 @@ const VehicleMechanics: React.FC = () => { }); const updatedPath = updatedPaths.find( - (path): path is Types.VehicleEventsSchema => + (path): path is SimulationTypes.VehicleEventsSchema => path.type === "Vehicle" && path.points.uuid === selectedActionSphere.points.uuid ); @@ -145,7 +145,7 @@ const VehicleMechanics: React.FC = () => { }); const updatedPath = updatedPaths.find( - (path): path is Types.VehicleEventsSchema => + (path): path is SimulationTypes.VehicleEventsSchema => path.type === "Vehicle" && path.points.uuid === selectedActionSphere.points.uuid ); diff --git a/app/src/components/ui/inputs/MultiLevelDropDown.tsx b/app/src/components/ui/inputs/MultiLevelDropDown.tsx index 50f7fc8..f2be121 100644 --- a/app/src/components/ui/inputs/MultiLevelDropDown.tsx +++ b/app/src/components/ui/inputs/MultiLevelDropDown.tsx @@ -258,7 +258,11 @@ const MultiLevelDropdown = ({ {open && (
-
+
+ + {/* loading list */} + {/*
*/} + {/* Unselect Option */} {/* Nested Dropdown Items */} diff --git a/app/src/modules/builder/geomentries/assets/addAssetModel.ts b/app/src/modules/builder/geomentries/assets/addAssetModel.ts index 1b1c959..97adec3 100644 --- a/app/src/modules/builder/geomentries/assets/addAssetModel.ts +++ b/app/src/modules/builder/geomentries/assets/addAssetModel.ts @@ -5,6 +5,7 @@ import { toast } from 'react-toastify'; import TempLoader from './tempLoader'; import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader'; import * as Types from "../../../../types/world/worldTypes"; +import * as SimulationTypes from "../../../../types/simulation"; import { retrieveGLTF, storeGLTF } from '../../../../utils/indexDB/idbUtils'; // import { setFloorItemApi } from '../../../../services/factoryBuilder/assest/floorAsset/setFloorItemApi'; import { Socket } from 'socket.io-client'; @@ -136,7 +137,7 @@ async function handleModelLoad( tempLoader.current = undefined; } - const newFloorItem: Types.EventData = { + const newFloorItem: SimulationTypes.EventData = { modeluuid: model.uuid, modelname: selectedItem.name, modelfileID: selectedItem.id, @@ -150,12 +151,11 @@ async function handleModelLoad( const organization = email ? email.split("@")[1].split(".")[0] : ""; getAssetEventType(selectedItem.id, organization).then(async (res) => { - console.log('res: ', res); if (res.type === "Conveyor") { const pointUUIDs = res.points.map(() => THREE.MathUtils.generateUUID()); - const backendEventData: Extract = { + const backendEventData: Extract = { type: 'Conveyor', points: res.points.map((point: any, index: number) => ({ uuid: pointUUIDs[index], @@ -220,9 +220,9 @@ async function handleModelLoad( eventData.position = newFloorItem.position; eventData.rotation = [model.rotation.x, model.rotation.y, model.rotation.z]; - setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => [ + setSimulationStates((prevEvents: (SimulationTypes.ConveyorEventsSchema | SimulationTypes.VehicleEventsSchema | SimulationTypes.StaticMachineEventsSchema | SimulationTypes.ArmBotEventsSchema)[]) => [ ...(prevEvents || []), - eventData as Types.ConveyorEventsSchema + eventData as SimulationTypes.ConveyorEventsSchema ]); console.log('data: ', data); @@ -232,7 +232,7 @@ async function handleModelLoad( const pointUUID = THREE.MathUtils.generateUUID(); - const backendEventData: Extract = { + const backendEventData: Extract = { type: "Vehicle", points: { uuid: pointUUID, @@ -284,9 +284,9 @@ async function handleModelLoad( return updatedItems; }); - setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => [ + setSimulationStates((prevEvents: (SimulationTypes.ConveyorEventsSchema | SimulationTypes.VehicleEventsSchema | SimulationTypes.StaticMachineEventsSchema | SimulationTypes.ArmBotEventsSchema)[]) => [ ...(prevEvents || []), - eventData as Types.VehicleEventsSchema + eventData as SimulationTypes.VehicleEventsSchema ]); socket.emit("v2:model-asset:add", data); @@ -295,7 +295,7 @@ async function handleModelLoad( const pointUUID = THREE.MathUtils.generateUUID(); - const backendEventData: Extract = { + const backendEventData: Extract = { type: "StaticMachine", points: { uuid: pointUUID, @@ -348,9 +348,9 @@ async function handleModelLoad( return updatedItems; }); - setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => [ + setSimulationStates((prevEvents: (SimulationTypes.ConveyorEventsSchema | SimulationTypes.VehicleEventsSchema | SimulationTypes.StaticMachineEventsSchema | SimulationTypes.ArmBotEventsSchema)[]) => [ ...(prevEvents || []), - eventData as Types.StaticMachineEventsSchema + eventData as SimulationTypes.StaticMachineEventsSchema ]); socket.emit("v2:model-asset:add", data); @@ -359,7 +359,7 @@ async function handleModelLoad( const pointUUID = THREE.MathUtils.generateUUID(); - const backendEventData: Extract = { + const backendEventData: Extract = { type: "ArmBot", points: { uuid: pointUUID, @@ -412,9 +412,9 @@ async function handleModelLoad( return updatedItems; }); - setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => [ + setSimulationStates((prevEvents: (SimulationTypes.ConveyorEventsSchema | SimulationTypes.VehicleEventsSchema | SimulationTypes.StaticMachineEventsSchema | SimulationTypes.ArmBotEventsSchema)[]) => [ ...(prevEvents || []), - eventData as Types.ArmBotEventsSchema + eventData as SimulationTypes.ArmBotEventsSchema ]); socket.emit("v2:model-asset:add", data); @@ -455,7 +455,6 @@ async function handleModelLoad( return updatedItems; }); - console.log('data: ', data); socket.emit("v2:model-asset:add", data); } diff --git a/app/src/modules/builder/geomentries/assets/deleteFloorItems.ts b/app/src/modules/builder/geomentries/assets/deleteFloorItems.ts index 028863c..e904947 100644 --- a/app/src/modules/builder/geomentries/assets/deleteFloorItems.ts +++ b/app/src/modules/builder/geomentries/assets/deleteFloorItems.ts @@ -2,6 +2,7 @@ import { toast } from 'react-toastify'; import * as THREE from 'three'; import * as Types from "../../../../types/world/worldTypes"; +import * as SimulationTypes from "../../../../types/simulation"; // import { deleteFloorItem } from '../../../../services/factoryBuilder/assest/floorAsset/deleteFloorItemApi'; import { Socket } from 'socket.io-client'; import { getFloorAssets } from '../../../../services/factoryBuilder/assest/floorAsset/getFloorItemsApi'; @@ -76,7 +77,7 @@ async function DeleteFloorItems( } setFloorItems(updatedItems); - setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema)[]) => { + setSimulationStates((prevEvents: (SimulationTypes.ConveyorEventsSchema | SimulationTypes.VehicleEventsSchema | SimulationTypes.StaticMachineEventsSchema | SimulationTypes.ArmBotEventsSchema)[]) => { const updatedEvents = (prevEvents || []).filter(event => event.modeluuid !== removedItem.modeluuid); return updatedEvents; }); diff --git a/app/src/modules/builder/groups/floorItemsGroup.tsx b/app/src/modules/builder/groups/floorItemsGroup.tsx index bc0791e..acc284f 100644 --- a/app/src/modules/builder/groups/floorItemsGroup.tsx +++ b/app/src/modules/builder/groups/floorItemsGroup.tsx @@ -313,7 +313,7 @@ const FloorItemsGroup = ({ itemsGroup, hoveredDeletableFloorItem, AttachedObject useFrame(() => { if (controls) - assetVisibility(itemsGroup, state.camera.position, renderDistance); + // assetVisibility(itemsGroup, state.camera.position, renderDistance); if (deleteTool && activeModule === "builder") { DeletableHoveredFloorItems(state, itemsGroup, hoveredDeletableFloorItem, setDeletableFloorItem); } else if (!deleteTool) { diff --git a/app/src/modules/collaboration/collabCams.tsx b/app/src/modules/collaboration/collabCams.tsx index 38ea548..ca0d1c5 100644 --- a/app/src/modules/collaboration/collabCams.tsx +++ b/app/src/modules/collaboration/collabCams.tsx @@ -26,12 +26,7 @@ const CamModelsGroup = () => { loader.setDRACOLoader(dracoLoader); const [cams, setCams] = useState([]); - const [models, setModels] = useState< - Record< - string, - { targetPosition: THREE.Vector3; targetRotation: THREE.Euler } - > - >({}); + const [models, setModels] = useState>({}); const dedupeCams = (cams: any[]) => { const seen = new Set(); diff --git a/app/src/modules/scene/IntialLoad/loadInitialFloorItems.ts b/app/src/modules/scene/IntialLoad/loadInitialFloorItems.ts index ea5ea74..08bed84 100644 --- a/app/src/modules/scene/IntialLoad/loadInitialFloorItems.ts +++ b/app/src/modules/scene/IntialLoad/loadInitialFloorItems.ts @@ -5,6 +5,7 @@ import * as THREE from 'three'; import * as CONSTANTS from '../../../types/world/worldConstants'; import { toast } from 'react-toastify'; import * as Types from "../../../types/world/worldTypes"; +import * as SimulationTypes from "../../..//types/simulation"; import { initializeDB, retrieveGLTF, storeGLTF } from '../../../utils/indexDB/idbUtils'; import { getCamera } from '../../../services/factoryBuilder/camera/getCameraApi'; import { getFloorAssets } from '../../../services/factoryBuilder/assest/floorAsset/getFloorItemsApi'; @@ -12,7 +13,7 @@ import { getFloorAssets } from '../../../services/factoryBuilder/assest/floorAss async function loadInitialFloorItems( itemsGroup: Types.RefGroup, setFloorItems: Types.setFloorItemSetState, - setSimulationStates: (paths: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => void + setSimulationStates: (paths: (SimulationTypes.ConveyorEventsSchema | SimulationTypes.VehicleEventsSchema | SimulationTypes.StaticMachineEventsSchema | SimulationTypes.ArmBotEventsSchema)[]) => void ): Promise { if (!itemsGroup.current) return; let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_MARKETPLACE_URL}`; @@ -26,7 +27,7 @@ async function loadInitialFloorItems( if (items.message === "floorItems not found") return; if (items) { - const storedFloorItems: Types.EventData[] = items; + const storedFloorItems: SimulationTypes.EventData[] = items; const loader = new GLTFLoader(); const dracoLoader = new DRACOLoader(); @@ -150,10 +151,10 @@ async function loadInitialFloorItems( function processLoadedModel( gltf: any, - item: Types.EventData, + item: SimulationTypes.EventData, itemsGroup: Types.RefGroup, setFloorItems: Types.setFloorItemSetState, - setSimulationStates: (paths: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => void + setSimulationStates: (paths: (SimulationTypes.ConveyorEventsSchema | SimulationTypes.VehicleEventsSchema | SimulationTypes.StaticMachineEventsSchema | SimulationTypes.ArmBotEventsSchema)[]) => void ) { const model = gltf; model.uuid = item.modeluuid; @@ -196,7 +197,7 @@ function processLoadedModel( gsap.to(model.scale, { x: 1, y: 1, z: 1, duration: 1.5, ease: 'power2.out' }); } -function processEventData(item: Types.EventData, setSimulationStates: any) { +function processEventData(item: SimulationTypes.EventData, setSimulationStates: any) { if (item.eventData?.type === 'Conveyor') { @@ -206,9 +207,9 @@ function processEventData(item: Types.EventData, setSimulationStates: any) { data.position = item.position; data.rotation = [item.rotation.x, item.rotation.y, item.rotation.z]; - setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => [ + setSimulationStates((prevEvents: (SimulationTypes.ConveyorEventsSchema | SimulationTypes.VehicleEventsSchema | SimulationTypes.StaticMachineEventsSchema | SimulationTypes.ArmBotEventsSchema)[]) => [ ...(prevEvents || []), - data as Types.ConveyorEventsSchema + data as SimulationTypes.ConveyorEventsSchema ]); } else if (item.eventData?.type === 'Vehicle') { @@ -219,22 +220,23 @@ function processEventData(item: Types.EventData, setSimulationStates: any) { data.position = item.position; data.rotation = [item.rotation.x, item.rotation.y, item.rotation.z]; - setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => [ + setSimulationStates((prevEvents: (SimulationTypes.ConveyorEventsSchema | SimulationTypes.VehicleEventsSchema | SimulationTypes.StaticMachineEventsSchema | SimulationTypes.ArmBotEventsSchema)[]) => [ ...(prevEvents || []), - data as Types.VehicleEventsSchema + data as SimulationTypes.VehicleEventsSchema ]); } else if (item.eventData?.type === 'StaticMachine') { const data: any = item.eventData; + item.eventData.points.position = [0, 1.5, 1] data.modeluuid = item.modeluuid; data.modelName = item.modelname; data.position = item.position; data.rotation = [item.rotation.x, item.rotation.y, item.rotation.z]; - setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => [ + setSimulationStates((prevEvents: (SimulationTypes.ConveyorEventsSchema | SimulationTypes.VehicleEventsSchema | SimulationTypes.StaticMachineEventsSchema | SimulationTypes.ArmBotEventsSchema)[]) => [ ...(prevEvents || []), - data as Types.StaticMachineEventsSchema + data as SimulationTypes.StaticMachineEventsSchema ]); } else if (item.eventData?.type === 'ArmBot') { @@ -245,9 +247,9 @@ function processEventData(item: Types.EventData, setSimulationStates: any) { data.position = item.position; data.rotation = [item.rotation.x, item.rotation.y, item.rotation.z]; - setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => [ + setSimulationStates((prevEvents: (SimulationTypes.ConveyorEventsSchema | SimulationTypes.VehicleEventsSchema | SimulationTypes.StaticMachineEventsSchema | SimulationTypes.ArmBotEventsSchema)[]) => [ ...(prevEvents || []), - data as Types.ArmBotEventsSchema + data as SimulationTypes.ArmBotEventsSchema ]); } diff --git a/app/src/modules/scene/controls/selection/copyPasteControls.tsx b/app/src/modules/scene/controls/selection/copyPasteControls.tsx index 5c07649..87ed646 100644 --- a/app/src/modules/scene/controls/selection/copyPasteControls.tsx +++ b/app/src/modules/scene/controls/selection/copyPasteControls.tsx @@ -5,6 +5,7 @@ import { useFloorItems, useSelectedAssets, useSimulationStates, useSocketStore, import { toast } from "react-toastify"; // import { setFloorItemApi } from '../../../../services/factoryBuilder/assest/floorAsset/setFloorItemApi'; import * as Types from "../../../../types/world/worldTypes"; +import * as SimulationTypes from "../../../../types/simulation"; import { detectModifierKeys } from "../../../../utils/shortcutkeys/detectModifierKeys"; const CopyPasteControls = ({ itemsGroupRef, copiedObjects, setCopiedObjects, pastedObjects, setpastedObjects, selectionGroup, setDuplicatedObjects, movedObjects, setMovedObjects, rotatedObjects, setRotatedObjects, boundingBoxRef }: any) => { @@ -154,7 +155,7 @@ const CopyPasteControls = ({ itemsGroupRef, copiedObjects, setCopiedObjects, pas return updatedItems; }); - let eventData: Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema | undefined = simulationStates.find((events) => events.modeluuid === obj.userData.modeluuid); + let eventData: SimulationTypes.ConveyorEventsSchema | SimulationTypes.VehicleEventsSchema | SimulationTypes.StaticMachineEventsSchema | SimulationTypes.ArmBotEventsSchema | undefined = simulationStates.find((events) => events.modeluuid === obj.userData.modeluuid); const email = localStorage.getItem("email"); const organization = email ? email.split("@")[1].split(".")[0] : "default"; @@ -162,7 +163,7 @@ const CopyPasteControls = ({ itemsGroupRef, copiedObjects, setCopiedObjects, pas if (eventData.type === 'Conveyor' && eventData) { const createConveyorPoint = (index: number) => { const pointUUID = THREE.MathUtils.generateUUID(); - const hasActions = (eventData as Types.ConveyorEventsSchema)?.points[index].actions.length > 0; + const hasActions = (eventData as SimulationTypes.ConveyorEventsSchema)?.points[index].actions.length > 0; const defaultAction = { uuid: THREE.MathUtils.generateUUID(), @@ -176,15 +177,15 @@ const CopyPasteControls = ({ itemsGroupRef, copiedObjects, setCopiedObjects, pas return { uuid: pointUUID, - position: (eventData as Types.ConveyorEventsSchema)?.points[index].position, - rotation: (eventData as Types.ConveyorEventsSchema)?.points[index].rotation, + position: (eventData as SimulationTypes.ConveyorEventsSchema)?.points[index].position, + rotation: (eventData as SimulationTypes.ConveyorEventsSchema)?.points[index].rotation, actions: hasActions - ? (eventData as Types.ConveyorEventsSchema)?.points[index].actions.map(action => ({ + ? (eventData as SimulationTypes.ConveyorEventsSchema)?.points[index].actions.map(action => ({ ...action, uuid: THREE.MathUtils.generateUUID() })) : [defaultAction], - triggers: (eventData as Types.ConveyorEventsSchema)?.points[index].triggers.map(trigger => ({ + triggers: (eventData as SimulationTypes.ConveyorEventsSchema)?.points[index].triggers.map(trigger => ({ ...trigger, uuid: THREE.MathUtils.generateUUID() })), @@ -202,7 +203,7 @@ const CopyPasteControls = ({ itemsGroupRef, copiedObjects, setCopiedObjects, pas createConveyorPoint(1), // middlePoint createConveyorPoint(2) // point2 ], - speed: (eventData as Types.ConveyorEventsSchema)?.speed + speed: (eventData as SimulationTypes.ConveyorEventsSchema)?.speed }; //REST @@ -240,9 +241,9 @@ const CopyPasteControls = ({ itemsGroupRef, copiedObjects, setCopiedObjects, pas newEventData.position = newFloorItem.position; newEventData.rotation = [obj.rotation.x, obj.rotation.y, obj.rotation.z]; - setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => [ + setSimulationStates((prevEvents: (SimulationTypes.ConveyorEventsSchema | SimulationTypes.VehicleEventsSchema | SimulationTypes.StaticMachineEventsSchema | SimulationTypes.ArmBotEventsSchema)[]) => [ ...(prevEvents || []), - newEventData as Types.ConveyorEventsSchema + newEventData as SimulationTypes.ConveyorEventsSchema ]); socket.emit("v2:model-asset:add", data); @@ -250,7 +251,7 @@ const CopyPasteControls = ({ itemsGroupRef, copiedObjects, setCopiedObjects, pas } else if (eventData.type === 'Vehicle' && eventData) { const createVehiclePoint = () => { const pointUUID = THREE.MathUtils.generateUUID(); - const vehiclePoint = (eventData as Types.VehicleEventsSchema)?.points; + const vehiclePoint = (eventData as SimulationTypes.VehicleEventsSchema)?.points; const hasActions = vehiclePoint?.actions !== undefined; const defaultAction = { @@ -321,9 +322,9 @@ const CopyPasteControls = ({ itemsGroupRef, copiedObjects, setCopiedObjects, pas newEventData.position = newFloorItem.position; newEventData.rotation = [obj.rotation.x, obj.rotation.y, obj.rotation.z]; - setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => [ + setSimulationStates((prevEvents: (SimulationTypes.ConveyorEventsSchema | SimulationTypes.VehicleEventsSchema | SimulationTypes.StaticMachineEventsSchema | SimulationTypes.ArmBotEventsSchema)[]) => [ ...(prevEvents || []), - newEventData as Types.VehicleEventsSchema + newEventData as SimulationTypes.VehicleEventsSchema ]); socket.emit("v2:model-asset:add", data); @@ -331,7 +332,7 @@ const CopyPasteControls = ({ itemsGroupRef, copiedObjects, setCopiedObjects, pas } else if (eventData.type === 'StaticMachine' && eventData) { const createStaticMachinePoint = () => { const pointUUID = THREE.MathUtils.generateUUID(); - const vehiclePoint = (eventData as Types.StaticMachineEventsSchema)?.points; + const vehiclePoint = (eventData as SimulationTypes.StaticMachineEventsSchema)?.points; const hasActions = vehiclePoint?.actions !== undefined; const defaultAction = { @@ -399,9 +400,9 @@ const CopyPasteControls = ({ itemsGroupRef, copiedObjects, setCopiedObjects, pas newEventData.position = newFloorItem.position; newEventData.rotation = [obj.rotation.x, obj.rotation.y, obj.rotation.z]; - setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => [ + setSimulationStates((prevEvents: (SimulationTypes.ConveyorEventsSchema | SimulationTypes.VehicleEventsSchema | SimulationTypes.StaticMachineEventsSchema | SimulationTypes.ArmBotEventsSchema)[]) => [ ...(prevEvents || []), - newEventData as Types.StaticMachineEventsSchema + newEventData as SimulationTypes.StaticMachineEventsSchema ]); socket.emit("v2:model-asset:add", data); @@ -409,7 +410,7 @@ const CopyPasteControls = ({ itemsGroupRef, copiedObjects, setCopiedObjects, pas } else if (eventData.type === 'ArmBot' && eventData) { const createArmBotPoint = () => { const pointUUID = THREE.MathUtils.generateUUID(); - const vehiclePoint = (eventData as Types.ArmBotEventsSchema)?.points; + const vehiclePoint = (eventData as SimulationTypes.ArmBotEventsSchema)?.points; const hasActions = vehiclePoint?.actions !== undefined; const defaultAction = { @@ -481,9 +482,9 @@ const CopyPasteControls = ({ itemsGroupRef, copiedObjects, setCopiedObjects, pas newEventData.position = newFloorItem.position; newEventData.rotation = [obj.rotation.x, obj.rotation.y, obj.rotation.z]; - setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => [ + setSimulationStates((prevEvents: (SimulationTypes.ConveyorEventsSchema | SimulationTypes.VehicleEventsSchema | SimulationTypes.StaticMachineEventsSchema | SimulationTypes.ArmBotEventsSchema)[]) => [ ...(prevEvents || []), - newEventData as Types.ArmBotEventsSchema + newEventData as SimulationTypes.ArmBotEventsSchema ]); socket.emit("v2:model-asset:add", data); diff --git a/app/src/modules/scene/controls/selection/duplicationControls.tsx b/app/src/modules/scene/controls/selection/duplicationControls.tsx index a127a30..41bbce3 100644 --- a/app/src/modules/scene/controls/selection/duplicationControls.tsx +++ b/app/src/modules/scene/controls/selection/duplicationControls.tsx @@ -5,6 +5,7 @@ import { useFloorItems, useSelectedAssets, useSimulationStates, useSocketStore, import { toast } from "react-toastify"; // import { setFloorItemApi } from '../../../../services/factoryBuilder/assest/floorAsset/setFloorItemApi'; import * as Types from "../../../../types/world/worldTypes"; +import * as SimulationTypes from "../../../../types/simulation"; import { setFloorItemApi } from "../../../../services/factoryBuilder/assest/floorAsset/setFloorItemApi"; import { detectModifierKeys } from "../../../../utils/shortcutkeys/detectModifierKeys"; @@ -40,11 +41,11 @@ const DuplicationControls = ({ itemsGroupRef, duplicatedObjects, setDuplicatedOb }; const onKeyDown = (event: KeyboardEvent) => { - const keyCombination = detectModifierKeys(event); + const keyCombination = detectModifierKeys(event); - if (keyCombination === "Ctrl+D" && selectedAssets.length > 0 && duplicatedObjects.length === 0 && movedObjects.length === 0 && rotatedObjects.length === 0) { - duplicateSelection(); - } + if (keyCombination === "Ctrl+D" && selectedAssets.length > 0 && duplicatedObjects.length === 0 && movedObjects.length === 0 && rotatedObjects.length === 0) { + duplicateSelection(); + } }; if (!toggleView) { @@ -132,7 +133,7 @@ const DuplicationControls = ({ itemsGroupRef, duplicatedObjects, setDuplicatedOb return updatedItems; }); - let eventData: Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema | undefined = simulationStates.find((events) => events.modeluuid === obj.userData.modeluuid); + let eventData: SimulationTypes.ConveyorEventsSchema | SimulationTypes.VehicleEventsSchema | SimulationTypes.StaticMachineEventsSchema | SimulationTypes.ArmBotEventsSchema | undefined = simulationStates.find((events) => events.modeluuid === obj.userData.modeluuid); const email = localStorage.getItem("email"); const organization = email ? email.split("@")[1].split(".")[0] : "default"; @@ -141,7 +142,7 @@ const DuplicationControls = ({ itemsGroupRef, duplicatedObjects, setDuplicatedOb if (eventData.type === 'Conveyor' && eventData) { const createConveyorPoint = (index: number) => { const pointUUID = THREE.MathUtils.generateUUID(); - const hasActions = (eventData as Types.ConveyorEventsSchema)?.points[index].actions.length > 0; + const hasActions = (eventData as SimulationTypes.ConveyorEventsSchema)?.points[index].actions.length > 0; const defaultAction = { uuid: THREE.MathUtils.generateUUID(), @@ -155,15 +156,15 @@ const DuplicationControls = ({ itemsGroupRef, duplicatedObjects, setDuplicatedOb return { uuid: pointUUID, - position: (eventData as Types.ConveyorEventsSchema)?.points[index].position, - rotation: (eventData as Types.ConveyorEventsSchema)?.points[index].rotation, + position: (eventData as SimulationTypes.ConveyorEventsSchema)?.points[index].position, + rotation: (eventData as SimulationTypes.ConveyorEventsSchema)?.points[index].rotation, actions: hasActions - ? (eventData as Types.ConveyorEventsSchema)?.points[index].actions.map(action => ({ + ? (eventData as SimulationTypes.ConveyorEventsSchema)?.points[index].actions.map(action => ({ ...action, uuid: THREE.MathUtils.generateUUID() })) : [defaultAction], - triggers: (eventData as Types.ConveyorEventsSchema)?.points[index].triggers.map(trigger => ({ + triggers: (eventData as SimulationTypes.ConveyorEventsSchema)?.points[index].triggers.map(trigger => ({ ...trigger, uuid: THREE.MathUtils.generateUUID() })), @@ -181,7 +182,7 @@ const DuplicationControls = ({ itemsGroupRef, duplicatedObjects, setDuplicatedOb createConveyorPoint(1), createConveyorPoint(2) ], - speed: (eventData as Types.ConveyorEventsSchema)?.speed + speed: (eventData as SimulationTypes.ConveyorEventsSchema)?.speed }; //REST @@ -219,9 +220,9 @@ const DuplicationControls = ({ itemsGroupRef, duplicatedObjects, setDuplicatedOb newEventData.position = newFloorItem.position; newEventData.rotation = [obj.rotation.x, obj.rotation.y, obj.rotation.z]; - setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => [ + setSimulationStates((prevEvents: (SimulationTypes.ConveyorEventsSchema | SimulationTypes.VehicleEventsSchema | SimulationTypes.StaticMachineEventsSchema | SimulationTypes.ArmBotEventsSchema)[]) => [ ...(prevEvents || []), - newEventData as Types.ConveyorEventsSchema + newEventData as SimulationTypes.ConveyorEventsSchema ]); socket.emit("v2:model-asset:add", data); @@ -229,7 +230,7 @@ const DuplicationControls = ({ itemsGroupRef, duplicatedObjects, setDuplicatedOb } else if (eventData.type === 'Vehicle' && eventData) { const createVehiclePoint = () => { const pointUUID = THREE.MathUtils.generateUUID(); - const vehiclePoint = (eventData as Types.VehicleEventsSchema)?.points; + const vehiclePoint = (eventData as SimulationTypes.VehicleEventsSchema)?.points; const hasActions = vehiclePoint?.actions !== undefined; const defaultAction = { @@ -300,9 +301,9 @@ const DuplicationControls = ({ itemsGroupRef, duplicatedObjects, setDuplicatedOb newEventData.position = newFloorItem.position; newEventData.rotation = [obj.rotation.x, obj.rotation.y, obj.rotation.z]; - setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => [ + setSimulationStates((prevEvents: (SimulationTypes.ConveyorEventsSchema | SimulationTypes.VehicleEventsSchema | SimulationTypes.StaticMachineEventsSchema | SimulationTypes.ArmBotEventsSchema)[]) => [ ...(prevEvents || []), - newEventData as Types.VehicleEventsSchema + newEventData as SimulationTypes.VehicleEventsSchema ]); socket.emit("v2:model-asset:add", data); @@ -310,7 +311,7 @@ const DuplicationControls = ({ itemsGroupRef, duplicatedObjects, setDuplicatedOb } else if (eventData.type === 'StaticMachine' && eventData) { const createStaticMachinePoint = () => { const pointUUID = THREE.MathUtils.generateUUID(); - const vehiclePoint = (eventData as Types.StaticMachineEventsSchema)?.points; + const vehiclePoint = (eventData as SimulationTypes.StaticMachineEventsSchema)?.points; const hasActions = vehiclePoint?.actions !== undefined; const defaultAction = { @@ -378,9 +379,9 @@ const DuplicationControls = ({ itemsGroupRef, duplicatedObjects, setDuplicatedOb newEventData.position = newFloorItem.position; newEventData.rotation = [obj.rotation.x, obj.rotation.y, obj.rotation.z]; - setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => [ + setSimulationStates((prevEvents: (SimulationTypes.ConveyorEventsSchema | SimulationTypes.VehicleEventsSchema | SimulationTypes.StaticMachineEventsSchema | SimulationTypes.ArmBotEventsSchema)[]) => [ ...(prevEvents || []), - newEventData as Types.StaticMachineEventsSchema + newEventData as SimulationTypes.StaticMachineEventsSchema ]); socket.emit("v2:model-asset:add", data); @@ -388,7 +389,7 @@ const DuplicationControls = ({ itemsGroupRef, duplicatedObjects, setDuplicatedOb } else if (eventData.type === 'ArmBot' && eventData) { const createArmBotPoint = () => { const pointUUID = THREE.MathUtils.generateUUID(); - const vehiclePoint = (eventData as Types.ArmBotEventsSchema)?.points; + const vehiclePoint = (eventData as SimulationTypes.ArmBotEventsSchema)?.points; const hasActions = vehiclePoint?.actions !== undefined; const defaultAction = { @@ -460,9 +461,9 @@ const DuplicationControls = ({ itemsGroupRef, duplicatedObjects, setDuplicatedOb newEventData.position = newFloorItem.position; newEventData.rotation = [obj.rotation.x, obj.rotation.y, obj.rotation.z]; - setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => [ + setSimulationStates((prevEvents: (SimulationTypes.ConveyorEventsSchema | SimulationTypes.VehicleEventsSchema | SimulationTypes.StaticMachineEventsSchema | SimulationTypes.ArmBotEventsSchema)[]) => [ ...(prevEvents || []), - newEventData as Types.ArmBotEventsSchema + newEventData as SimulationTypes.ArmBotEventsSchema ]); socket.emit("v2:model-asset:add", data); diff --git a/app/src/modules/scene/controls/selection/moveControls.tsx b/app/src/modules/scene/controls/selection/moveControls.tsx index 47a3747..99b9a43 100644 --- a/app/src/modules/scene/controls/selection/moveControls.tsx +++ b/app/src/modules/scene/controls/selection/moveControls.tsx @@ -5,6 +5,7 @@ import { useFloorItems, useSelectedAssets, useSimulationStates, useSocketStore, // import { setFloorItemApi } from '../../../../services/factoryBuilder/assest/floorAsset/setFloorItemApi'; import { toast } from "react-toastify"; import * as Types from "../../../../types/world/worldTypes"; +import * as SimulationTypes from "../../../../types/simulation"; import { detectModifierKeys } from "../../../../utils/shortcutkeys/detectModifierKeys"; function MoveControls({ movedObjects, setMovedObjects, itemsGroupRef, copiedObjects, setCopiedObjects, pastedObjects, setpastedObjects, duplicatedObjects, setDuplicatedObjects, selectionGroup, rotatedObjects, setRotatedObjects, boundingBoxRef }: any) { @@ -183,7 +184,7 @@ function MoveControls({ movedObjects, setMovedObjects, itemsGroupRef, copiedObje return updatedItems; }); - let eventData: Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema | undefined = simulationStates.find((events) => events.modeluuid === obj.userData.modeluuid); + let eventData: SimulationTypes.ConveyorEventsSchema | SimulationTypes.VehicleEventsSchema | SimulationTypes.StaticMachineEventsSchema | SimulationTypes.ArmBotEventsSchema | undefined = simulationStates.find((events) => events.modeluuid === obj.userData.modeluuid); const email = localStorage.getItem("email"); const organization = email ? email.split("@")[1].split(".")[0] : "default"; @@ -194,7 +195,7 @@ function MoveControls({ movedObjects, setMovedObjects, itemsGroupRef, copiedObje const backendEventData = { type: 'Conveyor', points: eventData.points, - speed: (eventData as Types.ConveyorEventsSchema)?.speed + speed: (eventData as SimulationTypes.ConveyorEventsSchema)?.speed }; //REST @@ -232,7 +233,7 @@ function MoveControls({ movedObjects, setMovedObjects, itemsGroupRef, copiedObje newEventData.position = newFloorItem.position; newEventData.rotation = [obj.rotation.x, obj.rotation.y, obj.rotation.z]; - setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => { + setSimulationStates((prevEvents: (SimulationTypes.ConveyorEventsSchema | SimulationTypes.VehicleEventsSchema | SimulationTypes.StaticMachineEventsSchema | SimulationTypes.ArmBotEventsSchema)[]) => { const updatedEvents = (prevEvents || []).map(event => event.modeluuid === newFloorItem.modeluuid ? { ...event, ...newEventData } @@ -284,7 +285,7 @@ function MoveControls({ movedObjects, setMovedObjects, itemsGroupRef, copiedObje newEventData.position = newFloorItem.position; newEventData.rotation = [obj.rotation.x, obj.rotation.y, obj.rotation.z]; - setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => { + setSimulationStates((prevEvents: (SimulationTypes.ConveyorEventsSchema | SimulationTypes.VehicleEventsSchema | SimulationTypes.StaticMachineEventsSchema | SimulationTypes.ArmBotEventsSchema)[]) => { const updatedEvents = (prevEvents || []).map(event => event.modeluuid === newFloorItem.modeluuid ? { ...event, ...newEventData } @@ -337,7 +338,7 @@ function MoveControls({ movedObjects, setMovedObjects, itemsGroupRef, copiedObje newEventData.position = newFloorItem.position; newEventData.rotation = [obj.rotation.x, obj.rotation.y, obj.rotation.z]; - setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => { + setSimulationStates((prevEvents: (SimulationTypes.ConveyorEventsSchema | SimulationTypes.VehicleEventsSchema | SimulationTypes.StaticMachineEventsSchema | SimulationTypes.ArmBotEventsSchema)[]) => { const updatedEvents = (prevEvents || []).map(event => event.modeluuid === newFloorItem.modeluuid ? { ...event, ...newEventData } @@ -390,7 +391,7 @@ function MoveControls({ movedObjects, setMovedObjects, itemsGroupRef, copiedObje newEventData.position = newFloorItem.position; newEventData.rotation = [obj.rotation.x, obj.rotation.y, obj.rotation.z]; - setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => { + setSimulationStates((prevEvents: (SimulationTypes.ConveyorEventsSchema | SimulationTypes.VehicleEventsSchema | SimulationTypes.StaticMachineEventsSchema | SimulationTypes.ArmBotEventsSchema)[]) => { const updatedEvents = (prevEvents || []).map(event => event.modeluuid === newFloorItem.modeluuid ? { ...event, ...newEventData } diff --git a/app/src/modules/scene/controls/selection/rotateControls.tsx b/app/src/modules/scene/controls/selection/rotateControls.tsx index bef64a2..611d14b 100644 --- a/app/src/modules/scene/controls/selection/rotateControls.tsx +++ b/app/src/modules/scene/controls/selection/rotateControls.tsx @@ -5,6 +5,7 @@ import { useFloorItems, useSelectedAssets, useSimulationStates, useSocketStore, // import { setFloorItemApi } from '../../../../services/factoryBuilder/assest/floorAsset/setFloorItemApi'; import { toast } from "react-toastify"; import * as Types from "../../../../types/world/worldTypes"; +import * as SimulationTypes from "../../../../types/simulation"; import { setFloorItemApi } from "../../../../services/factoryBuilder/assest/floorAsset/setFloorItemApi"; function RotateControls({ rotatedObjects, setRotatedObjects, movedObjects, setMovedObjects, itemsGroupRef, copiedObjects, setCopiedObjects, pastedObjects, setpastedObjects, duplicatedObjects, setDuplicatedObjects, selectionGroup, boundingBoxRef }: any) { @@ -184,7 +185,7 @@ function RotateControls({ rotatedObjects, setRotatedObjects, movedObjects, setMo return updatedItems; }); - let eventData: Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema | undefined = simulationStates.find((events) => events.modeluuid === obj.userData.modeluuid); + let eventData: SimulationTypes.ConveyorEventsSchema | SimulationTypes.VehicleEventsSchema | SimulationTypes.StaticMachineEventsSchema | SimulationTypes.ArmBotEventsSchema | undefined = simulationStates.find((events) => events.modeluuid === obj.userData.modeluuid); const email = localStorage.getItem("email"); const organization = email ? email.split("@")[1].split(".")[0] : "default"; @@ -195,7 +196,7 @@ function RotateControls({ rotatedObjects, setRotatedObjects, movedObjects, setMo const backendEventData = { type: 'Conveyor', points: eventData.points, - speed: (eventData as Types.ConveyorEventsSchema)?.speed + speed: (eventData as SimulationTypes.ConveyorEventsSchema)?.speed }; // REST @@ -233,7 +234,7 @@ function RotateControls({ rotatedObjects, setRotatedObjects, movedObjects, setMo newEventData.position = newFloorItem.position; newEventData.rotation = [obj.rotation.x, obj.rotation.y, obj.rotation.z]; - setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => { + setSimulationStates((prevEvents: (SimulationTypes.ConveyorEventsSchema | SimulationTypes.VehicleEventsSchema | SimulationTypes.StaticMachineEventsSchema | SimulationTypes.ArmBotEventsSchema)[]) => { const updatedEvents = (prevEvents || []).map(event => event.modeluuid === newFloorItem.modeluuid ? { ...event, ...newEventData } @@ -286,7 +287,7 @@ function RotateControls({ rotatedObjects, setRotatedObjects, movedObjects, setMo newEventData.position = newFloorItem.position; newEventData.rotation = [obj.rotation.x, obj.rotation.y, obj.rotation.z]; - setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => { + setSimulationStates((prevEvents: (SimulationTypes.ConveyorEventsSchema | SimulationTypes.VehicleEventsSchema | SimulationTypes.StaticMachineEventsSchema | SimulationTypes.ArmBotEventsSchema)[]) => { const updatedEvents = (prevEvents || []).map(event => event.modeluuid === newFloorItem.modeluuid ? { ...event, ...newEventData } @@ -339,7 +340,7 @@ function RotateControls({ rotatedObjects, setRotatedObjects, movedObjects, setMo newEventData.position = newFloorItem.position; newEventData.rotation = [obj.rotation.x, obj.rotation.y, obj.rotation.z]; - setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => { + setSimulationStates((prevEvents: (SimulationTypes.ConveyorEventsSchema | SimulationTypes.VehicleEventsSchema | SimulationTypes.StaticMachineEventsSchema | SimulationTypes.ArmBotEventsSchema)[]) => { const updatedEvents = (prevEvents || []).map(event => event.modeluuid === newFloorItem.modeluuid ? { ...event, ...newEventData } @@ -392,7 +393,7 @@ function RotateControls({ rotatedObjects, setRotatedObjects, movedObjects, setMo newEventData.position = newFloorItem.position; newEventData.rotation = [obj.rotation.x, obj.rotation.y, obj.rotation.z]; - setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => { + setSimulationStates((prevEvents: (SimulationTypes.ConveyorEventsSchema | SimulationTypes.VehicleEventsSchema | SimulationTypes.StaticMachineEventsSchema | SimulationTypes.ArmBotEventsSchema)[]) => { const updatedEvents = (prevEvents || []).map(event => event.modeluuid === newFloorItem.modeluuid ? { ...event, ...newEventData } diff --git a/app/src/modules/scene/controls/selection/selectionControls.tsx b/app/src/modules/scene/controls/selection/selectionControls.tsx index 0396bc9..d1eed1e 100644 --- a/app/src/modules/scene/controls/selection/selectionControls.tsx +++ b/app/src/modules/scene/controls/selection/selectionControls.tsx @@ -3,17 +3,12 @@ import { useEffect, useMemo, useRef, useState } from "react"; import { SelectionBox } from "three/examples/jsm/interactive/SelectionBox"; import { SelectionHelper } from "./selectionHelper"; import { useFrame, useThree } from "@react-three/fiber"; -import { - useFloorItems, - useSelectedAssets, - useSimulationStates, - useSocketStore, - useToggleView, -} from "../../../../store/store"; +import { useFloorItems, useSelectedAssets, useSimulationStates, useSocketStore, useToggleView, } from "../../../../store/store"; import BoundingBox from "./boundingBoxHelper"; import { toast } from "react-toastify"; // import { deleteFloorItem } from '../../../../services/factoryBuilder/assest/floorAsset/deleteFloorItemApi'; import * as Types from "../../../../types/world/worldTypes"; +import * as SimulationTypes from "../../../../types/simulation"; import DuplicationControls from "./duplicationControls"; import CopyPasteControls from "./copyPasteControls"; @@ -22,733 +17,622 @@ import RotateControls from "./rotateControls"; import useModuleStore from "../../../../store/useModuleStore"; const SelectionControls: React.FC = () => { - const { camera, controls, gl, scene, pointer } = useThree(); - const itemsGroupRef = useRef(undefined); - const selectionGroup = useRef() as Types.RefGroup; - const { toggleView } = useToggleView(); - const { simulationStates, setSimulationStates } = useSimulationStates(); - const { selectedAssets, setSelectedAssets } = useSelectedAssets(); - const [movedObjects, setMovedObjects] = useState([]); - const [rotatedObjects, setRotatedObjects] = useState([]); - const [copiedObjects, setCopiedObjects] = useState([]); - const [pastedObjects, setpastedObjects] = useState([]); - const [duplicatedObjects, setDuplicatedObjects] = useState( - [] - ); - const boundingBoxRef = useRef(); - const { floorItems, setFloorItems } = useFloorItems(); - const { activeModule } = useModuleStore(); - const { socket } = useSocketStore(); - const selectionBox = useMemo( - () => new SelectionBox(camera, scene), - [camera, scene] - ); - - useEffect(() => { - if (!camera || !scene || toggleView) return; - - const canvasElement = gl.domElement; - canvasElement.tabIndex = 0; - - const itemsGroup: any = scene.getObjectByName("itemsGroup"); - itemsGroupRef.current = itemsGroup; - - let isSelecting = false; - let isRightClick = false; - let rightClickMoved = false; - let isCtrlSelecting = false; - - const helper = new SelectionHelper(gl); - - if (!itemsGroup) { - toast.warn("itemsGroup not found in the scene."); - return; - } - - const onPointerDown = (event: PointerEvent) => { - if (event.button === 2) { - isRightClick = true; - rightClickMoved = false; - } else if (event.button === 0) { - isSelecting = false; - isCtrlSelecting = event.ctrlKey; - if (event.ctrlKey && duplicatedObjects.length === 0) { - if (controls) (controls as any).enabled = false; - selectionBox.startPoint.set(pointer.x, pointer.y, 0); - } - } - }; - - const onPointerMove = (event: PointerEvent) => { - if (isRightClick) { - rightClickMoved = true; - } - isSelecting = true; - if ( - helper.isDown && - event.ctrlKey && - duplicatedObjects.length === 0 && - isCtrlSelecting - ) { - selectionBox.endPoint.set(pointer.x, pointer.y, 0); - } - }; - - const onPointerUp = (event: PointerEvent) => { - if (event.button === 2) { - isRightClick = false; - if (!rightClickMoved) { - clearSelection(); - } - return; - } - - if (isSelecting && isCtrlSelecting) { - isCtrlSelecting = false; - isSelecting = false; - if (event.ctrlKey && duplicatedObjects.length === 0) { - selectAssets(); - } - } else if ( - !isSelecting && - selectedAssets.length > 0 && - ((pastedObjects.length === 0 && - duplicatedObjects.length === 0 && - movedObjects.length === 0 && - rotatedObjects.length === 0) || - event.button !== 0) - ) { - clearSelection(); - helper.enabled = true; - isCtrlSelecting = false; - } - }; - - const onKeyDown = (event: KeyboardEvent) => { - if (movedObjects.length > 0 || rotatedObjects.length > 0) return; - if (event.key.toLowerCase() === "escape") { - event.preventDefault(); - clearSelection(); - } - if (event.key.toLowerCase() === "delete") { - event.preventDefault(); - deleteSelection(); - } - }; - - const onContextMenu = (event: MouseEvent) => { - event.preventDefault(); - if (!rightClickMoved) { - clearSelection(); - } - }; - - if (!toggleView && activeModule === "builder") { - helper.enabled = true; - if (duplicatedObjects.length === 0 && pastedObjects.length === 0) { - canvasElement.addEventListener("pointerdown", onPointerDown); - canvasElement.addEventListener("pointermove", onPointerMove); - canvasElement.addEventListener("pointerup", onPointerUp); - } else { - helper.enabled = false; - helper.dispose(); - } - canvasElement.addEventListener("contextmenu", onContextMenu); - canvasElement.addEventListener("keydown", onKeyDown); - } else { - helper.enabled = false; - helper.dispose(); - } - - return () => { - canvasElement.removeEventListener("pointerdown", onPointerDown); - canvasElement.removeEventListener("pointermove", onPointerMove); - canvasElement.removeEventListener("contextmenu", onContextMenu); - canvasElement.removeEventListener("pointerup", onPointerUp); - canvasElement.removeEventListener("keydown", onKeyDown); - helper.enabled = false; - helper.dispose(); - }; - }, [ - camera, - controls, - scene, - toggleView, - selectedAssets, - copiedObjects, - pastedObjects, - duplicatedObjects, - movedObjects, - socket, - floorItems, - rotatedObjects, - activeModule, - ]); - - useEffect(() => { - if (activeModule !== "builder") { - clearSelection(); - } - }, [activeModule]); - - useFrame(() => { - if ( - pastedObjects.length === 0 && - duplicatedObjects.length === 0 && - movedObjects.length === 0 && - rotatedObjects.length === 0 - ) { - selectionGroup.current.position.set(0, 0, 0); - } - }); - - const selectAssets = () => { - selectionBox.endPoint.set(pointer.x, pointer.y, 0); - if (controls) (controls as any).enabled = true; - - let selectedObjects = selectionBox.select(); - let Objects = new Set(); - - selectedObjects.map((object) => { - let currentObject: THREE.Object3D | null = object; - while (currentObject) { - if (currentObject.userData.modelId) { - Objects.add(currentObject); - break; - } - currentObject = currentObject.parent || null; - } - }); - - if (Objects.size === 0) { - clearSelection(); - return; - } - - const updatedSelections = new Set(selectedAssets); - Objects.forEach((obj) => { - updatedSelections.has(obj) - ? updatedSelections.delete(obj) - : updatedSelections.add(obj); - }); - - const selected = Array.from(updatedSelections); - - setSelectedAssets(selected); - }; - - const clearSelection = () => { - selectionGroup.current.children = []; - selectionGroup.current.position.set(0, 0, 0); - selectionGroup.current.rotation.set(0, 0, 0); - setpastedObjects([]); - setDuplicatedObjects([]); - setSelectedAssets([]); - }; - const updateBackend = async ( - updatedPaths: ( - | Types.ConveyorEventsSchema - | Types.VehicleEventsSchema - | Types.StaticMachineEventsSchema - | Types.ArmBotEventsSchema - )[] - ) => { - if (updatedPaths.length === 0) return; - const email = localStorage.getItem("email"); - const organization = email ? email.split("@")[1].split(".")[0] : ""; - - updatedPaths.forEach(async (updatedPath) => { - if (updatedPath.type === "Conveyor") { - // await setEventApi( - // organization, - // updatedPath.modeluuid, - // { type: "Conveyor", points: updatedPath.points, speed: updatedPath.speed } - // ); - - const data = { - organization: organization, - modeluuid: updatedPath.modeluuid, - eventData: { - type: "Conveyor", - points: updatedPath.points, - speed: updatedPath.speed, - }, - }; - - socket.emit("v2:model-asset:updateEventData", data); - } else if (updatedPath.type === "Vehicle") { - // await setEventApi( - // organization, - // updatedPath.modeluuid, - // { type: "Vehicle", points: updatedPath.points } - // ); - - const data = { - organization: organization, - modeluuid: updatedPath.modeluuid, - eventData: { type: "Vehicle", points: updatedPath.points }, - }; - - socket.emit("v2:model-asset:updateEventData", data); - } else if (updatedPath.type === "StaticMachine") { - // await setEventApi( - // organization, - // updatedPath.modeluuid, - // { type: "StaticMachine", points: updatedPath.points } - // ); - - const data = { - organization: organization, - modeluuid: updatedPath.modeluuid, - eventData: { type: "StaticMachine", points: updatedPath.points }, - }; - - socket.emit("v2:model-asset:updateEventData", data); - } else if (updatedPath.type === "ArmBot") { - // await setEventApi( - // organization, - // updatedPath.modeluuid, - // { type: "ArmBot", points: updatedPath.points } - // ); - - const data = { - organization: organization, - modeluuid: updatedPath.modeluuid, - eventData: { type: "ArmBot", points: updatedPath.points }, - }; - - socket.emit("v2:model-asset:updateEventData", data); - } - }); - }; - // const removeConnection = (modelUUID: any) => { - // - // const removedPath = simulationStates?.flatMap((state) => { - // let shouldInclude = false; - - // if (state.type === "Conveyor") { - // state.points.forEach((point: any) => { - // const sourceMatch = - // point.connections?.source?.modelUUID === modelUUID; - // const targetMatch = point.connections?.targets?.some( - // (target: any) => target.modelUUID === modelUUID - // ); - - // if (sourceMatch || targetMatch) shouldInclude = true; - // }); - // } - - // if (state.type === "Vehicle") { - // const targetMatch = state.points.connections?.targets?.some( - // (target: any) => target.modelUUID === modelUUID - // ); - - // if (targetMatch) shouldInclude = true; - // } - - // if (state.type === "StaticMachine") { - // const targetMatch = state.points.connections?.targets?.some( - // (target: any) => target.modelUUID === modelUUID - // ); - - // if (targetMatch) shouldInclude = true; - // } - - // if (state.type === "ArmBot") { - // const sourceMatch = - // state.points.connections?.source?.modelUUID === modelUUID; - // const targetMatch = state.points.connections?.targets?.some( - // (target: any) => target.modelUUID === modelUUID - // ); - - // const processMatch = - // state.points.actions?.processes?.some( - // (process: any) => - // process.startPoint === modelUUID || process.endPoint === modelUUID - // ) ?? false; - - // if (sourceMatch || targetMatch || processMatch) shouldInclude = true; - // } - - // return shouldInclude ? [state] : []; - // }); - // updateBackend(removedPath); - // - // return removedPath; - // // updateBackend(updatedPaths); - - // // setSimulationStates(updatedStates); - // }; - // const removeConnection = (modelUUIDs: any[]) => { - // - // const removedPath = simulationStates?.flatMap((state) => { - // let shouldInclude = false; - - // if (state.type === "Conveyor") { - // state.points.forEach((point: any) => { - // const sourceMatch = modelUUIDs.includes( - // point.connections?.source?.modelUUID - // ); - // const targetMatch = point.connections?.targets?.some((target: any) => - // modelUUIDs.includes(target.modelUUID) - // ); - - // if (sourceMatch || targetMatch) shouldInclude = true; - // }); - // } - - // if (state.type === "Vehicle") { - // const targetMatch = state.points.connections?.targets?.some( - // (target: any) => modelUUIDs.includes(target.modelUUID) - // ); - - // if (targetMatch) shouldInclude = true; - // } - - // if (state.type === "StaticMachine") { - // const targetMatch = state.points.connections?.targets?.some( - // (target: any) => modelUUIDs.includes(target.modelUUID) - // ); - - // if (targetMatch) shouldInclude = true; - // } - - // if (state.type === "ArmBot") { - // const sourceMatch = modelUUIDs.includes( - // state.points.connections?.source?.modelUUID - // ); - // const targetMatch = state.points.connections?.targets?.some( - // (target: any) => modelUUIDs.includes(target.modelUUID) - // ); - - // const processMatch = - // state.points.actions?.processes?.some( - // (process: any) => - // modelUUIDs.includes(process.startPoint) || - // modelUUIDs.includes(process.endPoint) - // ) ?? false; - - // if (sourceMatch || targetMatch || processMatch) shouldInclude = true; - // } - - // return shouldInclude ? [state] : []; - // }); - // updateBackend(removedPath); - // - // return removedPath; - // }; - const removeConnection = (modelUUIDs: any[]) => { - const removedPath = simulationStates?.flatMap((state: any) => { - let shouldInclude = false; - - // Conveyor type - if (state.type === "Conveyor") { - state.points.forEach((point: any) => { - const sourceMatch = modelUUIDs.includes( - point.connections?.source?.modelUUID - ); - const targetMatch = point.connections?.targets?.some((target: any) => - modelUUIDs.includes(target.modelUUID) - ); - - if (sourceMatch) { - point.connections.source = {}; - shouldInclude = true; - } - - if (targetMatch) { - point.connections.targets = []; - shouldInclude = true; - } - }); - } - - // Vehicle & StaticMachine types - if (state.type === "Vehicle") { - const targets = state.points?.connections?.targets || []; - const targetMatch = targets.some((target: any) => - modelUUIDs.includes(target.modelUUID) - ); - - if (targetMatch) { - state.points.connections.targets = []; - shouldInclude = true; - } - } - if (state.type === "StaticMachine") { - const targets = state.points?.connections?.targets || []; - const targetMatch = targets.some((target: any) => - modelUUIDs.includes(target.modelUUID) - ); - - if (targetMatch) { - state.points.connections.targets = []; - shouldInclude = true; - } - } - - // ArmBot type - if (state.type === "ArmBot") { - const sourceMatch = modelUUIDs.includes( - state.points.connections?.source?.modelUUID - ); - - const targetMatch = state.points.connections?.targets?.some( - (target: any) => modelUUIDs.includes(target.modelUUID) - ); - // state.points.actions.processes = state.points.actions.processes.filter( - // (process: any) => - // console.log( - // !modelUUIDs.includes(process.startPoint), - // !modelUUIDs.includes(process.endPoint), - // modelUUIDs, - // process.startPoint, - // process.endPoint - // ) - // ); - - // shouldInclude = true; - - // const processMatches = state.points.actions?.processes?.some( - // (process: any) => - // console.log( - // "process: ", - // process, - // modelUUIDs, - // process.startPoint, - // process.endPoint - // ) - // // modelUUIDs.includes(process.startPoint) || - // // modelUUIDs.includes(process.endPoint) - // ); - // const processMatch = state.points.actions?.processes?.some( - // (process: any) => - // modelUUIDs.includes(String(process.startPoint)) || - // modelUUIDs.includes(String(process.endPoint)) - // ); - - // console.log("processMatch: ", processMatch); - if (sourceMatch) { - state.points.connections.source = {}; - shouldInclude = true; + const { camera, controls, gl, scene, pointer } = useThree(); + const itemsGroupRef = useRef(undefined); + const selectionGroup = useRef() as Types.RefGroup; + const { toggleView } = useToggleView(); + const { simulationStates, setSimulationStates } = useSimulationStates(); + const { selectedAssets, setSelectedAssets } = useSelectedAssets(); + const [movedObjects, setMovedObjects] = useState([]); + const [rotatedObjects, setRotatedObjects] = useState([]); + const [copiedObjects, setCopiedObjects] = useState([]); + const [pastedObjects, setpastedObjects] = useState([]); + const [duplicatedObjects, setDuplicatedObjects] = useState([]); + const boundingBoxRef = useRef(); + const { floorItems, setFloorItems } = useFloorItems(); + const { activeModule } = useModuleStore(); + const { socket } = useSocketStore(); + const selectionBox = useMemo(() => new SelectionBox(camera, scene), [camera, scene]); + + useEffect(() => { + if (!camera || !scene || toggleView) return; + + const canvasElement = gl.domElement; + canvasElement.tabIndex = 0; + + const itemsGroup: any = scene.getObjectByName("itemsGroup"); + itemsGroupRef.current = itemsGroup; + + let isSelecting = false; + let isRightClick = false; + let rightClickMoved = false; + let isCtrlSelecting = false; + + const helper = new SelectionHelper(gl); + + if (!itemsGroup) { + toast.warn("itemsGroup not found in the scene."); + return; } - if (targetMatch) { - state.points.connections.targets = - state.points.connections.targets.filter( - (target: any) => !modelUUIDs.includes(target.modelUUID) - ); - shouldInclude = true; - } - - // console.log("processMatch: ", processMatch); - // if (processMatch) { - // state.points.actions.processes = - // state.points.actions.processes.filter((process: any) => { - // const shouldRemove = - // modelUUIDs.includes(process.startPoint) || - // modelUUIDs.includes(process.endPoint); - - // console.log("shouldRemove: ", shouldRemove); - // return !shouldRemove; - // }); - // shouldInclude = true; - // } - } - - return shouldInclude ? [state] : []; - }); - - updateBackend(removedPath); - return removedPath; - }; - - const deleteSelection = () => { - if (selectedAssets.length > 0 && duplicatedObjects.length === 0) { - const email = localStorage.getItem("email"); - const organization = email!.split("@")[1].split(".")[0]; - - const storedItems = JSON.parse( - localStorage.getItem("FloorItems") || "[]" - ); - const selectedUUIDs = selectedAssets.map( - (mesh: THREE.Object3D) => mesh.uuid - ); - - const updatedStoredItems = storedItems.filter( - (item: { modeluuid: string }) => !selectedUUIDs.includes(item.modeluuid) - ); - localStorage.setItem("FloorItems", JSON.stringify(updatedStoredItems)); - - selectedAssets.forEach((selectedMesh: THREE.Object3D) => { - //REST - - // const response = await deleteFloorItem(organization, selectedMesh.uuid, selectedMesh.userData.name); - - //SOCKET - - const data = { - organization: organization, - modeluuid: selectedMesh.uuid, - modelname: selectedMesh.userData.name, - socketId: socket.id, - }; - - socket.emit("v2:model-asset:delete", data); - - selectedMesh.traverse((child: THREE.Object3D) => { - if (child instanceof THREE.Mesh) { - if (child.geometry) child.geometry.dispose(); - if (Array.isArray(child.material)) { - child.material.forEach((material) => { - if (material.map) material.map.dispose(); - material.dispose(); - }); - } else if (child.material) { - if (child.material.map) child.material.map.dispose(); - child.material.dispose(); + const onPointerDown = (event: PointerEvent) => { + if (event.button === 2) { + isRightClick = true; + rightClickMoved = false; + } else if (event.button === 0) { + isSelecting = false; + isCtrlSelecting = event.ctrlKey; + if (event.ctrlKey && duplicatedObjects.length === 0) { + if (controls) (controls as any).enabled = false; + selectionBox.startPoint.set(pointer.x, pointer.y, 0); + } + } + }; + + const onPointerMove = (event: PointerEvent) => { + if (isRightClick) { + rightClickMoved = true; + } + isSelecting = true; + if (helper.isDown && event.ctrlKey && duplicatedObjects.length === 0 && isCtrlSelecting) { + selectionBox.endPoint.set(pointer.x, pointer.y, 0); + } + }; + + const onPointerUp = (event: PointerEvent) => { + if (event.button === 2) { + isRightClick = false; + if (!rightClickMoved) { + clearSelection(); + } + return; + } + + if (isSelecting && isCtrlSelecting) { + isCtrlSelecting = false; + isSelecting = false; + if (event.ctrlKey && duplicatedObjects.length === 0) { + selectAssets(); + } + } else if (!isSelecting && selectedAssets.length > 0 && ((pastedObjects.length === 0 && duplicatedObjects.length === 0 && movedObjects.length === 0 && rotatedObjects.length === 0) || event.button !== 0)) { + clearSelection(); + helper.enabled = true; + isCtrlSelecting = false; + } + }; + + const onKeyDown = (event: KeyboardEvent) => { + if (movedObjects.length > 0 || rotatedObjects.length > 0) return; + if (event.key.toLowerCase() === "escape") { + event.preventDefault(); + clearSelection(); + } + if (event.key.toLowerCase() === "delete") { + event.preventDefault(); + deleteSelection(); + } + }; + + const onContextMenu = (event: MouseEvent) => { + event.preventDefault(); + if (!rightClickMoved) { + clearSelection(); + } + }; + + if (!toggleView && activeModule === "builder") { + helper.enabled = true; + if (duplicatedObjects.length === 0 && pastedObjects.length === 0) { + canvasElement.addEventListener("pointerdown", onPointerDown); + canvasElement.addEventListener("pointermove", onPointerMove); + canvasElement.addEventListener("pointerup", onPointerUp); + } else { + helper.enabled = false; + helper.dispose(); + } + canvasElement.addEventListener("contextmenu", onContextMenu); + canvasElement.addEventListener("keydown", onKeyDown); + } else { + helper.enabled = false; + helper.dispose(); + } + + return () => { + canvasElement.removeEventListener("pointerdown", onPointerDown); + canvasElement.removeEventListener("pointermove", onPointerMove); + canvasElement.removeEventListener("contextmenu", onContextMenu); + canvasElement.removeEventListener("pointerup", onPointerUp); + canvasElement.removeEventListener("keydown", onKeyDown); + helper.enabled = false; + helper.dispose(); + }; + }, [camera, controls, scene, toggleView, selectedAssets, copiedObjects, pastedObjects, duplicatedObjects, movedObjects, socket, floorItems, rotatedObjects, activeModule,]); + + useEffect(() => { + if (activeModule !== "builder") { + clearSelection(); + } + }, [activeModule]); + + useFrame(() => { + if (pastedObjects.length === 0 && duplicatedObjects.length === 0 && movedObjects.length === 0 && rotatedObjects.length === 0) { + selectionGroup.current.position.set(0, 0, 0); + } + }); + + const selectAssets = () => { + selectionBox.endPoint.set(pointer.x, pointer.y, 0); + if (controls) (controls as any).enabled = true; + + let selectedObjects = selectionBox.select(); + let Objects = new Set(); + + selectedObjects.map((object) => { + let currentObject: THREE.Object3D | null = object; + while (currentObject) { + if (currentObject.userData.modelId) { + Objects.add(currentObject); + break; + } + currentObject = currentObject.parent || null; } - } }); - setSimulationStates( - ( - prevEvents: ( - | Types.ConveyorEventsSchema - | Types.VehicleEventsSchema - | Types.StaticMachineEventsSchema - | Types.ArmBotEventsSchema - )[] - ) => { - const updatedEvents = (prevEvents || []).filter( - (event) => event.modeluuid !== selectedMesh.uuid + if (Objects.size === 0) { + clearSelection(); + return; + } + + const updatedSelections = new Set(selectedAssets); + Objects.forEach((obj) => { updatedSelections.has(obj) ? updatedSelections.delete(obj) : updatedSelections.add(obj); }); + + const selected = Array.from(updatedSelections); + + setSelectedAssets(selected); + }; + + const clearSelection = () => { + selectionGroup.current.children = []; + selectionGroup.current.position.set(0, 0, 0); + selectionGroup.current.rotation.set(0, 0, 0); + setpastedObjects([]); + setDuplicatedObjects([]); + setSelectedAssets([]); + }; + const updateBackend = async (updatedPaths: (SimulationTypes.ConveyorEventsSchema | SimulationTypes.VehicleEventsSchema | SimulationTypes.StaticMachineEventsSchema | SimulationTypes.ArmBotEventsSchema)[]) => { + if (updatedPaths.length === 0) return; + const email = localStorage.getItem("email"); + const organization = email ? email.split("@")[1].split(".")[0] : ""; + + updatedPaths.forEach(async (updatedPath) => { + + if (updatedPath.type === "Conveyor") { + // await setEventApi( + // organization, + // updatedPath.modeluuid, + // { type: "Conveyor", points: updatedPath.points, speed: updatedPath.speed } + // ); + + const data = { + organization: organization, + modeluuid: updatedPath.modeluuid, + eventData: { + type: "Conveyor", + points: updatedPath.points, + speed: updatedPath.speed, + }, + }; + + socket.emit("v2:model-asset:updateEventData", data); + + } else if (updatedPath.type === "Vehicle") { + + // await setEventApi( + // organization, + // updatedPath.modeluuid, + // { type: "Vehicle", points: updatedPath.points } + // ); + + const data = { + organization: organization, + modeluuid: updatedPath.modeluuid, + eventData: { type: "Vehicle", points: updatedPath.points }, + }; + + socket.emit("v2:model-asset:updateEventData", data); + + } else if (updatedPath.type === "StaticMachine") { + + // await setEventApi( + // organization, + // updatedPath.modeluuid, + // { type: "StaticMachine", points: updatedPath.points } + // ); + + const data = { + organization: organization, + modeluuid: updatedPath.modeluuid, + eventData: { type: "StaticMachine", points: updatedPath.points }, + }; + + socket.emit("v2:model-asset:updateEventData", data); + + } else if (updatedPath.type === "ArmBot") { + + // await setEventApi( + // organization, + // updatedPath.modeluuid, + // { type: "ArmBot", points: updatedPath.points } + // ); + + const data = { + organization: organization, + modeluuid: updatedPath.modeluuid, + eventData: { type: "ArmBot", points: updatedPath.points }, + }; + + socket.emit("v2:model-asset:updateEventData", data); + } + + }); + }; + + // const removeConnection = (modelUUID: any) => { + // + // const removedPath = simulationStates?.flatMap((state) => { + // let shouldInclude = false; + + // if (state.type === "Conveyor") { + // state.points.forEach((point: any) => { + // const sourceMatch = + // point.connections?.source?.modelUUID === modelUUID; + // const targetMatch = point.connections?.targets?.some( + // (target: any) => target.modelUUID === modelUUID + // ); + + // if (sourceMatch || targetMatch) shouldInclude = true; + // }); + // } + + // if (state.type === "Vehicle") { + // const targetMatch = state.points.connections?.targets?.some( + // (target: any) => target.modelUUID === modelUUID + // ); + + // if (targetMatch) shouldInclude = true; + // } + + // if (state.type === "StaticMachine") { + // const targetMatch = state.points.connections?.targets?.some( + // (target: any) => target.modelUUID === modelUUID + // ); + + // if (targetMatch) shouldInclude = true; + // } + + // if (state.type === "ArmBot") { + // const sourceMatch = + // state.points.connections?.source?.modelUUID === modelUUID; + // const targetMatch = state.points.connections?.targets?.some( + // (target: any) => target.modelUUID === modelUUID + // ); + + // const processMatch = + // state.points.actions?.processes?.some( + // (process: any) => + // process.startPoint === modelUUID || process.endPoint === modelUUID + // ) ?? false; + + // if (sourceMatch || targetMatch || processMatch) shouldInclude = true; + // } + + // return shouldInclude ? [state] : []; + // }); + // updateBackend(removedPath); + // + // return removedPath; + // // updateBackend(updatedPaths); + + // // setSimulationStates(updatedStates); + // }; + // const removeConnection = (modelUUIDs: any[]) => { + // + // const removedPath = simulationStates?.flatMap((state) => { + // let shouldInclude = false; + + // if (state.type === "Conveyor") { + // state.points.forEach((point: any) => { + // const sourceMatch = modelUUIDs.includes( + // point.connections?.source?.modelUUID + // ); + // const targetMatch = point.connections?.targets?.some((target: any) => + // modelUUIDs.includes(target.modelUUID) + // ); + + // if (sourceMatch || targetMatch) shouldInclude = true; + // }); + // } + + // if (state.type === "Vehicle") { + // const targetMatch = state.points.connections?.targets?.some( + // (target: any) => modelUUIDs.includes(target.modelUUID) + // ); + + // if (targetMatch) shouldInclude = true; + // } + + // if (state.type === "StaticMachine") { + // const targetMatch = state.points.connections?.targets?.some( + // (target: any) => modelUUIDs.includes(target.modelUUID) + // ); + + // if (targetMatch) shouldInclude = true; + // } + + // if (state.type === "ArmBot") { + // const sourceMatch = modelUUIDs.includes( + // state.points.connections?.source?.modelUUID + // ); + // const targetMatch = state.points.connections?.targets?.some( + // (target: any) => modelUUIDs.includes(target.modelUUID) + // ); + + // const processMatch = + // state.points.actions?.processes?.some( + // (process: any) => + // modelUUIDs.includes(process.startPoint) || + // modelUUIDs.includes(process.endPoint) + // ) ?? false; + + // if (sourceMatch || targetMatch || processMatch) shouldInclude = true; + // } + + // return shouldInclude ? [state] : []; + // }); + // updateBackend(removedPath); + // + // return removedPath; + // }; + + const removeConnection = (modelUUIDs: any[]) => { + const removedPath = simulationStates?.flatMap((state: any) => { + let shouldInclude = false; + + // Conveyor type + if (state.type === "Conveyor") { + state.points.forEach((point: any) => { + const sourceMatch = modelUUIDs.includes(point.connections?.source?.modelUUID); + const targetMatch = point.connections?.targets?.some((target: any) => modelUUIDs.includes(target.modelUUID)); + + if (sourceMatch) { + point.connections.source = {}; + shouldInclude = true; + } + + if (targetMatch) { + point.connections.targets = []; + shouldInclude = true; + } + }); + } + + // Vehicle & StaticMachine types + if (state.type === "Vehicle") { + const targets = state.points?.connections?.targets || []; + const targetMatch = targets.some((target: any) => modelUUIDs.includes(target.modelUUID)); + + if (targetMatch) { + state.points.connections.targets = []; + shouldInclude = true; + } + } + if (state.type === "StaticMachine") { + const targets = state.points?.connections?.targets || []; + const targetMatch = targets.some((target: any) => modelUUIDs.includes(target.modelUUID)); + + if (targetMatch) { + state.points.connections.targets = []; + shouldInclude = true; + } + } + + // ArmBot type + if (state.type === "ArmBot") { + const sourceMatch = modelUUIDs.includes(state.points.connections?.source?.modelUUID); + + const targetMatch = state.points.connections?.targets?.some( + (target: any) => modelUUIDs.includes(target.modelUUID) + ); + // state.points.actions.processes = state.points.actions.processes.filter( + // (process: any) => + // console.log( + // !modelUUIDs.includes(process.startPoint), + // !modelUUIDs.includes(process.endPoint), + // modelUUIDs, + // process.startPoint, + // process.endPoint + // ) + // ); + + // shouldInclude = true; + + // const processMatches = state.points.actions?.processes?.some( + // (process: any) => + // console.log( + // "process: ", + // process, + // modelUUIDs, + // process.startPoint, + // process.endPoint + // ) + // // modelUUIDs.includes(process.startPoint) || + // // modelUUIDs.includes(process.endPoint) + // ); + // const processMatch = state.points.actions?.processes?.some( + // (process: any) => + // modelUUIDs.includes(String(process.startPoint)) || + // modelUUIDs.includes(String(process.endPoint)) + // ); + + // console.log("processMatch: ", processMatch); + if (sourceMatch) { + state.points.connections.source = {}; + shouldInclude = true; + } + + if (targetMatch) { + state.points.connections.targets = + state.points.connections.targets.filter((target: any) => !modelUUIDs.includes(target.modelUUID)); + shouldInclude = true; + } + + // console.log("processMatch: ", processMatch); + // if (processMatch) { + // state.points.actions.processes = + // state.points.actions.processes.filter((process: any) => { + // const shouldRemove = + // modelUUIDs.includes(process.startPoint) || + // modelUUIDs.includes(process.endPoint); + + // console.log("shouldRemove: ", shouldRemove); + // return !shouldRemove; + // }); + // shouldInclude = true; + // } + } + + return shouldInclude ? [state] : []; + }); + + updateBackend(removedPath); + return removedPath; + }; + + const deleteSelection = () => { + if (selectedAssets.length > 0 && duplicatedObjects.length === 0) { + const email = localStorage.getItem("email"); + const organization = email!.split("@")[1].split(".")[0]; + + const storedItems = JSON.parse(localStorage.getItem("FloorItems") || "[]"); + const selectedUUIDs = selectedAssets.map((mesh: THREE.Object3D) => mesh.uuid); + + const updatedStoredItems = storedItems.filter((item: { modeluuid: string }) => !selectedUUIDs.includes(item.modeluuid)); + localStorage.setItem("FloorItems", JSON.stringify(updatedStoredItems)); + + selectedAssets.forEach((selectedMesh: THREE.Object3D) => { + //REST + + // const response = await deleteFloorItem(organization, selectedMesh.uuid, selectedMesh.userData.name); + + //SOCKET + + const data = { + organization: organization, + modeluuid: selectedMesh.uuid, + modelname: selectedMesh.userData.name, + socketId: socket.id, + }; + + socket.emit("v2:model-asset:delete", data); + + selectedMesh.traverse((child: THREE.Object3D) => { + if (child instanceof THREE.Mesh) { + if (child.geometry) child.geometry.dispose(); + if (Array.isArray(child.material)) { + child.material.forEach((material) => { + if (material.map) material.map.dispose(); + material.dispose(); + }); + } else if (child.material) { + if (child.material.map) child.material.map.dispose(); + child.material.dispose(); + } + } + }); + + setSimulationStates((prevEvents: (| SimulationTypes.ConveyorEventsSchema | SimulationTypes.VehicleEventsSchema | SimulationTypes.StaticMachineEventsSchema | SimulationTypes.ArmBotEventsSchema)[]) => { + const updatedEvents = (prevEvents || []).filter( + (event) => event.modeluuid !== selectedMesh.uuid + ); + return updatedEvents; + } + ); + + itemsGroupRef.current?.remove(selectedMesh); + }); + + const allUUIDs = selectedAssets.map((val: any) => val.uuid); + removeConnection(allUUIDs); + + // const removedPath = simulationStates?.flatMap((path: any) => { + // let shouldInclude = false; + + // if (Array.isArray(path.points)) { + // path.points.forEach((point: any) => { + // const sourceMatch = + // point.connections?.source?.modelUUID === selectedAssets[0].uuid; + // const targetMatch = point.connections?.targets?.some( + // (target: any) => target.modelUUID === selectedAssets[0].uuid + // ); + + // if (sourceMatch) { + // point.connections.source = {}; + // shouldInclude = true; + // } + + // if (targetMatch) { + // point.connections.targets = []; + // shouldInclude = true; + // } + // }); + // } else { + // const sourceMatch = + // path.connections?.source?.modelUUID === selectedAssets[0].uuid; + // const targetMatch = path.connections?.targets?.some( + // (target: any) => target.modelUUID === selectedAssets[0].uuid + // ); + + // if (sourceMatch) { + // path.connections.source = {}; + // shouldInclude = true; + // } + + // if (targetMatch) { + // path.connections.targets = []; + // shouldInclude = true; + // } + // } + + // return shouldInclude ? [path] : []; + // }); + // updateBackend(removedPath); + + const updatedItems = floorItems.filter( + (item: { modeluuid: string }) => !selectedUUIDs.includes(item.modeluuid) ); - return updatedEvents; - } - ); + setFloorItems(updatedItems); + } + toast.success("Selected models removed!"); + clearSelection(); + }; - itemsGroupRef.current?.remove(selectedMesh); - }); + return ( + <> + + + + + - const allUUIDs = selectedAssets.map((val: any) => val.uuid); - removeConnection(allUUIDs); - // const removedPath = simulationStates?.flatMap((path: any) => { - // let shouldInclude = false; + - // if (Array.isArray(path.points)) { - // path.points.forEach((point: any) => { - // const sourceMatch = - // point.connections?.source?.modelUUID === selectedAssets[0].uuid; - // const targetMatch = point.connections?.targets?.some( - // (target: any) => target.modelUUID === selectedAssets[0].uuid - // ); + - // if (sourceMatch) { - // point.connections.source = {}; - // shouldInclude = true; - // } + - // if (targetMatch) { - // point.connections.targets = []; - // shouldInclude = true; - // } - // }); - // } else { - // const sourceMatch = - // path.connections?.source?.modelUUID === selectedAssets[0].uuid; - // const targetMatch = path.connections?.targets?.some( - // (target: any) => target.modelUUID === selectedAssets[0].uuid - // ); - - // if (sourceMatch) { - // path.connections.source = {}; - // shouldInclude = true; - // } - - // if (targetMatch) { - // path.connections.targets = []; - // shouldInclude = true; - // } - // } - - // return shouldInclude ? [path] : []; - // }); - // updateBackend(removedPath); - - const updatedItems = floorItems.filter( - (item: { modeluuid: string }) => !selectedUUIDs.includes(item.modeluuid) - ); - setFloorItems(updatedItems); - } - toast.success("Selected models removed!"); - clearSelection(); - }; - - return ( - <> - - - - - - - - - - - ); + + + ); }; export default SelectionControls; diff --git a/app/src/modules/scene/scene.tsx b/app/src/modules/scene/scene.tsx index b26dca9..941616c 100644 --- a/app/src/modules/scene/scene.tsx +++ b/app/src/modules/scene/scene.tsx @@ -17,7 +17,7 @@ import MeasurementTool from "./tools/measurementTool"; import Simulation from "../simulation/simulation"; // import Simulation from "./simulationtemp/simulation"; -import ZoneCentreTarget from "../../components/ui/componets/zoneCameraTarget"; +import ZoneCentreTarget from "../visualization/functions/zoneCameraTarget"; import Dropped3dWidgets from "../../modules/visualization/widgets/3d/Dropped3dWidget"; import ZoneAssets from "../visualization/zoneAssets"; diff --git a/app/src/modules/scene/world/world.tsx b/app/src/modules/scene/world/world.tsx index 8743030..dcd1adb 100644 --- a/app/src/modules/scene/world/world.tsx +++ b/app/src/modules/scene/world/world.tsx @@ -55,7 +55,6 @@ import DrieHtmlTemp from "../mqttTemp/drieHtmlTemp"; import ZoneGroup from "../../builder/groups/zoneGroup"; import useModuleStore from "../../../store/useModuleStore"; import NavMeshCreator from "../../builder/agv/navMeshCreator"; -import ArmReplace from "../../simulation/ik/ArmReplace"; export default function World() { const state = useThree(); // Importing the state from the useThree hook, which contains the scene, camera, and other Three.js elements. @@ -110,8 +109,7 @@ export default function World() { const cursorPosition = new THREE.Vector3(); // 3D vector for storing the cursor position. - const [selectedItemsIndex, setSelectedItemsIndex] = - useState(null); // State for tracking the index of the selected item. + const [selectedItemsIndex, setSelectedItemsIndex] = useState(null); // State for tracking the index of the selected item. const { activeLayer, setActiveLayer } = useActiveLayer(); // State that changes based on which layer the user chooses in Layers.jsx. const { toggleView, setToggleView } = useToggleView(); // State for toggling between 2D and 3D. const { toolMode, setToolMode } = useToolMode(); @@ -371,9 +369,6 @@ export default function World() { - {/* replacing exsisting arms with rigged ones */} - - ); } diff --git a/app/src/modules/simulation/armbot/ArmBot.tsx b/app/src/modules/simulation/armbot/ArmBot.tsx new file mode 100644 index 0000000..db0f956 --- /dev/null +++ b/app/src/modules/simulation/armbot/ArmBot.tsx @@ -0,0 +1,62 @@ +import React, { useEffect, useState } from "react"; +import { useThree } from "@react-three/fiber"; +import useModuleStore from "../../../store/useModuleStore"; +import { useSimulationStates } from "../../../store/store"; +import * as SimulationTypes from '../../../types/simulation'; +import { ArmbotInstances } from "./ArmBotInstances"; + +interface ArmBotState { + uuid: string; + position: [number, number, number]; + rotation: [number, number, number]; + status: string; + material: string; + triggerId: string; + connections: any +} + +const ArmBot: React.FC = () => { + const { activeModule } = useModuleStore(); + const { scene } = useThree(); + const { simulationStates } = useSimulationStates(); + const [armBots, setArmBots] = useState([]); + + useEffect(() => { + const filtered = simulationStates.filter((s): s is SimulationTypes.ArmBotEventsSchema => s.type === "ArmBot"); + const initialStates: ArmBotState[] = filtered.map(bot => ({ + uuid: bot.modeluuid, + position: bot.position, + rotation: bot.rotation, + status: "idle", + material: "default", + triggerId: '', + connections: bot.points.connections + })); + setArmBots(initialStates); + }, [simulationStates]); + + useEffect(() => { + armBots.forEach((bot) => { + const object = scene.getObjectByProperty("uuid", bot.uuid); + if (object) { + object.visible = activeModule !== "simulation"; + } + }); + }, [scene, activeModule, armBots]); + + return ( + <> + {activeModule === "simulation" && + armBots.map((bot, i) => ( + + ))} + + ); +}; + +export default ArmBot; diff --git a/app/src/modules/simulation/armbot/ArmBotInstances.tsx b/app/src/modules/simulation/armbot/ArmBotInstances.tsx new file mode 100644 index 0000000..6ce4e01 --- /dev/null +++ b/app/src/modules/simulation/armbot/ArmBotInstances.tsx @@ -0,0 +1,25 @@ +import IkInstances from "./IkInstances"; +import armModel from "../../../assets/gltf-glb/rigged/ik_arm_4.glb"; + +interface ArmBotState { + uuid: string; + position: [number, number, number]; + rotation: [number, number, number]; + status: string; + material: string; + triggerId: string; + connections: any +} + +interface ArmbotInstancesProps { + index: number; + armBot: ArmBotState; + setArmBots: (armBots: ArmBotState[]) => void; +} + +export const ArmbotInstances: React.FC = ({ index, armBot, setArmBots }) => { + + return ( + + ); +}; \ No newline at end of file diff --git a/app/src/modules/simulation/armbot/IKAnimationController.tsx b/app/src/modules/simulation/armbot/IKAnimationController.tsx new file mode 100644 index 0000000..45d482f --- /dev/null +++ b/app/src/modules/simulation/armbot/IKAnimationController.tsx @@ -0,0 +1,101 @@ +import { useEffect, useMemo, useState } from "react"; +import { useFrame } from "@react-three/fiber"; +import * as THREE from "three"; + +const IKAnimationController = ({ + ikSolver, + process, + selectedTrigger, + targetBoneName, +}: { + ikSolver: any; + process: { + trigger: string; + start: THREE.Vector3; + end: THREE.Vector3; + speed: number; + }[]; + selectedTrigger: string; + targetBoneName: string; +}) => { + const [progress, setProgress] = useState(0); + const restSpeed = 0.1; + + useEffect(() => { + setProgress(0); + }, [selectedTrigger]); + + const processedCurves = useMemo(() => { + const restPosition = new THREE.Vector3(0.2, 2.3, 1.6); + return process.map((p) => { + const mid = new THREE.Vector3( + (p.start.x + p.end.x) / 1, + Math.max(p.start.y, p.end.y) + 0.8, + (p.start.z + p.end.z) / 0.9 + ); + const points = [ + restPosition.clone(), + p.start.clone(), + mid.clone(), + p.end.clone(), + restPosition.clone(), + ]; + const curve = new THREE.CatmullRomCurve3(points); + const restToStartDist = points[0].distanceTo(points[1]); + const startToEndDist = points[1].distanceTo(points[3]); + const endToRestDist = points[3].distanceTo(points[4]); + + const totalDist = restToStartDist + startToEndDist + endToRestDist; + const restToStartRange = [0, restToStartDist / totalDist]; + const startToEndRange = [ + restToStartRange[1], + restToStartRange[1] + startToEndDist / totalDist, + ]; + const endToRestRange = [startToEndRange[1], 1]; + + return { + trigger: p.trigger, + curve, + speed: p.speed, + restToStartRange, + startToEndRange, + endToRestRange, + }; + }); + }, [process]); + + const activeCurve = useMemo(() => { + return processedCurves.find((c) => c.trigger === selectedTrigger); + }, [processedCurves, selectedTrigger]); + + useFrame((_, delta) => { + if (!ikSolver || !activeCurve) return; + + const { curve, speed, startToEndRange } = activeCurve; + const targetBone = ikSolver.mesh.skeleton.bones.find( + (b: any) => b.name === targetBoneName + ); + if (!targetBone) return; + + let currentSpeed = restSpeed; + if (progress >= startToEndRange[0] && progress < startToEndRange[1]) { + currentSpeed = speed; + } + + setProgress((prev) => { + const next = prev + delta * currentSpeed; + if (next >= 1) { + targetBone.position.copy(curve.getPoint(1)); + return 1; + } + targetBone.position.copy(curve.getPoint(next)); + return next; + }); + + ikSolver.update(); + }); + + return null; +}; + +export default IKAnimationController; diff --git a/app/src/modules/simulation/armbot/IkInstances.tsx b/app/src/modules/simulation/armbot/IkInstances.tsx new file mode 100644 index 0000000..b789f3a --- /dev/null +++ b/app/src/modules/simulation/armbot/IkInstances.tsx @@ -0,0 +1,128 @@ +import * as THREE from "three"; +import { useEffect, useMemo, useRef, useState } from "react"; +import { useLoader } from "@react-three/fiber"; +import { DRACOLoader } from "three/examples/jsm/loaders/DRACOLoader"; +import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader"; +import { clone } from "three/examples/jsm/utils/SkeletonUtils"; +import { CCDIKSolver, CCDIKHelper, } from "three/examples/jsm/animation/CCDIKSolver"; +import IKAnimationController from "./IKAnimationController"; + +const IkInstances = ({ modelUrl, position, rotation }: { modelUrl: string; position: [number, number, number]; rotation: [number, number, number]; }) => { + const [ikSolver, setIkSolver] = useState(null); + const [selectedTrigger, setSelectedTrigger] = useState("idle"); + const gltf = useLoader(GLTFLoader, modelUrl, (loader) => { + const draco = new DRACOLoader(); + draco.setDecoderPath( + "https://cdn.jsdelivr.net/npm/three@0.160.0/examples/jsm/libs/draco/" + ); + loader.setDRACOLoader(draco); + }); + const cloned = useMemo(() => clone(gltf.scene), [gltf]); + const groupRef = useRef(null); + const [selectedArm, setSelectedArm] = useState(); + const targetBoneName = "Target"; + const skinnedMeshName = "link_0"; + + const process = useMemo(() => [ + { + trigger: "Trigger1", + start: new THREE.Vector3(-0.75, 1.5, -2.2), + end: new THREE.Vector3(0, 1.2, 2.2), + speed: 0.25, + }, + { + trigger: "Trigger2", + start: new THREE.Vector3(0, 1.2, 2.2), + end: new THREE.Vector3(0.75, 1.5, -2.2), + speed: 0.22, + } + ], []); + + useEffect(() => { + if (!gltf) return; + const OOI: any = {}; + cloned.traverse((n: any) => { + if (n.name === targetBoneName) OOI.Target_Bone = n; + if (n.name === skinnedMeshName) OOI.Skinned_Mesh = n; + }); + + if (!OOI.Target_Bone || !OOI.Skinned_Mesh) return; + + const iks = [ + { + target: 7, + effector: 6, + links: [ + { + index: 5, + enabled: true, + rotationMin: new THREE.Vector3(-Math.PI / 2, 0, 0), + rotationMax: new THREE.Vector3(Math.PI / 2, 0, 0), + }, + { + index: 4, + enabled: true, + rotationMin: new THREE.Vector3(-Math.PI / 2, 0, 0), + rotationMax: new THREE.Vector3(0, 0, 0), + }, + { + index: 3, + enabled: true, + rotationMin: new THREE.Vector3(0, 0, 0), + rotationMax: new THREE.Vector3(2, 0, 0), + }, + { index: 1, enabled: true, limitation: new THREE.Vector3(0, 1, 0) }, + { index: 0, enabled: false, limitation: new THREE.Vector3(0, 0, 0) }, + ], + }, + ]; + + const solver = new CCDIKSolver(OOI.Skinned_Mesh, iks); + setIkSolver(solver); + + const helper = new CCDIKHelper(OOI.Skinned_Mesh, iks, 0.05); + // groupRef.current.add(helper); + + }, [gltf]); + + useEffect(() => { + const triggers = ['Trigger1', 'Trigger2']; + let index = 0; + + const cycleTriggers = setInterval(() => { + setSelectedTrigger(triggers[index]); + index = (index + 1) % triggers.length; + }, 10000); + + return () => clearInterval(cycleTriggers); + }, []); + + return ( + <> + { + e.stopPropagation(); + setSelectedArm(groupRef.current?.getObjectByName(targetBoneName)) + }} + > + + + + {/* {selectedArm && } */} + + ); +}; + +export default IkInstances; \ No newline at end of file diff --git a/app/src/modules/simulation/behaviour/behaviour.tsx b/app/src/modules/simulation/behaviour/behaviour.tsx deleted file mode 100644 index 0ddc3aa..0000000 --- a/app/src/modules/simulation/behaviour/behaviour.tsx +++ /dev/null @@ -1,88 +0,0 @@ -import { useFloorItems, useSimulationStates } from '../../../store/store'; -import * as THREE from 'three'; -import * as Types from '../../../types/world/worldTypes'; -import { useEffect } from 'react'; - -function Behaviour() { - const { setSimulationStates } = useSimulationStates(); - const { floorItems } = useFloorItems(); - - useEffect(() => { - const newPaths: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema)[] = []; - - // floorItems.forEach((item: Types.FloorItemType) => { - // if (item.modelfileID === "672a090f80d91ac979f4d0bd") { - // const point1Position = new THREE.Vector3(0, 0.85, 2.2); - // const middlePointPosition = new THREE.Vector3(0, 0.85, 0); - // const point2Position = new THREE.Vector3(0, 0.85, -2.2); - - // const point1UUID = THREE.MathUtils.generateUUID(); - // const middlePointUUID = THREE.MathUtils.generateUUID(); - // const point2UUID = THREE.MathUtils.generateUUID(); - - // const newPath: Types.ConveyorEventsSchema = { - // modeluuid: item.modeluuid, - // modelName: item.modelname, - // type: 'Conveyor', - // points: [ - // { - // uuid: point1UUID, - // position: [point1Position.x, point1Position.y, point1Position.z], - // rotation: [0, 0, 0], - // actions: [{ uuid: THREE.MathUtils.generateUUID(), name: 'Action 1', type: 'Inherit', material: 'Inherit', delay: 'Inherit', spawnInterval: 'Inherit', isUsed: true }], - // triggers: [], - // connections: { source: { modelUUID: item.modeluuid, pointUUID: point1UUID }, targets: [] }, - // }, - // { - // uuid: middlePointUUID, - // position: [middlePointPosition.x, middlePointPosition.y, middlePointPosition.z], - // rotation: [0, 0, 0], - // actions: [{ uuid: THREE.MathUtils.generateUUID(), name: 'Action 1', type: 'Inherit', material: 'Inherit', delay: 'Inherit', spawnInterval: 'Inherit', isUsed: true }], - // triggers: [], - // connections: { source: { modelUUID: item.modeluuid, pointUUID: middlePointUUID }, targets: [] }, - // }, - // { - // uuid: point2UUID, - // position: [point2Position.x, point2Position.y, point2Position.z], - // rotation: [0, 0, 0], - // actions: [{ uuid: THREE.MathUtils.generateUUID(), name: 'Action 1', type: 'Inherit', material: 'Inherit', delay: 'Inherit', spawnInterval: 'Inherit', isUsed: true }], - // triggers: [], - // connections: { source: { modelUUID: item.modeluuid, pointUUID: point2UUID }, targets: [] }, - // }, - // ], - // position: [...item.position], - // rotation: [item.rotation.x, item.rotation.y, item.rotation.z], - // speed: 'Inherit', - // }; - - // newPaths.push(newPath); - // } else if (item.modelfileID === "67e3da19c2e8f37134526e6a") { - // const pointUUID = THREE.MathUtils.generateUUID(); - // const pointPosition = new THREE.Vector3(0, 1.3, 0); - - // const newVehiclePath: Types.VehicleEventsSchema = { - // modeluuid: item.modeluuid, - // modelName: item.modelname, - // type: 'Vehicle', - // point: { - // uuid: pointUUID, - // position: [pointPosition.x, pointPosition.y, pointPosition.z], - // actions: { uuid: THREE.MathUtils.generateUUID(), name: 'Action 1', type: 'Start', start: {}, hitCount: 1, end: {}, buffer: 0 }, - // connections: { source: { modelUUID: item.modeluuid, pointUUID: pointUUID }, targets: [] }, - // speed: 2, - // }, - // position: [...item.position], - // }; - - // newPaths.push(newVehiclePath); - // } - // }); - - // setSimulationStates(newPaths); - // console.log('floorItems: ', floorItems); - }, [floorItems]); - - return null; -} - -export default Behaviour; \ No newline at end of file diff --git a/app/src/modules/simulation/ik/ArmReplace.tsx b/app/src/modules/simulation/ik/ArmReplace.tsx deleted file mode 100644 index 092f781..0000000 --- a/app/src/modules/simulation/ik/ArmReplace.tsx +++ /dev/null @@ -1,56 +0,0 @@ -import React, { useEffect } from "react"; -import { useThree } from "@react-three/fiber"; - -// store -import useModuleStore from "../../../store/useModuleStore"; - -// functions -import { findLinkObjects } from "./functions/findLinkObjects"; -// components -import { MultiGLTFInstances } from "./MultiGLTFInstances"; - -// impory model from model folder -import armModel from "../../../assets/gltf-glb/rigged/ik_arm_4.glb"; - -// Main component to include the logic -const ArmReplace: React.FC = () => { - const { activeModule } = useModuleStore(); - - const { scene } = useThree(); // Access the Three.js scene from the React Fiber context - - // State to store positions, rotations, and count - const [positions, setPositions] = React.useState<[number, number, number][]>( - [] - ); - const [rotations, setRotations] = React.useState<[number, number, number][]>( - [] - ); - const [count, setCount] = React.useState([]); - - useEffect(() => { - // Call the function to find objects and update states - findLinkObjects( - scene, - setPositions, - setRotations, - setCount, - activeModule === "simulation" ? false : true - ); - }, [scene, activeModule]); // Re-run this effect if the scene changes or activeModule changes - - return ( - <> - {useModuleStore.getState().activeModule === "simulation" && - count.map((_, i: number) => ( - - ))} - - ); -}; - -export default ArmReplace; diff --git a/app/src/modules/simulation/ik/MultiGLTFInstances.tsx b/app/src/modules/simulation/ik/MultiGLTFInstances.tsx deleted file mode 100644 index 7a1812d..0000000 --- a/app/src/modules/simulation/ik/MultiGLTFInstances.tsx +++ /dev/null @@ -1,43 +0,0 @@ -import { useLoader } from "@react-three/fiber"; -import { DRACOLoader } from "three/examples/jsm/loaders/DRACOLoader"; -import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader"; -import { clone } from "three/examples/jsm/utils/SkeletonUtils"; - -interface MultiGLTFInstancesProps { - index: number; - modelUrl: string; - position: [number, number, number]; - rotation: [number, number, number]; -} - -export const MultiGLTFInstances: React.FC = ({ - index, - modelUrl, - position, - rotation, -}) => { - // Load GLTF model with DRACO loader for compression - const originalGltf = useLoader(GLTFLoader, modelUrl, (loader) => { - const draco = new DRACOLoader(); - draco.setDecoderPath( - "https://cdn.jsdelivr.net/npm/three@0.160.0/examples/jsm/libs/draco/" - ); - loader.setDRACOLoader(draco); - }); - - // Clone the model for independent transformations - const cloned = clone(originalGltf.scene); - - // Render the cloned model - return ( - - - - ); -}; diff --git a/app/src/modules/simulation/ik/functions/findLinkObjects.ts b/app/src/modules/simulation/ik/functions/findLinkObjects.ts deleted file mode 100644 index bd38dd7..0000000 --- a/app/src/modules/simulation/ik/functions/findLinkObjects.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { Object3D, Vector3 } from "three"; - -// Function to find objects named 'link_0' and update positions, rotations, and count -export const findLinkObjects = ( - scene: Object3D, - setPositions: React.Dispatch< - React.SetStateAction<[number, number, number][]> - >, - setRotations: React.Dispatch< - React.SetStateAction<[number, number, number][]> - >, - setCount: React.Dispatch>, - visibility: boolean -) => { - const positions: [number, number, number][] = []; - const rotations: [number, number, number][] = []; - const count: string[] = []; - let i = 0; - - scene.traverse((object) => { - if (object.name === "link_0") { - if (object.parent && object.type !== "SkinnedMesh") { - // count - count[i] = object.uuid; - i++; - // Save the position and rotation of the parent object - const { x: px, y: py, z: pz } = object.parent.position; - positions.push([px, py, pz]); - - const { x: rx, y: ry, z: rz } = object.parent.rotation; - rotations.push([rx, ry, rz]); - - // Change visibility of the object - object.visible = visibility; - } - } - }); - - // Update the state with the collected positions, rotations, and count - setPositions(positions); - setRotations(rotations); - setCount(count); -}; diff --git a/app/src/modules/simulation/path/pathConnector.tsx b/app/src/modules/simulation/path/pathConnector.tsx index f6ee51f..1e93bd5 100644 --- a/app/src/modules/simulation/path/pathConnector.tsx +++ b/app/src/modules/simulation/path/pathConnector.tsx @@ -2,6 +2,7 @@ import { useFrame, useThree } from "@react-three/fiber"; import React, { useEffect, useRef, useState } from "react"; import * as THREE from "three"; import * as Types from "../../../types/world/worldTypes"; +import * as SimulationTypes from "../../../types/simulation"; import { QuadraticBezierLine } from "@react-three/drei"; import { useDeleteTool, @@ -423,10 +424,10 @@ function PathConnector({ const updateBackend = async ( updatedPaths: ( - | Types.ConveyorEventsSchema - | Types.VehicleEventsSchema - | Types.StaticMachineEventsSchema - | Types.ArmBotEventsSchema + | SimulationTypes.ConveyorEventsSchema + | SimulationTypes.VehicleEventsSchema + | SimulationTypes.StaticMachineEventsSchema + | SimulationTypes.ArmBotEventsSchema )[] ) => { if (updatedPaths.length === 0) return; @@ -1062,7 +1063,7 @@ function PathConnector({ const updatedStates = simulationStates.map((state) => { // Handle Conveyor (which has multiple points) if (state.type === "Conveyor") { - const updatedConveyor: Types.ConveyorEventsSchema = { + const updatedConveyor: SimulationTypes.ConveyorEventsSchema = { ...state, points: state.points.map((point) => { // Check if this point is either connection1 or connection2 @@ -1101,7 +1102,7 @@ function PathConnector({ (state.modeluuid === connection2.model && state.points.uuid === connection2.point) ) { - const updatedVehicle: Types.VehicleEventsSchema = { + const updatedVehicle: SimulationTypes.VehicleEventsSchema = { ...state, points: { ...state.points, @@ -1132,7 +1133,7 @@ function PathConnector({ (state.modeluuid === connection2.model && state.points.uuid === connection2.point) ) { - const updatedStaticMachine: Types.StaticMachineEventsSchema = { + const updatedStaticMachine: SimulationTypes.StaticMachineEventsSchema = { ...state, points: { ...state.points, @@ -1163,7 +1164,7 @@ function PathConnector({ (state.modeluuid === connection2.model && state.points.uuid === connection2.point) ) { - const updatedArmBot: Types.ArmBotEventsSchema = { + const updatedArmBot: SimulationTypes.ArmBotEventsSchema = { ...state, points: { ...state.points, diff --git a/app/src/modules/simulation/path/pathCreation.tsx b/app/src/modules/simulation/path/pathCreation.tsx index 345fff3..4a8da49 100644 --- a/app/src/modules/simulation/path/pathCreation.tsx +++ b/app/src/modules/simulation/path/pathCreation.tsx @@ -1,5 +1,5 @@ import * as THREE from "three"; -import * as Types from "../../../types/world/worldTypes"; +import * as SimulationTypes from "../../../types/simulation"; import { useRef, useState, useEffect, useMemo } from "react"; import { Sphere, TransformControls } from "@react-three/drei"; import { @@ -94,7 +94,7 @@ function PathCreation({ pathsGroupRef, }: { pathsGroupRef: React.MutableRefObjec } else { return path; } - }) as Types.ConveyorEventsSchema[]; + }) as SimulationTypes.ConveyorEventsSchema[]; const updatedPath = updatedPaths.find( (path) => path.type === "Conveyor" && path.points.some((point) => point.uuid === selectedActionSphere.points.uuid) @@ -161,7 +161,7 @@ function PathCreation({ pathsGroupRef, }: { pathsGroupRef: React.MutableRefObjec }; }, [eyeDropMode, editingPoint, previewPosition]); - const updateBackend = async (updatedPath: Types.VehicleEventsSchema | undefined) => { + const updateBackend = async (updatedPath: SimulationTypes.VehicleEventsSchema | undefined) => { if (!updatedPath) return; const email = localStorage.getItem("email"); const organization = email ? email.split("@")[1].split(".")[0] : ""; @@ -191,7 +191,7 @@ function PathCreation({ pathsGroupRef, }: { pathsGroupRef: React.MutableRefObjec return path; }); - const updatedPath = updatedPaths.find((path): path is Types.VehicleEventsSchema => path.type === "Vehicle" && path.points.uuid === selectedActionSphere.points.uuid); + const updatedPath = updatedPaths.find((path): path is SimulationTypes.VehicleEventsSchema => path.type === "Vehicle" && path.points.uuid === selectedActionSphere.points.uuid); updateBackend(updatedPath); setSimulationStates(updatedPaths); @@ -282,6 +282,7 @@ function PathCreation({ pathsGroupRef, }: { pathsGroupRef: React.MutableRefObjec key={path.modeluuid} ref={(el) => (groupRefs.current[path.modeluuid] = el!)} position={path.position} + rotation={path.rotation} onClick={(e) => { if (isConnecting || eyeDropMode) return; e.stopPropagation(); @@ -335,6 +336,7 @@ function PathCreation({ pathsGroupRef, }: { pathsGroupRef: React.MutableRefObjec key={path.modeluuid} ref={(el) => (groupRefs.current[path.modeluuid] = el!)} position={path.position} + rotation={path.rotation} onClick={(e) => { if (isConnecting || eyeDropMode) return; e.stopPropagation(); @@ -388,6 +390,7 @@ function PathCreation({ pathsGroupRef, }: { pathsGroupRef: React.MutableRefObjec key={path.modeluuid} ref={(el) => (groupRefs.current[path.modeluuid] = el!)} position={path.position} + rotation={path.rotation} onClick={(e) => { if (isConnecting || eyeDropMode) return; e.stopPropagation(); diff --git a/app/src/modules/simulation/process/processCreator.tsx b/app/src/modules/simulation/process/processCreator.tsx index 041b4ec..f7f9974 100644 --- a/app/src/modules/simulation/process/processCreator.tsx +++ b/app/src/modules/simulation/process/processCreator.tsx @@ -458,7 +458,7 @@ import { useThree } from "@react-three/fiber"; import { ConveyorEventsSchema, VehicleEventsSchema, -} from "../../../types/world/worldTypes"; +} from "../../../types/simulation"; import { usePlayButtonStore } from "../../../store/usePlayButtonStore"; // Type definitions diff --git a/app/src/modules/simulation/simulation.tsx b/app/src/modules/simulation/simulation.tsx index 0741b5f..b1f961e 100644 --- a/app/src/modules/simulation/simulation.tsx +++ b/app/src/modules/simulation/simulation.tsx @@ -1,16 +1,11 @@ -import { useState, useEffect, useRef, useMemo } from "react"; -import { - useSelectedActionSphere, - useSelectedPath, - useSimulationStates, -} from "../../store/store"; +import { useState, useRef } from "react"; import * as THREE from "three"; -import Behaviour from "./behaviour/behaviour"; import PathCreation from "./path/pathCreation"; import PathConnector from "./path/pathConnector"; import useModuleStore from "../../store/useModuleStore"; import ProcessContainer from "./process/processContainer"; import Agv from "../builder/agv/agv"; +import ArmBot from "./armbot/ArmBot"; function Simulation() { const { activeModule } = useModuleStore(); @@ -21,24 +16,28 @@ function Simulation() { return ( <> - {activeModule === "simulation" && ( <> + + + + )} + ); } diff --git a/app/src/modules/visualization/DisplayZone.tsx b/app/src/modules/visualization/DisplayZone.tsx index f4033f9..dfe68f6 100644 --- a/app/src/modules/visualization/DisplayZone.tsx +++ b/app/src/modules/visualization/DisplayZone.tsx @@ -97,11 +97,16 @@ const DisplayZone: React.FC = ({ if (container) { const isOverflowing = container.scrollWidth > container.clientWidth; const canScrollLeft = container.scrollLeft > 0; - const canScrollRight = - container.scrollLeft + container.clientWidth < container.scrollWidth; + const canScrollRight = + container.scrollLeft + container.clientWidth + 1 < + container.scrollWidth; setShowLeftArrow(isOverflowing && canScrollLeft); setShowRightArrow(isOverflowing && canScrollRight); + + console.log('canScrollRight: ', canScrollRight); + console.log('isOverflowing: ', isOverflowing); + } }, []); @@ -166,7 +171,7 @@ const DisplayZone: React.FC = ({ if (selectedZone?.zoneId === zoneId) { return; } - setSelectedChartId(null); + // setSelectedChartId(null); const email = localStorage.getItem("email") || ""; const organization = email?.split("@")[1]?.split(".")[0]; let response = await getSelect2dZoneData(zoneId, organization); diff --git a/app/src/modules/visualization/RealTimeVisulization.tsx b/app/src/modules/visualization/RealTimeVisulization.tsx index 6a5145f..e039592 100644 --- a/app/src/modules/visualization/RealTimeVisulization.tsx +++ b/app/src/modules/visualization/RealTimeVisulization.tsx @@ -34,6 +34,7 @@ import { import Dropped3dWidgets from "./widgets/3d/Dropped3dWidget"; import OuterClick from "../../utils/outerClick"; import { useWidgetStore } from "../../store/useWidgetStore"; +import { getActiveProperties } from "./functions/getActiveProperties"; type Side = "top" | "bottom" | "left" | "right"; @@ -92,6 +93,7 @@ const RealTimeVisulization: React.FC = () => { "sidebar-right-wrapper", "card", "dropdown-menu", + "dropdown-options", ], setMenuVisible: () => setSelectedChartId(null), }); @@ -157,96 +159,102 @@ const RealTimeVisulization: React.FC = () => { try { const email = localStorage.getItem("email") || ""; const organization = email?.split("@")[1]?.split(".")[0]; - + const data = event.dataTransfer.getData("text/plain"); if (widgetSubOption === "3D") return; if (!data || selectedZone.zoneName === "") return; - + const droppedData = JSON.parse(data); const canvasElement = document.getElementById("real-time-vis-canvas"); if (!canvasElement) throw new Error("Canvas element not found"); - - // Get canvas dimensions and mouse position + const rect = canvasElement.getBoundingClientRect(); - let relativeX = (event.clientX - rect.left) ; - let relativeY = event.clientY - rect.top; - - // Widget dimensions (with defaults) - const widgetWidth = droppedData.width || 125; // 250/2 as default - const widgetHeight = droppedData.height || 100; // 83/2 as default - - // Clamp to ensure widget stays fully inside canvas - const clampedX = Math.max( - 0, // Prevent going beyond left edge - Math.min( - relativeX, - rect.width - widgetWidth // Prevent going beyond right edge - ) - ); - - console.log('clampedX: ', clampedX); - const clampedY = Math.max( - 0, // Prevent going beyond top edge - Math.min( - relativeY, - rect.height - widgetHeight // Prevent going beyond bottom edge - ) - ); - - // Debug logging (optional) - console.log("Drop coordinates:", { - rawX: relativeX, - rawY: relativeY, - clampedX, - clampedY, - canvasWidth: rect.width, - canvasHeight: rect.height, - widgetWidth, - widgetHeight - }); - - const finalPosition = determinePosition(rect, clampedX, clampedY); - + const relativeX = event.clientX - rect.left; + const relativeY = event.clientY - rect.top; + + // Widget dimensions + const widgetWidth = droppedData.width || 125; + const widgetHeight = droppedData.height || 100; + + // Center the widget at cursor + const centerOffsetX = widgetWidth / 2; + const centerOffsetY = widgetHeight / 2; + + const adjustedX = relativeX - centerOffsetX; + const adjustedY = relativeY - centerOffsetY; + + const finalPosition = determinePosition(rect, adjustedX, adjustedY); + const [activeProp1, activeProp2] = getActiveProperties(finalPosition); + + let finalY = 0; + let finalX = 0; + + if (activeProp1 === "top") { + finalY = adjustedY; + } else { + finalY = rect.height - (adjustedY + widgetHeight); + } + + if (activeProp2 === "left") { + finalX = adjustedX; + } else { + finalX = rect.width - (adjustedX + widgetWidth); + } + + // Clamp to boundaries + finalX = Math.max(0, Math.min(rect.width - widgetWidth, finalX)); + finalY = Math.max(0, Math.min(rect.height - widgetHeight, finalY)); + + const boundedPosition = { + ...finalPosition, + [activeProp1]: finalY, + [activeProp2]: finalX, + [activeProp1 === "top" ? "bottom" : "top"]: "auto", + [activeProp2 === "left" ? "right" : "left"]: "auto", + }; + const newObject = { ...droppedData, id: generateUniqueId(), - position: finalPosition, + position: boundedPosition, }; - - // Zone management - const existingZone = useDroppedObjectsStore.getState().zones[selectedZone.zoneName]; + + const existingZone = + useDroppedObjectsStore.getState().zones[selectedZone.zoneName]; if (!existingZone) { - useDroppedObjectsStore.getState().setZone(selectedZone.zoneName, selectedZone.zoneId); + useDroppedObjectsStore + .getState() + .setZone(selectedZone.zoneName, selectedZone.zoneId); } - - // Socket emission + const addFloatingWidget = { organization, widget: newObject, zoneId: selectedZone.zoneId, }; - + if (visualizationSocket) { visualizationSocket.emit("v2:viz-float:add", addFloatingWidget); } - - // Store update - useDroppedObjectsStore.getState().addObject(selectedZone.zoneName, newObject); - - // Post-drop verification + + useDroppedObjectsStore + .getState() + .addObject(selectedZone.zoneName, newObject); + const droppedObjectsStore = useDroppedObjectsStore.getState(); const currentZone = droppedObjectsStore.zones[selectedZone.zoneName]; - + if (currentZone && currentZone.zoneId === selectedZone.zoneId) { - console.log(`Objects for Zone ${selectedZone.zoneId}:`, currentZone.objects); + console.log( + `Objects for Zone ${selectedZone.zoneId}:`, + currentZone.objects + ); setFloatingWidget(currentZone.objects); } else { console.warn("Zone not found or zoneId mismatch"); } - } catch (error) { console.error("Error in handleDrop:", error); - // Consider adding user feedback here (e.g., toast notification) } }; @@ -270,8 +278,41 @@ const RealTimeVisulization: React.FC = () => { }; }, [setRightClickSelected]); + const [canvasDimensions, setCanvasDimensions] = useState({ + width: 0, + height: 0, + }); + useEffect(() => { + const canvas = document.getElementById("real-time-vis-canvas"); + if (!canvas) return; + + const updateCanvasDimensions = () => { + const rect = canvas.getBoundingClientRect(); + setCanvasDimensions({ + width: rect.width, + height: rect.height, + }); + }; + + updateCanvasDimensions(); + const resizeObserver = new ResizeObserver(updateCanvasDimensions); + resizeObserver.observe(canvas); + + return () => resizeObserver.unobserve(canvas); + }, []); + return ( <> +
{ - // Memoize Font Weight Mapping - const chartFontWeightMap = useMemo( - () => ({ - Light: "lighter" as const, - Regular: "normal" as const, - Bold: "bold" as const, - }), - [] - ); - - // Parse and Memoize Font Size - const fontSizeValue = useMemo( - () => (fontSize ? parseInt(fontSize) : 12), - [fontSize] - ); - - // Determine and Memoize Font Weight - const fontWeightValue = useMemo( - () => chartFontWeightMap[fontWeight], - [fontWeight, chartFontWeightMap] - ); - - // Memoize Chart Font Style - const chartFontStyle = useMemo( - () => ({ - family: fontFamily || "Arial", - size: fontSizeValue, - weight: fontWeightValue, - }), - [fontFamily, fontSizeValue, fontWeightValue] - ); - - const options = useMemo( - () => ({ - responsive: true, - maintainAspectRatio: false, - plugins: { - title: { - display: true, - text: title, - font: chartFontStyle, - }, - legend: { - display: false, - }, - }, - scales: { - x: { - ticks: { - display: false, // This hides the x-axis labels - }, - }, - }, - }), - [title, chartFontStyle] - ); - - const chartData = { - labels: ["January", "February", "March", "April", "May", "June", "July"], - datasets: [ - { - label: "My First Dataset", - data: [65, 59, 80, 81, 56, 55, 40], - backgroundColor: "#6f42c1", - borderColor: "#ffffff", - borderWidth: 2, - fill: false, - }, - ], - }; - - return ; -}; - -export default LineGraphComponent; +import { useMemo } from "react"; + +import { Bar } from "react-chartjs-2"; + +interface ChartComponentProps { + type: any; + title: string; + fontFamily?: string; + fontSize?: string; + fontWeight?: "Light" | "Regular" | "Bold"; + data: any; +} + +const LineGraphComponent = ({ + title, + fontFamily, + fontSize, + fontWeight = "Regular", +}: ChartComponentProps) => { + // Memoize Font Weight Mapping + const chartFontWeightMap = useMemo( + () => ({ + Light: "lighter" as const, + Regular: "normal" as const, + Bold: "bold" as const, + }), + [] + ); + + // Parse and Memoize Font Size + const fontSizeValue = useMemo( + () => (fontSize ? parseInt(fontSize) : 12), + [fontSize] + ); + + // Determine and Memoize Font Weight + const fontWeightValue = useMemo( + () => chartFontWeightMap[fontWeight], + [fontWeight, chartFontWeightMap] + ); + + // Memoize Chart Font Style + const chartFontStyle = useMemo( + () => ({ + family: fontFamily || "Arial", + size: fontSizeValue, + weight: fontWeightValue, + }), + [fontFamily, fontSizeValue, fontWeightValue] + ); + + const options = useMemo( + () => ({ + responsive: true, + maintainAspectRatio: false, + plugins: { + title: { + display: true, + text: title, + font: chartFontStyle, + }, + legend: { + display: false, + }, + }, + scales: { + x: { + ticks: { + display: false, // This hides the x-axis labels + }, + }, + }, + }), + [title, chartFontStyle] + ); + + const chartData = { + labels: ["January", "February", "March", "April", "May", "June", "July"], + datasets: [ + { + label: "My First Dataset", + data: [65, 59, 80, 81, 56, 55, 40], + backgroundColor: "#6f42c1", + borderColor: "#ffffff", + borderWidth: 2, + fill: false, + }, + ], + }; + + return ; +}; + +export default LineGraphComponent; diff --git a/app/src/components/ui/charts/LineGraphComponent.tsx b/app/src/modules/visualization/charts/LineGraphComponent.tsx similarity index 95% rename from app/src/components/ui/charts/LineGraphComponent.tsx rename to app/src/modules/visualization/charts/LineGraphComponent.tsx index 7f420d7..cf1a47f 100644 --- a/app/src/components/ui/charts/LineGraphComponent.tsx +++ b/app/src/modules/visualization/charts/LineGraphComponent.tsx @@ -1,93 +1,93 @@ -import { useMemo } from "react"; -import { Line } from "react-chartjs-2"; - -interface ChartComponentProps { - type: any; - title: string; - fontFamily?: string; - fontSize?: string; - fontWeight?: "Light" | "Regular" | "Bold"; - data: any; -} - -const LineGraphComponent = ({ - title, - fontFamily, - fontSize, - fontWeight = "Regular", -}: ChartComponentProps) => { - // Memoize Font Weight Mapping - const chartFontWeightMap = useMemo( - () => ({ - Light: "lighter" as const, - Regular: "normal" as const, - Bold: "bold" as const, - }), - [] - ); - - // Parse and Memoize Font Size - const fontSizeValue = useMemo( - () => (fontSize ? parseInt(fontSize) : 12), - [fontSize] - ); - - // Determine and Memoize Font Weight - const fontWeightValue = useMemo( - () => chartFontWeightMap[fontWeight], - [fontWeight, chartFontWeightMap] - ); - - // Memoize Chart Font Style - const chartFontStyle = useMemo( - () => ({ - family: fontFamily || "Arial", - size: fontSizeValue, - weight: fontWeightValue, - }), - [fontFamily, fontSizeValue, fontWeightValue] - ); - - const options = useMemo( - () => ({ - responsive: true, - maintainAspectRatio: false, - plugins: { - title: { - display: true, - text: title, - font: chartFontStyle, - }, - legend: { - display: false, - }, - }, - scales: { - x: { - ticks: { - display: false, // This hides the x-axis labels - }, - }, - }, - }), - [title, chartFontStyle] - ); - - const chartData = { - labels: ["January", "February", "March", "April", "May", "June", "July"], - datasets: [ - { - label: "My First Dataset", - data: [65, 59, 80, 81, 56, 55, 40], - backgroundColor: "#6f42c1", // Updated to #6f42c1 (Purple) - borderColor: "#ffffff", // Keeping border color white - borderWidth: 2, - fill: false, - }, - ], - }; - - return ; -}; - -export default LineGraphComponent; +import { useMemo } from "react"; +import { Line } from "react-chartjs-2"; + +interface ChartComponentProps { + type: any; + title: string; + fontFamily?: string; + fontSize?: string; + fontWeight?: "Light" | "Regular" | "Bold"; + data: any; +} + +const LineGraphComponent = ({ + title, + fontFamily, + fontSize, + fontWeight = "Regular", +}: ChartComponentProps) => { + // Memoize Font Weight Mapping + const chartFontWeightMap = useMemo( + () => ({ + Light: "lighter" as const, + Regular: "normal" as const, + Bold: "bold" as const, + }), + [] + ); + + // Parse and Memoize Font Size + const fontSizeValue = useMemo( + () => (fontSize ? parseInt(fontSize) : 12), + [fontSize] + ); + + // Determine and Memoize Font Weight + const fontWeightValue = useMemo( + () => chartFontWeightMap[fontWeight], + [fontWeight, chartFontWeightMap] + ); + + // Memoize Chart Font Style + const chartFontStyle = useMemo( + () => ({ + family: fontFamily || "Arial", + size: fontSizeValue, + weight: fontWeightValue, + }), + [fontFamily, fontSizeValue, fontWeightValue] + ); + + const options = useMemo( + () => ({ + responsive: true, + maintainAspectRatio: false, + plugins: { + title: { + display: true, + text: title, + font: chartFontStyle, + }, + legend: { + display: false, + }, + }, + scales: { + x: { + ticks: { + display: false, // This hides the x-axis labels + }, + }, + }, + }), + [title, chartFontStyle] + ); + + const chartData = { + labels: ["January", "February", "March", "April", "May", "June", "July"], + datasets: [ + { + label: "My First Dataset", + data: [65, 59, 80, 81, 56, 55, 40], + backgroundColor: "#6f42c1", // Updated to #6f42c1 (Purple) + borderColor: "#ffffff", // Keeping border color white + borderWidth: 2, + fill: false, + }, + ], + }; + + return ; +}; + +export default LineGraphComponent; diff --git a/app/src/components/ui/charts/PieGraphComponent.tsx b/app/src/modules/visualization/charts/PieGraphComponent.tsx similarity index 95% rename from app/src/components/ui/charts/PieGraphComponent.tsx rename to app/src/modules/visualization/charts/PieGraphComponent.tsx index 7c8bb1d..912cbc3 100644 --- a/app/src/components/ui/charts/PieGraphComponent.tsx +++ b/app/src/modules/visualization/charts/PieGraphComponent.tsx @@ -1,90 +1,90 @@ -import { useMemo } from "react"; -import { Pie } from "react-chartjs-2"; - -interface ChartComponentProps { - type: any; - title: string; - fontFamily?: string; - fontSize?: string; - fontWeight?: "Light" | "Regular" | "Bold"; - data: any; -} - -const PieChartComponent = ({ - title, - fontFamily, - fontSize, - fontWeight = "Regular", -}: ChartComponentProps) => { - // Memoize Font Weight Mapping - const chartFontWeightMap = useMemo( - () => ({ - Light: "lighter" as const, - Regular: "normal" as const, - Bold: "bold" as const, - }), - [] - ); - - // Parse and Memoize Font Size - const fontSizeValue = useMemo( - () => (fontSize ? parseInt(fontSize) : 12), - [fontSize] - ); - - // Determine and Memoize Font Weight - const fontWeightValue = useMemo( - () => chartFontWeightMap[fontWeight], - [fontWeight, chartFontWeightMap] - ); - - // Memoize Chart Font Style - const chartFontStyle = useMemo( - () => ({ - family: fontFamily || "Arial", - size: fontSizeValue, - weight: fontWeightValue, - }), - [fontFamily, fontSizeValue, fontWeightValue] - ); - - // Access the CSS variable for the primary accent color - const accentColor = getComputedStyle(document.documentElement) - .getPropertyValue("--accent-color") - .trim(); - - const options = useMemo( - () => ({ - responsive: true, - maintainAspectRatio: false, - plugins: { - title: { - display: true, - text: title, - font: chartFontStyle, - }, - legend: { - display: false, - }, - }, - }), - [title, chartFontStyle] - ); - - const chartData = { - labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"], - datasets: [ - { - label: "Dataset", - data: [12, 19, 3, 5, 2, 3], - backgroundColor: ["#6f42c1"], - borderColor: "#ffffff", - borderWidth: 2, - }, - ], - }; - - return ; -}; - -export default PieChartComponent; +import { useMemo } from "react"; +import { Pie } from "react-chartjs-2"; + +interface ChartComponentProps { + type: any; + title: string; + fontFamily?: string; + fontSize?: string; + fontWeight?: "Light" | "Regular" | "Bold"; + data: any; +} + +const PieChartComponent = ({ + title, + fontFamily, + fontSize, + fontWeight = "Regular", +}: ChartComponentProps) => { + // Memoize Font Weight Mapping + const chartFontWeightMap = useMemo( + () => ({ + Light: "lighter" as const, + Regular: "normal" as const, + Bold: "bold" as const, + }), + [] + ); + + // Parse and Memoize Font Size + const fontSizeValue = useMemo( + () => (fontSize ? parseInt(fontSize) : 12), + [fontSize] + ); + + // Determine and Memoize Font Weight + const fontWeightValue = useMemo( + () => chartFontWeightMap[fontWeight], + [fontWeight, chartFontWeightMap] + ); + + // Memoize Chart Font Style + const chartFontStyle = useMemo( + () => ({ + family: fontFamily || "Arial", + size: fontSizeValue, + weight: fontWeightValue, + }), + [fontFamily, fontSizeValue, fontWeightValue] + ); + + // Access the CSS variable for the primary accent color + const accentColor = getComputedStyle(document.documentElement) + .getPropertyValue("--accent-color") + .trim(); + + const options = useMemo( + () => ({ + responsive: true, + maintainAspectRatio: false, + plugins: { + title: { + display: true, + text: title, + font: chartFontStyle, + }, + legend: { + display: false, + }, + }, + }), + [title, chartFontStyle] + ); + + const chartData = { + labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"], + datasets: [ + { + label: "Dataset", + data: [12, 19, 3, 5, 2, 3], + backgroundColor: ["#6f42c1"], + borderColor: "#ffffff", + borderWidth: 2, + }, + ], + }; + + return ; +}; + +export default PieChartComponent; diff --git a/app/src/components/ui/componets/zoneCameraTarget.tsx b/app/src/modules/visualization/functions/zoneCameraTarget.tsx similarity index 100% rename from app/src/components/ui/componets/zoneCameraTarget.tsx rename to app/src/modules/visualization/functions/zoneCameraTarget.tsx diff --git a/app/src/modules/visualization/widgets/2d/DraggableWidget.tsx b/app/src/modules/visualization/widgets/2d/DraggableWidget.tsx index 3b9e8d7..7e6ad6d 100644 --- a/app/src/modules/visualization/widgets/2d/DraggableWidget.tsx +++ b/app/src/modules/visualization/widgets/2d/DraggableWidget.tsx @@ -89,9 +89,7 @@ export const DraggableWidget = ({ width: 0, height: 0, }); - useEffect(() => { - console.log("changes loggggg", measurements, duration, name); - }, [measurements, duration, name]) + useEffect(() => {}, [measurements, duration, name]); const handlePointerDown = () => { if (selectedChartId?.id !== widget.id) { setSelectedChartId(widget); @@ -148,7 +146,7 @@ export const DraggableWidget = ({ const getCurrentWidgetCount = (panel: Side) => selectedZone.widgets.filter((w) => w.panel === panel).length; // Calculate panel capacity - + const calculatePanelCapacity = (panel: Side) => { const CHART_WIDTH = panelSize; const CHART_HEIGHT = panelSize; @@ -167,25 +165,22 @@ export const DraggableWidget = ({ const currentWidgetCount = getCurrentWidgetCount(panel); const panelCapacity = calculatePanelCapacity(panel); - return currentWidgetCount > panelCapacity; + return currentWidgetCount > panelCapacity; }; const duplicateWidget = async () => { try { const email = localStorage.getItem("email") || ""; const organization = email?.split("@")[1]?.split(".")[0]; - console.log("widget data sent", widget); - const duplicatedWidget: Widget = { ...widget, Data: { duration: duration, - measurements: { ...measurements } + measurements: { ...measurements }, }, id: `${widget.id}-copy-${Date.now()}`, }; - console.log("duplicatedWidget: ", duplicatedWidget); let duplicateWidget = { organization: organization, @@ -193,8 +188,6 @@ export const DraggableWidget = ({ widget: duplicatedWidget, }; if (visualizationSocket) { - console.log("duplecate widget", duplicateWidget); - visualizationSocket.emit("v2:viz-widget:add", duplicateWidget); } setSelectedZone((prevZone: any) => ({ @@ -293,20 +286,12 @@ export const DraggableWidget = ({ return ( <> -
diff --git a/app/src/modules/visualization/widgets/2d/charts/DoughnutGraphComponent.tsx b/app/src/modules/visualization/widgets/2d/charts/DoughnutGraphComponent.tsx index 4947b94..3108d09 100644 --- a/app/src/modules/visualization/widgets/2d/charts/DoughnutGraphComponent.tsx +++ b/app/src/modules/visualization/widgets/2d/charts/DoughnutGraphComponent.tsx @@ -1,5 +1,5 @@ import React, { useEffect, useMemo, useState } from "react"; -import { Line } from "react-chartjs-2"; +import { Doughnut } from "react-chartjs-2"; import io from "socket.io-client"; import axios from "axios"; @@ -16,7 +16,7 @@ interface ChartComponentProps { fontWeight?: "Light" | "Regular" | "Bold"; } -const LineGraphComponent = ({ +const DoughnutGraphComponent = ({ id, type, title, @@ -52,7 +52,7 @@ const LineGraphComponent = ({ }; useEffect(() => { - + },[]) // Memoize Theme Colors @@ -97,11 +97,11 @@ const LineGraphComponent = ({ }, }, scales: { - x: { - ticks: { - display: true, // This hides the x-axis labels - }, - }, + // x: { + // ticks: { + // display: true, // This hides the x-axis labels + // }, + // }, }, }), [title, chartFontStyle, name] @@ -161,8 +161,6 @@ const LineGraphComponent = ({ try { const response = await axios.get(`http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/v2/WidgetData/${id}/${organization}`); if (response.status === 200) { - console.log('line chart res',response); - setmeasurements(response.data.Data.measurements) setDuration(response.data.Data.duration) setName(response.data.widgetName) @@ -186,7 +184,7 @@ const LineGraphComponent = ({ } ,[chartMeasurements, chartDuration, widgetName]) - return 0 ? chartData : defaultData} options={options} />; + return 0 ? chartData : defaultData} options={options} />; }; -export default LineGraphComponent; +export default DoughnutGraphComponent; diff --git a/app/src/modules/visualization/widgets/3d/cards/ReturnOfInvestment.tsx b/app/src/modules/visualization/widgets/3d/cards/ReturnOfInvestment.tsx index a4c04ca..5a975f1 100644 --- a/app/src/modules/visualization/widgets/3d/cards/ReturnOfInvestment.tsx +++ b/app/src/modules/visualization/widgets/3d/cards/ReturnOfInvestment.tsx @@ -238,7 +238,7 @@ const ReturnOfInvestment: React.FC = ({ rotation={rotation} scale={[0.5, 0.5, 0.5]} transform - zIndexRange={[1, 0]} + sprite={false} // style={{ // transform: transformStyle.transform, diff --git a/app/src/modules/visualization/widgets/floating/DroppedFloatingWidgets.tsx b/app/src/modules/visualization/widgets/floating/DroppedFloatingWidgets.tsx index de48ef6..62c1de7 100644 --- a/app/src/modules/visualization/widgets/floating/DroppedFloatingWidgets.tsx +++ b/app/src/modules/visualization/widgets/floating/DroppedFloatingWidgets.tsx @@ -121,10 +121,12 @@ const DroppedObjects: React.FC = () => { function handleDuplicate(zoneName: string, index: number) { setOpenKebabId(null); duplicateObject(zoneName, index); // Call the duplicateObject method from the store + setSelectedChartId(null); } async function handleDelete(zoneName: string, id: string) { try { + setSelectedChartId(null); const email = localStorage.getItem("email") || ""; const organization = email?.split("@")[1]?.split(".")[0]; @@ -532,7 +534,7 @@ const DroppedObjects: React.FC = () => { typeof obj.position.left === "number" ? `calc(${obj.position.left}px + ${ isPlaying && selectedZone.activeSides.includes("left") - ? `${widthMultiplier - 100}px` + ? `${widthMultiplier - 150}px` : "0px" })` : "auto"; @@ -541,11 +543,10 @@ const DroppedObjects: React.FC = () => { typeof obj.position.right === "number" ? `calc(${obj.position.right}px + ${ isPlaying && selectedZone.activeSides.includes("right") - ? `${widthMultiplier - 100}px` + ? `${widthMultiplier - 150}px` : "0px" })` : "auto"; - const bottomPosition = typeof obj.position.bottom === "number" ? `calc(${obj.position.bottom}px + ${ @@ -663,4 +664,3 @@ const DroppedObjects: React.FC = () => { }; export default DroppedObjects; - diff --git a/app/src/modules/visualization/widgets/floating/cards/FleetEfficiencyComponent.tsx b/app/src/modules/visualization/widgets/floating/cards/FleetEfficiencyComponent.tsx index 6799dcb..f50bec9 100644 --- a/app/src/modules/visualization/widgets/floating/cards/FleetEfficiencyComponent.tsx +++ b/app/src/modules/visualization/widgets/floating/cards/FleetEfficiencyComponent.tsx @@ -1,113 +1,117 @@ -import React, { useState, useEffect } from 'react' -import { Line } from 'react-chartjs-2' -import useChartStore from '../../../../../store/useChartStore'; -import { useWidgetStore } from '../../../../../store/useWidgetStore'; -import axios from 'axios'; +import React, { useState, useEffect } from "react"; +import { Line } from "react-chartjs-2"; +import useChartStore from "../../../../../store/useChartStore"; +import { useWidgetStore } from "../../../../../store/useWidgetStore"; +import axios from "axios"; import io from "socket.io-client"; +import { usePlayButtonStore } from "../../../../../store/usePlayButtonStore"; -const FleetEfficiencyComponent = ({object}: any) => { - const [ progress, setProgress ] = useState(0) - const [measurements, setmeasurements] = useState({}); - const [duration, setDuration] = useState("1h") - const [name, setName] = useState(object.header ? object.header : '') - const email = localStorage.getItem("email") || ""; - const organization = email?.split("@")[1]?.split(".")[0] - const { header, flotingDuration, flotingMeasurements } = useChartStore(); - const { selectedChartId } = useWidgetStore(); +const FleetEfficiencyComponent = ({ object }: any) => { + const [progress, setProgress] = useState(0); + const [measurements, setmeasurements] = useState({}); + const [duration, setDuration] = useState("1h"); + const [name, setName] = useState(object.header ? object.header : ""); + const email = localStorage.getItem("email") || ""; + const organization = email?.split("@")[1]?.split(".")[0]; + const { header, flotingDuration, flotingMeasurements } = useChartStore(); + const { selectedChartId } = useWidgetStore(); + const { isPlaying } = usePlayButtonStore(); - const iotApiUrl = process.env.REACT_APP_IOT_SOCKET_SERVER_URL; + const iotApiUrl = process.env.REACT_APP_IOT_SOCKET_SERVER_URL; - // Calculate the rotation angle for the progress bar - const rotationAngle = 45 + progress * 1.8; + // Calculate the rotation angle for the progress bar + const rotationAngle = 45 + progress * 1.8; + useEffect(() => { + if (!iotApiUrl || !measurements || Object.keys(measurements).length === 0) + return; - useEffect(() => { - if (!iotApiUrl || !measurements || Object.keys(measurements).length === 0) return; - - const socket = io(`http://${iotApiUrl}`); - - const inputData = { - measurements, - duration, - interval: 1000, - }; - - - const startStream = () => { - socket.emit("lastInput", inputData); - }; - - socket.on("connect", startStream); - - socket.on("lastOutput", (response) => { - const responseData = response.input1; - // console.log(responseData); - - if (typeof responseData === "number") { - console.log("It's a number!"); - setProgress(responseData); - } - }); - - return () => { - socket.off("lastOutput"); - socket.emit("stop_stream"); // Stop streaming when component unmounts - socket.disconnect(); - }; - }, [measurements, duration, iotApiUrl]); - - const fetchSavedInputes = async() => { - - if (object?.id !== "") { - try { - const response = await axios.get(`http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/v2/A_floatWidget/${object?.id}/${organization}`); - if (response.status === 200) { - setmeasurements(response.data.Data.measurements) - setDuration(response.data.Data.duration) - setName(response.data.header) - } else { - console.log("Unexpected response:", response); - } - } catch (error) { - console.error("There was an error!", error); - } - } + const socket = io(`http://${iotApiUrl}`); + + const inputData = { + measurements, + duration, + interval: 1000, + }; + + const startStream = () => { + socket.emit("lastInput", inputData); + }; + + socket.on("connect", startStream); + + socket.on("lastOutput", (response) => { + const responseData = response.input1; + // console.log(responseData); + + if (typeof responseData === "number") { + console.log("It's a number!"); + setProgress(responseData); } - - useEffect(() => { - fetchSavedInputes(); - }, []); - - useEffect(() => { - if (selectedChartId?.id === object?.id) { - fetchSavedInputes(); - } - } - ,[header, flotingDuration, flotingMeasurements]) - - return ( - <> -

{name}

-
-
-
-
-
-
-
-
- 0% -
-
{progress}%
-
Optimal
-
- 100% -
- - ) -} + }); -export default FleetEfficiencyComponent \ No newline at end of file + return () => { + socket.off("lastOutput"); + socket.emit("stop_stream"); // Stop streaming when component unmounts + socket.disconnect(); + }; + }, [measurements, duration, iotApiUrl]); + + const fetchSavedInputes = async () => { + if (object?.id !== "") { + try { + const response = await axios.get( + `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/v2/A_floatWidget/${object?.id}/${organization}` + ); + if (response.status === 200) { + setmeasurements(response.data.Data.measurements); + setDuration(response.data.Data.duration); + setName(response.data.header); + } else { + console.log("Unexpected response:", response); + } + } catch (error) { + console.error("There was an error!", error); + } + } + }; + + useEffect(() => { + fetchSavedInputes(); + }, []); + + useEffect(() => { + if (selectedChartId?.id === object?.id) { + fetchSavedInputes(); + } + }, [header, flotingDuration, flotingMeasurements]); + + return ( + <> +

{name}

+
+
+
+
+
+
+
+
+ 0% +
+
{progress}%
+
Optimal
+
+ 100% +
+ + ); +}; + +export default FleetEfficiencyComponent; diff --git a/app/src/modules/visualization/widgets/panel/AddButtons.tsx b/app/src/modules/visualization/widgets/panel/AddButtons.tsx index 5469ffa..5d45d3f 100644 --- a/app/src/modules/visualization/widgets/panel/AddButtons.tsx +++ b/app/src/modules/visualization/widgets/panel/AddButtons.tsx @@ -128,6 +128,12 @@ const AddButtons: React.FC = ({ const cleanPanel = async (side: Side) => { //add api // console.log('side: ', side); + if ( + hiddenPanels[selectedZone.zoneId]?.includes(side) || + selectedZone.lockedPanels.includes(side) + ) + return; + const email = localStorage.getItem("email") || ""; const organization = email?.split("@")[1]?.split(".")[0]; // Fallback value @@ -197,13 +203,12 @@ const AddButtons: React.FC = ({ } setSelectedZone(updatedZone); - - if (hiddenPanels[selectedZone.zoneId]?.includes(side)) { - - setHiddenPanels(prev => ({ + setHiddenPanels((prev) => ({ ...prev, - [selectedZone.zoneId]: prev[selectedZone.zoneId].filter(s => s !== side) + [selectedZone.zoneId]: prev[selectedZone.zoneId].filter( + (s) => s !== side + ), })); } @@ -284,10 +289,11 @@ const AddButtons: React.FC = ({
{/* Hide Panel */}
= ({ className="icon" title="Clean Panel" onClick={() => cleanPanel(side)} + style={{ + cursor: + hiddenPanels[selectedZone.zoneId]?.includes(side) || + selectedZone.lockedPanels.includes(side) + ? "not-allowed" + : "pointer", + }} >
diff --git a/app/src/pages/Project.tsx b/app/src/pages/Project.tsx index a772634..2daa091 100644 --- a/app/src/pages/Project.tsx +++ b/app/src/pages/Project.tsx @@ -26,7 +26,7 @@ import KeyPressListener from "../utils/shortcutkeys/handleShortcutKeys"; const Project: React.FC = () => { let navigate = useNavigate(); - const { activeModule } = useModuleStore(); + const { activeModule, setActiveModule } = useModuleStore(); const { loadingProgress } = useLoadingProgress(); const { setUserName } = useUserName(); const { setOrganization } = useOrganization(); @@ -38,6 +38,7 @@ const Project: React.FC = () => { setFloorItems([]); setWallItems([]); setZones([]); + setActiveModule('builder') const email = localStorage.getItem("email"); if (email) { const Organization = email!.split("@")[1].split(".")[0]; diff --git a/app/src/store/store.ts b/app/src/store/store.ts index 3210afc..0b15b3e 100644 --- a/app/src/store/store.ts +++ b/app/src/store/store.ts @@ -1,500 +1,479 @@ import * as THREE from "three"; import * as Types from "../types/world/worldTypes"; +import * as SimulationTypes from "../types/simulation"; import { create } from "zustand"; import { io } from "socket.io-client"; export const useSocketStore = create((set: any, get: any) => ({ - socket: null, - initializeSocket: (email: string, organization: string) => { - const existingSocket = get().socket; - if (existingSocket) { - return; - } + socket: null, + initializeSocket: (email: string, organization: string) => { + const existingSocket = get().socket; + if (existingSocket) { + return; + } - const socket = io( - `http://${process.env.REACT_APP_SERVER_SOCKET_API_BASE_URL}/Builder`, - { - reconnection: true, - auth: { email, organization }, - } - ); + const socket = io( + `http://${process.env.REACT_APP_SERVER_SOCKET_API_BASE_URL}/Builder`, + { + reconnection: true, + auth: { email, organization }, + } + ); - const visualizationSocket = io( - `http://${process.env.REACT_APP_SERVER_SOCKET_API_BASE_URL}/Visualization`, - { - reconnection: true, - auth: { email, organization }, - } - ); + const visualizationSocket = io( + `http://${process.env.REACT_APP_SERVER_SOCKET_API_BASE_URL}/Visualization`, + { + reconnection: true, + auth: { email, organization }, + } + ); - set({ socket, visualizationSocket }); - }, - disconnectSocket: () => { - set((state: any) => { - state.socket?.disconnect(); - state.visualizationSocket?.disconnect(); - return { socket: null }; - }); - }, + set({ socket, visualizationSocket }); + }, + disconnectSocket: () => { + set((state: any) => { + state.socket?.disconnect(); + state.visualizationSocket?.disconnect(); + return { socket: null }; + }); + }, })); export const useLoadingProgress = create<{ - loadingProgress: number; - setLoadingProgress: (x: number) => void; + loadingProgress: number; + setLoadingProgress: (x: number) => void; }>((set) => ({ - loadingProgress: 1, - setLoadingProgress: (x: number) => set({ loadingProgress: x }), + loadingProgress: 1, + setLoadingProgress: (x: number) => set({ loadingProgress: x }), })); export const useOrganization = create((set: any) => ({ - organization: "", - setOrganization: (x: any) => set(() => ({ organization: x })), + organization: "", + setOrganization: (x: any) => set(() => ({ organization: x })), })); export const useToggleView = create((set: any) => ({ - toggleView: false, - setToggleView: (x: any) => set(() => ({ toggleView: x })), + toggleView: false, + setToggleView: (x: any) => set(() => ({ toggleView: x })), })); export const useUpdateScene = create((set: any) => ({ - updateScene: false, - setUpdateScene: (x: any) => set(() => ({ updateScene: x })), + updateScene: false, + setUpdateScene: (x: any) => set(() => ({ updateScene: x })), })); export const useWalls = create((set: any) => ({ - walls: [], - setWalls: (x: any) => set(() => ({ walls: x })), + walls: [], + setWalls: (x: any) => set(() => ({ walls: x })), })); export const useZones = create((set: any) => ({ - zones: [], - setZones: (callback: any) => - set((state: any) => ({ - zones: typeof callback === "function" ? callback(state.zones) : callback, - })), + zones: [], + setZones: (callback: any) => + set((state: any) => ({ + zones: typeof callback === "function" ? callback(state.zones) : callback, + })), })); interface ZonePointsState { - zonePoints: THREE.Vector3[]; - setZonePoints: (points: THREE.Vector3[]) => void; + zonePoints: THREE.Vector3[]; + setZonePoints: (points: THREE.Vector3[]) => void; } export const useZonePoints = create((set) => ({ - zonePoints: [], - setZonePoints: (points) => set({ zonePoints: points }), + zonePoints: [], + setZonePoints: (points) => set({ zonePoints: points }), })); export const useSelectedItem = create((set: any) => ({ - selectedItem: { name: "", id: "" }, - setSelectedItem: (x: any) => set(() => ({ selectedItem: x })), + selectedItem: { name: "", id: "" }, + setSelectedItem: (x: any) => set(() => ({ selectedItem: x })), })); export const useSelectedAssets = create((set: any) => ({ - selectedAssets: [], - setSelectedAssets: (x: any) => set(() => ({ selectedAssets: x })), + selectedAssets: [], + setSelectedAssets: (x: any) => set(() => ({ selectedAssets: x })), })); export const useLayers = create((set: any) => ({ - Layers: 1, - setLayers: (x: any) => set(() => ({ Layers: x })), + Layers: 1, + setLayers: (x: any) => set(() => ({ Layers: x })), })); export const useCamPosition = create((set: any) => ({ - camPosition: { x: undefined, y: undefined, z: undefined }, - setCamPosition: (newCamPosition: any) => set({ camPosition: newCamPosition }), + camPosition: { x: undefined, y: undefined, z: undefined }, + setCamPosition: (newCamPosition: any) => set({ camPosition: newCamPosition }), })); export const useMenuVisible = create((set: any) => ({ - menuVisible: false, - setMenuVisible: (x: any) => set(() => ({ menuVisible: x })), + menuVisible: false, + setMenuVisible: (x: any) => set(() => ({ menuVisible: x })), })); export const useDeleteTool = create((set: any) => ({ - deleteTool: false, - setDeleteTool: (x: any) => set(() => ({ deleteTool: x })), + deleteTool: false, + setDeleteTool: (x: any) => set(() => ({ deleteTool: x })), })); export const useToolMode = create((set: any) => ({ - toolMode: null, - setToolMode: (x: any) => set(() => ({ toolMode: x })), + toolMode: null, + setToolMode: (x: any) => set(() => ({ toolMode: x })), })); export const useNewLines = create((set: any) => ({ - newLines: [], - setNewLines: (x: any) => set(() => ({ newLines: x })), + newLines: [], + setNewLines: (x: any) => set(() => ({ newLines: x })), })); export const useDeletedLines = create((set: any) => ({ - deletedLines: [], - setDeletedLines: (x: any) => set(() => ({ deletedLines: x })), + deletedLines: [], + setDeletedLines: (x: any) => set(() => ({ deletedLines: x })), })); export const useMovePoint = create((set: any) => ({ - movePoint: false, - setMovePoint: (x: any) => set(() => ({ movePoint: x })), + movePoint: false, + setMovePoint: (x: any) => set(() => ({ movePoint: x })), })); export const useTransformMode = create((set: any) => ({ - transformMode: null, - setTransformMode: (x: any) => set(() => ({ transformMode: x })), + transformMode: null, + setTransformMode: (x: any) => set(() => ({ transformMode: x })), })); export const useDeletePointOrLine = create((set: any) => ({ - deletePointOrLine: false, - setDeletePointOrLine: (x: any) => set(() => ({ deletePointOrLine: x })), + deletePointOrLine: false, + setDeletePointOrLine: (x: any) => set(() => ({ deletePointOrLine: x })), })); export const useFloorItems = create((set: any) => ({ - floorItems: null, - setFloorItems: (callback: any) => - set((state: any) => ({ - floorItems: - typeof callback === "function" ? callback(state.floorItems) : callback, - })), + floorItems: null, + setFloorItems: (callback: any) => + set((state: any) => ({ + floorItems: + typeof callback === "function" ? callback(state.floorItems) : callback, + })), })); export const useWallItems = create((set: any) => ({ - wallItems: [], - setWallItems: (callback: any) => - set((state: any) => ({ - wallItems: - typeof callback === "function" ? callback(state.wallItems) : callback, - })), + wallItems: [], + setWallItems: (callback: any) => + set((state: any) => ({ + wallItems: + typeof callback === "function" ? callback(state.wallItems) : callback, + })), })); export const useSelectedWallItem = create((set: any) => ({ - selectedWallItem: null, - setSelectedWallItem: (x: any) => set(() => ({ selectedWallItem: x })), + selectedWallItem: null, + setSelectedWallItem: (x: any) => set(() => ({ selectedWallItem: x })), })); export const useSelectedFloorItem = create((set: any) => ({ - selectedFloorItem: null, - setSelectedFloorItem: (x: any) => set(() => ({ selectedFloorItem: x })), + selectedFloorItem: null, + setSelectedFloorItem: (x: any) => set(() => ({ selectedFloorItem: x })), })); export const useDeletableFloorItem = create((set: any) => ({ - deletableFloorItem: null, - setDeletableFloorItem: (x: any) => set(() => ({ deletableFloorItem: x })), + deletableFloorItem: null, + setDeletableFloorItem: (x: any) => set(() => ({ deletableFloorItem: x })), })); export const useSetScale = create((set: any) => ({ - scale: null, - setScale: (x: any) => set(() => ({ scale: x })), + scale: null, + setScale: (x: any) => set(() => ({ scale: x })), })); export const useRoofVisibility = create((set: any) => ({ - roofVisibility: false, - setRoofVisibility: (x: any) => set(() => ({ roofVisibility: x })), + roofVisibility: false, + setRoofVisibility: (x: any) => set(() => ({ roofVisibility: x })), })); export const useWallVisibility = create((set: any) => ({ - wallVisibility: false, - setWallVisibility: (x: any) => set(() => ({ wallVisibility: x })), + wallVisibility: false, + setWallVisibility: (x: any) => set(() => ({ wallVisibility: x })), })); export const useShadows = create((set: any) => ({ - shadows: false, - setShadows: (x: any) => set(() => ({ shadows: x })), + shadows: false, + setShadows: (x: any) => set(() => ({ shadows: x })), })); export const useSunPosition = create((set: any) => ({ - sunPosition: { x: undefined, y: undefined, z: undefined }, - setSunPosition: (newSuntPosition: any) => - set({ sunPosition: newSuntPosition }), + sunPosition: { x: undefined, y: undefined, z: undefined }, + setSunPosition: (newSuntPosition: any) => + set({ sunPosition: newSuntPosition }), })); export const useRemoveLayer = create((set: any) => ({ - removeLayer: false, - setRemoveLayer: (x: any) => set(() => ({ removeLayer: x })), + removeLayer: false, + setRemoveLayer: (x: any) => set(() => ({ removeLayer: x })), })); export const useRemovedLayer = create((set: any) => ({ - removedLayer: null, - setRemovedLayer: (x: any) => set(() => ({ removedLayer: x })), + removedLayer: null, + setRemovedLayer: (x: any) => set(() => ({ removedLayer: x })), })); export const useActiveLayer = create((set: any) => ({ - activeLayer: 1, - setActiveLayer: (x: any) => set({ activeLayer: x }), + activeLayer: 1, + setActiveLayer: (x: any) => set({ activeLayer: x }), })); interface RefTextUpdateState { - refTextupdate: number; - setRefTextUpdate: ( - callback: (currentValue: number) => number | number - ) => void; + refTextupdate: number; + setRefTextUpdate: ( + callback: (currentValue: number) => number | number + ) => void; } export const useRefTextUpdate = create((set) => ({ - refTextupdate: -1000, - setRefTextUpdate: (callback) => - set((state) => ({ - refTextupdate: - typeof callback === "function" - ? callback(state.refTextupdate) - : callback, - })), + refTextupdate: -1000, + setRefTextUpdate: (callback) => + set((state) => ({ + refTextupdate: + typeof callback === "function" + ? callback(state.refTextupdate) + : callback, + })), })); export const useResetCamera = create((set: any) => ({ - resetCamera: false, - setResetCamera: (x: any) => set({ resetCamera: x }), + resetCamera: false, + setResetCamera: (x: any) => set({ resetCamera: x }), })); export const useAddAction = create((set: any) => ({ - addAction: null, - setAddAction: (x: any) => set({ addAction: x }), + addAction: null, + setAddAction: (x: any) => set({ addAction: x }), })); export const useActiveTool = create((set: any) => ({ - activeTool: "cursor", - setActiveTool: (x: any) => set({ activeTool: x }), + activeTool: "cursor", + setActiveTool: (x: any) => set({ activeTool: x }), })); export const useActiveSubTool = create((set: any) => ({ - activeSubTool: "cursor", - setActiveSubTool: (x: any) => set({ activeSubTool: x }), + activeSubTool: "cursor", + setActiveSubTool: (x: any) => set({ activeSubTool: x }), })); export const use2DUndoRedo = create((set: any) => ({ - is2DUndoRedo: null, - set2DUndoRedo: (x: any) => set({ is2DUndoRedo: x }), + is2DUndoRedo: null, + set2DUndoRedo: (x: any) => set({ is2DUndoRedo: x }), })); export const useElevation = create((set: any) => ({ - elevation: 45, - setElevation: (x: any) => set({ elevation: x }), + elevation: 45, + setElevation: (x: any) => set({ elevation: x }), })); export const useAzimuth = create((set: any) => ({ - azimuth: -160, - setAzimuth: (x: any) => set({ azimuth: x }), + azimuth: -160, + setAzimuth: (x: any) => set({ azimuth: x }), })); export const useRenderDistance = create((set: any) => ({ - renderDistance: 40, - setRenderDistance: (x: any) => set({ renderDistance: x }), + renderDistance: 40, + setRenderDistance: (x: any) => set({ renderDistance: x }), })); export const useCamMode = create((set: any) => ({ - camMode: "ThirdPerson", - setCamMode: (x: any) => set({ camMode: x }), + camMode: "ThirdPerson", + setCamMode: (x: any) => set({ camMode: x }), })); export const useUserName = create((set: any) => ({ - userName: "", - setUserName: (x: any) => set({ userName: x }), + userName: "", + setUserName: (x: any) => set({ userName: x }), })); export const useObjectPosition = create((set: any) => ({ - objectPosition: { x: undefined, y: undefined, z: undefined }, - setObjectPosition: (newObjectPosition: any) => - set({ objectPosition: newObjectPosition }), + objectPosition: { x: undefined, y: undefined, z: undefined }, + setObjectPosition: (newObjectPosition: any) => + set({ objectPosition: newObjectPosition }), })); export const useObjectScale = create((set: any) => ({ - objectScale: { x: undefined, y: undefined, z: undefined }, - setObjectScale: (newObjectScale: any) => set({ objectScale: newObjectScale }), + objectScale: { x: undefined, y: undefined, z: undefined }, + setObjectScale: (newObjectScale: any) => set({ objectScale: newObjectScale }), })); export const useObjectRotation = create((set: any) => ({ - objectRotation: { x: undefined, y: undefined, z: undefined }, - setObjectRotation: (newObjectRotation: any) => - set({ objectRotation: newObjectRotation }), + objectRotation: { x: undefined, y: undefined, z: undefined }, + setObjectRotation: (newObjectRotation: any) => + set({ objectRotation: newObjectRotation }), })); export const useDrieTemp = create((set: any) => ({ - drieTemp: undefined, - setDrieTemp: (x: any) => set({ drieTemp: x }), + drieTemp: undefined, + setDrieTemp: (x: any) => set({ drieTemp: x }), })); export const useActiveUsers = create((set: any) => ({ - activeUsers: [], - setActiveUsers: (callback: (prev: any[]) => any[] | any[]) => - set((state: { activeUsers: any[] }) => ({ - activeUsers: - typeof callback === "function" ? callback(state.activeUsers) : callback, - })), + activeUsers: [], + setActiveUsers: (callback: (prev: any[]) => any[] | any[]) => + set((state: { activeUsers: any[] }) => ({ + activeUsers: + typeof callback === "function" ? callback(state.activeUsers) : callback, + })), })); export const useDrieUIValue = create((set: any) => ({ - drieUIValue: { touch: null, temperature: null, humidity: null }, + drieUIValue: { touch: null, temperature: null, humidity: null }, - setDrieUIValue: (x: any) => - set((state: any) => ({ drieUIValue: { ...state.drieUIValue, ...x } })), + setDrieUIValue: (x: any) => + set((state: any) => ({ drieUIValue: { ...state.drieUIValue, ...x } })), - setTouch: (value: any) => - set((state: any) => ({ - drieUIValue: { ...state.drieUIValue, touch: value }, - })), - setTemperature: (value: any) => - set((state: any) => ({ - drieUIValue: { ...state.drieUIValue, temperature: value }, - })), - setHumidity: (value: any) => - set((state: any) => ({ - drieUIValue: { ...state.drieUIValue, humidity: value }, - })), + setTouch: (value: any) => + set((state: any) => ({ + drieUIValue: { ...state.drieUIValue, touch: value }, + })), + setTemperature: (value: any) => + set((state: any) => ({ + drieUIValue: { ...state.drieUIValue, temperature: value }, + })), + setHumidity: (value: any) => + set((state: any) => ({ + drieUIValue: { ...state.drieUIValue, humidity: value }, + })), })); export const useDrawMaterialPath = create((set: any) => ({ - drawMaterialPath: false, - setDrawMaterialPath: (x: any) => set({ drawMaterialPath: x }), + drawMaterialPath: false, + setDrawMaterialPath: (x: any) => set({ drawMaterialPath: x }), })); export const useSelectedActionSphere = create((set: any) => ({ - selectedActionSphere: undefined, - setSelectedActionSphere: (x: any) => set({ selectedActionSphere: x }), + selectedActionSphere: undefined, + setSelectedActionSphere: (x: any) => set({ selectedActionSphere: x }), })); export const useSelectedPath = create((set: any) => ({ - selectedPath: undefined, - setSelectedPath: (x: any) => set({ selectedPath: x }), + selectedPath: undefined, + setSelectedPath: (x: any) => set({ selectedPath: x }), })); interface SimulationPathsStore { - simulationStates: ( - | Types.ConveyorEventsSchema - | Types.VehicleEventsSchema - | Types.StaticMachineEventsSchema - | Types.ArmBotEventsSchema - )[]; - setSimulationStates: ( - paths: - | ( - | Types.ConveyorEventsSchema - | Types.VehicleEventsSchema - | Types.StaticMachineEventsSchema - | Types.ArmBotEventsSchema - )[] - | (( - prev: ( - | Types.ConveyorEventsSchema - | Types.VehicleEventsSchema - | Types.StaticMachineEventsSchema - | Types.ArmBotEventsSchema - )[] - ) => ( - | Types.ConveyorEventsSchema - | Types.VehicleEventsSchema - | Types.StaticMachineEventsSchema - | Types.ArmBotEventsSchema - )[]) - ) => void; + simulationStates: (SimulationTypes.ConveyorEventsSchema | SimulationTypes.VehicleEventsSchema | SimulationTypes.StaticMachineEventsSchema | SimulationTypes.ArmBotEventsSchema)[]; + setSimulationStates: ( + paths: (| SimulationTypes.ConveyorEventsSchema | SimulationTypes.VehicleEventsSchema | SimulationTypes.StaticMachineEventsSchema | SimulationTypes.ArmBotEventsSchema)[] + | ((prev: (| SimulationTypes.ConveyorEventsSchema | SimulationTypes.VehicleEventsSchema | SimulationTypes.StaticMachineEventsSchema | SimulationTypes.ArmBotEventsSchema)[]) + => (| SimulationTypes.ConveyorEventsSchema | SimulationTypes.VehicleEventsSchema | SimulationTypes.StaticMachineEventsSchema | SimulationTypes.ArmBotEventsSchema)[]) + ) => void; } export const useSimulationStates = create((set) => ({ - simulationStates: [], - setSimulationStates: (paths) => - set((state) => ({ - simulationStates: - typeof paths === "function" ? paths(state.simulationStates) : paths, - })), + simulationStates: [], + setSimulationStates: (paths) => + set((state) => ({ + simulationStates: + typeof paths === "function" ? paths(state.simulationStates) : paths, + })), })); export const useNavMesh = create((set: any) => ({ - navMesh: null, - setNavMesh: (x: any) => set({ navMesh: x }), + navMesh: null, + setNavMesh: (x: any) => set({ navMesh: x }), })); export const useIsConnecting = create((set: any) => ({ - isConnecting: false, - setIsConnecting: (x: any) => set({ isConnecting: x }), + isConnecting: false, + setIsConnecting: (x: any) => set({ isConnecting: x }), })); export const useStartSimulation = create((set: any) => ({ - startSimulation: false, - setStartSimulation: (x: any) => set({ startSimulation: x }), + startSimulation: false, + setStartSimulation: (x: any) => set({ startSimulation: x }), })); export const useEyeDropMode = create((set: any) => ({ - eyeDropMode: false, - setEyeDropMode: (x: any) => set({ eyeDropMode: x }), + eyeDropMode: false, + setEyeDropMode: (x: any) => set({ eyeDropMode: x }), })); export const useEditingPoint = create((set: any) => ({ - editingPoint: false, - setEditingPoint: (x: any) => set({ editingPoint: x }), + editingPoint: false, + setEditingPoint: (x: any) => set({ editingPoint: x }), })); export const usePreviewPosition = create<{ - previewPosition: { x: number; y: number } | null; - setPreviewPosition: (position: { x: number; y: number } | null) => void; + previewPosition: { x: number; y: number } | null; + setPreviewPosition: (position: { x: number; y: number } | null) => void; }>((set) => ({ - previewPosition: null, - setPreviewPosition: (position) => set({ previewPosition: position }), + previewPosition: null, + setPreviewPosition: (position) => set({ previewPosition: position }), })); export const usezoneTarget = create((set: any) => ({ - zoneTarget: [], - setZoneTarget: (x: any) => set({ zoneTarget: x }), + zoneTarget: [], + setZoneTarget: (x: any) => set({ zoneTarget: x }), })); export const usezonePosition = create((set: any) => ({ - zonePosition: [], - setZonePosition: (x: any) => set({ zonePosition: x }), + zonePosition: [], + setZonePosition: (x: any) => set({ zonePosition: x }), })); interface EditPositionState { - Edit: boolean; - setEdit: (value: boolean) => void; + Edit: boolean; + setEdit: (value: boolean) => void; } export const useEditPosition = create((set) => ({ - Edit: false, - setEdit: (value) => set({ Edit: value }), // Properly updating the state + Edit: false, + setEdit: (value) => set({ Edit: value }), // Properly updating the state })); export const useAsset3dWidget = create((set: any) => ({ - widgetSelect: "", - setWidgetSelect: (x: any) => set({ widgetSelect: x }), + widgetSelect: "", + setWidgetSelect: (x: any) => set({ widgetSelect: x }), })); export const useWidgetSubOption = create((set: any) => ({ - widgetSubOption: "2D", - setWidgetSubOption: (x: any) => set({ widgetSubOption: x }), + widgetSubOption: "2D", + setWidgetSubOption: (x: any) => set({ widgetSubOption: x }), })); export const useLimitDistance = create((set: any) => ({ - limitDistance: true, - setLimitDistance: (x: any) => set({ limitDistance: x }), + limitDistance: true, + setLimitDistance: (x: any) => set({ limitDistance: x }), })); export const useTileDistance = create((set: any) => ({ - gridValue: { size: 300, divisions: 75 }, - planeValue: { height: 300, width: 300 }, + gridValue: { size: 300, divisions: 75 }, + planeValue: { height: 300, width: 300 }, - setGridValue: (value: any) => - set((state: any) => ({ - gridValue: { ...state.gridValue, ...value }, - })), + setGridValue: (value: any) => + set((state: any) => ({ + gridValue: { ...state.gridValue, ...value }, + })), - setPlaneValue: (value: any) => - set((state: any) => ({ - planeValue: { ...state.planeValue, ...value }, - })), + setPlaneValue: (value: any) => + set((state: any) => ({ + planeValue: { ...state.planeValue, ...value }, + })), })); export const usePlayAgv = create((set, get) => ({ - PlayAgv: [], - setPlayAgv: (updateFn: (prev: any[]) => any[]) => - set({ PlayAgv: updateFn(get().PlayAgv) }), + PlayAgv: [], + setPlayAgv: (updateFn: (prev: any[]) => any[]) => + set({ PlayAgv: updateFn(get().PlayAgv) }), })); // Define the Asset type type Asset = { - id: string; - name: string; - position?: [number, number, number]; // Optional: 3D position - rotation?: { x: number; y: number; z: number }; // Optional: Euler rotation + id: string; + name: string; + position?: [number, number, number]; // Optional: 3D position + rotation?: { x: number; y: number; z: number }; // Optional: Euler rotation }; // Zustand store type type ZoneAssetState = { - zoneAssetId: Asset | null; - setZoneAssetId: (asset: Asset | null) => void; + zoneAssetId: Asset | null; + setZoneAssetId: (asset: Asset | null) => void; }; // Zustand store export const useZoneAssetId = create((set) => ({ - zoneAssetId: null, - setZoneAssetId: (asset) => set({ zoneAssetId: asset }), + zoneAssetId: null, + setZoneAssetId: (asset) => set({ zoneAssetId: asset }), })); diff --git a/app/src/styles/components/input.scss b/app/src/styles/components/input.scss index 990d243..0c89cc5 100644 --- a/app/src/styles/components/input.scss +++ b/app/src/styles/components/input.scss @@ -344,6 +344,45 @@ input { padding: 10px; } + + .loading { + position: absolute; + bottom: 0; + left: 0; + height: 2px; + /* slim progress bar */ + width: 100%; + overflow: hidden; + background: rgba(0, 0, 0, 0.05); + /* optional track background */ + } + + .loading::before { + content: ""; + position: absolute; + top: 0; + left: -50%; + height: 100%; + width: 50%; + background: linear-gradient(to right, + var(--accent-color), + transparent); + animation: loadingAnimation 1.2s linear infinite; + border-radius: 4px; + } + + @keyframes loadingAnimation { + 0% { + left: -50%; + } + + 100% { + left: 100%; + } + } + + + .dropdown-item { display: block; padding: 5px 10px; diff --git a/app/src/styles/components/visualization/floating/common.scss b/app/src/styles/components/visualization/floating/common.scss index d4afa7a..d138959 100644 --- a/app/src/styles/components/visualization/floating/common.scss +++ b/app/src/styles/components/visualization/floating/common.scss @@ -480,3 +480,6 @@ } // progress should be progress {progress} + + + diff --git a/app/src/types/simulation.d.ts b/app/src/types/simulation.d.ts new file mode 100644 index 0000000..bea52fa --- /dev/null +++ b/app/src/types/simulation.d.ts @@ -0,0 +1,163 @@ + +interface PathConnection { + fromModelUUID: string; + fromUUID: string; + toConnections: { + toModelUUID: string; + toUUID: string; + }[]; +} + +interface ConnectionStore { + connections: PathConnection[]; + setConnections: (connections: PathConnection[]) => void; + addConnection: (newConnection: PathConnection) => void; + removeConnection: (fromUUID: string, toUUID: string) => void; +} + +interface ConveyorEventsSchema { + modeluuid: string; + modelName: string; + type: "Conveyor"; + points: { + uuid: string; + position: [number, number, number]; + rotation: [number, number, number]; + actions: { uuid: string; name: string; type: string; material: string; delay: number | string; spawnInterval: number | string; isUsed: boolean; }[] | []; + triggers: { uuid: string; name: string; type: string; isUsed: boolean; bufferTime: number; }[] | []; + connections: { + source: { modelUUID: string; pointUUID: string }; + targets: { modelUUID: string; pointUUID: string }[]; + }; + }[]; + position: [number, number, number]; + rotation: [number, number, number]; + speed: number | string; +} + +interface VehicleEventsSchema { + modeluuid: string; + modelName: string; + type: "Vehicle"; + points: { + uuid: string; + position: [number, number, number]; + rotation: [number, number, number]; + actions: { uuid: string; name: string; type: string; start: { x: number; y: number } | {}; hitCount: number; end: { x: number; y: number } | {}; buffer: number; }; + connections: { + source: { modelUUID: string; pointUUID: string }; + targets: { modelUUID: string; pointUUID: string }[]; + }; + speed: number; + isPlaying: boolean; + }; + + position: [number, number, number]; + rotation: [number, number, number]; +} + +interface StaticMachineEventsSchema { + modeluuid: string; + modelName: string; + type: "StaticMachine"; + points: { + uuid: string; + position: [number, number, number]; + rotation: [number, number, number]; + actions: { uuid: string; name: string; buffer: number | string; material: string; isUsed: boolean; }; + triggers: { uuid: string; name: string; type: string }; + connections: { + source: { modelUUID: string; pointUUID: string }; + targets: { modelUUID: string; pointUUID: string }[]; + }; + }; + position: [number, number, number]; + rotation: [number, number, number]; +} + +interface ArmBotEventsSchema { + modeluuid: string; + modelName: string; + type: "ArmBot"; + points: { + uuid: string; + position: [number, number, number]; + rotation: [number, number, number]; + actions: { uuid: string; name: string; speed: number; processes: { triggerId: string; startPoint: string; endPoint: string }[]; }; + triggers: { uuid: string; name: string; type: string }; + connections: { + source: { modelUUID: string; pointUUID: string }; + targets: { modelUUID: string; pointUUID: string }[]; + }; + }; + position: [number, number, number]; + rotation: [number, number, number]; +} + +export type EventData = { + modeluuid: string; + modelname: string; + position: [number, number, number]; + rotation: { x: number; y: number; z: number }; + modelfileID: string; + isLocked: boolean; + isVisible: boolean; + eventData?: + | { + type: "Conveyor"; + points: { + uuid: string; + position: [number, number, number]; + rotation: [number, number, number]; + actions: { uuid: string; name: string; type: string; material: string; delay: number | string; spawnInterval: number | string; isUsed: boolean; }[] | []; + triggers: { uuid: string; name: string; type: string; isUsed: boolean; bufferTime: number; }[] | []; + connections: { + source: { modelUUID: string; pointUUID: string }; + targets: { modelUUID: string; pointUUID: string }[]; + }; + }[]; + speed: number | string; + } + | { + type: "Vehicle"; + points: { + uuid: string; + position: [number, number, number]; + rotation: [number, number, number]; + actions: { uuid: string; name: string; type: string; start: { x: number; y: number } | {}; hitCount: number; end: { x: number; y: number } | {}; buffer: number; }; + connections: { + source: { modelUUID: string; pointUUID: string }; + targets: { modelUUID: string; pointUUID: string }[]; + }; + speed: number; + }; + } + | { + type: "StaticMachine"; + points: { + uuid: string; + position: [number, number, number]; + rotation: [number, number, number]; + actions: { uuid: string; name: string; buffer: number; material: string; }; + triggers: { uuid: string; name: string; type: string }; + connections: { + source: { modelUUID: string; pointUUID: string }; + targets: { modelUUID: string; pointUUID: string }[]; + }; + }; + } + | { + type: "ArmBot"; + points: { + uuid: string; + position: [number, number, number]; + rotation: [number, number, number]; + actions: { uuid: string; name: string; speed: number; processes: { triggerId: string; startPoint: string; endPoint: string; }[]; }; + triggers: { uuid: string; name: string; type: string }; + connections: { + source: { modelUUID: string; pointUUID: string }; + targets: { modelUUID: string; pointUUID: string }[]; + }; + }; + }; +}; diff --git a/app/src/types/world/worldTypes.d.ts b/app/src/types/world/worldTypes.d.ts index 3197198..fa6c129 100644 --- a/app/src/types/world/worldTypes.d.ts +++ b/app/src/types/world/worldTypes.d.ts @@ -47,9 +47,7 @@ export type Shape = THREE.Shape; export type IntersectionEvent = THREE.Intersection; // Array type for intersections with objects in the scene -export type IntersectsType = THREE.Intersection< - THREE.Object3D ->[]; +export type IntersectsType = THREE.Intersection>[]; // Event type for mesh interactions export type MeshEvent = IntersectionEvent; @@ -107,9 +105,7 @@ export type NumberArray = number[]; export type RefRaycaster = React.MutableRefObject; // Camera reference, supporting both perspective and basic cameras -export type RefCamera = React.MutableRefObject< - THREE.Camera | THREE.PerspectiveCamera ->; +export type RefCamera = React.MutableRefObject; /** Three.js Root State Management **/ @@ -134,11 +130,11 @@ export type Lines = Array; // Defines a wall with its geometry, position, rotation, material, and layer information export type Wall = [ - THREE.ExtrudeGeometry, - [number, number, number], - [number, number, number], - string, - number + THREE.ExtrudeGeometry, + [number, number, number], + [number, number, number], + string, + number ]; // Collection of walls, useful in scene construction @@ -148,18 +144,10 @@ export type Walls = Array; export type RefWalls = React.MutableRefObject; // Room type, containing coordinates and layer metadata for spatial management -export type Rooms = Array<{ - coordinates: Array<{ position: THREE.Vector3; uuid: string }>; - layer: number; -}>; +export type Rooms = Array<{ coordinates: Array<{ position: THREE.Vector3; uuid: string }>; layer: number; }>; // Reference for room objects, enabling updates within React components -export type RefRooms = React.MutableRefObject< - Array<{ - coordinates: Array<{ position: THREE.Vector3; uuid: string }>; - layer: number; - }> ->; +export type RefRooms = React.MutableRefObject; layer: number; }>>; // Reference for lines, supporting React-based state changes export type RefLines = React.MutableRefObject; @@ -182,10 +170,10 @@ export type RefOnlyFloorLines = React.MutableRefObject; // Structure for representing GeoJSON lines, integrating external data sources export type GeoJsonLine = { - line: any; - uuids: [string, string]; - layer: number; - type: string; + line: any; + uuids: [string, string]; + layer: number; + type: string; }; /** State Management Types for React Components **/ @@ -201,67 +189,59 @@ export type RefTubeGeometry = React.MutableRefObject; // Type for individual items placed on the floor, with positioning and rotation metadata export type FloorItemType = { - modeluuid: string; - modelname: string; - position: [number, number, number]; - rotation: { x: number; y: number; z: number }; - modelfileID: string; - isLocked: boolean; - isVisible: boolean; + modeluuid: string; + modelname: string; + position: [number, number, number]; + rotation: { x: number; y: number; z: number }; + modelfileID: string; + isLocked: boolean; + isVisible: boolean; }; // Array of floor items for managing multiple objects on the floor export type FloorItems = Array; // Dispatch type for setting floor item state in React -export type setFloorItemSetState = React.Dispatch< - React.SetStateAction ->; +export type setFloorItemSetState = React.Dispatch>; /** Asset Configuration for Loading and Positioning **/ // Configuration for assets, allowing model URLs, scaling, positioning, and types interface AssetConfiguration { - modelUrl: string; - scale?: [number, number, number]; - csgscale?: [number, number, number]; - csgposition?: [number, number, number]; - positionY?: (intersectionPoint: { point: THREE.Vector3 }) => number; - type?: "Fixed-Move" | "Free-Move"; + modelUrl: string; + scale?: [number, number, number]; + csgscale?: [number, number, number]; + csgposition?: [number, number, number]; + positionY?: (intersectionPoint: { point: THREE.Vector3 }) => number; + type?: "Fixed-Move" | "Free-Move"; } // Collection of asset configurations, keyed by unique identifiers -export type AssetConfigurations = { - [key: string]: AssetConfiguration; -}; +export type AssetConfigurations = { [key: string]: AssetConfiguration; }; /** Wall Item Configuration **/ // Configuration for wall items, including model, scale, position, and rotation interface WallItem { - type: "Fixed-Move" | "Free-Move" | undefined; - model?: THREE.Group; - modeluuid?: string; - modelname?: string; - scale?: [number, number, number]; - csgscale?: [number, number, number]; - csgposition?: [number, number, number]; - position?: [number, number, number]; - quaternion?: Types.QuaternionType; + type: "Fixed-Move" | "Free-Move" | undefined; + model?: THREE.Group; + modeluuid?: string; + modelname?: string; + scale?: [number, number, number]; + csgscale?: [number, number, number]; + csgposition?: [number, number, number]; + position?: [number, number, number]; + quaternion?: Types.QuaternionType; } // Collection of wall items, allowing for multiple items in a scene export type wallItems = Array; // Dispatch for setting wall item state in React -export type setWallItemSetState = React.Dispatch< - React.SetStateAction ->; +export type setWallItemSetState = React.Dispatch>; // Dispatch for setting vector3 state in React -export type setVector3State = React.Dispatch< - React.SetStateAction ->; +export type setVector3State = React.Dispatch>; // Dispatch for setting euler state in React export type setEulerState = React.Dispatch>; @@ -274,245 +254,8 @@ export type RefWallItems = React.MutableRefObject; // State management for selecting, removing, and indexing wall items export type setRemoveLayerSetState = (layer: number | null) => void; export type setSelectedWallItemSetState = (item: THREE.Object3D | null) => void; -export type setSelectedFloorItemSetState = ( - item: THREE.Object3D | null -) => void; +export type setSelectedFloorItemSetState = (item: THREE.Object3D | null) => void; export type setSelectedItemsIndexSetState = (index: number | null) => void; export type RefCSM = React.MutableRefObject; -export type RefCSMHelper = React.MutableRefObject; - -interface PathConnection { - fromModelUUID: string; - fromUUID: string; - toConnections: { - toModelUUID: string; - toUUID: string; - }[]; -} - -interface ConnectionStore { - connections: PathConnection[]; - setConnections: (connections: PathConnection[]) => void; - addConnection: (newConnection: PathConnection) => void; - removeConnection: (fromUUID: string, toUUID: string) => void; -} - -interface ConveyorEventsSchema { - modeluuid: string; - modelName: string; - type: "Conveyor"; - points: { - uuid: string; - position: [number, number, number]; - rotation: [number, number, number]; - actions: - | { - uuid: string; - name: string; - type: string; - material: string; - delay: number | string; - spawnInterval: number | string; - isUsed: boolean; - }[] - | []; - triggers: - | { - uuid: string; - name: string; - type: string; - isUsed: boolean; - bufferTime: number; - }[] - | []; - connections: { - source: { modelUUID: string; pointUUID: string }; - targets: { modelUUID: string; pointUUID: string }[]; - }; - }[]; - position: [number, number, number]; - rotation: [number, number, number]; - speed: number | string; -} - -interface VehicleEventsSchema { - modeluuid: string; - modelName: string; - type: "Vehicle"; - points: { - uuid: string; - position: [number, number, number]; - actions: { - uuid: string; - name: string; - type: string; - start: { x: number; y: number } | {}; - hitCount: number; - end: { x: number; y: number } | {}; - buffer: number; - }; - connections: { - source: { modelUUID: string; pointUUID: string }; - targets: { modelUUID: string; pointUUID: string }[]; - }; - speed: number; - isPlaying: boolean; - }; - - position: [number, number, number]; -} - -interface StaticMachineEventsSchema { - modeluuid: string; - modelName: string; - type: "StaticMachine"; - points: { - uuid: string; - position: [number, number, number]; - actions: { - uuid: string; - name: string; - buffer: number | string; - material: string; - isUsed: boolean; - }; - triggers: { uuid: string; name: string; type: string }; - connections: { - source: { modelUUID: string; pointUUID: string }; - targets: { modelUUID: string; pointUUID: string }[]; - }; - }; - position: [number, number, number]; -} - -interface ArmBotEventsSchema { - modeluuid: string; - modelName: string; - type: "ArmBot"; - points: { - uuid: string; - position: [number, number, number]; - actions: { - uuid: string; - name: string; - speed: number; - processes: { triggerId: string; startPoint: string; endPoint: string }[]; - }; - triggers: { uuid: string; name: string; type: string }; - connections: { - source: { modelUUID: string; pointUUID: string }; - targets: { modelUUID: string; pointUUID: string }[]; - }; - }; - position: [number, number, number]; -} - -export type EventData = { - modeluuid: string; - modelname: string; - position: [number, number, number]; - rotation: { x: number; y: number; z: number }; - modelfileID: string; - isLocked: boolean; - isVisible: boolean; - eventData?: - | { - type: "Conveyor"; - points: { - uuid: string; - position: [number, number, number]; - rotation: [number, number, number]; - actions: - | { - uuid: string; - name: string; - type: string; - material: string; - delay: number | string; - spawnInterval: number | string; - isUsed: boolean; - }[] - | []; - triggers: - | { - uuid: string; - name: string; - type: string; - isUsed: boolean; - bufferTime: number; - }[] - | []; - connections: { - source: { modelUUID: string; pointUUID: string }; - targets: { modelUUID: string; pointUUID: string }[]; - }; - }[]; - speed: number | string; - } - | { - type: "Vehicle"; - points: { - uuid: string; - position: [number, number, number]; - rotation: [number, number, number]; - actions: { - uuid: string; - name: string; - type: string; - start: { x: number; y: number } | {}; - hitCount: number; - end: { x: number; y: number } | {}; - buffer: number; - }; - connections: { - source: { modelUUID: string; pointUUID: string }; - targets: { modelUUID: string; pointUUID: string }[]; - }; - speed: number; - }; - } - | { - type: "StaticMachine"; - points: { - uuid: string; - position: [number, number, number]; - rotation: [number, number, number]; - actions: { - uuid: string; - name: string; - buffer: number; - material: string; - }; - triggers: { uuid: string; name: string; type: string }; - connections: { - source: { modelUUID: string; pointUUID: string }; - targets: { modelUUID: string; pointUUID: string }[]; - }; - }; - } - | { - type: "ArmBot"; - points: { - uuid: string; - position: [number, number, number]; - rotation: [number, number, number]; - actions: { - uuid: string; - name: string; - speed: number; - processes: { - triggerId: string; - startPoint: string; - endPoint: string; - }[]; - }; - triggers: { uuid: string; name: string; type: string }; - connections: { - source: { modelUUID: string; pointUUID: string }; - targets: { modelUUID: string; pointUUID: string }[]; - }; - }; - }; -}; - +export type RefCSMHelper = React.MutableRefObject; \ No newline at end of file