Refactor asset model handling and event data management

- Removed redundant data structure in handleModelLoad function.
- Introduced eventData object to encapsulate event-related information for different asset types (Conveyor, Vehicle, ArmBot, StaticMachine).
- Updated socket emission to include complete data with eventData.
- Enhanced copy-paste and duplication controls to maintain eventData integrity during object duplication.
- Integrated event data updates in move and rotate controls to reflect changes in the simulation state.
- Improved PointsCreator component to handle rotation for event groups.
- Updated handleAddEventToProduct function to support event data management.
- Enhanced product management to fetch existing products from the server and handle new product creation.
- Added new types for eventData in worldTypes and simulationTypes for better type safety.
- Refactored IndexedDB utility functions for cleaner code.
This commit is contained in:
2025-04-29 19:15:17 +05:30
parent ea53af62c4
commit 882c81a385
22 changed files with 1379 additions and 1209 deletions

View File

@@ -62,7 +62,7 @@ function PointsCreator() {
{events.map((event, i) => {
if (event.type === 'transfer') {
return (
<group key={i} position={new THREE.Vector3(...event.position)}>
<group key={i} position={[...event.position]} rotation={[...event.rotation]} >
{event.points.map((point, j) => (
<mesh
name='Event-Sphere'
@@ -78,6 +78,7 @@ function PointsCreator() {
}}
key={`${i}-${j}`}
position={new THREE.Vector3(...point.position)}
// rotation={new THREE.Euler(...point.rotation)}
userData={{ modelUuid: event.modelUuid, pointUuid: point.uuid }}
>
<sphereGeometry args={[0.1, 16, 16]} />
@@ -88,7 +89,7 @@ function PointsCreator() {
);
} else if (event.type === 'vehicle') {
return (
<group key={i} position={new THREE.Vector3(...event.position)}>
<group key={i} position={[...event.position]} rotation={[...event.rotation]} >
<mesh
name='Event-Sphere'
uuid={event.point.uuid}
@@ -102,6 +103,7 @@ function PointsCreator() {
setTransformMode(null);
}}
position={new THREE.Vector3(...event.point.position)}
// rotation={new THREE.Euler(...event.point.rotation)}
userData={{ modelUuid: event.modelUuid, pointUuid: event.point.uuid }}
>
<sphereGeometry args={[0.1, 16, 16]} />
@@ -111,7 +113,7 @@ function PointsCreator() {
);
} else if (event.type === 'roboticArm') {
return (
<group key={i} position={new THREE.Vector3(...event.position)}>
<group key={i} position={[...event.position]} rotation={[...event.rotation]} >
<mesh
name='Event-Sphere'
uuid={event.point.uuid}
@@ -125,6 +127,7 @@ function PointsCreator() {
setTransformMode(null);
}}
position={new THREE.Vector3(...event.point.position)}
// rotation={new THREE.Euler(...event.point.rotation)}
userData={{ modelUuid: event.modelUuid, pointUuid: event.point.uuid }}
>
<sphereGeometry args={[0.1, 16, 16]} />
@@ -134,7 +137,7 @@ function PointsCreator() {
);
} else if (event.type === 'machine') {
return (
<group key={i} position={new THREE.Vector3(...event.position)}>
<group key={i} position={[...event.position]} rotation={[...event.rotation]} >
<mesh
name='Event-Sphere'
uuid={event.point.uuid}
@@ -148,6 +151,7 @@ function PointsCreator() {
setTransformMode(null);
}}
position={new THREE.Vector3(...event.point.position)}
// rotation={new THREE.Euler(...event.point.rotation)}
userData={{ modelUuid: event.modelUuid, pointUuid: event.point.uuid }}
>
<sphereGeometry args={[0.1, 16, 16]} />

View File

@@ -1,28 +1,38 @@
import { upsertProductOrEventApi } from "../../../../../services/simulation/UpsertProductOrEventApi";
interface HandleAddEventToProductParams {
selectedAsset: any; // Replace `any` with specific type if you have it
addEvent: (productId: string, asset: any) => void;
event: EventsSchema | undefined;
addEvent: (productId: string, event: EventsSchema) => void;
selectedProduct: {
productId: string;
productName: string;
// Add other fields if needed
};
clearSelectedAsset: () => void;
}
clearSelectedAsset?: () => void;
}
export const handleAddEventToProduct = ({
selectedAsset,
event,
addEvent,
selectedProduct,
clearSelectedAsset,
clearSelectedAsset
}: HandleAddEventToProductParams) => {
console.log('selectedProduct: ', selectedProduct);
if (selectedAsset) {
addEvent(selectedProduct.productId, selectedAsset);
// upsertProductOrEventApi({
// productName: selectedProduct.productName,
// productId: selectedProduct.productId,
// eventDatas: selectedAsset
// });
clearSelectedAsset();
if (event && selectedProduct.productId) {
addEvent(selectedProduct.productId, event);
const email = localStorage.getItem('email')
const organization = (email!.split("@")[1]).split(".")[0];
upsertProductOrEventApi({
productName: selectedProduct.productName,
productId: selectedProduct.productId,
organization: organization,
eventDatas: event
}).then((data) => {
// console.log(data);
})
if (clearSelectedAsset) {
clearSelectedAsset();
}
}
};

View File

@@ -7,28 +7,27 @@ import { upsertProductOrEventApi } from '../../../services/simulation/UpsertProd
import { getAllProductsApi } from '../../../services/simulation/getallProductsApi';
function Products() {
const { products, addProduct } = useProductStore();
const { products, addProduct, setProducts } = useProductStore();
const { setSelectedProduct } = useSelectedProduct();
useEffect(() => {
if (products.length === 0) {
const id = THREE.MathUtils.generateUUID();
const name = 'Product 1';
addProduct(name, id);
// upsertProductOrEventApi({ productName: name, productId: id }).then((data) => {
// console.log('data: ', data);
// });
setSelectedProduct(id, name);
}
}, [products])
const email = localStorage.getItem('email')
const organization = (email!.split("@")[1]).split(".")[0];
getAllProductsApi(organization).then((data) => {
if (data.length === 0) {
const id = THREE.MathUtils.generateUUID();
const name = 'Product 1';
addProduct(name, id);
upsertProductOrEventApi({ productName: name, productId: id, organization: organization })
setSelectedProduct(id, name);
} else {
setProducts(data);
setSelectedProduct(data[0].productId, data[0].productName);
}
})
}, [])
useEffect(() => {
// const email = localStorage.getItem('email')
// const organization = (email!.split("@")[1]).split(".")[0];
// console.log(organization);
// getAllProductsApi(organization).then((data) => {
// console.log('data: ', data);
// })
}, [])
return (

View File

@@ -19,11 +19,11 @@ function Simulation() {
const { products } = useProductStore();
useEffect(() => {
// console.log('events: ', events);
console.log('events: ', events);
}, [events])
useEffect(() => {
// console.log('products: ', products);
console.log('products: ', products);
}, [products])
return (

View File

@@ -1,19 +1,85 @@
import { useEffect } from "react";
import { useEffect, useRef, useState } from "react";
import { useThree } from "@react-three/fiber";
import * as THREE from "three";
import { useSubModuleStore } from "../../../../store/useModuleStore";
import { useSelectedAsset } from "../../../../store/simulation/useSimulationStore";
import { useProductStore } from "../../../../store/simulation/useProductStore";
import { useEventsStore } from "../../../../store/simulation/useEventsStore";
import { useSelectedProduct } from "../../../../store/simulation/useSimulationStore";
import { handleAddEventToProduct } from "../../events/points/functions/handleAddEventToProduct";
interface ConnectionLine {
id: string;
start: THREE.Vector3;
end: THREE.Vector3;
mid: THREE.Vector3;
trigger: TriggerSchema;
}
function TriggerConnector() {
const { gl, raycaster, scene } = useThree();
const { subModule } = useSubModuleStore();
const { getPointByUuid, getIsEventInProduct } = useProductStore();
const { products, getPointByUuid, getIsEventInProduct, getActionByUuid, addTrigger, addEvent, getEventByModelUuid } = useProductStore();
const { selectedAsset, clearSelectedAsset } = useSelectedAsset();
const { selectedProduct } = useSelectedProduct();
useEffect(() => {
const [firstSelectedPoint, setFirstSelectedPoint] = useState<{
productId: string;
modelUuid: string;
pointUuid: string;
actionUuid?: string;
} | null>(null);
const [connections, setConnections] = useState<ConnectionLine[]>([]);
useEffect(() => {
const newConnections: ConnectionLine[] = [];
products.forEach(product => {
product.eventDatas.forEach(event => {
if ('points' in event) {
event.points.forEach(point => {
if ('action' in point && point.action?.triggers) {
point.action.triggers.forEach(trigger => {
if (trigger.triggeredAsset) {
const targetPoint = getPointByUuid(
product.productId,
trigger.triggeredAsset.triggeredModel.modelUuid,
trigger.triggeredAsset.triggeredPoint.pointUuid
);
if (targetPoint) {
const startPos = new THREE.Vector3(...point.position);
const endPos = new THREE.Vector3(...targetPoint.position);
const midPos = new THREE.Vector3()
.addVectors(startPos, endPos)
.multiplyScalar(0.5)
.add(new THREE.Vector3(0, 2, 0));
newConnections.push({
id: `${point.uuid}-${targetPoint.uuid}-${trigger.triggerUuid}`,
start: startPos,
end: endPos,
mid: midPos,
trigger
});
}
}
});
}
});
}
});
});
setConnections(newConnections);
}, [products]);
useEffect(() => {
console.log('connections: ', connections);
}, connections)
useEffect(() => {
const canvasElement = gl.domElement;
let drag = false;
@@ -44,37 +110,114 @@ function TriggerConnector() {
const handleRightClick = (evt: MouseEvent) => {
if (drag) return;
evt.preventDefault();
const canvasElement = gl.domElement;
if (!canvasElement) return;
let intersects = raycaster.intersectObjects(scene.children, true);
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;
const intersects = raycaster.intersectObjects(scene.children, true);
if (intersects.length === 0) return;
if (currentObject && currentObject.name === 'Event-Sphere') {
const currentObject = intersects[0].object;
if (!currentObject || currentObject.name !== 'Event-Sphere') return;
const isInProduct = getIsEventInProduct(
selectedProduct.productId,
currentObject.userData.modelUuid
);
const modelUuid = currentObject.userData.modelUuid;
const pointUuid = currentObject.userData.pointUuid;
// You left Here
if (selectedProduct && getIsEventInProduct(selectedProduct.productId, modelUuid)) {
if (isInProduct) {
const point = getPointByUuid(
selectedProduct.productId,
modelUuid,
pointUuid
);
const event = getPointByUuid(
selectedProduct.productId,
currentObject.userData.modelUuid,
currentObject.userData.pointUuid
);
console.log('event: ', event);
} else {
if (!point) return;
}
let actionUuid: string | undefined;
if ('action' in point && point.action) {
actionUuid = point.action.actionUuid;
} else if ('actions' in point && point.actions.length === 1) {
actionUuid = point.actions[0].actionUuid;
}
} else {
if (!firstSelectedPoint) {
setFirstSelectedPoint({
productId: selectedProduct.productId,
modelUuid,
pointUuid,
actionUuid
});
} else {
const trigger: TriggerSchema = {
triggerUuid: THREE.MathUtils.generateUUID(),
triggerName: `Trigger ${firstSelectedPoint.pointUuid.slice(0, 4)}${pointUuid.slice(0, 4)}`,
triggerType: "onComplete",
delay: 0,
triggeredAsset: {
triggeredModel: {
modelName: currentObject.parent?.parent?.name || 'Unknown',
modelUuid: modelUuid
},
triggeredPoint: {
pointName: currentObject.name,
pointUuid: pointUuid
},
triggeredAction: actionUuid ? {
actionName: getActionByUuid(selectedProduct.productId, actionUuid)?.actionName || 'Action',
actionUuid: actionUuid
} : null
}
};
if (firstSelectedPoint.actionUuid) {
addTrigger(firstSelectedPoint.actionUuid, trigger);
}
setFirstSelectedPoint(null);
}
} else if (!getIsEventInProduct(selectedProduct.productId, modelUuid) && firstSelectedPoint) {
handleAddEventToProduct({
event: useEventsStore.getState().getEventByModelUuid(modelUuid),
addEvent,
selectedProduct,
})
const point = getPointByUuid(
selectedProduct.productId,
modelUuid,
pointUuid
);
if (!point) return;
let actionUuid: string | undefined;
if ('action' in point && point.action) {
actionUuid = point.action.actionUuid;
} else if ('actions' in point && point.actions.length === 1) {
actionUuid = point.actions[0].actionUuid;
}
const trigger: TriggerSchema = {
triggerUuid: THREE.MathUtils.generateUUID(),
triggerName: `Trigger ${firstSelectedPoint.pointUuid.slice(0, 4)}${pointUuid.slice(0, 4)}`,
triggerType: "onComplete",
delay: 0,
triggeredAsset: {
triggeredModel: {
modelName: currentObject.parent?.parent?.name || 'Unknown',
modelUuid: modelUuid
},
triggeredPoint: {
pointName: currentObject.name,
pointUuid: pointUuid
},
triggeredAction: actionUuid ? {
actionName: getActionByUuid(selectedProduct.productId, actionUuid)?.actionName || 'Action',
actionUuid: actionUuid
} : null
}
};
if (firstSelectedPoint.actionUuid) {
addTrigger(firstSelectedPoint.actionUuid, trigger);
}
setFirstSelectedPoint(null);
}
};
@@ -92,12 +235,12 @@ function TriggerConnector() {
canvasElement.removeEventListener('contextmenu', handleRightClick);
};
}, [gl, subModule]);
}, [gl, subModule, selectedProduct, firstSelectedPoint]);
return (
<>
</>
)
);
}
export default TriggerConnector
export default TriggerConnector;