HOOPS Communicator Assembly Creator Demo


This demo introduces an unique workflow using HOOPS Communicator that loads parts from a parts list and constructs an assembly model using custom mate operators such as collinear, concentric and coplanar. This workflow can be utilized in various industries such as maintenance manual, work instruction or e-commerce (custom order), etc.
The created assembly structure can be represented in a JSON string and reproduced.

Sample project

Download the sample project from the following Git repository:

git clone https://github.com/techsoft3d/assembly_creator.git

Setup and Usage

Please refer README.MD in the Git repository.

Custom operators

This demo realizes several custom operators.
Each custom operator can be used independently for other projects.

PartDragDropOperator (part_drag_drop_operator.js)

The PartDragDropOperator class is a custom operator used to insert a part by starting a drag in a parts list and dropping it into the Web viewer.


  1. Register the custom operator and activated
this.partDropOp = new PartDragDropOperator(this.viewer, this);
this.partDropOpHandle = this.viewer.operatorManager.registerCustomOperator(this.partDropOp);
  1. Create a parts list
    Each part image belongs the partList_thumbnail class and has an SC model name as a dataset property: data-model

  2. Register a mouse down event handler to the part thumbnail images.
    When a part thumbnail is dragged, its SC model name will be set to the operator using the setPart function.

    $('.partsList_thumbnail').on('mousedown', (e) => {
        const partName = e.currentTarget.dataset.model;


  • LoadSubtreeConfig.attachInvisibly
    When the setPart function loads the dragged part SC model, setting LoadSubtreeConfig.attachInvisibly = true avoids displaying loaded model before the mouse cursor is placed in the Web viewer.

  • Dragged part positioning
    Although the mouse cursor slides on the 2D screen, the part’s position should be determined from its 2D position in 3D.

    In this operator, part position is determined like below:

    1. Create an anchor plane which is at the center of bounding box (anchor) of existing models and normal to a vector (current camera position - anchor)
    2. Compute the ray of current mouse position (2D) using View.raycastFromPoint
    3. Compute the intersection point (3D) between the anchor plane and ray using Plane.intersectsRay

CollinearMateOperator (collinear_mate_operator.js)

The CollinearMateOperator class is a custom operator used to align parts by selecting two liner edges to match.

Mobile part direction is reversible using the Flip button.


  • Pre-selection
    In the mate operators, target line / face entities for mating are computed during onMouseMove event using SelectionItem returned by View.pickFromPoint method.
    SelectionItem provides various methods such as isLineSelection, isFaceSelection, getLineEntity, getFaceEntity, etc. for retrieving entity parameters.
    Pre-selected entities are represented using Model.setNodeLineHighlighted, Model.setNodeFaceHighlighted and ArrowMarkup (common_utilities.js).

  • Part alignment
    In the mate operators, part position is applied using the following steps with selected entity vectors:

    1. Compute a rotation axis using Point3.cross and angle using Point3.dot APIs in the vectorsAngleDeg function (common_utilities.js)
    2. Create a rotation matrix of the axis and angle using Matrix.createFromOffAxisRotation API and apply it to the mobile part node using Model.setNodeMatrix
    3. Compute a translation distance
    4. Create a translation matrix of the distance using Matrix.setTranslationComponent and apply it to the mobile part node
      Actual rotation and translation processes are performed in a separate custom class, called nodeTranslation (node_translation.js)

ConcentricMateOperator (concentric_mate_operator.js)

The ConcentricMateOperator class is a custom operator used to align parts by selecting two circular edges / faces to be concentric.

The angle and location of the mobile parts can be adjusted using the buttons.

CoplanarMateOperator (coplanar_mate_operator.js)

The CoplanarMateOperator class is a custom operator used to align parts by selecting two planer faces to match.

Position of the mobile parts can be adjusted using the buttons.

HandleOperatorOperator (handle_oprator_oprator.js)

Apart from the three mate operators, part can be moved by drag & drop the handle operator.
In default (no command is running), HandleOperatorOperator is activated. The HandleOperatorOperator customizes the behaviors of the built-in HandleOperator so that it can translate a part using an inclining axis.


Although the handle operator can be activated using HandleOperator.addHandles, the position and rotation of the handle can be updated using HandleOperator.updatePosition.
The HandleOperatorOperator update handle rotation according to the selected entity:

  • When a cylindrical face is selected, it aligns the Z axis with the center axis of the face
  • When a planer face is selected, it aligns the Z axis with the normal vector of the face
  • When an liner edge is selected, it aligns the Z axis with the edge direction

Model tree

This demo is using a jquery plugin: jsTree to represent a model structure and control visibility of parts.
The ModelTree class (model_tree.js) is a wrapper class providing functions for creating a model structure such as createRoot, addNode and deleteNode.

Undo / Redo support

Although the Web viewer API doesn’t provide undo / redo functionalities, this demo supports undo / redo operation using an original objects and methods.

const history = {
    type: "transform",
    nodeId: this._mobileNode,
    initialMatrix: initialMatrix,
    newMatrix: newMatrix,


Saving assembly structure using JSON

In this demo, result of the assembly structure (member parts and each visibility and location) is represented using a JSON string.

By keeping the JSON string, this demo can reproduce result of the assembly structure even after re-loading the page.