Fix DICOM UPP model pivot
This commit is contained in:
@@ -94,6 +94,8 @@ const state = {
|
||||
modelMeshes: [],
|
||||
stlSignature: "",
|
||||
baseModelScale: 1,
|
||||
modelBoundsFrame: null,
|
||||
modelLocalBounds: null,
|
||||
dicomSceneBox: null,
|
||||
mappingViewport: { scale: 1, offsetX: 0, offsetY: 0, rotation: 0 },
|
||||
mappingDrag: null,
|
||||
@@ -1018,6 +1020,8 @@ function clearFusion() {
|
||||
state.dicomPlane = null;
|
||||
state.dicomPoints = null;
|
||||
state.dicomSlicePlanes = [];
|
||||
state.modelBoundsFrame = null;
|
||||
state.modelLocalBounds = null;
|
||||
$("fusionMeta").textContent = "DICOM - · STL -";
|
||||
$("fusionStatus").textContent = "等待选择 DICOM 与 STL";
|
||||
updateSliceControl();
|
||||
@@ -1449,6 +1453,7 @@ async function buildDicomVolume(volume) {
|
||||
const centerIndex = Number(volume.center || 0);
|
||||
const total = Math.max(1, Number(volume.total || 1));
|
||||
const indices = volume.indices || [];
|
||||
const frames = volume.frames || [];
|
||||
const centerPosition = indices.length ? Math.floor(indices.length / 2) : 0;
|
||||
state.volumeScene = {
|
||||
width,
|
||||
@@ -1477,7 +1482,7 @@ async function buildDicomVolume(volume) {
|
||||
const rangeDepth = Math.max(0.015, Math.abs(sliceToSceneZ(localEnd) - sliceToSceneZ(localStart)));
|
||||
const rangeBox = new THREE.LineSegments(
|
||||
new THREE.EdgesGeometry(new THREE.BoxGeometry(width * 0.94, height * 0.94, rangeDepth)),
|
||||
new THREE.LineBasicMaterial({ color: 0xfacc15, transparent: true, opacity: 0.56 }),
|
||||
new THREE.LineBasicMaterial({ color: 0x38bdf8, transparent: true, opacity: 0.24 }),
|
||||
);
|
||||
rangeBox.position.z = (sliceToSceneZ(localStart) + sliceToSceneZ(localEnd)) / 2;
|
||||
state.dicomGroup.add(rangeBox);
|
||||
@@ -1527,7 +1532,6 @@ async function buildDicomVolume(volume) {
|
||||
|
||||
const pointPositions = [];
|
||||
const pointColors = [];
|
||||
const frames = volume.frames || [];
|
||||
for (const [index, frame] of frames.entries()) {
|
||||
const image = await loadImageData(frame, 180);
|
||||
const stride = Math.max(2, Math.round(Math.max(image.width, image.height) / fusionDetail.pointGrid));
|
||||
@@ -1578,6 +1582,8 @@ async function buildStlModels(volume, onProgress = null) {
|
||||
}
|
||||
clearGroup(state.rawModelGroup);
|
||||
state.modelMeshes = [];
|
||||
state.modelBoundsFrame = null;
|
||||
state.modelLocalBounds = null;
|
||||
state.stlSignature = signature;
|
||||
const files = state.stlFiles.filter((file) => state.selectedStlIds.has(Number(file.id)));
|
||||
if (!files.length) {
|
||||
@@ -1618,8 +1624,33 @@ async function buildStlModels(volume, onProgress = null) {
|
||||
}
|
||||
const bbox = new THREE.Box3().setFromObject(state.rawModelGroup);
|
||||
const center = new THREE.Vector3();
|
||||
const size = new THREE.Vector3();
|
||||
bbox.getCenter(center);
|
||||
state.rawModelGroup.position.set(-center.x, -center.y, -center.z);
|
||||
bbox.getSize(size);
|
||||
state.rawModelGroup.position.set(0, 0, 0);
|
||||
state.rawModelGroup.traverse((object) => {
|
||||
if (!object.geometry) return;
|
||||
object.geometry.translate(-center.x, -center.y, -center.z);
|
||||
object.geometry.computeBoundingBox?.();
|
||||
object.geometry.computeBoundingSphere?.();
|
||||
object.geometry.computeVertexNormals?.();
|
||||
});
|
||||
const maxModelSize = Math.max(size.x, size.y, size.z, 1);
|
||||
const volumeSize = state.volumeScene
|
||||
? Math.max(state.volumeScene.width, state.volumeScene.height, state.volumeScene.depth, 1)
|
||||
: 4.8;
|
||||
state.baseModelScale = (volumeSize / maxModelSize) * 0.92;
|
||||
state.modelLocalBounds = {
|
||||
center: { x: center.x, y: center.y, z: center.z },
|
||||
size: { x: size.x, y: size.y, z: size.z },
|
||||
};
|
||||
const modelBounds = new THREE.LineSegments(
|
||||
new THREE.EdgesGeometry(new THREE.BoxGeometry(size.x, size.y, size.z)),
|
||||
new THREE.LineBasicMaterial({ color: 0xfacc15, transparent: true, opacity: 0.78 }),
|
||||
);
|
||||
modelBounds.name = "model-bounds";
|
||||
state.rawModelGroup.add(modelBounds);
|
||||
state.modelBoundsFrame = modelBounds;
|
||||
applyPose();
|
||||
scheduleMappingDraw();
|
||||
onProgress?.(100);
|
||||
|
||||
Reference in New Issue
Block a user