feat: Jump to measurement moves the camera if it is not in the viewport (#5023)
Co-authored-by: Joe Boccanfuso <109477394+jbocce@users.noreply.github.com> Co-authored-by: Bill Wallace <wayfarer3130@gmail.com> Co-authored-by: Igor Octaviano <igoroctaviano@gmail.com>
This commit is contained in:
6 files changed
+148
-44
No files matched your search
@@ -0,0 +1,46 @@
|
||||
/**
|
||||
* Calculates the center point and bounding box extent of a measurement based on its points.
|
||||
* @param {Object} measurement - The measurement object containing points
|
||||
* @param {Array<Array<number>>} measurement.points - Array of 3D points [x, y, z]
|
||||
* @returns {Object} Object containing center and extent
|
||||
* @returns {Array<number>} returns.center - The center point [x, y, z]
|
||||
* @returns {Object} returns.extent - The bounding box extent with min and max points
|
||||
*/
|
||||
export const getCenterExtent = (measurement: { points?: number[][] }) => {
|
||||
const { points } = measurement;
|
||||
|
||||
if (!points || !Array.isArray(points) || points.length === 0) {
|
||||
// Return default values if no points are available
|
||||
const defaultCenter: [number, number, number] = [0, 0, 0];
|
||||
const defaultExtent = {
|
||||
min: [0, 0, 0] as [number, number, number],
|
||||
max: [0, 0, 0] as [number, number, number],
|
||||
};
|
||||
return { center: defaultCenter, extent: defaultExtent };
|
||||
}
|
||||
|
||||
// Initialize min and max with the first point
|
||||
const min: [number, number, number] = [...points[0]] as [number, number, number];
|
||||
const max: [number, number, number] = [...points[0]] as [number, number, number];
|
||||
|
||||
// Find the bounding box by iterating through all points
|
||||
for (let i = 1; i < points.length; i++) {
|
||||
const point = points[i];
|
||||
for (let j = 0; j < 3; j++) {
|
||||
min[j] = Math.min(min[j], point[j]);
|
||||
max[j] = Math.max(max[j], point[j]);
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate the center point
|
||||
const center: [number, number, number] = [
|
||||
(min[0] + max[0]) / 2,
|
||||
(min[1] + max[1]) / 2,
|
||||
(min[2] + max[2]) / 2,
|
||||
];
|
||||
|
||||
return {
|
||||
center,
|
||||
extent: { min, max },
|
||||
};
|
||||
};
|
||||
@@ -9,6 +9,7 @@ import promptHydrationDialog, {
|
||||
HydrationCallback,
|
||||
HydrationSRResult,
|
||||
} from './promptHydrationDialog';
|
||||
import { getCenterExtent } from './getCenterExtent';
|
||||
|
||||
const utils = {
|
||||
handleSegmentChange,
|
||||
@@ -16,6 +17,7 @@ const utils = {
|
||||
setupSegmentationDataModifiedHandler,
|
||||
setupSegmentationModifiedHandler,
|
||||
promptHydrationDialog,
|
||||
getCenterExtent,
|
||||
};
|
||||
|
||||
export type { HydrationDialogProps, HydrationCallback, HydrationSRResult };
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
import { getCenterExtent } from './getCenterExtent';
|
||||
|
||||
/**
|
||||
* Determines if a measurement is within the current viewport extent.
|
||||
* Uses the measurement's bounding box extent to efficiently check if the entire
|
||||
* measurement fits within the viewport's visible area.
|
||||
*
|
||||
* @param {Object} viewport - The viewport object containing camera information
|
||||
* @param {Object} measurement - The measurement object containing points to check
|
||||
* @returns {boolean} True if the measurement extent is within the viewport, false otherwise
|
||||
*/
|
||||
export const isMeasurementWithinViewport = (viewport, measurement) => {
|
||||
const camera = viewport.getCamera();
|
||||
const { focalPoint, parallelScale } = camera;
|
||||
|
||||
// Get the measurement's bounding box extent
|
||||
const { extent } = getCenterExtent(measurement);
|
||||
const { min, max } = extent;
|
||||
|
||||
// Check if the entire bounding box fits within the viewport extent
|
||||
// We need to check both the min and max corners of the bounding box
|
||||
for (let i = 0; i < 3; i++) {
|
||||
const minDistance = Math.abs(min[i] - focalPoint[i]);
|
||||
const maxDistance = Math.abs(max[i] - focalPoint[i]);
|
||||
|
||||
// If either the min or max point is outside the viewport extent, return false
|
||||
if (minDistance > parallelScale || maxDistance > parallelScale) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true; // The entire measurement extent is within the viewport
|
||||
};
|
||||
Reference in new issue
Block a user