I am going over an example from ami.js https://github.com/FNNDSC/ami/blob/dev/examples/viewers_quadview/viewers_quadview.js to visualize a 2D slice of a 3D model of a bone overlayed as a segmentation mask over a 2D image of a corresponding CT scan.
The only difference is that I modified it to read the 3D model mesh from a STL file instead of freesurfer.
The problem is that it renders artifacts of the segmentation mask from previous slices on top of the current CT scan. Instead of rendering a mask corresponding to the current CT scan.
In order to visualize the slices of the 3D model as 2D segmentation mask over 2D CT scans, the example creates a plane corresponding to the 2D slice with the CT scan.
function updateClipPlane(refObj, clipPlane) {
const stackHelper = refObj.stackHelper;
const camera = refObj.camera;
let vertices = stackHelper.slice.geometry.vertices;
let p1 = new THREE.Vector3(vertices[0].x, vertices[0].y, vertices[0].z)
.applyMatrix4(stackHelper._stack.ijk2LPS);
let p2 = new THREE.Vector3(vertices[1].x, vertices[1].y, vertices[1].z)
.applyMatrix4(stackHelper._stack.ijk2LPS);
let p3 = new THREE.Vector3(vertices[2].x, vertices[2].y, vertices[2].z)
.applyMatrix4(stackHelper._stack.ijk2LPS);
clipPlane.setFromCoplanarPoints(p1, p2, p3);
let cameraDirection = new THREE.Vector3(1, 1, 1);
cameraDirection.applyQuaternion(camera.quaternion);
if (cameraDirection.dot(clipPlane.normal) > 0) {
clipPlane.negate();
}
}
and applies it to the 3D mesh as a clipping plane during rendering
function render() {
... some code ...
// render r2 view
r2.renderer.clear();
r2.renderer.render(r2.scene, r2.camera);
// mesh
r2.renderer.clearDepth();
data.forEach(function(object, key) {
object.materialFront.clippingPlanes = [clipPlane2];
object.materialBack.clippingPlanes = [clipPlane2];
});
r2.renderer.render(sceneClip, r2.camera);
... some code...
}
jsfiddle that illustrates the problem is here http://jsfiddle.net/crfs6ugq/226/