refactor: update VehicleMechanics to use LabledDropdown for start and end point selection; clean up unused MQTT code and improve zone data fetching logic
This commit is contained in:
@@ -1,9 +1,9 @@
|
|||||||
import React, { useRef, useMemo } from "react";
|
import React, { useRef, useMemo } from "react";
|
||||||
import { InfoIcon } from "../../../icons/ExportCommonIcons";
|
import { InfoIcon } from "../../../icons/ExportCommonIcons";
|
||||||
import InputWithDropDown from "../../../ui/inputs/InputWithDropDown";
|
import InputWithDropDown from "../../../ui/inputs/InputWithDropDown";
|
||||||
import EyeDropInput from "../../../ui/inputs/EyeDropInput";
|
|
||||||
import { useSelectedActionSphere, useSimulationPaths } from "../../../../store/store";
|
import { useSelectedActionSphere, useSimulationPaths } from "../../../../store/store";
|
||||||
import * as Types from '../../../../types/world/worldTypes';
|
import * as Types from '../../../../types/world/worldTypes';
|
||||||
|
import LabledDropdown from "../../../ui/inputs/LabledDropdown";
|
||||||
|
|
||||||
const VehicleMechanics: React.FC = () => {
|
const VehicleMechanics: React.FC = () => {
|
||||||
const { selectedActionSphere } = useSelectedActionSphere();
|
const { selectedActionSphere } = useSelectedActionSphere();
|
||||||
@@ -11,17 +11,31 @@ const VehicleMechanics: React.FC = () => {
|
|||||||
|
|
||||||
const propertiesContainerRef = useRef<HTMLDivElement>(null);
|
const propertiesContainerRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
const selectedPoint = useMemo(() => {
|
const { selectedPoint, connectedPointUuids } = useMemo(() => {
|
||||||
if (!selectedActionSphere?.point?.uuid) return null;
|
if (!selectedActionSphere?.point?.uuid) return { selectedPoint: null, connectedPointUuids: [] };
|
||||||
|
|
||||||
const vehiclePaths = simulationPaths.filter(
|
const vehiclePaths = simulationPaths.filter(
|
||||||
(path): path is Types.VehicleEventsSchema => path.type === "Vehicle"
|
(path): path is Types.VehicleEventsSchema => path.type === "Vehicle"
|
||||||
);
|
);
|
||||||
|
|
||||||
return vehiclePaths.find(
|
const point = vehiclePaths.find(
|
||||||
(path) => path.point.uuid === selectedActionSphere.point.uuid
|
(path) => path.point.uuid === selectedActionSphere.point.uuid
|
||||||
)?.point;
|
)?.point;
|
||||||
}, [selectedActionSphere, simulationPaths, selectedActionSphere?.point?.uuid]);
|
|
||||||
|
if (!point) return { selectedPoint: null, connectedPointUuids: [] };
|
||||||
|
|
||||||
|
const connectedUuids: string[] = [];
|
||||||
|
if (point.connections?.targets) {
|
||||||
|
point.connections.targets.forEach(target => {
|
||||||
|
connectedUuids.push(target.pointUUID);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
selectedPoint: point,
|
||||||
|
connectedPointUuids: connectedUuids
|
||||||
|
};
|
||||||
|
}, [selectedActionSphere, simulationPaths]);
|
||||||
|
|
||||||
const handleActionUpdate = React.useCallback((updatedAction: Partial<Types.VehicleEventsSchema['point']['actions']>) => {
|
const handleActionUpdate = React.useCallback((updatedAction: Partial<Types.VehicleEventsSchema['point']['actions']>) => {
|
||||||
if (!selectedActionSphere?.point?.uuid) return;
|
if (!selectedActionSphere?.point?.uuid) return;
|
||||||
@@ -45,12 +59,12 @@ const VehicleMechanics: React.FC = () => {
|
|||||||
setSimulationPaths(updatedPaths);
|
setSimulationPaths(updatedPaths);
|
||||||
}, [selectedActionSphere?.point?.uuid, simulationPaths, setSimulationPaths]);
|
}, [selectedActionSphere?.point?.uuid, simulationPaths, setSimulationPaths]);
|
||||||
|
|
||||||
const handleStartPointChange = React.useCallback((position: string) => {
|
const handleStartPointChange = React.useCallback((uuid: string) => {
|
||||||
handleActionUpdate({ start: position });
|
handleActionUpdate({ start: uuid });
|
||||||
}, [handleActionUpdate]);
|
}, [handleActionUpdate]);
|
||||||
|
|
||||||
const handleEndPointChange = React.useCallback((position: string) => {
|
const handleEndPointChange = React.useCallback((uuid: string) => {
|
||||||
handleActionUpdate({ end: position });
|
handleActionUpdate({ end: uuid });
|
||||||
}, [handleActionUpdate]);
|
}, [handleActionUpdate]);
|
||||||
|
|
||||||
const handleHitCountChange = React.useCallback((hitCount: number) => {
|
const handleHitCountChange = React.useCallback((hitCount: number) => {
|
||||||
@@ -92,18 +106,20 @@ const VehicleMechanics: React.FC = () => {
|
|||||||
|
|
||||||
{selectedPoint && (
|
{selectedPoint && (
|
||||||
<>
|
<>
|
||||||
<EyeDropInput
|
<LabledDropdown
|
||||||
key={`start-${selectedPoint.uuid}`}
|
key={`start-${selectedPoint.uuid}`}
|
||||||
label="Start Point"
|
label="Start Point"
|
||||||
value={selectedPoint.actions.start}
|
defaultOption={selectedPoint.actions.start || "Select start point"}
|
||||||
onChange={handleStartPointChange}
|
options={connectedPointUuids}
|
||||||
|
onSelect={handleStartPointChange}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<EyeDropInput
|
<LabledDropdown
|
||||||
key={`end-${selectedPoint.uuid}`}
|
key={`end-${selectedPoint.uuid}`}
|
||||||
label="End Point"
|
label="End Point"
|
||||||
value={selectedPoint.actions.end}
|
defaultOption={selectedPoint.actions.end || "Select end point"}
|
||||||
onChange={handleEndPointChange}
|
options={connectedPointUuids}
|
||||||
|
onSelect={handleEndPointChange}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<InputWithDropDown
|
<InputWithDropDown
|
||||||
@@ -128,7 +144,6 @@ const VehicleMechanics: React.FC = () => {
|
|||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="footer">
|
<div className="footer">
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ const RealTimeVisulization: React.FC = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
GetZoneData();
|
GetZoneData();
|
||||||
}, []); // Removed `zones` from dependencies
|
}, [activeModule]); // Removed `zones` from dependencies
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { EyeDroperIcon } from "../../icons/ExportCommonIcons";
|
import { EyeDroperIcon } from "../../icons/ExportCommonIcons";
|
||||||
|
import RegularDropDown from "./RegularDropDown";
|
||||||
|
|
||||||
interface EyeDropInputProps {
|
interface EyeDropInputProps {
|
||||||
label: string;
|
label: string;
|
||||||
@@ -23,7 +24,12 @@ const EyeDropInput: React.FC<EyeDropInputProps> = ({
|
|||||||
<div className="eye-dropper-input-container">
|
<div className="eye-dropper-input-container">
|
||||||
<div className="label">{label}</div>
|
<div className="label">{label}</div>
|
||||||
<div className="input-container">
|
<div className="input-container">
|
||||||
<input disabled type="text" />
|
{/* <input disabled type="text" /> */}
|
||||||
|
<RegularDropDown
|
||||||
|
header="select object"
|
||||||
|
options={[]}
|
||||||
|
onSelect={() => { }}
|
||||||
|
/>
|
||||||
<div className="eye-picker-button" onClick={handleEyeDropClick}>
|
<div className="eye-picker-button" onClick={handleEyeDropClick}>
|
||||||
<EyeDroperIcon isActive={false} />
|
<EyeDroperIcon isActive={false} />
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,24 +1,17 @@
|
|||||||
import PolygonGenerator from "./polygonGenerator";
|
import PolygonGenerator from "./polygonGenerator";
|
||||||
import { useThree } from "@react-three/fiber";
|
import { useThree } from "@react-three/fiber";
|
||||||
import { useEffect, useRef, useState } from "react";
|
import { useEffect, useMemo, useRef, useState } from "react";
|
||||||
import * as THREE from "three";
|
import * as THREE from "three";
|
||||||
import * as Types from "../../../types/world/worldTypes";
|
import * as Types from "../../../types/world/worldTypes";
|
||||||
import PathNavigator from "./pathNavigator";
|
import PathNavigator from "./pathNavigator";
|
||||||
import NavMeshDetails from "./navMeshDetails";
|
import NavMeshDetails from "./navMeshDetails";
|
||||||
|
|
||||||
const Agv = ({
|
const Agv = ({ lines, plane }: { lines: Types.RefLines; plane: Types.RefMesh; }) => {
|
||||||
lines,
|
const pathPoints = useMemo(() => [
|
||||||
plane,
|
|
||||||
}: {
|
|
||||||
lines: Types.RefLines;
|
|
||||||
plane: Types.RefMesh;
|
|
||||||
}) => {
|
|
||||||
let pathPoints = [
|
|
||||||
[
|
[
|
||||||
{ x: 8.477161935339709, y: 0, z: 17.41343083550102 },
|
{ x: 8.477161935339709, y: 0, z: 17.41343083550102 },
|
||||||
{ x: 9.175416491482693, y: 0, z: -12.361001232663693 },
|
{ x: 9.175416491482693, y: 0, z: -12.361001232663693 },
|
||||||
],
|
],
|
||||||
,
|
|
||||||
// [
|
// [
|
||||||
// { x: 13.508213355232144, y: 0, z: -15.456970649652018 },
|
// { x: 13.508213355232144, y: 0, z: -15.456970649652018 },
|
||||||
// { x: -30.464866520869617, y: 0, z: 9.779806557688929 },
|
// { x: -30.464866520869617, y: 0, z: 9.779806557688929 },
|
||||||
@@ -27,7 +20,8 @@ const Agv = ({
|
|||||||
{ x: 16.792040856420844, y: 0, z: 15.86281907549489 },
|
{ x: 16.792040856420844, y: 0, z: 15.86281907549489 },
|
||||||
{ x: -42.77173264503395, y: 0, z: -15.821322764400804 },
|
{ x: -42.77173264503395, y: 0, z: -15.821322764400804 },
|
||||||
],
|
],
|
||||||
];
|
], []);
|
||||||
|
|
||||||
let groupRef = useRef() as Types.RefGroup;
|
let groupRef = useRef() as Types.RefGroup;
|
||||||
const [navMesh, setNavMesh] = useState();
|
const [navMesh, setNavMesh] = useState();
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,8 @@ function hideRoof(
|
|||||||
if (roofChild.material) {
|
if (roofChild.material) {
|
||||||
const materials = Array.isArray(roofChild.material) ? roofChild.material : [roofChild.material];
|
const materials = Array.isArray(roofChild.material) ? roofChild.material : [roofChild.material];
|
||||||
materials.forEach(material => {
|
materials.forEach(material => {
|
||||||
material.visible = v.dot(u) < 0.25;
|
// material.visible = v.dot(u) < 0.25;
|
||||||
|
material.visible = true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -86,6 +86,7 @@ function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObjec
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// In the updatePathConnections function, modify the Vehicle handling section:
|
||||||
else if (path.type === 'Vehicle') {
|
else if (path.type === 'Vehicle') {
|
||||||
// Handle outgoing connections from Vehicle
|
// Handle outgoing connections from Vehicle
|
||||||
if (path.modeluuid === fromPathUUID && path.point.uuid === fromPointUUID) {
|
if (path.modeluuid === fromPathUUID && path.point.uuid === fromPointUUID) {
|
||||||
@@ -95,6 +96,27 @@ function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObjec
|
|||||||
};
|
};
|
||||||
const existingTargets = path.point.connections.targets || [];
|
const existingTargets = path.point.connections.targets || [];
|
||||||
|
|
||||||
|
// Check if we're trying to add a connection to a Conveyor
|
||||||
|
const toPath = simulationPaths.find(p => p.modeluuid === toPathUUID);
|
||||||
|
const isConnectingToConveyor = toPath?.type === 'Conveyor';
|
||||||
|
|
||||||
|
// Count existing connections
|
||||||
|
if (existingTargets.length >= 2) {
|
||||||
|
console.log("Vehicle can have maximum 2 connections");
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if we already have a Conveyor connection and trying to add another
|
||||||
|
const hasConveyorConnection = existingTargets.some(target => {
|
||||||
|
const targetPath = simulationPaths.find(p => p.modeluuid === target.pathUUID);
|
||||||
|
return targetPath?.type === 'Conveyor';
|
||||||
|
});
|
||||||
|
|
||||||
|
if (hasConveyorConnection && isConnectingToConveyor) {
|
||||||
|
console.log("Vehicle can only have one connection to a Conveyor");
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
if (!existingTargets.some(target =>
|
if (!existingTargets.some(target =>
|
||||||
target.pathUUID === newTarget.pathUUID &&
|
target.pathUUID === newTarget.pathUUID &&
|
||||||
target.pointUUID === newTarget.pointUUID
|
target.pointUUID === newTarget.pointUUID
|
||||||
@@ -119,6 +141,27 @@ function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObjec
|
|||||||
};
|
};
|
||||||
const existingTargets = path.point.connections.targets || [];
|
const existingTargets = path.point.connections.targets || [];
|
||||||
|
|
||||||
|
// Check if we're receiving a connection from a Conveyor
|
||||||
|
const fromPath = simulationPaths.find(p => p.modeluuid === fromPathUUID);
|
||||||
|
const isConnectingFromConveyor = fromPath?.type === 'Conveyor';
|
||||||
|
|
||||||
|
// Count existing connections
|
||||||
|
if (existingTargets.length >= 2) {
|
||||||
|
console.log("Vehicle can have maximum 2 connections");
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if we already have a Conveyor connection and trying to add another
|
||||||
|
const hasConveyorConnection = existingTargets.some(target => {
|
||||||
|
const targetPath = simulationPaths.find(p => p.modeluuid === target.pathUUID);
|
||||||
|
return targetPath?.type === 'Conveyor';
|
||||||
|
});
|
||||||
|
|
||||||
|
if (hasConveyorConnection && isConnectingFromConveyor) {
|
||||||
|
console.log("Vehicle can only have one connection to a Conveyor");
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
if (!existingTargets.some(target =>
|
if (!existingTargets.some(target =>
|
||||||
target.pathUUID === reverseTarget.pathUUID &&
|
target.pathUUID === reverseTarget.pathUUID &&
|
||||||
target.pointUUID === reverseTarget.pointUUID
|
target.pointUUID === reverseTarget.pointUUID
|
||||||
@@ -135,6 +178,7 @@ function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObjec
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return path;
|
||||||
}
|
}
|
||||||
return path;
|
return path;
|
||||||
});
|
});
|
||||||
@@ -168,7 +212,6 @@ function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObjec
|
|||||||
drag = true;
|
drag = true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const onContextMenu = (evt: MouseEvent) => {
|
const onContextMenu = (evt: MouseEvent) => {
|
||||||
evt.preventDefault();
|
evt.preventDefault();
|
||||||
if (drag || evt.button === 0) return;
|
if (drag || evt.button === 0) return;
|
||||||
@@ -200,29 +243,126 @@ function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObjec
|
|||||||
const firstPath = simulationPaths.find(p => p.modeluuid === firstSelected?.pathUUID);
|
const firstPath = simulationPaths.find(p => p.modeluuid === firstSelected?.pathUUID);
|
||||||
const secondPath = simulationPaths.find(p => p.modeluuid === pathUUID);
|
const secondPath = simulationPaths.find(p => p.modeluuid === pathUUID);
|
||||||
|
|
||||||
|
// Prevent vehicle-to-vehicle connections
|
||||||
if (firstPath && secondPath && firstPath.type === 'Vehicle' && secondPath.type === 'Vehicle') {
|
if (firstPath && secondPath && firstPath.type === 'Vehicle' && secondPath.type === 'Vehicle') {
|
||||||
console.log("Cannot connect two vehicle paths together");
|
console.log("Cannot connect two vehicle paths together");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Prevent conveyor middle point to conveyor connections
|
||||||
|
if (firstPath && secondPath &&
|
||||||
|
firstPath.type === 'Conveyor' &&
|
||||||
|
secondPath.type === 'Conveyor' &&
|
||||||
|
!firstSelected?.isCorner) {
|
||||||
|
console.log("Conveyor middle points can only connect to non-conveyor paths");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if this specific connection already exists
|
||||||
|
const isDuplicateConnection = firstSelected
|
||||||
|
? simulationPaths.some(path => {
|
||||||
|
if (path.modeluuid === firstSelected.pathUUID) {
|
||||||
|
if (path.type === 'Conveyor') {
|
||||||
|
const point = path.points.find(p => p.uuid === firstSelected.sphereUUID);
|
||||||
|
return point?.connections.targets.some(t =>
|
||||||
|
t.pathUUID === pathUUID && t.pointUUID === sphereUUID
|
||||||
|
);
|
||||||
|
} else if (path.type === 'Vehicle') {
|
||||||
|
return path.point.connections.targets.some(t =>
|
||||||
|
t.pathUUID === pathUUID && t.pointUUID === sphereUUID
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
})
|
||||||
|
: false;
|
||||||
|
|
||||||
|
if (isDuplicateConnection) {
|
||||||
|
console.log("These points are already connected. Ignoring.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// For Vehicles, skip the "already connected" check since they can have multiple connections
|
||||||
|
if (intersected.userData.path.type !== 'Vehicle') {
|
||||||
const isAlreadyConnected = simulationPaths.some(path => {
|
const isAlreadyConnected = simulationPaths.some(path => {
|
||||||
if (path.type === 'Conveyor') {
|
if (path.type === 'Conveyor') {
|
||||||
return path.points.some(point =>
|
return path.points.some(point =>
|
||||||
point.uuid === sphereUUID &&
|
point.uuid === sphereUUID &&
|
||||||
point.connections.targets.length > 0
|
point.connections.targets.length > 0
|
||||||
);
|
);
|
||||||
} else if (path.type === 'Vehicle') {
|
|
||||||
return path.point.uuid === sphereUUID &&
|
|
||||||
path.point.connections.targets.length > 0;
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
if (isAlreadyConnected) {
|
if (isAlreadyConnected) {
|
||||||
console.log("Sphere is already connected. Ignoring.");
|
console.log("Conveyor point is already connected. Ignoring.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check vehicle connection limits
|
||||||
|
const checkVehicleConnections = (pathUUID: string) => {
|
||||||
|
const path = simulationPaths.find(p => p.modeluuid === pathUUID);
|
||||||
|
if (path?.type === 'Vehicle') {
|
||||||
|
return path.point.connections.targets.length >= 2;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (firstSelected) {
|
||||||
|
// Check if either selected point is from a Vehicle with max connections
|
||||||
|
if (checkVehicleConnections(firstSelected.pathUUID) ||
|
||||||
|
checkVehicleConnections(pathUUID)) {
|
||||||
|
console.log("Vehicle already has maximum connections");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!firstSelected) {
|
// Check if we're trying to add a second Conveyor connection to a Vehicle
|
||||||
|
if (firstPath?.type === 'Vehicle' && secondPath?.type === 'Conveyor') {
|
||||||
|
const hasConveyorConnection = firstPath.point.connections.targets.some(target => {
|
||||||
|
const targetPath = simulationPaths.find(p => p.modeluuid === target.pathUUID);
|
||||||
|
return targetPath?.type === 'Conveyor';
|
||||||
|
});
|
||||||
|
|
||||||
|
if (hasConveyorConnection) {
|
||||||
|
console.log("Vehicle can only have one connection to a Conveyor");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (secondPath?.type === 'Vehicle' && firstPath?.type === 'Conveyor') {
|
||||||
|
const hasConveyorConnection = secondPath.point.connections.targets.some(target => {
|
||||||
|
const targetPath = simulationPaths.find(p => p.modeluuid === target.pathUUID);
|
||||||
|
return targetPath?.type === 'Conveyor';
|
||||||
|
});
|
||||||
|
|
||||||
|
if (hasConveyorConnection) {
|
||||||
|
console.log("Vehicle can only have one connection to a Conveyor");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prevent same-path connections
|
||||||
|
if (firstSelected.pathUUID === pathUUID) {
|
||||||
|
console.log("Cannot connect spheres on the same path.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// At least one must be start/end point
|
||||||
|
if (!firstSelected.isCorner && !isStartOrEnd) {
|
||||||
|
console.log("At least one of the selected spheres must be a start or end point.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// All checks passed - make the connection
|
||||||
|
handleAddConnection(
|
||||||
|
firstSelected.pathUUID,
|
||||||
|
firstSelected.sphereUUID,
|
||||||
|
pathUUID,
|
||||||
|
sphereUUID
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
// First selection - just store it
|
||||||
setFirstSelected({
|
setFirstSelected({
|
||||||
pathUUID,
|
pathUUID,
|
||||||
sphereUUID,
|
sphereUUID,
|
||||||
@@ -230,28 +370,11 @@ function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObjec
|
|||||||
isCorner: isStartOrEnd
|
isCorner: isStartOrEnd
|
||||||
});
|
});
|
||||||
setIsConnecting(true);
|
setIsConnecting(true);
|
||||||
} else {
|
|
||||||
if (firstSelected.sphereUUID === sphereUUID) return;
|
|
||||||
|
|
||||||
if (firstSelected.pathUUID === pathUUID) {
|
|
||||||
console.log("Cannot connect spheres on the same path.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!firstSelected.isCorner && !isStartOrEnd) {
|
|
||||||
console.log("At least one of the selected spheres must be a start or end point.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
handleAddConnection(
|
|
||||||
firstSelected.pathUUID,
|
|
||||||
firstSelected.sphereUUID,
|
|
||||||
pathUUID,
|
|
||||||
sphereUUID
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
// Clicked outside - cancel connection
|
||||||
setFirstSelected(null);
|
setFirstSelected(null);
|
||||||
setCurrentLine(null);
|
setCurrentLine(null);
|
||||||
setIsConnecting(false);
|
setIsConnecting(false);
|
||||||
@@ -294,7 +417,6 @@ function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObjec
|
|||||||
|
|
||||||
if (intersects.length > 0) {
|
if (intersects.length > 0) {
|
||||||
point = intersects[0].point;
|
point = intersects[0].point;
|
||||||
|
|
||||||
if (point.y < 0.05) {
|
if (point.y < 0.05) {
|
||||||
point = new THREE.Vector3(point.x, 0.05, point.z);
|
point = new THREE.Vector3(point.x, 0.05, point.z);
|
||||||
}
|
}
|
||||||
@@ -316,28 +438,68 @@ function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObjec
|
|||||||
const secondPath = simulationPaths.find(p => p.modeluuid === pathUUID);
|
const secondPath = simulationPaths.find(p => p.modeluuid === pathUUID);
|
||||||
const isVehicleToVehicle = firstPath?.type === 'Vehicle' && secondPath?.type === 'Vehicle';
|
const isVehicleToVehicle = firstPath?.type === 'Vehicle' && secondPath?.type === 'Vehicle';
|
||||||
|
|
||||||
|
// Inside the useFrame hook, where we check for snapped spheres:
|
||||||
const isConnectable = (pathData.type === 'Vehicle' ||
|
const isConnectable = (pathData.type === 'Vehicle' ||
|
||||||
(pathData.points.length > 0 && (
|
(pathData.points.length > 0 && (
|
||||||
sphereUUID === pathData.points[0].uuid ||
|
sphereUUID === pathData.points[0].uuid ||
|
||||||
sphereUUID === pathData.points[pathData.points.length - 1].uuid
|
sphereUUID === pathData.points[pathData.points.length - 1].uuid
|
||||||
))) && !isVehicleToVehicle;
|
))) &&
|
||||||
|
!isVehicleToVehicle &&
|
||||||
|
!(firstPath?.type === 'Conveyor' &&
|
||||||
|
pathData.type === 'Conveyor' &&
|
||||||
|
!firstSelected.isCorner);
|
||||||
|
|
||||||
const isAlreadyConnected = simulationPaths.some(path => {
|
// Check for duplicate connection (regardless of path type)
|
||||||
|
const isDuplicateConnection = simulationPaths.some(path => {
|
||||||
|
if (path.modeluuid === firstSelected.pathUUID) {
|
||||||
|
if (path.type === 'Conveyor') {
|
||||||
|
const point = path.points.find(p => p.uuid === firstSelected.sphereUUID);
|
||||||
|
return point?.connections.targets.some(t =>
|
||||||
|
t.pathUUID === pathUUID && t.pointUUID === sphereUUID
|
||||||
|
);
|
||||||
|
} else if (path.type === 'Vehicle') {
|
||||||
|
return path.point.connections.targets.some(t =>
|
||||||
|
t.pathUUID === pathUUID && t.pointUUID === sphereUUID
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
// For non-Vehicle paths, check if already connected
|
||||||
|
const isNonVehicleAlreadyConnected = pathData.type !== 'Vehicle' &&
|
||||||
|
simulationPaths.some(path => {
|
||||||
if (path.type === 'Conveyor') {
|
if (path.type === 'Conveyor') {
|
||||||
return path.points.some(point =>
|
return path.points.some(point =>
|
||||||
point.uuid === sphereUUID &&
|
point.uuid === sphereUUID &&
|
||||||
point.connections.targets.length > 0
|
point.connections.targets.length > 0
|
||||||
);
|
);
|
||||||
} else if (path.type === 'Vehicle') {
|
|
||||||
return path.point.uuid === sphereUUID &&
|
|
||||||
path.point.connections.targets.length > 0;
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Check vehicle connection limits
|
||||||
|
const isVehicleAtMaxConnections = pathData.type === 'Vehicle' &&
|
||||||
|
pathData.point.connections.targets.length >= 2;
|
||||||
|
|
||||||
|
const isVehicleConveyorConflict =
|
||||||
|
(firstPath?.type === 'Vehicle' && secondPath?.type === 'Conveyor' &&
|
||||||
|
firstPath.point.connections.targets.some(t => {
|
||||||
|
const targetPath = simulationPaths.find(p => p.modeluuid === t.pathUUID);
|
||||||
|
return targetPath?.type === 'Conveyor';
|
||||||
|
})) ||
|
||||||
|
(secondPath?.type === 'Vehicle' && firstPath?.type === 'Conveyor' &&
|
||||||
|
secondPath.point.connections.targets.some(t => {
|
||||||
|
const targetPath = simulationPaths.find(p => p.modeluuid === t.pathUUID);
|
||||||
|
return targetPath?.type === 'Conveyor';
|
||||||
|
}));
|
||||||
|
|
||||||
if (
|
if (
|
||||||
!isAlreadyConnected &&
|
!isDuplicateConnection &&
|
||||||
!isVehicleToVehicle &&
|
!isVehicleToVehicle &&
|
||||||
|
!isNonVehicleAlreadyConnected &&
|
||||||
|
!isVehicleAtMaxConnections &&
|
||||||
|
!isVehicleConveyorConflict &&
|
||||||
firstSelected.sphereUUID !== sphereUUID &&
|
firstSelected.sphereUUID !== sphereUUID &&
|
||||||
firstSelected.pathUUID !== pathUUID &&
|
firstSelected.pathUUID !== pathUUID &&
|
||||||
(firstSelected.isCorner || isConnectable)
|
(firstSelected.isCorner || isConnectable)
|
||||||
@@ -371,13 +533,6 @@ function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObjec
|
|||||||
end: point,
|
end: point,
|
||||||
mid: midPoint,
|
mid: midPoint,
|
||||||
});
|
});
|
||||||
console.log({
|
|
||||||
start: firstSelected.position,
|
|
||||||
end: point,
|
|
||||||
mid: midPoint,
|
|
||||||
});
|
|
||||||
|
|
||||||
// setIsConnecting(true);
|
|
||||||
|
|
||||||
if (sphereIntersects.length > 0) {
|
if (sphereIntersects.length > 0) {
|
||||||
setHelperLineColor(isInvalidConnection ? 'red' : '#6cf542');
|
setHelperLineColor(isInvalidConnection ? 'red' : '#6cf542');
|
||||||
|
|||||||
@@ -6,37 +6,37 @@ const MqttEvents = () => {
|
|||||||
const { setTouch, setTemperature, setHumidity } = useDrieUIValue();
|
const { setTouch, setTemperature, setHumidity } = useDrieUIValue();
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
||||||
const client = mqtt.connect(`ws://${process.env.REACT_APP_SERVER_MQTT_URL}`);
|
// const client = mqtt.connect(`ws://${process.env.REACT_APP_SERVER_MQTT_URL}`);
|
||||||
|
|
||||||
client.subscribe("touch");
|
// client.subscribe("touch");
|
||||||
client.subscribe("temperature");
|
// client.subscribe("temperature");
|
||||||
client.subscribe("humidity");
|
// client.subscribe("humidity");
|
||||||
|
|
||||||
const handleMessage = (topic: string, message: any) => {
|
// const handleMessage = (topic: string, message: any) => {
|
||||||
const value = message.toString();
|
// const value = message.toString();
|
||||||
|
|
||||||
if (topic === "touch") {
|
// if (topic === "touch") {
|
||||||
setTouch(value);
|
// setTouch(value);
|
||||||
} else if (topic === "temperature") {
|
// } else if (topic === "temperature") {
|
||||||
setTemperature(parseFloat(value));
|
// setTemperature(parseFloat(value));
|
||||||
} else if (topic === "humidity") {
|
// } else if (topic === "humidity") {
|
||||||
setHumidity(parseFloat(value));
|
// setHumidity(parseFloat(value));
|
||||||
}
|
// }
|
||||||
};
|
// };
|
||||||
|
|
||||||
client.on("message", handleMessage);
|
// client.on("message", handleMessage);
|
||||||
|
|
||||||
client.on("error", (err) => {
|
// client.on("error", (err) => {
|
||||||
console.error("MQTT Connection Error:", err);
|
// console.error("MQTT Connection Error:", err);
|
||||||
});
|
// });
|
||||||
|
|
||||||
client.on("close", () => {
|
// client.on("close", () => {
|
||||||
console.log("MQTT Connection Closed");
|
// console.log("MQTT Connection Closed");
|
||||||
});
|
// });
|
||||||
|
|
||||||
return () => {
|
// return () => {
|
||||||
client.end();
|
// client.end();
|
||||||
};
|
// };
|
||||||
}, [setTouch, setTemperature, setHumidity]);
|
}, [setTouch, setTemperature, setHumidity]);
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`;
|
let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`;
|
||||||
console.log("url_Backend_dwinzo: ", url_Backend_dwinzo);
|
|
||||||
|
|
||||||
export const getSelect2dZoneData = async (
|
export const getSelect2dZoneData = async (
|
||||||
ZoneId?: string,
|
ZoneId?: string,
|
||||||
|
|||||||
Reference in New Issue
Block a user