diff --git a/app/src/components/layout/sidebarRight/simulation/Simulations.tsx b/app/src/components/layout/sidebarRight/simulation/Simulations.tsx index 316269c..492a91a 100644 --- a/app/src/components/layout/sidebarRight/simulation/Simulations.tsx +++ b/app/src/components/layout/sidebarRight/simulation/Simulations.tsx @@ -28,7 +28,7 @@ import { useSaveVersion, } from "../../../../store/builder/store"; import CompareLayOut from "../../../ui/compareVersion/CompareLayOut"; -import {useToggleStore} from "../../../../store/useUIToggleStore"; +import { useToggleStore } from "../../../../store/useUIToggleStore"; interface Event { modelName: string; @@ -179,11 +179,10 @@ const Simulations: React.FC = () => { {products.map((product, index) => (
{/* eslint-disable-next-line */}
= ({ }; const [zoneDataList, setZoneDataList] = useState([]); - const { floorItems } = useFloorItems(); + const { assets } = useAssetsStore(); const isPointInsidePolygon = ( point: [number, number], @@ -80,7 +81,7 @@ const DropDownList: React.FC = ({ p[2], ]); - const assetsInZone = floorItems + const assetsInZone = assets .filter((item: any) => { const [x, , z] = item.position; return isPointInsidePolygon([x, z], polygon2D as [number, number][]); @@ -98,9 +99,9 @@ const DropDownList: React.FC = ({ assets: assetsInZone, }; }); - + setZoneDataList(updatedZoneList); - }, [zones, floorItems]); + }, [zones, assets]); return (
@@ -143,7 +144,7 @@ const DropDownList: React.FC = ({ value="Buildings" showKebabMenu={false} showAddIcon={false} - // items={zoneDataList} + // items={zoneDataList} /> = ({ items = [], remove }) => { const [expandedZones, setExpandedZones] = useState>( {} ); - const { setFloorItems } = useFloorItems(); + const { setName } = useAssetsStore(); useEffect(() => { useSelectedZoneStore.getState().setSelectedZone({ @@ -148,13 +148,8 @@ const List: React.FC = ({ items = [], remove }) => { newName ); // console.log("response: ", response); - setFloorItems((prevFloorItems: any[]) => - prevFloorItems.map((floorItems) => - floorItems.modelUuid === zoneAssetId.id - ? { ...floorItems, modelName: response.modelName } - : floorItems - ) - ); + + setName(zoneAssetId.id, response.modelName); } } const checkZoneNameDuplicate = (name: string) => { diff --git a/app/src/modules/builder/assetGroup/functions/addAssetModel.ts b/app/src/modules/builder/assetGroup/functions/addAssetModel.ts index 5949cf2..d0b6461 100644 --- a/app/src/modules/builder/assetGroup/functions/addAssetModel.ts +++ b/app/src/modules/builder/assetGroup/functions/addAssetModel.ts @@ -94,8 +94,8 @@ async function handleModelLoad( ) { const model = gltf.scene.clone(); model.userData = { name: selectedItem.name, modelId: selectedItem.id, modelUuid: model.uuid }; - model.position.set(intersectPoint!.x, 3 + intersectPoint!.y, intersectPoint!.z); - model.scale.set(...CONSTANTS.assetConfig.defaultScaleBeforeGsap); + model.position.set(intersectPoint!.x, intersectPoint!.y, intersectPoint!.z); + model.scale.set(...CONSTANTS.assetConfig.defaultScaleAfterGsap); model.traverse((child: any) => { if (child) { diff --git a/app/src/modules/builder/assetGroup/models/model/model.tsx b/app/src/modules/builder/assetGroup/models/model/model.tsx index 719af1d..fe1649b 100644 --- a/app/src/modules/builder/assetGroup/models/model/model.tsx +++ b/app/src/modules/builder/assetGroup/models/model/model.tsx @@ -3,19 +3,30 @@ import { useEffect, useRef, useState } from 'react'; import { retrieveGLTF, storeGLTF } from '../../../../../utils/indexDB/idbUtils'; import { GLTF, GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'; import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader'; -import { useFrame, useThree } from '@react-three/fiber'; +import { ThreeEvent, useFrame, useThree } from '@react-three/fiber'; import { useActiveTool, useDeletableFloorItem, useRenderDistance, useSelectedFloorItem } from '../../../../../store/builder/store'; import { AssetBoundingBox } from '../../functions/assetBoundingBox'; -import { CameraControls, Detailed } from '@react-three/drei'; +import { CameraControls } from '@react-three/drei'; import { useAssetsStore } from '../../../../../store/builder/useAssetStore'; import { useEventsStore } from "../../../../../store/simulation/useEventsStore"; import { useProductStore } from "../../../../../store/simulation/useProductStore"; import { useSocketStore } from '../../../../../store/builder/store'; +import useModuleStore, { useSubModuleStore } from '../../../../../store/useModuleStore'; +import { useLeftData, useTopData } from '../../../../../store/visualization/useZone3DWidgetStore'; +import { useSelectedAsset, useSelectedProduct } from '../../../../../store/simulation/useSimulationStore'; function Model({ asset }: { asset: Asset }) { - const { camera, controls } = useThree(); + const { camera, controls, gl } = useThree(); const { activeTool } = useActiveTool(); + const { subModule } = useSubModuleStore(); + const { activeModule } = useModuleStore(); const { removeAsset } = useAssetsStore(); + const { setTop } = useTopData(); + const { setLeft } = useLeftData(); + const { getIsEventInProduct } = useProductStore(); + const { getEventByModelUuid } = useEventsStore(); + const { selectedProduct } = useSelectedProduct(); + const { setSelectedAsset, clearSelectedAsset } = useSelectedAsset(); const { socket } = useSocketStore(); const { deletableFloorItem, setDeletableFloorItem } = useDeletableFloorItem(); const { setSelectedFloorItem } = useSelectedFloorItem(); @@ -101,7 +112,7 @@ function Model({ asset }: { asset: Asset }) { const handleDblClick = (asset: Asset) => { if (asset) { - if (activeTool === "cursor" && boundingBox && groupRef.current) { + if (activeTool === "cursor" && boundingBox && groupRef.current && activeModule === 'builder') { const size = boundingBox.getSize(new THREE.Vector3()); const center = boundingBox.getCenter(new THREE.Vector3()); @@ -127,7 +138,6 @@ function Model({ asset }: { asset: Asset }) { paddingRight: 5, }); setSelectedFloorItem(groupRef.current); - } } }; @@ -137,7 +147,6 @@ function Model({ asset }: { asset: Asset }) { const email = localStorage.getItem('email') const organization = (email!.split("@")[1]).split(".")[0]; - //REST // const response = await deleteFloorItem(organization, asset.modelUuid, asset.modelName); @@ -158,10 +167,6 @@ function Model({ asset }: { asset: Asset }) { if (response) { - const storedItems = JSON.parse(localStorage.getItem("FloorItems") || '[]'); - const updatedStoredItems = storedItems.filter((item: { modelUuid: string }) => item.modelUuid !== asset.modelUuid); - localStorage.setItem("FloorItems", JSON.stringify(updatedStoredItems)); - removeAsset(asset.modelUuid); echo.success("Model Removed!"); @@ -186,6 +191,45 @@ function Model({ asset }: { asset: Asset }) { } } + const handleContextMenu = (asset: Asset, evt: ThreeEvent) => { + if (activeTool === "cursor" && subModule === 'simulations') { + if (asset.modelUuid) { + const canvasElement = gl.domElement; + const isInProduct = getIsEventInProduct(selectedProduct.productId, asset.modelUuid); + if (isInProduct) { + const event = getEventByModelUuid(asset.modelUuid); + if (event) { + setSelectedAsset(event); + const canvasRect = canvasElement.getBoundingClientRect(); + const relativeX = evt.clientX - canvasRect.left; + const relativeY = evt.clientY - canvasRect.top; + setTop(relativeY); + setLeft(relativeX); + } else { + clearSelectedAsset(); + } + } else { + const event = getEventByModelUuid(asset.modelUuid); + if (event) { + setSelectedAsset(event) + const canvasRect = canvasElement.getBoundingClientRect(); + const relativeX = evt.clientX - canvasRect.left; + const relativeY = evt.clientY - canvasRect.top; + + setTop(relativeY); + setLeft(relativeX); + } else { + clearSelectedAsset() + } + } + } else { + clearSelectedAsset() + } + } else { + clearSelectedAsset() + } + } + return ( { e.stopPropagation(); - handleDblClick(asset); }} onClick={(e) => { e.stopPropagation(); + handleDblClick(asset); handleClick(asset); }} onPointerOver={(e) => { @@ -211,6 +255,10 @@ function Model({ asset }: { asset: Asset }) { e.stopPropagation(); handlePointerOut(asset); }} + onContextMenu={(e) => { + e.stopPropagation(); + handleContextMenu(asset, e); + }} > {gltfScene && ( isRendered ? ( diff --git a/app/src/modules/builder/assetGroup/models/models.tsx b/app/src/modules/builder/assetGroup/models/models.tsx index 4553531..e67a649 100644 --- a/app/src/modules/builder/assetGroup/models/models.tsx +++ b/app/src/modules/builder/assetGroup/models/models.tsx @@ -4,11 +4,13 @@ import { useThree } from '@react-three/fiber'; import { CameraControls } from '@react-three/drei'; import { Vector3 } from 'three'; import { useSelectedFloorItem } from '../../../../store/builder/store'; +import { useSelectedAsset } from '../../../../store/simulation/useSimulationStore'; function Models() { const { controls } = useThree(); const { assets } = useAssetsStore(); const { selectedFloorItem, setSelectedFloorItem } = useSelectedFloorItem(); + const { selectedAsset, clearSelectedAsset } = useSelectedAsset(); return ( {assets.map((asset) => diff --git a/app/src/modules/collaboration/socket/socketResponses.dev.tsx b/app/src/modules/collaboration/socket/socketResponses.dev.tsx index 6e0051c..b36aa34 100644 --- a/app/src/modules/collaboration/socket/socketResponses.dev.tsx +++ b/app/src/modules/collaboration/socket/socketResponses.dev.tsx @@ -7,7 +7,6 @@ import { useSocketStore, useActiveLayer, useWallItems, - useFloorItems, useLayers, useUpdateScene, useWalls, @@ -32,6 +31,9 @@ import RemoveConnectedLines from "../../builder/geomentries/lines/removeConnecte import Layer2DVisibility from "../../builder/geomentries/layers/layer2DVisibility"; import { retrieveGLTF, storeGLTF } from "../../../utils/indexDB/idbUtils"; import { getZonesApi } from "../../../services/factoryBuilder/zones/getZonesApi"; +import { useAssetsStore } from "../../../store/builder/useAssetStore"; +import { useEventsStore } from "../../../store/simulation/useEventsStore"; +import { useProductStore } from "../../../store/simulation/useProductStore"; export default function SocketResponses({ floorPlanGroup, @@ -53,13 +55,13 @@ export default function SocketResponses({ const { activeLayer, setActiveLayer } = useActiveLayer(); const { wallItems, setWallItems } = useWallItems(); const { setLayers } = useLayers(); - const { setFloorItems } = useFloorItems(); const { setUpdateScene } = useUpdateScene(); const { setWalls } = useWalls(); const { setDeletedLines } = useDeletedLines(); const { setNewLines } = useNewLines(); const { zones, setZones } = useZones(); const { zonePoints, setZonePoints } = useZonePoints(); + const { addAsset, updateAsset, removeAsset } = useAssetsStore(); useEffect(() => { const email = localStorage.getItem("email"); @@ -95,235 +97,54 @@ export default function SocketResponses({ if (organization !== data.organization) { return; } + console.log('data.data: ', data); if (data.message === "Model created successfully") { - const loader = new GLTFLoader(); - const dracoLoader = new DRACOLoader(); - - dracoLoader.setDecoderPath( - "https://cdn.jsdelivr.net/npm/three@0.160.0/examples/jsm/libs/draco/gltf/" - ); - loader.setDRACOLoader(dracoLoader); - let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_MARKETPLACE_URL}`; - try { - isTempLoader.current = true; - const cachedModel = THREE.Cache.get(data.data.modelName); - let url; - if (cachedModel) { - // console.log(`Getting ${data.data.modelName} from cache`); - const model = cachedModel.scene.clone(); - model.uuid = data.data.modelUuid; - model.userData = { - name: data.data.modelName, - modelId: data.data.modelfileID, - modelUuid: data.data.modelUuid, - }; - model.position.set( - ...(data.data.position as [number, number, number]) - ); - model.rotation.set( - data.data.rotation.x, - data.data.rotation.y, - data.data.rotation.z - ); - model.scale.set(...CONSTANTS.assetConfig.defaultScaleBeforeGsap); - model.traverse((child: any) => { - if (child.isMesh) { - // Clone the material to ensure changes are independent - // child.material = child.material.clone(); - - child.castShadow = true; - child.receiveShadow = true; - } - }); - - itemsGroup.current.add(model); - - if (tempLoader.current) { - tempLoader.current.material.dispose(); - tempLoader.current.geometry.dispose(); - itemsGroup.current.remove(tempLoader.current); - tempLoader.current = undefined; - } - - const newFloorItem: Types.FloorItemType = { - modelUuid: data.data.modelUuid, - modelName: data.data.modelName, - modelfileID: data.data.modelfileID, - position: [...(data.data.position as [number, number, number])], - rotation: { - x: model.rotation.x, - y: model.rotation.y, - z: model.rotation.z, - }, - isLocked: data.data.isLocked, - isVisible: data.data.isVisible, - }; - - setFloorItems((prevItems: any) => { - const updatedItems = [...(prevItems || []), newFloorItem]; - localStorage.setItem("FloorItems", JSON.stringify(updatedItems)); - return updatedItems; - }); - - gsap.to(model.position, { - y: data.data.position[1], - duration: 1.5, - ease: "power2.out", - }); - gsap.to(model.scale, { - x: 1, - y: 1, - z: 1, - duration: 1.5, - ease: "power2.out", - onComplete: () => { - echo.success("Model Added!"); - }, - }); - } else { - const indexedDBModel = await retrieveGLTF(data.data.modelName); - if (indexedDBModel) { - // console.log(`Getting ${data.data.modelName} from IndexedDB`); - url = URL.createObjectURL(indexedDBModel); - } else { - // console.log(`Getting ${data.data.modelName} from Backend`); - url = `${url_Backend_dwinzo}/api/v2/AssetFile/${data.data.modelfileID}`; - const modelBlob = await fetch(url).then((res) => res.blob()); - await storeGLTF(data.data.modelfileID, modelBlob); - } + const asset: Asset = { + modelUuid: data.data.modelUuid, + modelName: data.data.modelName, + assetId: data.data.modelfileID, + position: data.data.position, + rotation: [data.data.rotation.x, data.data.rotation.y, data.data.rotation.z], + isLocked: data.data.isLocked, + isCollidable: false, + isVisible: data.data.isVisible, + opacity: 1, } - if (url) { - loadModel(url); - } + addAsset(asset); + + echo.success("Added model through collaboration"); } catch (error) { - echo.error("Failed to update responce"); - console.error("Error fetching asset model:", error); - } - - function loadModel(url: string) { - loader.load( - url, - (gltf) => { - URL.revokeObjectURL(url); - THREE.Cache.remove(url); - const model = gltf.scene; - model.uuid = data.data.modelUuid; - model.userData = { - name: data.data.modelName, - modelId: data.data.modelfileID, - modelUuid: data.data.modelUuid, - }; - model.position.set( - ...(data.data.position as [number, number, number]) - ); - model.rotation.set( - data.data.rotation.x, - data.data.rotation.y, - data.data.rotation.z - ); - model.scale.set(...CONSTANTS.assetConfig.defaultScaleBeforeGsap); - - model.traverse((child: any) => { - if (child.isMesh) { - // Clone the material to ensure changes are independent - // child.material = child.material.clone(); - - child.castShadow = true; - child.receiveShadow = true; - } - }); - - itemsGroup.current.add(model); - - if (tempLoader.current) { - tempLoader.current.material.dispose(); - tempLoader.current.geometry.dispose(); - itemsGroup.current.remove(tempLoader.current); - tempLoader.current = undefined; - } - - const newFloorItem: Types.FloorItemType = { - modelUuid: data.data.modelUuid, - modelName: data.data.modelName, - modelfileID: data.data.modelfileID, - position: [...(data.data.position as [number, number, number])], - rotation: { - x: model.rotation.x, - y: model.rotation.y, - z: model.rotation.z, - }, - isLocked: data.data.isLocked, - isVisible: data.data.isVisible, - }; - - setFloorItems((prevItems: any) => { - const updatedItems = [...(prevItems || []), newFloorItem]; - localStorage.setItem( - "FloorItems", - JSON.stringify(updatedItems) - ); - return updatedItems; - }); - - gsap.to(model.position, { - y: data.data.position[1], - duration: 1.5, - ease: "power2.out", - }); - gsap.to(model.scale, { - x: 1, - y: 1, - z: 1, - duration: 1.5, - ease: "power2.out", - onComplete: () => { - echo.success("Model Added!"); - }, - }); - - THREE.Cache.add(data.data.modelName, gltf); - } - ); + echo.error("Failed to create model through collaboration"); } } else if (data.message === "Model updated successfully") { - itemsGroup.current?.children.forEach((item: THREE.Group) => { - if (item.uuid === data.data.modelUuid) { - item.position.set( - ...(data.data.position as [number, number, number]) - ); - item.rotation.set( - data.data.rotation.x, - data.data.rotation.y, - data.data.rotation.z - ); - } - }); + try { - setFloorItems((prevItems: Types.FloorItems) => { - if (!prevItems) { - return; + const asset: Asset = { + modelUuid: data.data.modelUuid, + modelName: data.data.modelName, + assetId: data.data.modelfileID, + position: data.data.position, + rotation: [data.data.rotation.x, data.data.rotation.y, data.data.rotation.z], + isLocked: data.data.isLocked, + isCollidable: false, + isVisible: data.data.isVisible, + opacity: 1, } - let updatedItem: any = null; - const updatedItems = prevItems.map((item) => { - if (item.modelUuid === data.data.modelUuid) { - updatedItem = { - ...item, - position: [...data.data.position] as [number, number, number], - rotation: { - x: data.data.rotation.x, - y: data.data.rotation.y, - z: data.data.rotation.z, - }, - }; - return updatedItem; - } - return item; + + updateAsset(asset.modelUuid, { + position: asset.position, + rotation: asset.rotation, }); - return updatedItems; - }); + + echo.success("Updated model through collaboration"); + } catch (error) { + echo.error("Failed to update model through collaboration"); + } + } else { + echo.error("Failed executing action from collaboration"); } }); @@ -335,28 +156,18 @@ export default function SocketResponses({ return; } if (data.message === "Model deleted successfully") { - const deletedUUID = data.data.modelUuid; - let items = JSON.parse(localStorage.getItem("FloorItems")!); + try { + const deletedUUID = data.data.modelUuid; - const updatedItems = items.filter( - (item: { modelUuid: string }) => item.modelUuid !== deletedUUID - ); + useEventsStore.getState().removeEvent(deletedUUID); + useProductStore.getState().deleteEvent(deletedUUID); - const storedItems = JSON.parse( - localStorage.getItem("FloorItems") || "[]" - ); - const updatedStoredItems = storedItems.filter( - (item: { modelUuid: string }) => item.modelUuid !== deletedUUID - ); - localStorage.setItem("FloorItems", JSON.stringify(updatedStoredItems)); + removeAsset(deletedUUID); - itemsGroup.current.children.forEach((item: any) => { - if (item.uuid === deletedUUID) { - itemsGroup.current.remove(item); - } - }); - setFloorItems(updatedItems); - echo.success("Model Removed!"); + echo.success("Model Removed successfully through collaboration"); + } catch (error) { + echo.error("Failed to remove model through collaboration"); + } } }); diff --git a/app/src/modules/scene/controls/selectionControls/copyPasteControls.tsx b/app/src/modules/scene/controls/selectionControls/copyPasteControls.tsx index 6c7a91c..f006870 100644 --- a/app/src/modules/scene/controls/selectionControls/copyPasteControls.tsx +++ b/app/src/modules/scene/controls/selectionControls/copyPasteControls.tsx @@ -1,7 +1,7 @@ import * as THREE from "three"; import { useEffect, useMemo } from "react"; import { useFrame, useThree } from "@react-three/fiber"; -import { useFloorItems, useSelectedAssets, useSocketStore, useToggleView } from "../../../../store/builder/store"; +import { useSelectedAssets, useSocketStore, useToggleView } from "../../../../store/builder/store"; // import { setFloorItemApi } from '../../../../services/factoryBuilder/assest/floorAsset/setFloorItemApi'; import * as Types from "../../../../types/world/worldTypes"; import { detectModifierKeys } from "../../../../utils/shortcutkeys/detectModifierKeys"; @@ -25,10 +25,9 @@ const CopyPasteControls = ({ const { toggleView } = useToggleView(); const { selectedAssets, setSelectedAssets } = useSelectedAssets(); const plane = useMemo(() => new THREE.Plane(new THREE.Vector3(0, 1, 0), 0), []); - const { floorItems, setFloorItems } = useFloorItems(); const { socket } = useSocketStore(); const { addEvent } = useEventsStore(); - const { addAsset } = useAssetsStore(); + const { assets, addAsset } = useAssetsStore(); useEffect(() => { if (!camera || !scene || toggleView) return; @@ -77,7 +76,7 @@ const CopyPasteControls = ({ canvasElement.removeEventListener("keydown", onKeyDown); }; - }, [camera, controls, scene, toggleView, selectedAssets, copiedObjects, pastedObjects, movedObjects, socket, floorItems, rotatedObjects]); + }, [assets, camera, controls, scene, toggleView, selectedAssets, copiedObjects, pastedObjects, movedObjects, socket, rotatedObjects]); useFrame(() => { if (pastedObjects.length > 0) { @@ -145,6 +144,9 @@ const CopyPasteControls = ({ const addPastedObjects = () => { if (pastedObjects.length === 0) return; + const email = localStorage.getItem("email"); + const organization = email ? email.split("@")[1].split(".")[0] : "default"; + pastedObjects.forEach(async (obj: THREE.Object3D) => { if (obj) { const worldPosition = new THREE.Vector3(); @@ -329,15 +331,6 @@ const CopyPasteControls = ({ newFloorItem.eventData = eventData; - setFloorItems((prevItems: Types.FloorItems) => { - const updatedItems = [...(prevItems || []), newFloorItem]; - localStorage.setItem("FloorItems", JSON.stringify(updatedItems)); - return updatedItems; - }); - - const email = localStorage.getItem("email"); - const organization = email ? email.split("@")[1].split(".")[0] : "default"; - //REST // await setFloorItemApi( @@ -391,14 +384,6 @@ const CopyPasteControls = ({ addAsset(asset); } else { - setFloorItems((prevItems: Types.FloorItems) => { - const updatedItems = [...(prevItems || []), newFloorItem]; - localStorage.setItem("FloorItems", JSON.stringify(updatedItems)); - return updatedItems; - }); - - const email = localStorage.getItem("email"); - const organization = email ? email.split("@")[1].split(".")[0] : "default"; //REST diff --git a/app/src/modules/scene/controls/selectionControls/duplicationControls.tsx b/app/src/modules/scene/controls/selectionControls/duplicationControls.tsx index 93c99fc..1d011ef 100644 --- a/app/src/modules/scene/controls/selectionControls/duplicationControls.tsx +++ b/app/src/modules/scene/controls/selectionControls/duplicationControls.tsx @@ -1,7 +1,7 @@ import * as THREE from "three"; import { useEffect, useMemo } from "react"; import { useFrame, useThree } from "@react-three/fiber"; -import { useFloorItems, useSelectedAssets, useSocketStore, useToggleView } from "../../../../store/builder/store"; +import { useSelectedAssets, useSocketStore, useToggleView } from "../../../../store/builder/store"; // import { setFloorItemApi } from '../../../../services/factoryBuilder/assest/floorAsset/setFloorItemApi'; import * as Types from "../../../../types/world/worldTypes"; import { detectModifierKeys } from "../../../../utils/shortcutkeys/detectModifierKeys"; @@ -23,10 +23,9 @@ const DuplicationControls = ({ const { toggleView } = useToggleView(); const { selectedAssets, setSelectedAssets } = useSelectedAssets(); const plane = useMemo(() => new THREE.Plane(new THREE.Vector3(0, 1, 0), 0), []); - const { floorItems, setFloorItems } = useFloorItems(); const { socket } = useSocketStore(); const { addEvent } = useEventsStore(); - const { addAsset } = useAssetsStore(); + const { assets, addAsset } = useAssetsStore(); useEffect(() => { if (!camera || !scene || toggleView) return; @@ -72,7 +71,7 @@ const DuplicationControls = ({ canvasElement.removeEventListener("keydown", onKeyDown); }; - }, [camera, controls, scene, toggleView, selectedAssets, duplicatedObjects, movedObjects, socket, floorItems, rotatedObjects]); + }, [assets, camera, controls, scene, toggleView, selectedAssets, duplicatedObjects, movedObjects, socket, rotatedObjects]); useFrame(() => { if (duplicatedObjects.length > 0) { @@ -120,6 +119,9 @@ const DuplicationControls = ({ const addDuplicatedAssets = () => { if (duplicatedObjects.length === 0) return; + const email = localStorage.getItem("email"); + const organization = email ? email.split("@")[1].split(".")[0] : "default"; + duplicatedObjects.forEach(async (obj: THREE.Object3D) => { if (obj) { const worldPosition = new THREE.Vector3(); @@ -303,15 +305,6 @@ const DuplicationControls = ({ newFloorItem.eventData = eventData; - setFloorItems((prevItems: Types.FloorItems) => { - const updatedItems = [...(prevItems || []), newFloorItem]; - localStorage.setItem("FloorItems", JSON.stringify(updatedItems)); - return updatedItems; - }); - - const email = localStorage.getItem("email"); - const organization = email ? email.split("@")[1].split(".")[0] : "default"; - //REST // await setFloorItemApi( @@ -358,14 +351,6 @@ const DuplicationControls = ({ addAsset(asset); } else { - setFloorItems((prevItems: Types.FloorItems) => { - const updatedItems = [...(prevItems || []), newFloorItem]; - localStorage.setItem("FloorItems", JSON.stringify(updatedItems)); - return updatedItems; - }); - - const email = localStorage.getItem("email"); - const organization = email ? email.split("@")[1].split(".")[0] : "default"; //REST diff --git a/app/src/modules/scene/controls/selectionControls/moveControls.tsx b/app/src/modules/scene/controls/selectionControls/moveControls.tsx index de50c84..d28e852 100644 --- a/app/src/modules/scene/controls/selectionControls/moveControls.tsx +++ b/app/src/modules/scene/controls/selectionControls/moveControls.tsx @@ -2,7 +2,6 @@ import * as THREE from "three"; import { useEffect, useMemo, useRef, useState } from "react"; import { useFrame, useThree } from "@react-three/fiber"; import { - useFloorItems, useSelectedAssets, useSocketStore, useToggleView, diff --git a/app/src/modules/scene/controls/selectionControls/rotateControls.tsx b/app/src/modules/scene/controls/selectionControls/rotateControls.tsx index b8b9095..83a1eb4 100644 --- a/app/src/modules/scene/controls/selectionControls/rotateControls.tsx +++ b/app/src/modules/scene/controls/selectionControls/rotateControls.tsx @@ -1,7 +1,7 @@ import * as THREE from "three"; import { useEffect, useMemo, useRef } from "react"; import { useFrame, useThree } from "@react-three/fiber"; -import { useFloorItems, useSelectedAssets, useSocketStore, useToggleView } from "../../../../store/builder/store"; +import { useSelectedAssets, useSocketStore, useToggleView } from "../../../../store/builder/store"; // import { setFloorItemApi } from '../../../../services/factoryBuilder/assest/floorAsset/setFloorItemApi'; import * as Types from "../../../../types/world/worldTypes"; import { useEventsStore } from "../../../../store/simulation/useEventsStore"; diff --git a/app/src/modules/scene/controls/selectionControls/selectionControls.tsx b/app/src/modules/scene/controls/selectionControls/selectionControls.tsx index 691bb7c..2dcd775 100644 --- a/app/src/modules/scene/controls/selectionControls/selectionControls.tsx +++ b/app/src/modules/scene/controls/selectionControls/selectionControls.tsx @@ -3,7 +3,7 @@ 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, useSocketStore, useToggleView, } from "../../../../store/builder/store"; +import { useSelectedAssets, useSocketStore, useToggleView, } from "../../../../store/builder/store"; import BoundingBox from "./boundingBoxHelper"; // import { deleteFloorItem } from '../../../../services/factoryBuilder/assest/floorAsset/deleteFloorItemApi'; import * as Types from "../../../../types/world/worldTypes"; diff --git a/app/src/modules/scene/controls/transformControls/transformControls.tsx b/app/src/modules/scene/controls/transformControls/transformControls.tsx index d1167f4..66e965f 100644 --- a/app/src/modules/scene/controls/transformControls/transformControls.tsx +++ b/app/src/modules/scene/controls/transformControls/transformControls.tsx @@ -1,6 +1,6 @@ import { TransformControls } from "@react-three/drei"; import * as THREE from "three"; -import { useSelectedFloorItem, useObjectPosition, useObjectRotation, useFloorItems, useActiveTool, useSocketStore } from "../../../../store/builder/store"; +import { useSelectedFloorItem, useObjectPosition, useObjectRotation, useActiveTool, useSocketStore } from "../../../../store/builder/store"; import { useThree } from "@react-three/fiber"; import * as Types from '../../../../types/world/worldTypes'; @@ -11,6 +11,7 @@ import { useProductStore } from "../../../../store/simulation/useProductStore"; import { useSelectedProduct } from "../../../../store/simulation/useSimulationStore"; import { upsertProductOrEventApi } from "../../../../services/simulation/products/UpsertProductOrEventApi"; import { setFloorItemApi } from "../../../../services/factoryBuilder/assest/floorAsset/setFloorItemApi"; +import { useAssetsStore } from "../../../../store/builder/useAssetStore"; export default function TransformControl() { const state = useThree(); @@ -18,10 +19,10 @@ export default function TransformControl() { const { selectedFloorItem, setSelectedFloorItem } = useSelectedFloorItem(); const { setObjectPosition } = useObjectPosition(); const { setObjectRotation } = useObjectRotation(); - const { setFloorItems } = useFloorItems(); const { activeTool } = useActiveTool(); const { socket } = useSocketStore(); const { selectedProduct } = useSelectedProduct(); + const { updateAsset, getAssetById } = useAssetsStore(); const email = localStorage.getItem('email') const organization = (email!.split("@")[1]).split(".")[0]; @@ -60,97 +61,76 @@ export default function TransformControl() { z: THREE.MathUtils.radToDeg(selectedFloorItem.rotation.z), }); } - setFloorItems((prevItems: Types.FloorItems) => { - if (!prevItems) { - return - } - let updatedItem: any = null; - const updatedItems = prevItems.map((item) => { - if (item.modelUuid === selectedFloorItem?.uuid) { - updatedItem = { - ...item, + const asset = getAssetById(selectedFloorItem?.uuid); + if (asset) { + if (asset.eventData) { + const eventData = useEventsStore.getState().getEventByModelUuid(asset.modelUuid); + const productData = useProductStore.getState().getEventByModelUuid(selectedProduct.productId, asset.modelUuid); + + if (eventData) { + useEventsStore.getState().updateEvent(asset.modelUuid, { position: [selectedFloorItem.position.x, 0, selectedFloorItem.position.z] as [number, number, number], - rotation: { x: selectedFloorItem.rotation.x, y: selectedFloorItem.rotation.y, z: selectedFloorItem.rotation.z }, - }; - return updatedItem; + rotation: [selectedFloorItem.rotation.x, selectedFloorItem.rotation.y, selectedFloorItem.rotation.z] as [number, number, number], + }); } - return item; - }); - if (updatedItem && selectedFloorItem) { - if (updatedItem.eventData) { - const eventData = useEventsStore.getState().getEventByModelUuid(updatedItem.modelUuid); - const productData = useProductStore.getState().getEventByModelUuid(selectedProduct.productId, updatedItem.modelUuid); - if (eventData) { - useEventsStore.getState().updateEvent(updatedItem.modelUuid, { - position: [selectedFloorItem.position.x, 0, selectedFloorItem.position.z], - rotation: [selectedFloorItem.rotation.x, selectedFloorItem.rotation.y, selectedFloorItem.rotation.z], - }); - } + if (productData) { + const event = useProductStore + .getState() + .updateEvent( + selectedProduct.productId, + asset.modelUuid, + { + position: [selectedFloorItem.position.x, 0, selectedFloorItem.position.z] as [number, number, number], + rotation: [selectedFloorItem.rotation.x, selectedFloorItem.rotation.y, selectedFloorItem.rotation.z] as [number, number, number], + } + ); - if (productData) { - const event = useProductStore - .getState() - .updateEvent( - selectedProduct.productId, - updatedItem.modelUuid, - { - position: [selectedFloorItem.position.x, 0, selectedFloorItem.position.z], - rotation: [selectedFloorItem.rotation.x, selectedFloorItem.rotation.y, selectedFloorItem.rotation.z], - } - ); - - if (event) { - updateBackend( - selectedProduct.productName, - selectedProduct.productId, - organization, - event - ); - } - - updatedItem.eventData = eventData; + if (event) { + updateBackend( + selectedProduct.productName, + selectedProduct.productId, + organization, + event + ); } } - - setFloorItems((prevItems: Types.FloorItems) => { - const updatedItems = [...(prevItems || []), updatedItem]; - localStorage.setItem("FloorItems", JSON.stringify(updatedItems)); - return updatedItems; - }); - - // REST - - // setFloorItemApi( - // organization, - // updatedItem.modelUuid, - // updatedItem.modelName, - // updatedItem.modelfileid, - // [selectedFloorItem.position.x, 0, selectedFloorItem.position.z,], - // { "x": selectedFloorItem.rotation.x, "y": selectedFloorItem.rotation.y, "z": selectedFloorItem.rotation.z }, - // false, - // true, - // ); - - // SOCKET - - const data = { - organization: organization, - modelUuid: updatedItem.modelUuid, - modelName: updatedItem.modelName, - modelfileID: updatedItem.modelfileID, - position: [selectedFloorItem.position.x, 0, selectedFloorItem.position.z], - rotation: { "x": selectedFloorItem.rotation.x, "y": selectedFloorItem.rotation.y, "z": selectedFloorItem.rotation.z }, - isLocked: false, - isVisible: true, - socketId: socket.id - } - - socket.emit("v2:model-asset:add", data); } - localStorage.setItem("FloorItems", JSON.stringify(updatedItems)); - return updatedItems; - }); + + updateAsset(asset.modelUuid, { + position: [selectedFloorItem.position.x, 0, selectedFloorItem.position.z], + rotation: [selectedFloorItem.rotation.x, selectedFloorItem.rotation.y, selectedFloorItem.rotation.z] as [number, number, number], + }); + + //REST + + // await setFloorItemApi( + // organization, + // asset.modelUuid, + // asset.modelName, + // [selectedFloorItem.position.x, 0, selectedFloorItem.position.z, + // { "x": selectedFloorItem.rotation.x, "y": selectedFloorItem.rotation.y, "z": selectedFloorItem.rotation.z }, + // asset.assetId, + // false, + // true, + // ); + + //SOCKET + + const data = { + organization, + modelUuid: asset.modelUuid, + modelName: asset.modelName, + modelfileID: asset.assetId, + position: [selectedFloorItem.position.x, 0, selectedFloorItem.position.z] as [number, number, number], + rotation: { x: selectedFloorItem.rotation.x, y: selectedFloorItem.rotation.y, z: selectedFloorItem.rotation.z }, + isLocked: false, + isVisible: true, + socketId: socket.id, + }; + + socket.emit("v2:model-asset:add", data); + } } useEffect(() => { diff --git a/app/src/modules/scene/environment/shadow.tsx b/app/src/modules/scene/environment/shadow.tsx index 59b348b..d8c8002 100644 --- a/app/src/modules/scene/environment/shadow.tsx +++ b/app/src/modules/scene/environment/shadow.tsx @@ -6,7 +6,6 @@ import { useElevation, useShadows, useSunPosition, - useFloorItems, useWallItems, useTileDistance, } from "../../../store/builder/store"; @@ -26,14 +25,13 @@ export default function Shadows() { const { controls, gl } = useThree(); const { elevation, setElevation } = useElevation(); const { azimuth, setAzimuth } = useAzimuth(); - const { floorItems } = useFloorItems(); const { wallItems } = useWallItems(); const { planeValue } = useTileDistance(); useEffect(() => { gl.shadowMap.enabled = true; gl.shadowMap.type = THREE.PCFShadowMap; - }, [gl, floorItems, wallItems]); + }, [gl, wallItems]); useEffect(() => { if (lightRef.current && targetRef.current) { diff --git a/app/src/modules/simulation/events/points/functions/handleAddEventToProduct.ts b/app/src/modules/simulation/events/points/functions/handleAddEventToProduct.ts index 86fd13f..236905b 100644 --- a/app/src/modules/simulation/events/points/functions/handleAddEventToProduct.ts +++ b/app/src/modules/simulation/events/points/functions/handleAddEventToProduct.ts @@ -28,7 +28,7 @@ export const handleAddEventToProduct = ({ organization: organization, eventDatas: event }).then((data) => { - // console.log(data); + console.log(data); }) if (clearSelectedAsset) { diff --git a/app/src/modules/simulation/products/events/addOrRemoveEventsInProducts.tsx b/app/src/modules/simulation/products/events/addOrRemoveEventsInProducts.tsx deleted file mode 100644 index 715aa37..0000000 --- a/app/src/modules/simulation/products/events/addOrRemoveEventsInProducts.tsx +++ /dev/null @@ -1,135 +0,0 @@ -import { useThree } from '@react-three/fiber' -import { useEffect } from 'react' -import { Object3D } from 'three'; -import { useSubModuleStore } from '../../../../store/useModuleStore'; -import { useLeftData, useTopData } from '../../../../store/visualization/useZone3DWidgetStore'; -import { useEventsStore } from '../../../../store/simulation/useEventsStore'; -import { useProductStore } from '../../../../store/simulation/useProductStore'; -import { useSelectedProduct } from '../../../../store/simulation/useSimulationStore'; -import { useSelectedAsset } from '../../../../store/simulation/useSimulationStore'; - -function AddOrRemoveEventsInProducts() { - const { gl, raycaster, scene } = useThree(); - const { subModule } = useSubModuleStore(); - const { setTop } = useTopData(); - const { setLeft } = useLeftData(); - const { getIsEventInProduct } = useProductStore(); - const { getEventByModelUuid } = useEventsStore(); - const { selectedProduct } = useSelectedProduct(); - const { selectedAsset, setSelectedAsset, clearSelectedAsset } = useSelectedAsset(); - - useEffect(() => { - - const canvasElement = gl.domElement; - - let drag = false; - let isRightMouseDown = false; - - const onMouseDown = (evt: MouseEvent) => { - if (selectedAsset) { - clearSelectedAsset(); - } - if (evt.button === 2) { - isRightMouseDown = true; - drag = false; - } - }; - - const onMouseUp = (evt: MouseEvent) => { - if (evt.button === 2) { - isRightMouseDown = false; - } - } - - const onMouseMove = () => { - if (isRightMouseDown) { - drag = true; - } - }; - - const handleRightClick = (evt: MouseEvent) => { - if (drag) return; - evt.preventDefault(); - const canvasElement = gl.domElement; - if (!canvasElement) return; - - const intersects = raycaster - .intersectObjects(scene.children, true) - .filter( - (intersect) => - !intersect.object.name.includes("Roof") && - !intersect.object.name.includes("MeasurementReference") && - !intersect.object.name.includes("agv-collider") && - !(intersect.object.type === "GridHelper") && - !(intersect.object?.parent?.name.includes('zones')) && - !(intersect.object?.parent?.name.includes('Zone')) - ); - if (intersects.length > 0 && intersects[0]?.object?.parent?.parent?.position && intersects[0]?.object?.parent?.parent?.scale && intersects[0]?.object?.parent?.parent?.rotation) { - let currentObject = intersects[0].object; - - while (currentObject) { - if (currentObject.name === "Scene") { - break; - } - currentObject = currentObject.parent as Object3D; - } - if (currentObject) { - const isInProduct = getIsEventInProduct(selectedProduct.productId, currentObject.uuid); - - if (isInProduct) { - const event = getEventByModelUuid(currentObject.uuid); - if (event) { - setSelectedAsset(event) - const canvasRect = canvasElement.getBoundingClientRect(); - const relativeX = evt.clientX - canvasRect.left; - const relativeY = evt.clientY - canvasRect.top; - - setTop(relativeY); - setLeft(relativeX); - } else { - clearSelectedAsset() - } - } else { - const event = getEventByModelUuid(currentObject.uuid); - if (event) { - setSelectedAsset(event) - const canvasRect = canvasElement.getBoundingClientRect(); - const relativeX = evt.clientX - canvasRect.left; - const relativeY = evt.clientY - canvasRect.top; - - setTop(relativeY); - setLeft(relativeX); - } else { - clearSelectedAsset() - } - } - - } - } else { - clearSelectedAsset() - } - - }; - - if (subModule === 'simulations') { - canvasElement.addEventListener("mousedown", onMouseDown); - canvasElement.addEventListener("mouseup", onMouseUp); - canvasElement.addEventListener("mousemove", onMouseMove); - canvasElement.addEventListener('contextmenu', handleRightClick); - } - - return () => { - canvasElement.removeEventListener("mousedown", onMouseDown); - canvasElement.removeEventListener("mouseup", onMouseUp); - canvasElement.removeEventListener("mousemove", onMouseMove); - canvasElement.removeEventListener('contextmenu', handleRightClick); - }; - - }, [gl, subModule, selectedProduct, selectedAsset]); - - return ( - <> - ) -} - -export default AddOrRemoveEventsInProducts \ No newline at end of file diff --git a/app/src/modules/simulation/products/products.tsx b/app/src/modules/simulation/products/products.tsx index f0fd1f4..1ea1b21 100644 --- a/app/src/modules/simulation/products/products.tsx +++ b/app/src/modules/simulation/products/products.tsx @@ -2,7 +2,6 @@ import * as THREE from 'three'; import { useEffect } from 'react'; import { useProductStore } from '../../../store/simulation/useProductStore'; import { useSelectedProduct } from '../../../store/simulation/useSimulationStore'; -import AddOrRemoveEventsInProducts from './events/addOrRemoveEventsInProducts'; import { upsertProductOrEventApi } from '../../../services/simulation/products/UpsertProductOrEventApi'; import { getAllProductsApi } from '../../../services/simulation/products/getallProductsApi'; import { useVehicleStore } from '../../../store/simulation/useVehicleStore'; @@ -127,8 +126,6 @@ function Products() { return ( <> - - ) } diff --git a/app/src/pages/Project.tsx b/app/src/pages/Project.tsx index 6e49734..dc6adc3 100644 --- a/app/src/pages/Project.tsx +++ b/app/src/pages/Project.tsx @@ -7,7 +7,6 @@ import RealTimeVisulization from "../modules/visualization/RealTimeVisulization" import Tools from "../components/ui/Tools"; import { useSocketStore, - useFloorItems, useOrganization, useUserName, useWallItems, @@ -34,10 +33,11 @@ import Footer from "../components/footer/Footer"; import SelectFloorPlan from "../components/temporary/SelectFloorPlan"; import ControlsPlayer from "../components/layout/controls/ControlsPlayer"; import CompareLayOut from "../components/ui/compareVersion/CompareLayOut"; -import {useToggleStore} from "../store/useUIToggleStore"; +import { useToggleStore } from "../store/useUIToggleStore"; import RegularDropDown from "../components/ui/inputs/RegularDropDown"; import VersionSaved from "../components/layout/sidebarRight/versionHisory/VersionSaved"; import SimulationPlayer from "../components/ui/simulation/simulationPlayer"; +import { useAssetsStore } from "../store/builder/useAssetStore"; const Project: React.FC = () => { let navigate = useNavigate(); @@ -46,9 +46,9 @@ const Project: React.FC = () => { const { activeModule, setActiveModule } = useModuleStore(); const { loadingProgress } = useLoadingProgress(); + const { setAssets } = useAssetsStore(); const { setUserName } = useUserName(); const { setOrganization } = useOrganization(); - const { setFloorItems } = useFloorItems(); const { setWallItems } = useWallItems(); const { setZones } = useZones(); const { isVersionSaved } = useSaveVersion(); @@ -61,7 +61,7 @@ const Project: React.FC = () => { }, [isVersionSaved]); useEffect(() => { - setFloorItems([]); + setAssets([]); setWallItems([]); setZones([]); setActiveModule("builder"); diff --git a/app/src/store/builder/store.ts b/app/src/store/builder/store.ts index f05a1b2..70e8a63 100644 --- a/app/src/store/builder/store.ts +++ b/app/src/store/builder/store.ts @@ -155,15 +155,6 @@ export const useDeletePointOrLine = create((set: any) => ({ 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, - })), -})); - export const useWallItems = create((set: any) => ({ wallItems: [], setWallItems: (callback: any) => diff --git a/app/src/store/builder/useAssetStore.ts b/app/src/store/builder/useAssetStore.ts index 326a877..ffa1d35 100644 --- a/app/src/store/builder/useAssetStore.ts +++ b/app/src/store/builder/useAssetStore.ts @@ -11,6 +11,7 @@ interface AssetsStore { setAssets: (assets: Assets) => void; // Asset properties + setName: (modelUuid: string, newName: string) => void; setPosition: (modelUuid: string, position: [number, number, number]) => void; setRotation: (modelUuid: string, rotation: [number, number, number]) => void; setLock: (modelUuid: string, isLocked: boolean) => void; @@ -70,6 +71,15 @@ export const useAssetsStore = create()( }, // Asset properties + setName: (modelUuid, newName) => { + set((state) => { + const asset = state.assets.find(a => a.modelUuid === modelUuid); + if (asset) { + asset.modelName = newName; + } + }); + }, + setPosition: (modelUuid, position) => { set((state) => { const asset = state.assets.find(a => a.modelUuid === modelUuid);