Skip to content

Commit

Permalink
feat(segmentation_user_layer) implemented getObjectPosition for MeshL…
Browse files Browse the repository at this point in the history
…ayer, finds the closest loaded associated mesh vertex to the global position
  • Loading branch information
chrisj committed Feb 15, 2024
1 parent 405557f commit fbafcf0
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 7 deletions.
70 changes: 70 additions & 0 deletions src/mesh/frontend.ts
Original file line number Diff line number Diff line change
Expand Up @@ -582,6 +582,76 @@ export class MeshLayer extends PerspectiveViewRenderLayer<ThreeDimensionalRender
);
return ready;
}

getObjectPosition(
id: Uint64,
nearestTo: Float32Array,
): Float32Array | undefined {
const transform = this.displayState.transform.value;
if (transform.error !== undefined) return undefined;
const chunk = this.source.chunks.get(getObjectKey(id));
if (chunk === undefined) return undefined;
const { rank } = transform;
const inverseModelToRenderLayerTransform = new Float32Array(
transform.modelToRenderLayerTransform.length,
);
matrix.inverse(
inverseModelToRenderLayerTransform,
rank + 1,
transform.modelToRenderLayerTransform,
rank + 1,
rank + 1,
);
const nearestPositionInModal = new Float32Array(rank);
matrix.transformPoint(
nearestPositionInModal,
inverseModelToRenderLayerTransform,
rank + 1,
nearestTo,
rank,
);
const { fragmentIds } = chunk;
let closestVertex = new Float32Array(rank);
let closestDistanceSq = Number.POSITIVE_INFINITY;
for (let fragmentId of fragmentIds) {
const fragmentChunk = this.source.fragmentSource.chunks.get(fragmentId);
if (fragmentChunk === undefined) continue;
const { state, meshData } = fragmentChunk;
if (
state !== ChunkState.SYSTEM_MEMORY &&
state !== ChunkState.GPU_MEMORY
) {
continue;
}
const { vertexPositions } = meshData;
if (vertexPositions.length < rank) continue;
for (let i = 0; i < vertexPositions.length; i += rank) {
let distanceSq = 0;
for (let j = 0; j < rank; j++) {
distanceSq += Math.pow(
vertexPositions[i + j] - nearestPositionInModal[j],
2,
);
}
if (distanceSq < closestDistanceSq) {
closestDistanceSq = distanceSq;
for (let j = 0; j < rank; j++) {
closestVertex[j] = vertexPositions[i + j];
}
}
}
}
if (closestDistanceSq === Number.POSITIVE_INFINITY) return undefined;
const layerCenter = new Float32Array(rank);
matrix.transformPoint(
layerCenter,
transform.modelToRenderLayerTransform,
rank + 1,
closestVertex,
rank,
);
return layerCenter;
}
}

export class ManifestChunk extends Chunk {
Expand Down
32 changes: 25 additions & 7 deletions src/segmentation_user_layer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ import {
MultiscaleMeshLayer,
MultiscaleMeshSource,
} from "#/mesh/frontend";
import { RenderLayerTransform } from "#/render_coordinate_transform";
import {
RenderScaleHistogram,
trackableRenderScaleTarget,
Expand Down Expand Up @@ -140,6 +139,7 @@ import {
fixedColorLayerControl,
} from "#/widget/segmentation_color_mode";
import { registerLayerShaderControlsTool } from "#/widget/shader_controls";
import { gatherUpdate } from "./util/array";

const SELECTED_ALPHA_JSON_KEY = "selectedAlpha";
const NOT_SELECTED_ALPHA_JSON_KEY = "notSelectedAlpha";
Expand Down Expand Up @@ -1259,13 +1259,31 @@ export class SegmentationUserLayer extends Base {

moveToSegment(id: Uint64) {
for (const layer of this.renderLayers) {
if (!(layer instanceof MultiscaleMeshLayer)) continue;
const layerPosition = layer.getObjectPosition(id);
if (layerPosition === undefined) continue;
this.setLayerPosition(
layer.displayState.transform.value as RenderLayerTransform,
layerPosition,
if (
!(layer instanceof MultiscaleMeshLayer || layer instanceof MeshLayer)
) {
continue;
}
const transform = layer.displayState.transform.value;
if (transform.error !== undefined) return undefined;
const { rank, globalToRenderLayerDimensions } = transform;
const { globalPosition } = this.manager.root;
const globalLayerPosition = new Float32Array(rank);
const renderToGlobalLayerDimensions = [];
for (let i = 0; i < rank; i++) {
renderToGlobalLayerDimensions[globalToRenderLayerDimensions[i]] = i;
}
gatherUpdate(
globalLayerPosition,
globalPosition.value,
renderToGlobalLayerDimensions,
);
const layerPosition =
layer instanceof MeshLayer
? layer.getObjectPosition(id, globalLayerPosition)
: layer.getObjectPosition(id);
if (layerPosition === undefined) continue;
this.setLayerPosition(transform, layerPosition);
return;
}
StatusMessage.showTemporaryMessage(
Expand Down

0 comments on commit fbafcf0

Please sign in to comment.