diff --git a/app/src/modules/builder/floor/Instances/Instance/floorInstance.tsx b/app/src/modules/builder/floor/Instances/Instance/floorInstance.tsx
index 1b6dcb7..6c9016e 100644
--- a/app/src/modules/builder/floor/Instances/Instance/floorInstance.tsx
+++ b/app/src/modules/builder/floor/Instances/Instance/floorInstance.tsx
@@ -1,10 +1,33 @@
-import React from 'react'
+import { useMemo } from 'react'
+import { Shape, Vector2, DoubleSide } from 'three';
+import { useLoader } from '@react-three/fiber';
+import { Extrude } from '@react-three/drei';
+import * as Constants from '../../../../../types/world/worldConstants';
function FloorInstance({ floor }: { floor: Floor }) {
+
+ const shape = useMemo(() => {
+ const shape = new Shape();
+ const points = floor.points.map(p => new Vector2(p.position[0], p.position[2]));
+ if (points.length < 3) return null;
+ shape.moveTo(points[0].x, points[0].y);
+ points.forEach((pt) => { shape.lineTo(pt.x, pt.y); });
+ return shape;
+ }, [floor]);
+
+ if (!shape) return null;
+
return (
- <>
- >
- )
+
+
+
+
+
+ );
}
export default FloorInstance
\ No newline at end of file
diff --git a/app/src/modules/builder/floor/Instances/floorInstances.tsx b/app/src/modules/builder/floor/Instances/floorInstances.tsx
index 75fd359..a5969eb 100644
--- a/app/src/modules/builder/floor/Instances/floorInstances.tsx
+++ b/app/src/modules/builder/floor/Instances/floorInstances.tsx
@@ -34,6 +34,7 @@ function FloorInstances() {
const allLines = useMemo(() => {
const lines: { start: Point; end: Point; key: string }[] = [];
+ const seenUuids = new Set();
floors.forEach((floor) => {
const points = floor.points;
@@ -42,11 +43,13 @@ function FloorInstances() {
for (let i = 0; i < points.length; i++) {
const current = points[i];
const next = points[(i + 1) % points.length];
- if (current.pointUuid !== next.pointUuid) {
+ const lineKey = `${current.pointUuid}-${next.pointUuid}`;
+ if (current.pointUuid !== next.pointUuid && !seenUuids.has(lineKey)) {
+ seenUuids.add(lineKey);
lines.push({
start: current,
end: next,
- key: `${current.pointUuid}-${next.pointUuid}`
+ key: lineKey
});
}
}
@@ -58,7 +61,7 @@ function FloorInstances() {
return (
<>
- {!toggleView && floors.length > 1 && (
+ {!toggleView && floors.length > 0 && (
{floors.map((floor) => (
diff --git a/app/src/modules/builder/floor/floorCreator/floorCreator.tsx b/app/src/modules/builder/floor/floorCreator/floorCreator.tsx
index 2d09ff9..aaeb0f3 100644
--- a/app/src/modules/builder/floor/floorCreator/floorCreator.tsx
+++ b/app/src/modules/builder/floor/floorCreator/floorCreator.tsx
@@ -4,9 +4,14 @@ import { useThree } from '@react-three/fiber';
import { useActiveLayer, useSocketStore, useToggleView, useToolMode } from '../../../../store/builder/store';
import { useSceneContext } from '../../../scene/sceneContext';
import { useBuilderStore } from '../../../../store/builder/useBuilderStore';
+import { useParams } from 'react-router-dom';
+import { useVersionContext } from '../../version/versionContext';
+import { getUserData } from '../../../../functions/getUserData';
import ReferencePoint from '../../point/reference/referencePoint';
import ReferenceFloor from './referenceFloor';
+// import { upsertFloorApi } from '../../../../services/factoryBuilder/floor/upsertFloorApi';
+
function FloorCreator() {
const { scene, camera, raycaster, gl, pointer } = useThree();
const plane = useMemo(() => new THREE.Plane(new THREE.Vector3(0, 1, 0), 0), []);
@@ -15,9 +20,13 @@ function FloorCreator() {
const { activeLayer } = useActiveLayer();
const { socket } = useSocketStore();
const { floorStore } = useSceneContext();
- const { addFloor, removeDecal, getFloorPointById, getFloorByPoints } = floorStore();
+ const { addFloor, getFloorPointById, getFloorByPoints } = floorStore();
const drag = useRef(false);
const isLeftMouseDown = useRef(false);
+ const { selectedVersionStore } = useVersionContext();
+ const { selectedVersion } = selectedVersionStore();
+ const { userId, organization } = getUserData();
+ const { projectId } = useParams();
const [tempPoints, setTempPoints] = useState([]);
const [isCreating, setIsCreating] = useState(false);
@@ -94,14 +103,33 @@ function FloorCreator() {
};
addFloor(floor);
+ if (projectId) {
+
+ // API
+
+ // upsertFloorApi(projectId, selectedVersion?.versionId || '', floor);
+
+ // SOCKET
+
+ const data = {
+ floorData: floor,
+ projectId: projectId,
+ versionId: selectedVersion?.versionId || '',
+ userId: userId,
+ organization: organization
+ }
+
+ socket.emit('v1:model-Floor:add', data);
+
+ }
setTempPoints([]);
setIsCreating(false);
- } else if (tempPoints.length === 0) {
+ } else if (tempPoints.length === 0 || (tempPoints.length > 1 && pointIntersects.object.uuid !== tempPoints[tempPoints.length - 2].pointUuid)) {
tempPoints.push(pointIntersects.object.userData as Point);
setIsCreating(true);
} else {
- setTempPoints([]);
- setIsCreating(false);
+ tempPoints.push(pointIntersects.object.userData as Point);
+ setIsCreating(true);
}
} else {
setTempPoints(prev => [...prev, newPoint]);
@@ -126,6 +154,25 @@ function FloorCreator() {
};
addFloor(floor);
+ if (projectId) {
+
+ // API
+
+ // upsertFloorApi(projectId, selectedVersion?.versionId || '', floor);
+
+ // SOCKET
+
+ const data = {
+ floorData: floor,
+ projectId: projectId,
+ versionId: selectedVersion?.versionId || '',
+ userId: userId,
+ organization: organization
+ }
+
+ socket.emit('v1:model-Floor:add', data);
+
+ }
}
setTempPoints([]);
setIsCreating(false);
@@ -155,7 +202,7 @@ function FloorCreator() {
canvasElement.removeEventListener("click", onMouseClick);
canvasElement.removeEventListener("contextmenu", onContext);
};
- }, [gl, camera, scene, raycaster, pointer, plane, toggleView, toolMode, activeLayer, socket, tempPoints, isCreating, addFloor, removeDecal, getFloorPointById, getFloorByPoints, floorDepth, isBeveled, bevelStrength, sideMaterial, topMaterial, snappedPosition, snappedPoint]);
+ }, [gl, camera, scene, raycaster, pointer, plane, toggleView, toolMode, activeLayer, socket, tempPoints, isCreating, addFloor, getFloorPointById, getFloorByPoints, floorDepth, isBeveled, bevelStrength, sideMaterial, topMaterial, snappedPosition, snappedPoint]);
return (
<>
diff --git a/app/src/modules/builder/floor/floorGroup.tsx b/app/src/modules/builder/floor/floorGroup.tsx
index fdcf37c..53a81f4 100644
--- a/app/src/modules/builder/floor/floorGroup.tsx
+++ b/app/src/modules/builder/floor/floorGroup.tsx
@@ -1,14 +1,23 @@
import { useEffect } from 'react';
import { useToggleView } from '../../../store/builder/store'
import { useBuilderStore } from '../../../store/builder/useBuilderStore';
+import { useVersionContext } from '../version/versionContext';
+import { useSceneContext } from '../../scene/sceneContext';
+import { useParams } from 'react-router-dom';
+import useModuleStore from '../../../store/useModuleStore';
import FloorCreator from './floorCreator/floorCreator';
import FloorInstances from './Instances/floorInstances';
-import useModuleStore from '../../../store/useModuleStore';
+import { getFloorsApi } from '../../../services/factoryBuilder/floor/getFloorsApi';
function FloorGroup() {
const { togglView } = useToggleView();
const { setSelectedFloor, setSelectedDecal } = useBuilderStore();
const { activeModule } = useModuleStore();
+ const { selectedVersionStore } = useVersionContext();
+ const { selectedVersion } = selectedVersionStore();
+ const { floorStore } = useSceneContext();
+ const { setFloors } = floorStore();
+ const { projectId } = useParams();
useEffect(() => {
if (togglView || activeModule !== 'builder') {
@@ -17,6 +26,21 @@ function FloorGroup() {
}
}, [togglView, activeModule])
+ useEffect(() => {
+ if (projectId && selectedVersion) {
+ getFloorsApi(projectId, selectedVersion?.versionId || '').then((floors) => {
+ console.log('floors: ', floors);
+ if (floors && floors.length > 0) {
+ setFloors(floors);
+ } else {
+ setFloors([]);
+ }
+ }).catch((err) => {
+ console.log(err);
+ })
+ }
+ }, [projectId, selectedVersion?.versionId])
+
return (
<>
diff --git a/app/src/modules/builder/line/line.tsx b/app/src/modules/builder/line/line.tsx
index 42aa5c2..f75be5d 100644
--- a/app/src/modules/builder/line/line.tsx
+++ b/app/src/modules/builder/line/line.tsx
@@ -6,12 +6,15 @@ import { useSocketStore, useToolMode } from '../../../store/builder/store';
import { useBuilderStore } from '../../../store/builder/useBuilderStore';
import { useSceneContext } from '../../scene/sceneContext';
import * as Constants from '../../../types/world/worldConstants';
-import { deleteWallApi } from '../../../services/factoryBuilder/wall/deleteWallApi';
import { useVersionContext } from '../version/versionContext';
import { useParams } from 'react-router-dom';
-import { upsertWallApi } from '../../../services/factoryBuilder/wall/upsertWallApi';
import { getUserData } from '../../../functions/getUserData';
+// import { upsertWallApi } from '../../../services/factoryBuilder/wall/upsertWallApi';
+// import { deleteWallApi } from '../../../services/factoryBuilder/wall/deleteWallApi';
+import { upsertFloorApi } from '../../../services/factoryBuilder/floor/upsertFloorApi';
+import { deleteFloorApi } from '../../../services/factoryBuilder/floor/deleteFloorApi';
+
interface LineProps {
points: [Point, Point];
}
@@ -25,7 +28,7 @@ function Line({ points }: Readonly) {
const { toolMode } = useToolMode();
const { wallStore, floorStore } = useSceneContext();
const { removeWallByPoints, setPosition: setWallPosition, getWallsByPointId } = wallStore();
- const { removeFloorByPoints, setPosition: setFloorPosition } = floorStore();
+ const { removeFloorByPoints, setPosition: setFloorPosition, getFloorsByPointId } = floorStore();
const { userId, organization } = getUserData();
const { selectedVersionStore } = useVersionContext();
const { selectedVersion } = selectedVersionStore();
@@ -112,7 +115,52 @@ function Line({ points }: Readonly) {
setHoveredLine(null);
}
if (points[0].pointType === 'Floor' && points[1].pointType === 'Floor') {
- removeFloorByPoints(points);
+ const { removedFloors, updatedFloors } = removeFloorByPoints(points);
+ if (removedFloors.length > 0) {
+ removedFloors.forEach(floor => {
+ if (projectId) {
+
+ // API
+
+ // deleteFloorApi(projectId, selectedVersion?.versionId || '', floor.floorUuid);
+
+ // SOCKET
+
+ const data = {
+ floorUuid: floor.floorUuid,
+ projectId: projectId,
+ versionId: selectedVersion?.versionId || '',
+ userId: userId,
+ organization: organization
+ }
+
+ socket.emit('v1:model-Floor:delete', data);
+ }
+ });
+ }
+ if (updatedFloors.length > 0) {
+ updatedFloors.forEach(floor => {
+ if (projectId) {
+
+ // API
+
+ // upsertFloorApi(projectId, selectedVersion?.versionId || '', floor);
+
+ // SOCKET
+
+ const data = {
+ floorData: floor,
+ projectId: projectId,
+ versionId: selectedVersion?.versionId || '',
+ userId: userId,
+ organization: organization
+ }
+
+ socket.emit('v1:model-Floor:add', data);
+ }
+ });
+ }
+
setHoveredLine(null);
}
gl.domElement.style.cursor = 'default';
@@ -197,7 +245,32 @@ function Line({ points }: Readonly) {
})
}
} else if (points[0].pointType === 'Floor' && points[1].pointType === 'Floor') {
- // Handle floor update logic here if needed
+ const updatedFloors1 = getFloorsByPointId(points[0].pointUuid);
+ const updatedFloors2 = getFloorsByPointId(points[1].pointUuid);
+ const updatedFloors = [...updatedFloors1, ...updatedFloors2].filter((floor, index, self) => index === self.findIndex((f) => f.floorUuid === floor.floorUuid));
+
+ if (updatedFloors.length > 0 && projectId) {
+ updatedFloors.forEach(updatedFloor => {
+
+ // API
+
+ // upsertFloorApi(projectId, selectedVersion?.versionId || '', updatedFloor).catch((error) => {
+ // console.error('Error updating floor:', error);
+ // });
+
+ // SOCKET
+
+ const data = {
+ floorData: updatedFloor,
+ projectId: projectId,
+ versionId: selectedVersion?.versionId || '',
+ userId: userId,
+ organization: organization
+ }
+
+ socket.emit('v1:model-Floor:add', data);
+ })
+ }
}
}
diff --git a/app/src/modules/builder/point/point.tsx b/app/src/modules/builder/point/point.tsx
index 504617d..fe2dd6e 100644
--- a/app/src/modules/builder/point/point.tsx
+++ b/app/src/modules/builder/point/point.tsx
@@ -14,7 +14,10 @@ import { upsertAisleApi } from '../../../services/factoryBuilder/aisle/upsertAis
import { deleteAisleApi } from '../../../services/factoryBuilder/aisle/deleteAisleApi';
// import { upsertWallApi } from '../../../services/factoryBuilder/wall/upsertWallApi';
// import { deleteWallApi } from '../../../services/factoryBuilder/wall/deleteWallApi';
+import { upsertFloorApi } from '../../../services/factoryBuilder/floor/upsertFloorApi';
+
import { getUserData } from '../../../functions/getUserData';
+import { deleteFloorApi } from '../../../services/factoryBuilder/floor/deleteFloorApi';
function Point({ point }: { readonly point: Point }) {
const materialRef = useRef(null);
@@ -27,7 +30,7 @@ function Point({ point }: { readonly point: Point }) {
const { aisleStore, wallStore, floorStore } = useSceneContext();
const { setPosition: setAislePosition, removePoint: removeAislePoint, getAislesByPointId } = aisleStore();
const { setPosition: setWallPosition, removePoint: removeWallPoint, getWallsByPointId } = wallStore();
- const { setPosition: setFloorPosition, removePoint: removeFloorPoint } = floorStore();
+ const { setPosition: setFloorPosition, removePoint: removeFloorPoint, getFloorsByPointId } = floorStore();
const { snapAislePoint, snapAisleAngle, snapWallPoint, snapWallAngle, snapFloorPoint, snapFloorAngle } = usePointSnapping({ uuid: point.pointUuid, pointType: point.pointType, position: point.position });
const { hoveredPoint, setHoveredPoint } = useBuilderStore();
const { userId, organization } = getUserData();
@@ -174,9 +177,28 @@ function Point({ point }: { readonly point: Point }) {
socket.emit('v1:model-Wall:add', data);
});
}
- // console.log('Wall after drag: ', point);
} else if (point.pointType === 'Floor') {
- // console.log('Floor after drag: ', point);
+ const updatedFloors = getFloorsByPointId(point.pointUuid);
+ if (updatedFloors && updatedFloors.length > 0 && projectId) {
+ updatedFloors.forEach((updatedFloor) => {
+
+ // API
+
+ // upsertFloorApi(projectId, selectedVersion?.versionId || '', updatedFloor);
+
+ // SOCKET
+
+ const data = {
+ floorData: updatedFloor,
+ projectId: projectId,
+ versionId: selectedVersion?.versionId || '',
+ userId: userId,
+ organization: organization
+ }
+
+ socket.emit('v1:model-Floor:add', data);
+ });
+ }
}
}
@@ -220,9 +242,51 @@ function Point({ point }: { readonly point: Point }) {
}
}
if (point.pointType === 'Floor') {
- const removedFloors = removeFloorPoint(point.pointUuid);
+ const { removedFloors, updatedFloors } = removeFloorPoint(point.pointUuid);
setHoveredPoint(null);
if (removedFloors.length > 0) {
+ removedFloors.forEach(floor => {
+ if (projectId) {
+
+ // API
+
+ // deleteFloorApi(projectId, selectedVersion?.versionId || '', floor.floorUuid);
+
+ // SOCKET
+
+ const data = {
+ floorUuid: floor.floorUuid,
+ projectId: projectId,
+ versionId: selectedVersion?.versionId || '',
+ userId: userId,
+ organization: organization
+ }
+
+ socket.emit('v1:model-Floor:delete', data);
+ }
+ });
+ }
+ if (updatedFloors.length > 0) {
+ updatedFloors.forEach(floor => {
+ if (projectId) {
+
+ // API
+
+ // upsertFloorApi(projectId, selectedVersion?.versionId || '', floor);
+
+ // SOCKET
+
+ const data = {
+ floorData: floor,
+ projectId: projectId,
+ versionId: selectedVersion?.versionId || '',
+ userId: userId,
+ organization: organization
+ }
+
+ socket.emit('v1:model-Floor:add', data);
+ }
+ });
}
}
gl.domElement.style.cursor = 'default';
diff --git a/app/src/modules/builder/wall/wallGroup.tsx b/app/src/modules/builder/wall/wallGroup.tsx
index 0722d56..bd8bad1 100644
--- a/app/src/modules/builder/wall/wallGroup.tsx
+++ b/app/src/modules/builder/wall/wallGroup.tsx
@@ -1,12 +1,13 @@
import { useEffect } from 'react';
import { useToggleView } from '../../../store/builder/store';
import { useBuilderStore } from '../../../store/builder/useBuilderStore';
+import { useVersionContext } from '../version/versionContext';
+import { useSceneContext } from '../../scene/sceneContext';
+import { useParams } from 'react-router-dom';
+import useModuleStore from '../../../store/useModuleStore';
import WallCreator from './wallCreator/wallCreator';
import WallInstances from './Instances/wallInstances';
-import useModuleStore from '../../../store/useModuleStore';
-import { useVersionContext } from '../version/versionContext';
-import { useParams } from 'react-router-dom';
-import { useSceneContext } from '../../scene/sceneContext';
+
import { getWallsApi } from '../../../services/factoryBuilder/wall/getWallsApi';
function WallGroup() {
diff --git a/app/src/services/factoryBuilder/floor/upsertFloorApi.ts b/app/src/services/factoryBuilder/floor/upsertFloorApi.ts
index a00d8f7..45590c1 100644
--- a/app/src/services/factoryBuilder/floor/upsertFloorApi.ts
+++ b/app/src/services/factoryBuilder/floor/upsertFloorApi.ts
@@ -3,7 +3,7 @@ let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_UR
export const upsertFloorApi = async (
projectId: string,
versionId: string,
- floorData: Wall
+ floorData: Floor
) => {
try {
const response = await fetch(`${url_Backend_dwinzo}/api/V1/UpsertFloor`, {
diff --git a/app/src/store/builder/useBuilderStore.ts b/app/src/store/builder/useBuilderStore.ts
index 18facd9..e35db75 100644
--- a/app/src/store/builder/useBuilderStore.ts
+++ b/app/src/store/builder/useBuilderStore.ts
@@ -97,7 +97,7 @@ export const useBuilderStore = create()(
insideMaterial: 'Material 1',
selectedFloor: null,
- floorDepth: 0.3,
+ floorDepth: 0.1,
isBeveled: false,
bevelStrength: 0.05,
sideMaterial: 'Default Side',
diff --git a/app/src/store/builder/useFloorStore.ts b/app/src/store/builder/useFloorStore.ts
index c3ddf7d..7d425eb 100644
--- a/app/src/store/builder/useFloorStore.ts
+++ b/app/src/store/builder/useFloorStore.ts
@@ -7,8 +7,8 @@ interface FloorStore {
addFloor: (floor: Floor) => void;
updateFloor: (uuid: string, updated: Partial) => void;
removeFloor: (uuid: string) => void;
- removePoint: (pointUuid: string) => Floor[];
- removeFloorByPoints: (Points: [Point, Point]) => Floor[];
+ removePoint: (pointUuid: string) => { removedFloors: Floor[], updatedFloors: Floor[] };
+ removeFloorByPoints: (Points: [Point, Point]) => { removedFloors: Floor[], updatedFloors: Floor[] };
clearFloors: () => void;
setPosition: (
pointUuid: string,
@@ -26,7 +26,7 @@ interface FloorStore {
updateDecalScale: (decalUuid: string, scale: number) => void;
getFloorById: (uuid: string) => Floor | undefined;
- getFloorsByPointId: (uuid: string) => Floor | undefined;
+ getFloorsByPointId: (uuid: string) => Floor[] | [];
getFloorByPoints: (points: Point[]) => Floor | undefined;
getFloorPointById: (uuid: string) => Point | undefined;
getConnectedPoints: (uuid: string) => Point[];
@@ -58,47 +58,46 @@ export const createFloorStore = () => {
removePoint: (pointUuid) => {
const removedFloors: Floor[] = [];
+ const updatedFloors: Floor[] = [];
set(state => {
- const updatedFloors: Floor[] = [];
-
for (const floor of state.floors) {
- const hasPoint = floor.points.some(p => p.pointUuid === pointUuid);
- if (!hasPoint) {
- updatedFloors.push(floor);
+ const pointIndex = floor.points.findIndex(p => p.pointUuid === pointUuid);
+ if (pointIndex === -1) {
+ updatedFloors.push(JSON.parse(JSON.stringify(floor)));
continue;
}
const remainingPoints = floor.points.filter(p => p.pointUuid !== pointUuid);
- if (remainingPoints.length > 2) {
- floor.points = remainingPoints;
- updatedFloors.push(floor);
- } else {
- removedFloors.push(floor);
+
+ if (remainingPoints.length <= 2) {
+ removedFloors.push(JSON.parse(JSON.stringify(floor)));
+ continue;
}
+ floor.points = remainingPoints;
+ updatedFloors.push(JSON.parse(JSON.stringify(floor)));
}
state.floors = updatedFloors;
});
- return removedFloors;
+ return { removedFloors, updatedFloors };
},
removeFloorByPoints: ([pointA, pointB]) => {
const removedFloors: Floor[] = [];
+ const updatedFloors: Floor[] = [];
set(state => {
- const updatedFloors: Floor[] = [];
for (const floor of state.floors) {
- const indices = floor.points
- .map((p, i) => ({ uuid: p.pointUuid, index: i }));
+ const indices = floor.points.map((p, i) => ({ uuid: p.pointUuid, index: i }));
const idxA = indices.find(i => i.uuid === pointA.pointUuid)?.index ?? -1;
const idxB = indices.find(i => i.uuid === pointB.pointUuid)?.index ?? -1;
if (idxA === -1 || idxB === -1) {
- updatedFloors.push(floor);
+ updatedFloors.push(JSON.parse(JSON.stringify(floor)));
continue;
}
@@ -108,7 +107,7 @@ export const createFloorStore = () => {
(idxB === 0 && idxA === floor.points.length - 1);
if (!areAdjacent) {
- updatedFloors.push(floor);
+ updatedFloors.push(JSON.parse(JSON.stringify(floor)));
continue;
}
@@ -118,16 +117,16 @@ export const createFloorStore = () => {
if (remainingPoints.length > 2) {
floor.points = remainingPoints;
- updatedFloors.push(floor);
+ updatedFloors.push(JSON.parse(JSON.stringify(floor)));
} else {
- removedFloors.push(floor);
+ removedFloors.push(JSON.parse(JSON.stringify(floor)));
}
}
state.floors = updatedFloors;
});
- return removedFloors;
+ return { removedFloors, updatedFloors };
},
clearFloors: () => set(state => {
@@ -236,9 +235,9 @@ export const createFloorStore = () => {
},
getFloorsByPointId: (pointUuid) => {
- return get().floors.find(floor =>
- floor.points.some(p => p.pointUuid === pointUuid)
- );
+ return get().floors.filter(floor => {
+ return floor.points.some(p => p.pointUuid === pointUuid);
+ });
},
getFloorByPoints: (points) => {