ClippingBox Class


(updated on 3/17/2023)
This fairly straightforward class essentially creates six cutting planes from the bounding box of a list of nodeids. The result is that only elements inside the bounding box will be visible. While it is of course possible to turn off visibilities of individual elements in HOOPS Communicator this approach allows for quickly “focusing in” on a precise area within a model. This can be particularly useful to limit the view to a “Space” in an IFC model where the individual items within that space are not children of the item in the tree hierarchy and might extend past the defined space.


Usage:

let myClippingBox = new ClippingBox(hwv);
Creates a new ClippingBox object.

myClippingBox.createFromNodes([hwv.selectionManager.getLast().getNodeId()]);
Activates and displays the clipping box from the bounding box of a list of nodeids (in this case the current selection is used)

myClippingBox.deactivate();
Hides the clipping box

myClippingBox.getActive();
If true clipping box is currently visible

myClippingBox.refresh();
Refreshes the clipping box. This function has to be called after a loadSubtree call which in some cases can remove custom cutting planes.

myClippingBox.setOpacity(opacity);
Sets the opacity level of the clip box geometry. (Default: 0.1)

myClippingBox.setEnableOnTop(onoff);
If true clipping box will be rendered on top of the model (Default: True)

myClippingBox.setEnableCutting(onoff);
If true the model will be clipped. (Default: True)

myClippingBox.getEnableCutting();
Returns if cutting planes are active

myClippingBox.calculateEntitiesInVolume(select = true, config = null)
Calculates all entities within the clipping box volume. If select is set to true, the found entities will be selected. In addition you can provide an optional IncrementalPickConfig object to control how the selection will be performed.
The function will return an array of nodeids which includes all entities found within the volume. This includes entities that are only partially within the volume.

myClippingBox.showMovementHandles();
Adds the standard handles to the clipping box.

The class works well with the new handles operators to interactively change the size and orientation of the clipping box. If you intend to utilize the new handles use the code below to register the ClippingBox class with those handles:

mySHandleManager.registerEventReceiver(function (nodeids) {
    myClippingBox.scaleEvent(nodeids[0]);
});

For a live demo of this class you can go here:
https://3dsandbox.techsoft3d.com/?snippet=3lV14CGX266sYaLINLR0sW&fullscreen=true&autorun=true


Below is the code for the ClippingBox class. It has no external dependencies except for the relevant HOOPS Web Viewer libraries. Simply include the JS file into your project.

It is important to note that this code is not production-ready and provided “as-is”. It is really meant as a starting point for your own development and as an example for some of the functionality and concepts used in HOOPS Communicator.

If you have any questions or comments please don’t hesitate to post them here in the forum.

ClippingBox.js (13.4 KB)

1 Like

After the box is generated. Rotate the model, the model will disappear

Can you be a little more specific? Would it be possible to provide me with a code snippet and/or the model you are testing with?

Guido

I used the wrong test model yesterday, and now the problem has been solved. Thank you very much.

1 Like

I asked you about the Clipping Box before.
But recently I found that when I use the handle, the model will move with the handle. The correct scenario should be that the handle can only be move the Clipping Box.
2

I tried to disable the rotation of the model in the onMouseMove method of the Clipping Box Class.Here is the code I tried to modify:

async onMouseMove(event) {
        // The model rotation is prohibited here
        const orbitOperator = hwv.getOperatorManager().getOperator(Communicator.OperatorId.Orbit)
        orbitOperator.stopInteraction()

        this._isClick = false;

        if (!this._shown) return;

        if (event.getButtons() ==0)
            return;

        if (this._dragAxis != null)
        {
            let smat = new Communicator.Matrix();    
            if (this._dragAxis < 3)
            {
                let d = this._calculatePlaneIntersect(event.getPosition());              
                smat.setScaleComponent(1+this._axisNodes[this._dragAxis].axis1.x*d,1+this._axisNodes[this._dragAxis].axis1.y*d,1+this._axisNodes[this._dragAxis].axis1.z*d);
            }
            else
            {
                let currentpos = event.getPosition();
                let d = this._startPos2D.y - currentpos.y;
                d /= 300;     //should probably be based on screen resolution
                smat.setScaleComponent(1+d,1+d,1+d);

            }
             
             let translateMatrix = new Communicator.Matrix();
             translateMatrix.setTranslationComponent(this._targetBoundingCenter.x, this._targetBoundingCenter.y,this._targetBoundingCenter.z);
             let translateMatrixInv = Communicator.Matrix.inverse(translateMatrix);

             let tempMat1 = Communicator.Matrix.multiply(translateMatrixInv, smat);
             let tempMat2 = Communicator.Matrix.multiply(tempMat1, translateMatrix);             
             let finalMat = Communicator.Matrix.multiply(tempMat2,this._startMatrix);

             await this._viewer.model.setNodeMatrix(this._targetNodeId, finalMat);

             for (let i=0;i<this._eventReceivers.length;i++)
             {
                (this._eventReceivers[i])(this._targetNodeId);
             }
             event.setHandled(true);
        }

    }

But this will cause the entire model to be unable to rotate.
What can I do to prevent the model from moving with the handle when using the handle
Thanks.

Here is an example of the clipping box as well as the standard and scale handles working together:

https://3dsandbox.techsoft3d.com/?snippet=7d3uQZ7gfeC8xQRULJ3Q6W

You must be doing something wrong in your code. It is possible that for some reason the operator stack is in a different order in your code. In particular, the handles should be pushed on the stack AFTER the orbit operator. Make sure that is the case.

Edit:
Here is a version of the above code that uses the new handle classes:
https://3dsandbox.techsoft3d.com/?snippet=3lV14CGX266sYaLINLR0sWv8&autorun=true

1 Like

I replaced the scale handle with the standard handle, so the model will not move with the handle. Thank you very much for your answer. :laughing:

1 Like