Fix repeated motion-id preview highlight
This commit is contained in:
@@ -4,7 +4,7 @@ import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
|
||||
import { projectXyzacVisual, type XyzacVisualSource, type XyzacVisualState } from "./xyzac-visual-adapter";
|
||||
|
||||
type Point = Record<string, number>;
|
||||
type Segment = { id?: number; active?: boolean; kind?: string; motion_type?: number; kinematics_mode?: number; turn?: number; center?: Point; normal?: Point; samples?: Point[]; start?: Point; end?: Point };
|
||||
type Segment = { id?: number; source_line?: number | null; active?: boolean; kind?: string; motion_type?: number; kinematics_mode?: number; turn?: number; center?: Point; normal?: Point; samples?: Point[]; start?: Point; end?: Point };
|
||||
type Props = { visual: XyzacVisualState; view?: "z" | "z2" | "x" | "y" | "y2" | "p"; zoom?: number; rotateMode?: boolean; showPath?: boolean; showLive?: boolean; showLimits?: boolean; showVelocity?: boolean; showOffsets?: boolean; showExtents?: boolean };
|
||||
|
||||
const DEG = Math.PI / 180;
|
||||
@@ -82,13 +82,18 @@ export function XyzacToolPreview({ visual, view = "p", zoom = 1, rotateMode = fa
|
||||
};
|
||||
const completed = new THREE.LineBasicMaterial({ color: 0xd8dfe3, depthTest: false });
|
||||
const rapid = new THREE.LineDashedMaterial({ color: 0xa85d5d, dashSize: .025, gapSize: .018, depthTest: false });
|
||||
const live = new THREE.LineBasicMaterial({ color: 0xffd166, depthTest: false });
|
||||
// LinuxCNC uses yellow for jog backplot. Coordinated program execution is
|
||||
// red (live plot), while an unambiguous current program block is cyan.
|
||||
const live = new THREE.LineBasicMaterial({ color: 0x00ffff, depthTest: false });
|
||||
const liveHistory = new THREE.LineBasicMaterial({ color: 0xff6b4a, depthTest: false });
|
||||
let frame = 0;
|
||||
let liveTick = -1;
|
||||
let liveTrace: THREE.Vector3[] = [];
|
||||
let pathSegments: Segment[] | null = null;
|
||||
let segmentById = new Map<number, Segment>();
|
||||
// Native TP active_id is the source line/motion id and may repeat (for
|
||||
// example, each call of the same helix subroutine). Preserve every
|
||||
// occurrence instead of letting a Map overwrite all but one geometry.
|
||||
let segmentCandidatesBySourceLine = new Map<number, Segment[]>();
|
||||
let bounds = { center: new THREE.Vector3(), radius: .12 };
|
||||
let playbackQueue: Array<{ tick: number; pose: Point; joints: number[]; activeSegmentId: number; activeProgress: number }> = [];
|
||||
let playbackStart = 0;
|
||||
@@ -203,7 +208,14 @@ export function XyzacToolPreview({ visual, view = "p", zoom = 1, rotateMode = fa
|
||||
// segments on every animation frame causes visible execution stalls.
|
||||
if (segments !== pathSegments) {
|
||||
pathSegments = segments;
|
||||
segmentById = new Map(segments.flatMap((segment) => Number.isSafeInteger(segment.id) ? [[Number(segment.id), segment] as [number, Segment]] : []));
|
||||
segmentCandidatesBySourceLine = new Map();
|
||||
for (const segment of segments) {
|
||||
const sourceLine = Number(segment.source_line);
|
||||
if (!Number.isSafeInteger(sourceLine) || sourceLine <= 0) continue;
|
||||
const candidates = segmentCandidatesBySourceLine.get(sourceLine) ?? [];
|
||||
candidates.push(segment);
|
||||
segmentCandidatesBySourceLine.set(sourceLine, candidates);
|
||||
}
|
||||
clearLines(pathGroup);
|
||||
clearLines(liveGroup);
|
||||
bounds = fit(segments);
|
||||
@@ -268,7 +280,11 @@ export function XyzacToolPreview({ visual, view = "p", zoom = 1, rotateMode = fa
|
||||
const nextActiveKey = `${renderedTick}:${renderedActiveSegment}:${renderedProgress}`;
|
||||
if (nextActiveKey !== lastActiveKey) {
|
||||
if (activeLiveLine) { activeLiveLine.geometry.dispose(); liveGroup.remove(activeLiveLine); activeLiveLine = null; }
|
||||
const activeSegment = segmentById.get(renderedActiveSegment) ?? segments.find((segment) => Boolean(segment.active));
|
||||
const candidates = segmentCandidatesBySourceLine.get(renderedActiveSegment) ?? [];
|
||||
// A repeated source line has no unique preview geometry. LinuxCNC's
|
||||
// current-line indicator remains authoritative in the program view;
|
||||
// do not invent a yellow/cyan path by selecting an arbitrary repeat.
|
||||
const activeSegment = candidates.length === 1 ? candidates[0] : null;
|
||||
if (activeSegment) {
|
||||
const start = activeSegment.start ?? {}; const end = activeSegment.end ?? {};
|
||||
const points = Array.isArray(activeSegment.samples) && activeSegment.samples.length > 1 ? activeSegment.samples.map(sourcePoint) : [sourcePoint(start), sourcePoint(end)];
|
||||
|
||||
Reference in New Issue
Block a user