bounds not correct for ImageResliceMapper

Dear VTK team
I think there is a bug for ImageResliceMapper.

ImageResliceMapper:
if (publicAPI.getSlicePolyData()) {
bds = publicAPI.getSlicePolyData().getBounds();
} else if (image) {
bds = image.getBounds();

  if (publicAPI.getSlicePlane()) {
    vtkBoundingBox.cutWithPlane(bds, publicAPI.getSlicePlane().getOrigin(), publicAPI.getSlicePlane().getNormal());
  }
}

if there is a slicePlane, it will call vtkBoundingBox.cutWithPlane

BoundingBox:
function _cutWithPlane(bounds, origin, normal) {
// Index[0…2] represents the order of traversing the corners of a cube
// in (x,y,z), (y,x,z) and (z,x,y) ordering, respectively
var index = [[0, 1, 2, 3, 4, 5, 6, 7], [0, 1, 4, 5, 2, 3, 6, 7], [0, 2, 4, 6, 1, 3, 5, 7]]; // stores the signed distance to a plane

var d = [0, 0, 0, 0, 0, 0, 0, 0];
var idx = 0;

for (var ix = 0; ix < 2; ix++) {
for (var iy = 2; iy < 4; iy++) {
for (var iz = 4; iz < 6; iz++) {
var x = [bounds[ix], bounds[iy], bounds[iz]];
d[idx++] = vtkPlane.evaluate(normal, origin, x);
}
}
}

var dir = 2;

while (dir–) {
// in each direction, we test if the vertices of two orthogonal faces
// are on either side of the plane
if (oppositeSign(d[index[dir][0]], d[index[dir][4]]) && oppositeSign(d[index[dir][1]], d[index[dir][5]]) && oppositeSign(d[index[dir][2]], d[index[dir][6]]) && oppositeSign(d[index[dir][3]], d[index[dir][7]])) {
break;
}
}

if (dir < 0) {
return false;
}

var sign = Math.sign(normal[dir]);
var size = Math.abs((bounds[dir * 2 + 1] - bounds[dir * 2]) * normal[dir]);
var t = sign > 0 ? 1 : 0;
/* eslint-disable no-continue */

for (var i = 0; i < 4; i++) {
if (size === 0) {
continue; // shouldn’t happen
}

var ti = Math.abs(d[index[dir][i]]) / size;

if (sign > 0 && ti < t) {
  t = ti;
}

if (sign < 0 && ti > t) {
  t = ti;
}

}
/* eslint-enable no-continue */

var bound = (1.0 - t) * bounds[dir * 2] + t * bounds[dir * 2 + 1];

if (sign > 0) {
bounds[dir * 2] = bound;
} else {
bounds[dir * 2 + 1] = bound;
}

return true;
}

issue1: the variable [dir] will never be 2, only will be 1 or 0, so the ordering will never be (z,x,y)
I have test by
var dir = 2;
while (dir–) {
console.log(dir);
}
It only print 1 and 0.

issue 2: follow the code below
if (sign > 0) {
bounds[dir * 2] = bound;
} else {
bounds[dir * 2 + 1] = bound;
}

if the dir = 2, only the bounds[4] or bounds[5] will be modified.
I think if there is a slicePlane in ImageResliceMaperr, and the plane is inside the cube, all of the bounds should be modified.

Best regards

Hello,

Can you, please, enclose the code between two ``` for adequate formatting?

thanks,

PC

I think there is a bug for ImageResliceMapper.

ImageResliceMapper:

function vtkImageResliceMapper(publicAPI, model) {
  // Set our className
  model.classHierarchy.push('vtkImageResliceMapper');

  publicAPI.getBounds = function () {
    var bds = _toConsumableArray(vtkBoundingBox.INIT_BOUNDS);

    var image = publicAPI.getInputData();

    if (publicAPI.getSlicePolyData()) {
      bds = publicAPI.getSlicePolyData().getBounds();
    } else if (image) {
      bds = image.getBounds();

      if (publicAPI.getSlicePlane()) {
        vtkBoundingBox.cutWithPlane(bds, publicAPI.getSlicePlane().getOrigin(), publicAPI.getSlicePlane().getNormal());
      }
    }

    return bds;
  };
}

if there is a slicePlane, it will call vtkBoundingBox.cutWithPlane

BoundingBox:

export function cutWithPlane(bounds, origin, normal) {
  // Index[0..2] represents the order of traversing the corners of a cube
  // in (x,y,z), (y,x,z) and (z,x,y) ordering, respectively
  const index = [
    [0, 1, 2, 3, 4, 5, 6, 7],
    [0, 1, 4, 5, 2, 3, 6, 7],
    [0, 2, 4, 6, 1, 3, 5, 7],
  ];

  // stores the signed distance to a plane
  const d = [0, 0, 0, 0, 0, 0, 0, 0];
  let idx = 0;
  for (let ix = 0; ix < 2; ix++) {
    for (let iy = 2; iy < 4; iy++) {
      for (let iz = 4; iz < 6; iz++) {
        const x = [bounds[ix], bounds[iy], bounds[iz]];
        d[idx++] = vtkPlane.evaluate(normal, origin, x);
      }
    }
  }

  let dir = 2;
  while (dir--) {
    // in each direction, we test if the vertices of two orthogonal faces
    // are on either side of the plane
    if (
      oppositeSign(d[index[dir][0]], d[index[dir][4]]) &&
      oppositeSign(d[index[dir][1]], d[index[dir][5]]) &&
      oppositeSign(d[index[dir][2]], d[index[dir][6]]) &&
      oppositeSign(d[index[dir][3]], d[index[dir][7]])
    ) {
      break;
    }
  }

  if (dir < 0) {
    return false;
  }

  const sign = Math.sign(normal[dir]);
  const size = Math.abs((bounds[dir * 2 + 1] - bounds[dir * 2]) * normal[dir]);
  let t = sign > 0 ? 1 : 0;
  /* eslint-disable no-continue */
  for (let i = 0; i < 4; i++) {
    if (size === 0) {
      continue; // shouldn't happen
    }
    const ti = Math.abs(d[index[dir][i]]) / size;
    if (sign > 0 && ti < t) {
      t = ti;
    }

    if (sign < 0 && ti > t) {
      t = ti;
    }
  }
  /* eslint-enable no-continue */
  const bound = (1.0 - t) * bounds[dir * 2] + t * bounds[dir * 2 + 1];

  if (sign > 0) {
    bounds[dir * 2] = bound;
  } else {
    bounds[dir * 2 + 1] = bound;
  }

  return true;
}

issue1: the variable [dir] will never be 2, only will be 1 or 0, so the ordering will never be (z,x,y)
I have test by

  let dir = 2;
  while (dir–) {
    console.log(dir);
  }

It only print 1 and 0.

issue 2: follow the code below

  if (sign > 0) {
    bounds[dir * 2] = bound;
  } else {
    bounds[dir * 2 + 1] = bound;
  }

if the dir = 2, only the bounds[4] or bounds[5] will be modified.
I think if there is a slicePlane in ImageResliceMaperr, and the plane is inside the cube, all of the bounds should be modified.

Best regards

@Paulo_Carvalho
I have formatted my question

1 Like

Try replacing this:

  let dir = 2;
  while (dir--) {
    console.log(dir);
  }

with this:

  let dir = 2;
  do {
    console.log(dir);
  } while (dir--) 

Then I belive the code is doing exatcly what was coded to do.