Model's Z-Axis is 2900 ft Above Ground & Cutting Plane Remains Unchanged After Adjustment

I am working with Hoops Communicator and trying to shift my model down to align its minimum Z with the world origin (Z = 0). The model was originally 2900 feet above the ground. I used the following code to translate it:

let actualBoundingBox = await this.viewer.model.getModelBounding(true, false);
// Shift the model so its minimum Z aligns with the world origin
const translationZ = -actualBoundingBox.min.z;
const translation = new Communicator.Point3(0, 0, translationZ);
const matrix = new Communicator.Matrix();
matrix.setTranslationComponent(translation.x, translation.y, translation.z);
await this.viewer.model.setNodeMatrix(this.viewer.model.getAbsoluteRootNode(), matrix);

await new Promise(resolve => {
  setTimeout(async () => {
    let updatedBB = await this.viewer.model.getModelBounding(true, false);
    // Adjust the camera position accordingly
    const camera = this.viewer.view.getCamera();
    const oldTarget = camera.getTarget();
    const oldPosition = camera.getPosition();
    const forwardDirection = oldTarget.subtract(oldPosition).normalize();
    const moveVector = forwardDirection.scale(-translationZ);
    camera.dolly(moveVector);
    const newTarget = updatedBB.center();
    camera.setTarget(newTarget);
    // Ensure camera up vector remains unchanged
    camera.setUp(camera.getUp());
    // Apply the updated camera
    await this.viewer.view.setCamera(camera);
    
    // **Set orbit target explicitly to the new model center**
    const orbitOperator = this.viewer.operatorManager.getOperator(Communicator.OperatorId.Orbit);
    if (orbitOperator) {
      orbitOperator.setOrbitTarget(newTarget); // Ensures orbiting uses the correct pivot
    }

    // Update bounding box after movement
    await this.updateBoundingBox();
    resolve();
  }, 3000);
});

Issue:

While this successfully moves the model, the cutting plane remains at the original height (2900 ft) instead of following the model down. I assume I need to update the cutting plane position, but I’m unsure how to adjust it correctly without disturbing the existing transformation logic.

Questions:

  1. How do I update the cutting plane position to align with the adjusted model?
  2. Are there any other elements (e.g., sectioning planes, measurement tools) that might also need adjustment after the transformation?
  3. Is there a better way to ensure all scene elements, including cutting planes, respect the new model position?

Would appreciate any insights! Thanks in advance.

also after transfomation the 3d model is pixelating or z-fighting on interaction

Hello @raja.r,

Our recommendation is to export the cutting sections using the function toJson(). Modify the 4 points of cutting plane reference geomemetry:

json.cuttingSections[0].planes[0].referenceGeometry

…accordingly taking into account the transformations applied. Then load the updated json via the function fromJson().

Indeed, if you have generated other elements then such elements will be out of place. You may be able to update the positions on those elements but perhaps your best bet is to apply those elements after transformation.

As to the rendering issue (pixellated and z-fighting), this may be because, by applying the transformation, the bounding box of the entire model is now much bigger than the original. Can you provide a video of this issue?

Thanks,
Tino

Is there a simple way to adjust the model’s Z position without modifying its transformation, possibly by adjusting the camera or another method?

Typically, models are constructed in object/local coordinates. Then, to orient that model in world space, the appropriate transformation matrix is applied. It sounds like to me that the object/local coordinates are actually already in world space — thus the need to apply the z-axis transformation as an offset. If you have access to the source model, you can try changing the model coordinate there.

It’s also possible to retrieve the geometry in the Web Viewer. An example is available in the Communicator package. To view this example, please do the following:

So will need to modify the points of the geometry accordingly to the desired values.

Thanks,
Tino

Got it! But will there be a performance impact for larger 3D models that are streamed dynamically each time?

Yes, retrieving the geometry would have to be done each time the model is loaded in the Web Viewer. For particulary large model assemblies, this might not be practical.

In your initial description, the model was inordinately high “above the ground.” Is the ground an arbitray plane or construct? Perhaps it might be easier to move the ground up, if possible.

