Refactor builder store and remove wall store

Refactor builder store and remove wall store

- Consolidated wall-related state management into the builder store by removing the useWallStore.
- Added new properties and setters for wall attributes (thickness, height, materials) in the builder store.
- Introduced SelectedWallProperties and WallProperties components for managing wall properties in the sidebar.
- Created a new floor store for managing floor-related state.
- Added a wall asset store for managing wall assets.
- Implemented a zone store for managing zones and their properties.
- Updated sidebar styles for better layout and appearance.
This commit is contained in:
2025-06-25 15:26:53 +05:30
parent 982c92cf26
commit 587ed6c9d7
21 changed files with 870 additions and 402 deletions

View File

@@ -276,7 +276,7 @@ export default function Builder() {
<LayoutImage />
</Bvh>
{/* <WallGroup /> */}
<WallGroup />
</>
);
}

View File

@@ -148,7 +148,7 @@ const FloorPlanGroup = ({ floorPlanGroup, floorPlanGroupLine, floorPlanGroupPoin
}
if (toolMode === "Wall") {
drawWall(raycaster, plane, floorPlanGroupPoint, snappedPoint, isSnapped, isSnappedUUID, line, ispreSnapped, anglesnappedPoint, isAngleSnapped, lines, floorPlanGroupLine, floorPlanGroup, ReferenceLineMesh, LineCreated, currentLayerPoint, dragPointControls, setNewLines, setDeletedLines, activeLayer, socket, projectId, selectedVersion?.versionId || '',);
// drawWall(raycaster, plane, floorPlanGroupPoint, snappedPoint, isSnapped, isSnappedUUID, line, ispreSnapped, anglesnappedPoint, isAngleSnapped, lines, floorPlanGroupLine, floorPlanGroup, ReferenceLineMesh, LineCreated, currentLayerPoint, dragPointControls, setNewLines, setDeletedLines, activeLayer, socket, projectId, selectedVersion?.versionId || '',);
}
if (toolMode === "Floor") {

View File

@@ -1,11 +1,11 @@
import * as THREE from 'three';
import { useThree } from '@react-three/fiber';
import { useEffect, useMemo, useState } from "react";
import * as Constants from '../../../types/world/worldConstants';
import { DragControls, Tube } from '@react-three/drei';
import { useToolMode } from '../../../store/builder/store';
import { useBuilderStore } from '../../../store/builder/useBuilderStore';
import { useWallStore } from '../../../store/builder/useWallStore';
import { useThree } from '@react-three/fiber';
import { useSceneContext } from '../../scene/sceneContext';
import * as Constants from '../../../types/world/worldConstants';
interface LineProps {
points: [Point, Point];
@@ -17,7 +17,8 @@ function Line({ points }: Readonly<LineProps>) {
const plane = useMemo(() => new THREE.Plane(new THREE.Vector3(0, 1, 0), 0), []);
const [isDeletable, setIsDeletable] = useState(false);
const { toolMode } = useToolMode();
const { removeWallByPoints, setPosition } = useWallStore();
const { wallStore } = useSceneContext();
const { removeWallByPoints, setPosition } = wallStore();
const [dragOffset, setDragOffset] = useState<THREE.Vector3 | null>(null);
const { hoveredLine, setHoveredLine, hoveredPoint } = useBuilderStore();
@@ -79,6 +80,7 @@ function Line({ points }: Readonly<LineProps>) {
if (toolMode === '2D-Delete') {
if (points[0].pointType === 'Wall' && points[1].pointType === 'Wall') {
removeWallByPoints(points);
setHoveredLine(null);
}
gl.domElement.style.cursor = 'default';
}

View File

@@ -1,6 +1,5 @@
import * as THREE from 'three';
import { useCallback } from 'react';
import { useWallStore } from '../../../../store/builder/useWallStore';
import { useSceneContext } from '../../../scene/sceneContext';
const POINT_SNAP_THRESHOLD = 0.5; // Distance threshold for snapping in meters
@@ -12,9 +11,9 @@ const ANGLE_SNAP_DISTANCE_THRESHOLD = 0.5; // Distance threshold for snapping i
const CAN_ANGLE_SNAP = true; // Whether snapping is enabled or not
export const usePointSnapping = (currentPoint: { uuid: string, pointType: string, position: [number, number, number] } | null) => {
const { aisleStore } = useSceneContext();
const { aisleStore, wallStore } = useSceneContext();
const { aisles, getConnectedPoints: getConnectedAislePoints } = aisleStore();
const { walls, getConnectedPoints: getConnectedWallPoints } = useWallStore();
const { walls, getConnectedPoints: getConnectedWallPoints } = wallStore();
// Wall Snapping

View File

@@ -6,7 +6,6 @@ import { DragControls } from '@react-three/drei';
import { useThree } from '@react-three/fiber';
import { useBuilderStore } from '../../../store/builder/useBuilderStore';
import { usePointSnapping } from './helpers/usePointSnapping';
import { useWallStore } from '../../../store/builder/useWallStore';
import { deleteAisleApi } from '../../../services/factoryBuilder/aisle/deleteAisleApi';
import { useParams } from 'react-router-dom';
import { createAisleApi } from '../../../services/factoryBuilder/aisle/createAisleApi';
@@ -20,9 +19,9 @@ function Point({ point }: { readonly point: Point }) {
const [isHovered, setIsHovered] = useState(false);
const [dragOffset, setDragOffset] = useState<THREE.Vector3 | null>(null);
const { toolMode } = useToolMode();
const { aisleStore } = useSceneContext();
const { aisleStore, wallStore } = useSceneContext();
const { setPosition: setAislePosition, removePoint: removeAislePoint, getAislesByPointId } = aisleStore();
const { setPosition: setWallPosition, removePoint: removeWallPoint } = useWallStore();
const { setPosition: setWallPosition, removePoint: removeWallPoint } = wallStore();
const { snapAislePoint, snapAisleAngle, snapWallPoint, snapWallAngle } = usePointSnapping({ uuid: point.pointUuid, pointType: point.pointType, position: point.position });
const { hoveredPoint, setHoveredPoint } = useBuilderStore();
const { selectedVersionStore } = useVersionContext();
@@ -31,6 +30,10 @@ function Point({ point }: { readonly point: Point }) {
const boxScale: [number, number, number] = Constants.pointConfig.boxScale;
const colors = getColor(point);
useEffect(() => {
gl.domElement.style.cursor = 'default';
}, [toolMode])
function getColor(point: Point) {
if (point.pointType === 'Aisle') {
return {

View File

@@ -1,18 +1,25 @@
import * as THREE from 'three';
import { Base } from '@react-three/csg';
import { useMemo, useRef, useState } from 'react';
import * as Constants from '../../../../../types/world/worldConstants';
import { Decal, MeshDiscardMaterial } from '@react-three/drei';
import { useFrame, useThree } from '@react-three/fiber';
import defaultMaterial from '../../../../../assets/textures/floor/wall-tex.png';
import material1 from '../../../../../assets/textures/floor/factory wall texture.jpg';
import { useWallStore } from '../../../../../store/builder/useWallStore';
import useModuleStore from '../../../../../store/useModuleStore';
import { useSceneContext } from '../../../../scene/sceneContext';
import { useWallClassification } from './helpers/useWallClassification';
import { useFrame, useThree } from '@react-three/fiber';
import { useWallVisibility } from '../../../../../store/builder/store';
import { Decal } from '@react-three/drei';
import { Base } from '@react-three/csg';
import { useToggleView, useWallVisibility } from '../../../../../store/builder/store';
import { useBuilderStore } from '../../../../../store/builder/useBuilderStore';
import * as Constants from '../../../../../types/world/worldConstants';
function Wall({ wall }: { readonly wall: Wall }) {
const { walls } = useWallStore();
const { wallStore } = useSceneContext();
const { walls } = wallStore();
const { togglView } = useToggleView();
const { setSelectedWall } = useBuilderStore();
const { activeModule } = useModuleStore();
const { camera } = useThree();
const { wallVisibility } = useWallVisibility();
const { getWallType, isWallFlipped } = useWallClassification(walls);
@@ -67,7 +74,7 @@ function Wall({ wall }: { readonly wall: Wall }) {
new THREE.MeshStandardMaterial({
color: Constants.wallConfig.defaultColor,
side: THREE.DoubleSide,
map: wall.outsideMaterial === 'Default Material`' ? defaultWallTexture : material1WallTexture,
map: wall.outsideMaterial === 'Default Material' ? defaultWallTexture : material1WallTexture,
}),
];
}, [defaultWallTexture, material1WallTexture, wall]);
@@ -100,6 +107,7 @@ function Wall({ wall }: { readonly wall: Wall }) {
geometry={geometry}
position={[centerX, centerY, centerZ]}
rotation={[0, -angle, 0]}
userData={wall}
>
{materials.map((material, index) => (
<primitive key={index} visible={visible} object={material} attach={`material-${index}`} />
@@ -112,6 +120,7 @@ function Wall({ wall }: { readonly wall: Wall }) {
position={[decal.decalPosition[0], decal.decalPosition[1], wall.wallThickness / 2]}
rotation={[0, 0, decal.decalRotation]}
scale={[decal.decalScale, decal.decalScale, 0.001]}
userData={decal}
>
<meshBasicMaterial
map={material1WallTexture}
@@ -123,6 +132,22 @@ function Wall({ wall }: { readonly wall: Wall }) {
)
})}
</Base>
<mesh
castShadow
geometry={geometry}
position={[centerX, centerY, centerZ]}
rotation={[0, -angle, 0]}
userData={wall}
name={`WallRaycastReference_${wall.wallUuid}`}
onClick={(e) => {
if (visible && !togglView && activeModule === 'builder') {
setSelectedWall(e.object)
}
}}
onPointerMissed={() => { setSelectedWall(null) }}
>
<MeshDiscardMaterial />
</mesh>
</mesh>
);
}

View File

@@ -2,9 +2,10 @@ import React, { useEffect, useMemo } from 'react';
import { DoubleSide, RepeatWrapping, Shape, SRGBColorSpace, TextureLoader, Vector2, Vector3 } from 'three';
import { Geometry } from '@react-three/csg';
import { Html, Extrude } from '@react-three/drei';
import { useWallStore } from '../../../../store/builder/useWallStore'
import { useWallClassification } from './instance/helpers/useWallClassification';
import { useLoader } from '@react-three/fiber';
import { useSceneContext } from '../../../scene/sceneContext';
import { useToggleView } from '../../../../store/builder/store';
import { useWallClassification } from './instance/helpers/useWallClassification';
import Line from '../../line/line';
import Point from '../../point/point';
import WallInstance from './instance/wallInstance';
@@ -12,10 +13,10 @@ import * as Constants from '../../../../types/world/worldConstants';
import texturePath from "../../../../assets/textures/floor/white.png";
import texturePathDark from "../../../../assets/textures/floor/black.png";
import { useLoader } from '@react-three/fiber';
function WallInstances() {
const { walls } = useWallStore();
const { wallStore } = useSceneContext();
const { walls } = wallStore();
const { rooms } = useWallClassification(walls)
const { toggleView } = useToggleView();

View File

@@ -3,7 +3,7 @@ import { useEffect, useMemo, useRef, useState } from 'react'
import { useThree } from '@react-three/fiber';
import { useActiveLayer, useSocketStore, useToggleView, useToolMode } from '../../../../store/builder/store';
import * as Constants from '../../../../types/world/worldConstants';
import { useWallStore } from '../../../../store/builder/useWallStore';
import { useSceneContext } from '../../../scene/sceneContext';
import { useBuilderStore } from '../../../../store/builder/useBuilderStore';
import ReferencePoint from '../../point/reference/referencePoint';
import ReferenceWall from './referenceWall';
@@ -16,7 +16,8 @@ function WallCreator() {
const { toolMode } = useToolMode();
const { activeLayer } = useActiveLayer();
const { socket } = useSocketStore();
const { addWall, getWallPointById, removeWall, getWallByPoints } = useWallStore();
const { wallStore } = useSceneContext();
const { addWall, getWallPointById, removeWall, getWallByPoints } = wallStore();
const drag = useRef(false);
const isLeftMouseDown = useRef(false);
const { wallThickness, wallHeight, insideMaterial, outsideMaterial, snappedPosition, snappedPoint } = useBuilderStore();

View File

@@ -1,7 +1,21 @@
import { useEffect } from 'react';
import { useToggleView } from '../../../store/builder/store'
import { useBuilderStore } from '../../../store/builder/useBuilderStore';
import WallCreator from './wallCreator/wallCreator'
import WallInstances from './Instances/wallInstances'
import useModuleStore from '../../../store/useModuleStore';
function WallGroup() {
const { togglView } = useToggleView();
const { setSelectedWall } = useBuilderStore();
const { activeModule } = useModuleStore();
useEffect(() => {
if (togglView || activeModule !== 'builder') {
setSelectedWall(null);
}
}, [togglView, activeModule])
return (
<>

View File

@@ -15,7 +15,7 @@ export default function PostProcessing() {
const { selectedWallItem } = useSelectedWallItem();
const { selectedFloorItem } = useSelectedFloorItem();
const { selectedEventSphere } = useSelectedEventSphere();
const { selectedAisle } = useBuilderStore();
const { selectedAisle, selectedWall } = useBuilderStore();
function flattenChildren(children: any[]) {
const allChildren: any[] = [];
@@ -40,6 +40,10 @@ export default function PostProcessing() {
// console.log('selectedAisle: ', selectedAisle);
}, [selectedAisle])
useEffect(() => {
// console.log('selectedWall: ', selectedWall);
}, [selectedWall])
return (
<EffectComposer autoClear={false}>
<N8AO
@@ -66,6 +70,21 @@ export default function PostProcessing() {
xRay={false}
/>
)}
{selectedWall && (
<Outline
selection={selectedWall}
selectionLayer={10}
width={2000}
blendFunction={BlendFunction.ALPHA}
edgeStrength={5}
resolutionScale={2}
pulseSpeed={0}
visibleEdgeColor={CONSTANTS.outlineConfig.assetSelectColor}
hiddenEdgeColor={CONSTANTS.outlineConfig.assetSelectColor}
blur={true}
xRay={true}
/>
)}
{deletableFloorItem && (
<Outline
selection={flattenChildren(deletableFloorItem.children)}

View File

@@ -1,7 +1,11 @@
import { createContext, useContext, useMemo } from 'react';
import { createAssetStore, AssetStoreType } from '../../store/builder/useAssetStore';
import { createWallAssetStore, WallAssetStoreType } from '../../store/builder/useWallAssetStore';
import { createWallStore, WallStoreType } from '../../store/builder/useWallStore';
import { createAisleStore, AisleStoreType } from '../../store/builder/useAisleStore';
import { createZoneStore, ZoneStoreType } from '../../store/builder/useZoneStore';
import { createFloorStore, FloorStoreType } from '../../store/builder/useFloorStore';
import { createEventStore, EventStoreType } from '../../store/simulation/useEventsStore';
import { createProductStore, ProductStoreType } from '../../store/simulation/useProductStore';
@@ -16,7 +20,11 @@ import { createStorageUnitStore, StorageUnitStoreType } from '../../store/simula
type SceneContextValue = {
assetStore: AssetStoreType,
wallAssetStore: WallAssetStoreType,
wallStore: WallStoreType,
aisleStore: AisleStoreType,
zoneStore: ZoneStoreType,
floorStore: FloorStoreType,
eventStore: EventStoreType,
productStore: ProductStoreType,
@@ -44,7 +52,11 @@ export function SceneProvider({
}) {
const assetStore = useMemo(() => createAssetStore(), []);
const wallAssetStore = useMemo(() => createWallAssetStore(), []);
const wallStore = useMemo(() => createWallStore(), []);
const aisleStore = useMemo(() => createAisleStore(), []);
const zoneStore = useMemo(() => createZoneStore(), []);
const floorStore = useMemo(() => createFloorStore(), []);
const eventStore = useMemo(() => createEventStore(), []);
const productStore = useMemo(() => createProductStore(), []);
@@ -58,7 +70,11 @@ export function SceneProvider({
const clearStores = useMemo(() => () => {
assetStore.getState().clearAssets();
wallAssetStore.getState().clearWallAssets();
wallStore.getState().clearWalls();
aisleStore.getState().clearAisles();
zoneStore.getState().clearZones();
floorStore.getState().clearFloors();
eventStore.getState().clearEvents();
productStore.getState().clearProducts();
materialStore.getState().clearMaterials();
@@ -67,12 +83,16 @@ export function SceneProvider({
conveyorStore.getState().clearConveyors();
vehicleStore.getState().clearVehicles();
storageUnitStore.getState().clearStorageUnits();
}, [assetStore, aisleStore, eventStore, productStore, materialStore, armBotStore, machineStore, conveyorStore, vehicleStore, storageUnitStore]);
}, [assetStore, wallAssetStore, wallStore, aisleStore, zoneStore, floorStore, eventStore, productStore, materialStore, armBotStore, machineStore, conveyorStore, vehicleStore, storageUnitStore]);
const contextValue = useMemo(() => (
{
assetStore,
wallAssetStore,
wallStore,
aisleStore,
zoneStore,
floorStore,
eventStore,
productStore,
materialStore,
@@ -84,7 +104,7 @@ export function SceneProvider({
clearStores,
layout
}
), [assetStore, aisleStore, eventStore, productStore, materialStore, armBotStore, machineStore, conveyorStore, vehicleStore, storageUnitStore, clearStores, layout]);
), [assetStore, wallAssetStore, wallStore, aisleStore, zoneStore, floorStore, eventStore, productStore, materialStore, armBotStore, machineStore, conveyorStore, vehicleStore, storageUnitStore, clearStores, layout]);
return (
<SceneContext.Provider value={contextValue}>