Add AXIS preview DRO and editor parity

This commit is contained in:
2026-08-23 09:47:34 +08:00
parent a7fcec9d33
commit 26c95e1400
11 changed files with 289 additions and 37 deletions

View File

@@ -2,18 +2,23 @@ import { useEffect, useRef } from "react";
import * as THREE from "three";
type ViewMode = "z" | "z2" | "x" | "y" | "y2" | "p";
type Props = { axes: number[]; view?: ViewMode; zoom?: number; rotateMode?: boolean };
type Segment = { start?: Record<string, number>; end?: Record<string, number> };
type Props = { axes: number[]; view?: ViewMode; zoom?: number; rotateMode?: boolean; segments?: Segment[]; showGrid?: boolean; showTool?: boolean; showPath?: boolean; showLive?: boolean; showLimits?: boolean; showVelocity?: boolean; showOffsets?: boolean; showExtents?: boolean };
export function ThreeMachineView({ axes, view = "p", zoom = 1, rotateMode = false }: Props) {
export function ThreeMachineView({ axes, view = "p", zoom = 1, rotateMode = false, segments = [], showGrid = true, showTool = true, showPath = true, showLive = true, showLimits = false, showVelocity = false, showOffsets = false, showExtents = false }: Props) {
const host = useRef<HTMLDivElement>(null);
const axesRef = useRef(axes);
const viewRef = useRef(view);
const zoomRef = useRef(zoom);
const rotateRef = useRef(rotateMode);
const segmentsRef = useRef(segments);
const layersRef = useRef({ showGrid, showTool, showPath, showLive, showLimits, showVelocity, showOffsets, showExtents });
axesRef.current = axes;
viewRef.current = view;
zoomRef.current = zoom;
rotateRef.current = rotateMode;
segmentsRef.current = segments;
layersRef.current = { showGrid, showTool, showPath, showLive, showLimits, showVelocity, showOffsets, showExtents };
useEffect(() => {
const element = host.current;
@@ -28,6 +33,7 @@ export function ThreeMachineView({ axes, view = "p", zoom = 1, rotateMode = fals
element.appendChild(renderer.domElement);
const grid = new THREE.GridHelper(8, 16, 0x405765, 0x1e303b);
grid.name = "axis-grid";
scene.add(grid);
scene.add(new THREE.AxesHelper(2.2));
const table = new THREE.Mesh(new THREE.BoxGeometry(5.2, 0.18, 3.6), new THREE.MeshStandardMaterial({ color: 0x263740, roughness: 0.8 }));
@@ -38,6 +44,8 @@ export function ThreeMachineView({ axes, view = "p", zoom = 1, rotateMode = fals
scene.add(gantry);
const tool = new THREE.Mesh(new THREE.ConeGeometry(0.12, 0.55, 16), new THREE.MeshStandardMaterial({ color: 0xc9e86d, emissive: 0x243200 }));
scene.add(tool);
const pathGroup = new THREE.Group(); pathGroup.name = "axis-toolpath"; scene.add(pathGroup);
const overlayGroup = new THREE.Group(); overlayGroup.name = "axis-overlays"; scene.add(overlayGroup);
const ambient = new THREE.HemisphereLight(0xc8e4ec, 0x111820, 1.8);
scene.add(ambient);
const key = new THREE.DirectionalLight(0xffffff, 2.2);
@@ -58,6 +66,21 @@ export function ThreeMachineView({ axes, view = "p", zoom = 1, rotateMode = fals
const render = () => {
const [x = 0, y = 0, z = 0] = axesRef.current;
tool.position.set(THREE.MathUtils.clamp(Number(x) || 0, -2.3, 2.3), 0.35 + THREE.MathUtils.clamp(Number(z) || 0, -1, 2), THREE.MathUtils.clamp(Number(y) || 0, -1.4, 1.4));
grid.visible = layersRef.current.showGrid;
tool.visible = layersRef.current.showTool;
pathGroup.visible = layersRef.current.showPath || layersRef.current.showLive;
pathGroup.clear();
const material = new THREE.LineBasicMaterial({ color: layersRef.current.showLive ? 0x5fc4d8 : 0x5c80a0 });
for (const segment of segmentsRef.current) {
const start = segment.start ?? {}; const end = segment.end ?? {};
const points = [new THREE.Vector3(Number(start.x ?? 0), Number(start.z ?? 0), Number(start.y ?? 0)), new THREE.Vector3(Number(end.x ?? 0), Number(end.z ?? 0), Number(end.y ?? 0))];
pathGroup.add(new THREE.Line(new THREE.BufferGeometry().setFromPoints(points), material));
}
if (layersRef.current.showLimits) {
const limits = new THREE.LineSegments(new THREE.EdgesGeometry(new THREE.BoxGeometry(5, 2, 3.5)), new THREE.LineBasicMaterial({ color: 0xd87d6c }));
limits.position.y = 0.9; overlayGroup.clear(); overlayGroup.add(limits);
} else overlayGroup.clear();
overlayGroup.visible = layersRef.current.showLimits || layersRef.current.showOffsets || layersRef.current.showExtents || layersRef.current.showVelocity;
const distance = 10 / Math.max(0.5, zoomRef.current);
const selectedView = viewRef.current;
if (selectedView === "z") camera.position.set(0, distance, 0.01);