Changes
Co-authored-by: Reifonas <211114984+Reifonas@users.noreply.github.com>
This commit is contained in:
@@ -352,15 +352,70 @@ function MeasurementLabel({ position, text, variant, fixed = false }: { position
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Renders all measurements, snap point, and hover info */
|
/** Renders a single measurement's geometry + label.
|
||||||
|
* Coordinates are interpreted in whichever frame the component is mounted in. */
|
||||||
|
function MeasurementGraphic({ m }: { m: import('@/stores/useModelStore').Measurement }) {
|
||||||
|
const a: [number, number, number] = [m.pointA.x, m.pointA.y, m.pointA.z];
|
||||||
|
const b: [number, number, number] = [m.pointB.x, m.pointB.y, m.pointB.z];
|
||||||
|
const mid: [number, number, number] = [
|
||||||
|
(a[0] + b[0]) / 2,
|
||||||
|
(a[1] + b[1]) / 2,
|
||||||
|
(a[2] + b[2]) / 2,
|
||||||
|
];
|
||||||
|
|
||||||
|
if (m.kind === 'hole') {
|
||||||
|
return (
|
||||||
|
<group>
|
||||||
|
<PointMarker position={a} color="#f59e0b" />
|
||||||
|
<MeasurementLabel position={a} text={m.label ?? `Ø ${m.distanceMM.toFixed(1)}`} variant="accent" />
|
||||||
|
</group>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m.kind === 'edge') {
|
||||||
|
return (
|
||||||
|
<group>
|
||||||
|
<PointMarker position={a} color="#22c55e" />
|
||||||
|
<PointMarker position={b} color="#22c55e" />
|
||||||
|
<Line points={[a, b]} color="#22c55e" lineWidth={2} depthTest={false} />
|
||||||
|
<MeasurementLabel position={mid} text={m.label ?? `${m.distanceMM.toFixed(1)} mm`} variant="success" />
|
||||||
|
</group>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<group>
|
||||||
|
<PointMarker position={a} color="#22c55e" />
|
||||||
|
<PointMarker position={b} color="#22c55e" />
|
||||||
|
<Line points={[a, b]} color="#22c55e" lineWidth={2} depthTest={false} />
|
||||||
|
<MeasurementLabel position={mid} text={`${m.distanceMM.toFixed(1)} mm`} variant="success" />
|
||||||
|
</group>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Renders measurements attached to a given model, in that model's local frame.
|
||||||
|
* Mounted inside GLBModel so they follow the model when it is repositioned. */
|
||||||
|
function ModelMeasurements({ modelId }: { modelId: string }) {
|
||||||
|
const measurements = useModelStore((s) => s.measurements);
|
||||||
|
const attached = measurements.filter((m) => m.modelId === modelId);
|
||||||
|
if (attached.length === 0) return null;
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{attached.map((m) => (
|
||||||
|
<MeasurementGraphic key={m.id} m={m} />
|
||||||
|
))}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Renders snap indicator, hover tooltip, pending point and any *legacy*
|
||||||
|
* world-frame measurements that aren't attached to a specific model. */
|
||||||
function MeasurementOverlay() {
|
function MeasurementOverlay() {
|
||||||
const measurements = useModelStore((s) => s.measurements);
|
const measurements = useModelStore((s) => s.measurements);
|
||||||
const measurePoints = useModelStore((s) => s.measurePoints);
|
const measurePoints = useModelStore((s) => s.measurePoints);
|
||||||
const snapPoint = useModelStore((s) => s.snapPoint);
|
const snapPoint = useModelStore((s) => s.snapPoint);
|
||||||
const hoverInfo = useModelStore((s) => s.hoverInfo);
|
const hoverInfo = useModelStore((s) => s.hoverInfo);
|
||||||
const measureMode = useModelStore((s) => s.measureMode);
|
const measureMode = useModelStore((s) => s.measureMode);
|
||||||
const scaleRatio = useModelStore((s) => s.scaleRatio);
|
|
||||||
const factor = scaleRatio?.factor ?? 1;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -381,55 +436,15 @@ function MeasurementOverlay() {
|
|||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Pending first point */}
|
{/* Pending first point (always in world coords) */}
|
||||||
{measurePoints.length === 1 && (
|
{measurePoints.length === 1 && (
|
||||||
<PointMarker position={[measurePoints[0].x, measurePoints[0].y, measurePoints[0].z]} color="#e8a838" />
|
<PointMarker position={[measurePoints[0].x, measurePoints[0].y, measurePoints[0].z]} color="#e8a838" />
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Completed measurements */}
|
{/* Legacy world-frame measurements (no modelId) */}
|
||||||
{measurements.map((m) => {
|
{measurements.filter((m) => !m.modelId).map((m) => (
|
||||||
const a: [number, number, number] = [m.pointA.x, m.pointA.y, m.pointA.z];
|
<MeasurementGraphic key={m.id} m={m} />
|
||||||
const b: [number, number, number] = [m.pointB.x, m.pointB.y, m.pointB.z];
|
))}
|
||||||
const mid: [number, number, number] = [
|
|
||||||
(a[0] + b[0]) / 2,
|
|
||||||
(a[1] + b[1]) / 2,
|
|
||||||
(a[2] + b[2]) / 2,
|
|
||||||
];
|
|
||||||
|
|
||||||
if (m.kind === 'hole') {
|
|
||||||
return (
|
|
||||||
<group key={m.id}>
|
|
||||||
<PointMarker position={a} color="#f59e0b" />
|
|
||||||
<MeasurementLabel position={a} text={m.label ?? `Ø ${m.distanceMM.toFixed(1)}`} variant="accent" />
|
|
||||||
</group>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m.kind === 'edge') {
|
|
||||||
return (
|
|
||||||
<group key={m.id}>
|
|
||||||
<PointMarker position={a} color="#22c55e" />
|
|
||||||
<PointMarker position={b} color="#22c55e" />
|
|
||||||
<Line points={[a, b]} color="#22c55e" lineWidth={2} depthTest={false} />
|
|
||||||
<MeasurementLabel position={mid} text={m.label ?? `${m.distanceMM.toFixed(1)} mm`} variant="success" />
|
|
||||||
</group>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<group key={m.id}>
|
|
||||||
<PointMarker position={a} color="#22c55e" />
|
|
||||||
<PointMarker position={b} color="#22c55e" />
|
|
||||||
<Line
|
|
||||||
points={[a, b]}
|
|
||||||
color="#22c55e"
|
|
||||||
lineWidth={2}
|
|
||||||
depthTest={false}
|
|
||||||
/>
|
|
||||||
<MeasurementLabel position={mid} text={`${m.distanceMM.toFixed(1)} mm`} variant="success" />
|
|
||||||
</group>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user