diff --git a/app/src/modules/builder/aisle/Instances/aisleInstances.tsx b/app/src/modules/builder/aisle/Instances/aisleInstances.tsx
new file mode 100644
index 0000000..1ec9308
--- /dev/null
+++ b/app/src/modules/builder/aisle/Instances/aisleInstances.tsx
@@ -0,0 +1,24 @@
+import { useEffect } from 'react';
+import { useAisleStore } from '../../../../store/builder/useAisleStore';
+import AisleInstance from './instance/aisleInstance';
+
+function AisleInstances() {
+ const { aisles } = useAisleStore();
+
+ useEffect(() => {
+ console.log('aisles: ', aisles);
+ }, [aisles]);
+
+ return (
+
+ <>
+
+ {aisles.map((aisle) =>
+
+ )}
+
+ >
+ )
+}
+
+export default AisleInstances
\ No newline at end of file
diff --git a/app/src/modules/builder/aisle/Instances/instance/aisleInstance.tsx b/app/src/modules/builder/aisle/Instances/instance/aisleInstance.tsx
new file mode 100644
index 0000000..beada6f
--- /dev/null
+++ b/app/src/modules/builder/aisle/Instances/instance/aisleInstance.tsx
@@ -0,0 +1,19 @@
+import DashedAisle from './aisleTypes/dashedAisle';
+import SolidAisle from './aisleTypes/solidAisle';
+
+function AisleInstance({ aisle }: { readonly aisle: Aisle }) {
+
+ return (
+ <>
+ {aisle.type.aisleType === 'solid-aisle' && (
+
+ )}
+
+ {aisle.type.aisleType === 'dashed-aisle' && (
+
+ )}
+ >
+ );
+}
+
+export default AisleInstance;
\ No newline at end of file
diff --git a/app/src/modules/builder/aisle/Instances/instance/aisleTypes/dashedAisle.tsx b/app/src/modules/builder/aisle/Instances/instance/aisleTypes/dashedAisle.tsx
new file mode 100644
index 0000000..5774fcd
--- /dev/null
+++ b/app/src/modules/builder/aisle/Instances/instance/aisleTypes/dashedAisle.tsx
@@ -0,0 +1,71 @@
+import * as THREE from 'three';
+import { useMemo } from 'react';
+import { Extrude } from '@react-three/drei';
+import * as Constants from '../../../../../../types/world/worldConstants';
+
+function DashedAisle({ aisle }: { readonly aisle: Aisle }) {
+ const shapes = useMemo(() => {
+ if (aisle.points.length < 2) return [];
+
+ const start = new THREE.Vector3(...aisle.points[0].position);
+ const end = new THREE.Vector3(...aisle.points[1].position);
+ const width = aisle.type.width || 0.1;
+ const dashLength = 0.5;
+ const gapLength = 0.3;
+
+ const direction = new THREE.Vector3().subVectors(end, start).normalize();
+ const perp = new THREE.Vector3(-direction.z, 0, direction.x).normalize();
+
+ const totalLength = new THREE.Vector3().subVectors(end, start).length();
+ const segmentCount = Math.floor(totalLength / (dashLength + gapLength));
+
+ const shapes = [];
+ const directionNormalized = new THREE.Vector3().subVectors(end, start).normalize();
+
+ for (let i = 0; i < segmentCount; i++) {
+ const segmentStart = new THREE.Vector3().copy(start).addScaledVector(directionNormalized, i * (dashLength + gapLength));
+ const segmentEnd = new THREE.Vector3().copy(segmentStart).addScaledVector(directionNormalized, dashLength);
+
+ const leftStart = new THREE.Vector3().copy(segmentStart).addScaledVector(perp, width / 2);
+ const rightStart = new THREE.Vector3().copy(segmentStart).addScaledVector(perp, -width / 2);
+ const leftEnd = new THREE.Vector3().copy(segmentEnd).addScaledVector(perp, width / 2);
+ const rightEnd = new THREE.Vector3().copy(segmentEnd).addScaledVector(perp, -width / 2);
+
+ const shape = new THREE.Shape();
+ shape.moveTo(leftStart.x, leftStart.z);
+ shape.lineTo(leftEnd.x, leftEnd.z);
+ shape.lineTo(rightEnd.x, rightEnd.z);
+ shape.lineTo(rightStart.x, rightStart.z);
+ shape.closePath();
+
+ shapes.push(shape);
+ }
+
+ return shapes;
+ }, [aisle]);
+
+ if (shapes.length === 0) return null;
+
+ return (
+
+ {shapes.map((shape, index) => (
+
+
+
+ ))}
+
+ );
+}
+
+export default DashedAisle;
\ No newline at end of file
diff --git a/app/src/modules/builder/aisle/Instances/instance/aisleTypes/solidAisle.tsx b/app/src/modules/builder/aisle/Instances/instance/aisleTypes/solidAisle.tsx
new file mode 100644
index 0000000..c2bfdab
--- /dev/null
+++ b/app/src/modules/builder/aisle/Instances/instance/aisleTypes/solidAisle.tsx
@@ -0,0 +1,53 @@
+import * as THREE from 'three';
+import { useMemo } from 'react';
+import { Extrude } from '@react-three/drei';
+import * as Constants from '../../../../../../types/world/worldConstants';
+
+function SolidAisle({ aisle }: { readonly aisle: Aisle }) {
+ const shape = useMemo(() => {
+ if (aisle.points.length < 2) return null;
+
+ const start = new THREE.Vector3(...aisle.points[0].position);
+ const end = new THREE.Vector3(...aisle.points[1].position);
+ const width = aisle.type.width || 0.1;
+
+ const direction = new THREE.Vector3().subVectors(end, start).normalize();
+ const perp = new THREE.Vector3(-direction.z, 0, direction.x).normalize();
+
+ const leftStart = new THREE.Vector3().copy(start).addScaledVector(perp, width / 2);
+ const rightStart = new THREE.Vector3().copy(start).addScaledVector(perp, -width / 2);
+ const leftEnd = new THREE.Vector3().copy(end).addScaledVector(perp, width / 2);
+ const rightEnd = new THREE.Vector3().copy(end).addScaledVector(perp, -width / 2);
+
+ const shape = new THREE.Shape();
+ shape.moveTo(leftStart.x, leftStart.z);
+ shape.lineTo(leftEnd.x, leftEnd.z);
+ shape.lineTo(rightEnd.x, rightEnd.z);
+ shape.lineTo(rightStart.x, rightStart.z);
+ shape.closePath();
+
+ return shape;
+ }, [aisle]);
+
+ if (!shape) return null;
+
+ return (
+
+
+
+
+
+ );
+}
+
+export default SolidAisle;
\ No newline at end of file
diff --git a/app/src/modules/builder/aisle/aisleCreator/aisleCreator.tsx b/app/src/modules/builder/aisle/aisleCreator/aisleCreator.tsx
new file mode 100644
index 0000000..593c437
--- /dev/null
+++ b/app/src/modules/builder/aisle/aisleCreator/aisleCreator.tsx
@@ -0,0 +1,196 @@
+import * as THREE from 'three'
+import { useEffect, useMemo, useState } from 'react'
+import { useThree } from '@react-three/fiber';
+import { useActiveLayer, useSocketStore, useToggleView, useToolMode } from '../../../../store/builder/store';
+import { useAisleStore } from '../../../../store/builder/useAisleStore';
+import * as Constants from '../../../../types/world/worldConstants';
+import ReferenceAisle from './referenceAisle';
+
+function AisleCreator() {
+ const { scene, camera, raycaster, gl, pointer } = useThree();
+ const plane = useMemo(() => new THREE.Plane(new THREE.Vector3(0, 1, 0), 0), []);
+ const { toggleView } = useToggleView();
+ const { toolMode } = useToolMode();
+ const { activeLayer } = useActiveLayer();
+ const { socket } = useSocketStore();
+ const { aisles, addAisle } = useAisleStore();
+
+ const [tempPoints, setTempPoints] = useState([]);
+ const [isCreating, setIsCreating] = useState(false);
+ const [aisleType, setAisleType] = useState<'solid-aisle' | 'dashed-aisle' | 'stripped-aisle' | 'dotted-aisle' | 'arrow-aisle' | 'arrows-aisle' | 'arc-aisle' | 'circle-aisle' | 'junction-aisle'>('dashed-aisle');
+
+ useEffect(() => {
+ if (tempPoints.length > 0) {
+ setTempPoints([]);
+ setIsCreating(false);
+ }
+ }, [aisleType]);
+
+ const allPoints = useMemo(() => {
+ const points: Point[] = [];
+ const seenUuids = new Set();
+
+ // Add points from existing aisles
+ aisles.forEach(aisle => {
+ aisle.points.forEach(point => {
+ if (!seenUuids.has(point.uuid)) {
+ seenUuids.add(point.uuid);
+ points.push(point);
+ }
+ });
+ });
+
+ // Add temporary points
+ tempPoints.forEach(point => {
+ if (!seenUuids.has(point.uuid)) {
+ seenUuids.add(point.uuid);
+ points.push(point);
+ }
+ });
+
+ return points;
+ }, [aisles, tempPoints]);
+
+
+ useEffect(() => {
+ const canvasElement = gl.domElement;
+
+ let drag = false;
+ let isLeftMouseDown = false;
+
+ const onMouseDown = (evt: any) => {
+ if (evt.button === 0) {
+ isLeftMouseDown = true;
+ drag = false;
+ }
+ };
+
+ const onMouseUp = (evt: any) => {
+ if (evt.button === 0) {
+ isLeftMouseDown = false;
+ }
+ };
+
+ const onMouseMove = () => {
+ if (isLeftMouseDown) {
+ drag = true;
+ }
+ };
+
+ const onMouseClick = () => {
+ if (drag || !toggleView) return;
+
+ raycaster.setFromCamera(pointer, camera);
+ const intersectionPoint = new THREE.Vector3();
+ const point = raycaster.ray.intersectPlane(plane, intersectionPoint);
+
+ if (!point) return;
+
+ if (['solid-aisle', 'dashed-aisle', 'stripped-aisle', 'dotted-aisle', 'arrows-aisle'].includes(aisleType)) {
+ const newPoint: Point = {
+ uuid: THREE.MathUtils.generateUUID(),
+ position: [point.x, point.y, point.z],
+ layer: activeLayer
+ };
+
+ if (tempPoints.length === 0) {
+ setTempPoints([newPoint]);
+ setIsCreating(true);
+ } else {
+ const aisle: Aisle = {
+ uuid: THREE.MathUtils.generateUUID(),
+ points: [tempPoints[0], newPoint],
+ type: {
+ typeName: 'Aisle',
+ material: 'default',
+ aisleType: aisleType,
+ color: Constants.aisleConfig.defaultColor,
+ width: Constants.aisleConfig.width
+ }
+ };
+
+ addAisle(aisle);
+
+ setTempPoints([newPoint]);
+ }
+ } else if (['arc-aisle', 'circle-aisle', 'arrow-aisle', 'junction-aisle'].includes(aisleType)) {
+ const newPoint: Point = {
+ uuid: THREE.MathUtils.generateUUID(),
+ position: [point.x, point.y, point.z],
+ layer: activeLayer
+ };
+
+ if (tempPoints.length === 0) {
+ setTempPoints([newPoint]);
+ setIsCreating(true);
+ } else {
+ const aisle: Aisle = {
+ uuid: THREE.MathUtils.generateUUID(),
+ points: [tempPoints[0], newPoint],
+ type: {
+ typeName: 'Aisle',
+ material: 'default',
+ aisleType: aisleType,
+ color: Constants.aisleConfig.defaultColor,
+ width: Constants.aisleConfig.width
+ }
+ };
+
+ addAisle(aisle);
+
+ setTempPoints([]);
+ setIsCreating(false);
+ }
+ }
+ };
+
+ const onContext = (event: any) => {
+ event.preventDefault();
+ if (isCreating) {
+ setTempPoints([]);
+ setIsCreating(false);
+ }
+ };
+
+ if (toolMode === "Aisle" && toggleView) {
+ canvasElement.addEventListener("mousedown", onMouseDown);
+ canvasElement.addEventListener("mouseup", onMouseUp);
+ canvasElement.addEventListener("mousemove", onMouseMove);
+ canvasElement.addEventListener("click", onMouseClick);
+ canvasElement.addEventListener("contextmenu", onContext);
+ } else {
+ setTempPoints([]);
+ setIsCreating(false);
+ }
+
+ return () => {
+ canvasElement.removeEventListener("mousedown", onMouseDown);
+ canvasElement.removeEventListener("mouseup", onMouseUp);
+ canvasElement.removeEventListener("mousemove", onMouseMove);
+ canvasElement.removeEventListener("click", onMouseClick);
+ canvasElement.removeEventListener("contextmenu", onContext);
+ };
+ }, [gl, camera, scene, raycaster, pointer, plane, toggleView, toolMode, activeLayer, socket, tempPoints, isCreating, addAisle, aisleType]);
+
+ return (
+ <>
+
+ {allPoints.map((point) => (
+
+
+
+
+ ))}
+
+
+
+ >
+ );
+}
+
+export default AisleCreator;
\ No newline at end of file
diff --git a/app/src/modules/builder/aisle/aisleCreator/referenceAisle.tsx b/app/src/modules/builder/aisle/aisleCreator/referenceAisle.tsx
new file mode 100644
index 0000000..437337a
--- /dev/null
+++ b/app/src/modules/builder/aisle/aisleCreator/referenceAisle.tsx
@@ -0,0 +1,193 @@
+import { useEffect, useMemo, useRef, useState } from 'react';
+import * as THREE from 'three';
+import { useFrame, useThree } from '@react-three/fiber';
+import { useActiveLayer, useToolMode, useToggleView } from '../../../../store/builder/store';
+import * as Constants from '../../../../types/world/worldConstants';
+import { Extrude } from '@react-three/drei';
+
+interface ReferenceAisleProps {
+ tempPoints: Point[];
+ aisleType: 'solid-aisle' | 'dashed-aisle' | 'stripped-aisle' | 'dotted-aisle' | 'arrow-aisle' | 'arrows-aisle' | 'arc-aisle' | 'circle-aisle' | 'junction-aisle';
+}
+
+function ReferenceAisle({ tempPoints, aisleType }: Readonly) {
+ const { pointer, raycaster, camera } = useThree();
+ const { toolMode } = useToolMode();
+ const { toggleView } = useToggleView();
+ const { activeLayer } = useActiveLayer();
+ const plane = new THREE.Plane(new THREE.Vector3(0, 1, 0), 0);
+
+ const [tempAisle, setTempAisle] = useState(null);
+ const mousePosRef = useRef(new THREE.Vector3());
+
+ useFrame(() => {
+ if (toolMode === "Aisle" && toggleView && tempPoints.length === 1) {
+ raycaster.setFromCamera(pointer, camera);
+ const intersectionPoint = new THREE.Vector3();
+ raycaster.ray.intersectPlane(plane, intersectionPoint);
+
+ if (intersectionPoint) {
+ mousePosRef.current.copy(intersectionPoint);
+
+ setTempAisle({
+ uuid: 'temp-aisle',
+ points: [
+ tempPoints[0],
+ {
+ uuid: 'temp-point',
+ position: [mousePosRef.current.x, mousePosRef.current.y, mousePosRef.current.z],
+ layer: activeLayer
+ }
+ ],
+ type: {
+ typeName: 'Aisle',
+ material: 'default',
+ aisleType: aisleType,
+ color: Constants.aisleConfig.defaultColor,
+ width: Constants.aisleConfig.width
+ }
+ });
+ }
+ } else if (tempAisle !== null) {
+ setTempAisle(null);
+ }
+ });
+
+ useEffect(() => {
+ setTempAisle(null);
+ }, [toolMode, toggleView, tempPoints.length, aisleType]);
+
+ if (!tempAisle) return null;
+
+ const renderAisle = () => {
+ switch (aisleType) {
+ case 'solid-aisle':
+ return ;
+ case 'dashed-aisle':
+ return ;
+ default:
+ return null;
+ }
+ };
+
+ return (
+
+ {renderAisle()}
+
+ );
+}
+
+export default ReferenceAisle;
+
+
+function SolidAisle({ aisle }: { readonly aisle: Aisle }) {
+ const shape = useMemo(() => {
+ if (aisle.points.length < 2) return null;
+
+ const start = new THREE.Vector3(...aisle.points[0].position);
+ const end = new THREE.Vector3(...aisle.points[1].position);
+ const width = aisle.type.width || 0.1;
+
+ const direction = new THREE.Vector3().subVectors(end, start).normalize();
+ const perp = new THREE.Vector3(-direction.z, 0, direction.x).normalize();
+
+ const leftStart = new THREE.Vector3().copy(start).addScaledVector(perp, width / 2);
+ const rightStart = new THREE.Vector3().copy(start).addScaledVector(perp, -width / 2);
+ const leftEnd = new THREE.Vector3().copy(end).addScaledVector(perp, width / 2);
+ const rightEnd = new THREE.Vector3().copy(end).addScaledVector(perp, -width / 2);
+
+ const shape = new THREE.Shape();
+ shape.moveTo(leftStart.x, leftStart.z);
+ shape.lineTo(leftEnd.x, leftEnd.z);
+ shape.lineTo(rightEnd.x, rightEnd.z);
+ shape.lineTo(rightStart.x, rightStart.z);
+ shape.closePath();
+
+ return shape;
+ }, [aisle]);
+
+ if (!shape) return null;
+
+ return (
+
+
+
+
+
+ );
+}
+
+function DashedAisle({ aisle }: { readonly aisle: Aisle }) {
+ const shapes = useMemo(() => {
+ if (aisle.points.length < 2) return [];
+
+ const start = new THREE.Vector3(...aisle.points[0].position);
+ const end = new THREE.Vector3(...aisle.points[1].position);
+ const width = aisle.type.width || 0.1;
+ const dashLength = 0.5;
+ const gapLength = 0.3;
+
+ const direction = new THREE.Vector3().subVectors(end, start).normalize();
+ const perp = new THREE.Vector3(-direction.z, 0, direction.x).normalize();
+
+ const totalLength = new THREE.Vector3().subVectors(end, start).length();
+ const segmentCount = Math.floor(totalLength / (dashLength + gapLength));
+
+ const shapes = [];
+ const directionNormalized = new THREE.Vector3().subVectors(end, start).normalize();
+
+ for (let i = 0; i < segmentCount; i++) {
+ const segmentStart = new THREE.Vector3().copy(start).addScaledVector(directionNormalized, i * (dashLength + gapLength));
+ const segmentEnd = new THREE.Vector3().copy(segmentStart).addScaledVector(directionNormalized, dashLength);
+
+ const leftStart = new THREE.Vector3().copy(segmentStart).addScaledVector(perp, width / 2);
+ const rightStart = new THREE.Vector3().copy(segmentStart).addScaledVector(perp, -width / 2);
+ const leftEnd = new THREE.Vector3().copy(segmentEnd).addScaledVector(perp, width / 2);
+ const rightEnd = new THREE.Vector3().copy(segmentEnd).addScaledVector(perp, -width / 2);
+
+ const shape = new THREE.Shape();
+ shape.moveTo(leftStart.x, leftStart.z);
+ shape.lineTo(leftEnd.x, leftEnd.z);
+ shape.lineTo(rightEnd.x, rightEnd.z);
+ shape.lineTo(rightStart.x, rightStart.z);
+ shape.closePath();
+
+ shapes.push(shape);
+ }
+
+ return shapes;
+ }, [aisle]);
+
+ if (shapes.length === 0) return null;
+
+ return (
+
+ {shapes.map((shape, index) => (
+
+
+
+ ))}
+
+ );
+}
diff --git a/app/src/modules/builder/aisle/aislesGroup.tsx b/app/src/modules/builder/aisle/aislesGroup.tsx
new file mode 100644
index 0000000..6639672
--- /dev/null
+++ b/app/src/modules/builder/aisle/aislesGroup.tsx
@@ -0,0 +1,21 @@
+import React from 'react'
+import AisleCreator from './aisleCreator/aisleCreator'
+import AisleInstances from './Instances/aisleInstances'
+
+function AislesGroup() {
+
+ return (
+
+ <>
+
+
+
+
+
+
+ >
+
+ )
+}
+
+export default AislesGroup
\ No newline at end of file
diff --git a/app/src/modules/builder/asset/models/model/model.tsx b/app/src/modules/builder/asset/models/model/model.tsx
index fe1649b..d7af8d4 100644
--- a/app/src/modules/builder/asset/models/model/model.tsx
+++ b/app/src/modules/builder/asset/models/model/model.tsx
@@ -4,18 +4,17 @@ 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 { ThreeEvent, useFrame, useThree } from '@react-three/fiber';
-import { useActiveTool, useDeletableFloorItem, useRenderDistance, useSelectedFloorItem } from '../../../../../store/builder/store';
+import { useActiveTool, useDeletableFloorItem, useRenderDistance, useSelectedFloorItem, useSocketStore } from '../../../../../store/builder/store';
import { AssetBoundingBox } from '../../functions/assetBoundingBox';
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 }) {
+function Model({ asset }: { readonly asset: Asset }) {
const { camera, controls, gl } = useThree();
const { activeTool } = useActiveTool();
const { subModule } = useSubModuleStore();
@@ -46,7 +45,8 @@ function Model({ asset }: { asset: Asset }) {
const loadModel = async () => {
try {
// Check Cache
- const cachedModel = THREE.Cache.get(asset.assetId!);
+ const assetId = asset.assetId;
+ const cachedModel = THREE.Cache.get(assetId);
if (cachedModel) {
setGltfScene(cachedModel);
calculateBoundingBox(cachedModel.scene);
@@ -54,13 +54,13 @@ function Model({ asset }: { asset: Asset }) {
}
// Check IndexedDB
- const indexedDBModel = await retrieveGLTF(asset.assetId!);
+ const indexedDBModel = await retrieveGLTF(assetId);
if (indexedDBModel) {
const blobUrl = URL.createObjectURL(indexedDBModel);
loader.load(blobUrl, (gltf) => {
URL.revokeObjectURL(blobUrl);
THREE.Cache.remove(blobUrl);
- THREE.Cache.add(asset.assetId!, gltf);
+ THREE.Cache.add(assetId, gltf);
setGltfScene(gltf);
calculateBoundingBox(gltf.scene);
},
@@ -74,14 +74,22 @@ function Model({ asset }: { asset: Asset }) {
}
// Fetch from Backend
- const modelUrl = `${url_Backend_dwinzo}/api/v2/AssetFile/${asset.assetId!}`;
- loader.load(modelUrl, async (gltf) => {
- const modelBlob = await fetch(modelUrl).then((res) => res.blob());
- await storeGLTF(asset.assetId!, modelBlob);
- THREE.Cache.add(asset.assetId!, gltf);
- setGltfScene(gltf);
- calculateBoundingBox(gltf.scene);
- },
+ const modelUrl = `${url_Backend_dwinzo}/api/v2/AssetFile/${assetId}`;
+ const handleBackendLoad = async (gltf: GLTF) => {
+ try {
+ const response = await fetch(modelUrl);
+ const modelBlob = await response.blob();
+ await storeGLTF(assetId, modelBlob);
+ THREE.Cache.add(assetId, gltf);
+ setGltfScene(gltf);
+ calculateBoundingBox(gltf.scene);
+ } catch (error) {
+ console.error(`[Backend] Error storing/loading ${asset.modelName}:`, error);
+ }
+ };
+ loader.load(
+ modelUrl,
+ handleBackendLoad,
undefined,
(error) => {
echo.error(`[Backend] Error loading ${asset.modelName}:`);
@@ -130,7 +138,7 @@ function Model({ asset }: { asset: Asset }) {
true
);
(controls as CameraControls).setTarget(center.x, center.y, center.z, true);
- (controls as CameraControls).fitToBox(groupRef.current!, true, {
+ (controls as CameraControls).fitToBox(groupRef.current, true, {
cover: true,
paddingTop: 5,
paddingLeft: 5,
@@ -191,6 +199,8 @@ function Model({ asset }: { asset: Asset }) {
}
}
+
+
const handleContextMenu = (asset: Asset, evt: ThreeEvent) => {
if (activeTool === "cursor" && subModule === 'simulations') {
if (asset.modelUuid) {
@@ -215,7 +225,6 @@ function Model({ asset }: { asset: Asset }) {
const canvasRect = canvasElement.getBoundingClientRect();
const relativeX = evt.clientX - canvasRect.left;
const relativeY = evt.clientY - canvasRect.top;
-
setTop(relativeY);
setLeft(relativeX);
} else {
diff --git a/app/src/modules/builder/builder.tsx b/app/src/modules/builder/builder.tsx
index c69252b..3263b90 100644
--- a/app/src/modules/builder/builder.tsx
+++ b/app/src/modules/builder/builder.tsx
@@ -48,6 +48,7 @@ import CalculateAreaGroup from "./groups/calculateAreaGroup";
import LayoutImage from "./layout/layoutImage";
import AssetsGroup from "./asset/assetsGroup";
import { Bvh } from "@react-three/drei";
+import AislesGroup from "./aisle/aislesGroup";
export default function Builder() {
const state = useThree(); // Importing the state from the useThree hook, which contains the scene, camera, and other Three.js elements.
@@ -274,7 +275,7 @@ export default function Builder() {
-
+ /> */}
+
+
diff --git a/app/src/modules/simulation/events/points/functions/handleAddEventToProduct.ts b/app/src/modules/simulation/events/points/functions/handleAddEventToProduct.ts
index 236905b..86fd13f 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/store/builder/useAisleStore.ts b/app/src/store/builder/useAisleStore.ts
new file mode 100644
index 0000000..22bdbd3
--- /dev/null
+++ b/app/src/store/builder/useAisleStore.ts
@@ -0,0 +1,86 @@
+import { create } from 'zustand';
+import { immer } from 'zustand/middleware/immer';
+
+interface AisleStore {
+ aisles: Aisles;
+ setAisles: (aisles: Aisles) => void;
+ addAisle: (aisle: Aisle) => void;
+ updateAisle: (uuid: string, updated: Partial) => void;
+ removeAisle: (uuid: string) => void;
+ setPosition: (pointUuid: string, position: [number, number, number]) => void;
+ setLayer: (pointUuid: string, layer: number) => void;
+ setMaterial: (aisleUuid: string, material: string) => void;
+ setColor: (aisleUuid: string, color: string) => void;
+ setWidth: (aisleUuid: string, width: number) => void;
+ getAisleById: (uuid: string) => Aisle | undefined;
+}
+
+export const useAisleStore = create()(
+ immer((set, get) => ({
+ aisles: [],
+
+ setAisles: (aisles) => set((state) => {
+ state.aisles = aisles;
+ }),
+
+ addAisle: (aisle) => set((state) => {
+ state.aisles.push(aisle);
+ }),
+
+ updateAisle: (uuid, updated) => set((state) => {
+ const aisle = state.aisles.find((a) => a.uuid === uuid);
+ if (aisle) {
+ Object.assign(aisle, updated);
+ }
+ }),
+
+ removeAisle: (uuid) => set((state) => {
+ state.aisles = state.aisles.filter((a) => a.uuid !== uuid);
+ }),
+
+ setPosition: (pointUuid: string, position: [number, number, number]) => set((state) => {
+ for (const aisle of state.aisles) {
+ const point = aisle.points.find(p => p.uuid === pointUuid);
+ if (point) {
+ point.position = position;
+ break;
+ }
+ }
+ }),
+
+ setLayer: (pointUuid: string, layer: number) => set((state) => {
+ for (const aisle of state.aisles) {
+ const point = aisle.points.find(p => p.uuid === pointUuid);
+ if (point) {
+ point.layer = layer;
+ break;
+ }
+ }
+ }),
+
+ setMaterial: (aisleUuid: string, material: string) => set((state) => {
+ const aisle = state.aisles.find(a => a.uuid === aisleUuid);
+ if (aisle) {
+ aisle.type.material = material;
+ }
+ }),
+
+ setColor: (aisleUuid: string, color: string) => set((state) => {
+ const aisle = state.aisles.find(a => a.uuid === aisleUuid);
+ if (aisle) {
+ aisle.type.color = color;
+ }
+ }),
+
+ setWidth: (aisleUuid: string, width: number) => set((state) => {
+ const aisle = state.aisles.find(a => a.uuid === aisleUuid);
+ if (aisle) {
+ aisle.type.width = width;
+ }
+ }),
+
+ getAisleById: (uuid) => {
+ return get().aisles.find((a) => a.uuid === uuid);
+ },
+ }))
+);
diff --git a/app/src/types/builderTypes.d.ts b/app/src/types/builderTypes.d.ts
index adfdc78..b2409a0 100644
--- a/app/src/types/builderTypes.d.ts
+++ b/app/src/types/builderTypes.d.ts
@@ -28,4 +28,27 @@ interface Asset {
}
};
-type Assets = Asset[];
\ No newline at end of file
+type Assets = Asset[];
+
+
+interface Point {
+ uuid: string;
+ position: [number, number, number];
+ layer: number;
+}
+
+interface AisleType {
+ typeName: 'Aisle';
+ material: string;
+ aisleType: 'solid-aisle' | 'dashed-aisle' | 'stripped-aisle' | 'dotted-aisle' | 'arrow-aisle'| 'arrows-aisle' | 'arc-aisle' | 'circle-aisle' | 'junction-aisle';
+ color: string;
+ width: number;
+}
+
+interface Aisle {
+ uuid: string;
+ points: [Point, Point];
+ type: AisleType;
+}
+
+type Aisles = Aisle[];
\ No newline at end of file
diff --git a/app/src/types/world/worldConstants.ts b/app/src/types/world/worldConstants.ts
index 5193ee1..c2cb62d 100644
--- a/app/src/types/world/worldConstants.ts
+++ b/app/src/types/world/worldConstants.ts
@@ -158,7 +158,7 @@ export type RoofConfig = {
export type AisleConfig = {
width: number;
height: number;
- defaultColor: number;
+ defaultColor: string;
};
export type ZoneConfig = {
@@ -345,7 +345,7 @@ export const roofConfig: RoofConfig = {
export const aisleConfig: AisleConfig = {
width: 0.1, // Width of the aisles
height: 0.01, // Height of the aisles
- defaultColor: 0xE2AC09, // Default color of the aisles
+ defaultColor: '#E2AC09', // Default color of the aisles
};
export const zoneConfig: ZoneConfig = {