async verticalShift() {
let actualBoundingBox = await this.viewer.model.getModelBounding(true, false);

  // Compute translation to bring model's min Z to 0
  const translationZ = -actualBoundingBox.min.z;
  const translation = new Communicator.Point3(0, 0, translationZ);
  
  // Apply transformation matrix
  const matrix = new Communicator.Matrix();
  matrix.setTranslationComponent(translation.x, translation.y, translation.z);
  await this.viewer.model.setNodeMatrix(this.viewer.model.getAbsoluteRootNode(), matrix);
  await this.viewer.waitForIdle();
  let updatedBB = await this.viewer.model.getModelBounding(true, false);
  // Adjust camera position accordingly
  const camera = this.viewer.view.getCamera();
  const oldPosition = camera.getPosition();

  // Move camera based on updated bounding box
  const newTarget = updatedBB.center();
  const cameraOffset = new Communicator.Point3(0, 0, translationZ); // Adjust position manually

  // Directly move camera to maintain the view
  camera.setTarget(newTarget);
  camera.setPosition(oldPosition.add(cameraOffset));

  camera.setUp(camera.getUp());
  camera.setNearLimit(0.001);

  // Apply new camera settings
  await this.viewer.view.setInitialCamera(camera);
  await this.viewer.view.setCamera(camera);
  await this.viewer.redraw();

  // Ensure orbit target is updated
  if (this.iafViewer.orbitOperator) {
      this.iafViewer.initializeOperators();
      this.iafViewer.orbitOperator.setOrbitTarget(newTarget);
      this.iafViewer.orbitOperator.setOrbitFallbackMode(Communicator.OrbitFallbackMode.Target);
  }

}

let planePosition = new Communicator.Matrix().loadIdentity().setTranslationComponent(+translation.x,+translation.y,+translation.z);
        plane.d = +d
        await cuttingSec.updatePlane(0,plane,planePosition, true, true)
      }

Update Cutting Plane:

  • Create a transformation matrix using the same translation.
  • Set the plane’s position (plane.d = +d).
  • Apply the updated position using cuttingSec.updatePlane(0, plane, planePosition, true, true). can you give me your code because bounding box is not aligning to model after ttransforamtion in cuttingplane with my approach

// // 1. Export the cutting planes to JSON
// let json = await this.viewer.cuttingManager.toJson();
// const minZ = this.iafViewer.modelBounding.min.z
// const boundingBox = this.iafViewer.modelBounding;

//   // 2. Apply the translation to each cutting plane reference geometry
//   json.cuttingSections.forEach(section => {
//     section.planes.forEach(plane => {
//         if (plane.referenceGeometry) {
//             plane.referenceGeometry.forEach(point => {
//                 point.z += minZ; // Adjust Z position
//             });
//         }

//         // Adjust the plane equation based on the bounding box transformation
//         if (plane.plane.normal.z !== 0) {
//             plane.plane.d += minZ * plane.plane.normal.z;
//         }
//         if (plane.plane.normal.x !== 0) {
//             plane.plane.d += boundingBox.min.x * plane.plane.normal.x;
//         }
//         if (plane.plane.normal.y !== 0) {
//             plane.plane.d += boundingBox.min.y * plane.plane.normal.y;
//         }
//     });
// });

//   // 3. Reload the modified JSON into the viewer
//   await this.viewer.cuttingManager.fromJson(json);
   THIS DID NOT WORKED

Let’s try the following:

Add a translation about the z-axis:

//Set up
let mat_z  = new Communicator.Matrix();
mat_z.setTranslationComponent(0, 0, -0.007);
hwv.model.setNodeMatrix(0, mat_z, false);

//Adjust the plane.d value and move the reference geometry:

//Assuming z-axis plane
let modelMat = hwv.model.getNodeMatrix(0);
let planeIndex = 0;
let cm = hwv.cuttingManager;
let cs = cm.getCuttingSection(2); //z-axis

let plane = cm.getCuttingSection(2).getPlane(planeIndex);
plane.d -= modelMat.m[14];//14 index is for z-axis
cs.updatePlane(planeIndex, plane, modelMat, true, false);

Here’s a short gif of the results:
cutting_plane