Recently, WE are talking about a project cooperation with a company. Their company is mainly engaged in oilfield related equipment, such as tank truck, pressure truck, pump truck and so on.

My impression as long as the oil related enterprises, and feel close to the money, 😄.

Their boss was impressed when he saw our company’s 3D products. Exclaim, our oil field management best also can use such a three-dimensional system.

We have never done 3d visualization projects in the oil field industry before, but we have a lot of experience in 3D visualization, such as 3d visualization projects of data center, hospital and school, as well as 3d visualization of directions of smart parks, smart cities and smart towns.

Let’s take a look at some three-dimensional visualizations:

Although we have not directly done 3d visualization of oil fields, it should not be too difficult to do with the technical accumulation of the above 3D solutions.

In fact, the customer’s demand is not to build a 3d visualization scene for an oilfield scene. Instead, I want to create a 3d layout tool for the oil field. Through the layout tool, I can build different oil field scenes freely.

It’s a lot harder than just building a three-dimensional scene.

All things are difficult at the beginning. When the world is difficult, it is done.

After the contract was established between the business personnel and the customer and the project was formally established, our design sister and development brother all performed their respective duties. Below, we will talk about the general content of the project.

Build a model library

The first step is modeling. The design team uses 3D modeling tools SUCH as 3D Max or C4D to model the oilfield equipment. After modeling, export files in obJ or GLTF format, which are the best file formats supported by our 3D rendering engine.

All model files after modeling will be put into the model library at the back end. The management directory of the model library is as follows:

Load model

Model loading can be done using the engine model loading function, such as obJ model loading, with the following example code:

new mono.OBJMTLLoader().load( 'yaliche.obj'.'yaliche.mtl'.' ',  (node)=> {
    node.type = 'obj'; box.addByDescendant(node); });Copy the code

Loaded a pressure above the car model, load model is an asynchronous process, so there will be a callback function, after the completion of loading in the callback function, the model file generated by the 3 d object into the scene container box, after joining, will show our 3 d objects in the scene, as shown in the figure below:

Build the editor framework

After discussion with the design team and the development team, we have preliminarily designed the framework and view of the editor, which looks like the following:

The top left corner of the view is our logo and the toolbar above. The left side is divided into the field area, which is the list for creating 3d scenes, and the component area, which is mainly the list of models, as well as some Echarts diagram components.

The middle part is the 3d scene display area.

I don’t need to go into too much technical detail about this page layout, but basically anyone who knows a little bit about front-end development can achieve similar results.

<div class="layui-layout layui-layout-admin">
      <div class="layui-side layui-bg-black" id="leftTreeWrap">
        <div class="layui-side-scroll">
          <div class="layui-collapse" id="leftTree">
            <div class="sceneTreeWrap">
              <div class="groupTitle"> Scene </div> </div> <div class="groupTitle"> Component </div> <div id="modelGroupWrap"> <! -- <div class="layui-colla-item modelGroup not-select" id="groundWrap">
                <h2 class="layui-colla-title"><span> Scene model </span></h2> <div class="layui-colla-content" id="groundTree">
                  <div class="tree-wrap"></div>
                </div>
              </div> -->
            </div>
          </div>
        </div>
      </div>
      <div class="layui-body">
        <div class="toolbar">
          <div class="temporaryTool"></div>
        </div>
        <div class="app" tabindex="0">
          <canvas id="monoCanvas"></canvas>
        </div>
      </div>
Copy the code

The left sidebar consists of two sections, a scene list and a model list. The scene list is a tree component, and the model list is an accordion component, as shown below:

The model list is created by first fetching all the models from the back end:

 getComponentTree({ params: { owner: user } }, 'Failed to synchronize cloud component tree').then((res) => {
      if (res) {
        const treeData = res.data.data;
        treeData.forEach(({ data }) => {
          this.appendModelBtn(data, true); }); // this.renderTreeDom(res.data.data); }});Copy the code

AppendModelBtn: Create model pairs of buttons from each model.

 appendModelBtn(modelData, isNew) {
    const domWrap = this.groupDom[modelData.group];
    if(! domWrap) { console.log('Missing group for this type', modelData.group);
      if (modelData.category === 'skyBox') {
        modelData.isNew = true; skyData.push({ modelData }); }}else {
      domWrap.querySelector('.tree-wrap').appendChild(this.createModelBtnDom(modelData, isNew)); }}Copy the code

Note that each model button needs to have the drag and drop function. The model button needs to listen for the Drag or dragstart event, which is encapsulated in a separate class called dragger.js that handles dragstart events:

 addDragger(parent, subClass, option) {
    parent.addEventListener('dragstart', (e) => {
      lettarget = null; Const path = eventPath(e);for (let i = 0; i < path.length; i += 1) {
        if (path[i].classList && path[i].classList.contains(subClass)) {
          target = path[i];
          break; }}... }Copy the code

The middle region is the 3d rendering region. First, create a Network3D object. Network3D object is an encapsulated 3D rendering page, whose bottom layer is composed of Canvas, and use WebGL technology for 3D rendering. Here is the code to create Network3D:

 const network = new mono.Network3D(box, null, 'monoCanvas');
    network.mode = 'editor';
    window.network = network; // todo
    this.network = network;
    network.bindApp(this);
    network.setRenderSelectFunction(() => false);
    make.Default.path = './static/myModellib/';

    network.setClearColor(0, 0, 0);
    network.setClearAlpha(0);
Copy the code

After creating the object, let the network adapt to the size of the middle region:

 mono.Utils.autoAdjustNetworkBounds(
      network,
      document.querySelector('.app'),
      'clientWidth'.'clientHeight',);Copy the code

The Box object on the network is used to manage the 3D object model to be loaded. Add a drag event to the model list, which can be added to a network object by dragging and dropping the model. Therefore, add the corresponding event to the network to add the object:

 onup: (e) => {
        if(! this.sceneTree.senceId && ! window.debug) { layui.layer.msg('Please create or select a scene first', {
            time: 2000,
          });
          return; } // Do not create when the mouse is not inside the canvasif(isPosInCanvas(network, e)) { network.createElement({ e, configString, senceId: this.sceneTree.senceId, }); }},Copy the code

After the model is dragged from the left model list to the Network object, after the mouseup event, create a model instance:

 network.createElement({
            e,
            configString,
            senceId: this.sceneTree.senceId,
          });
Copy the code

So far, you have completed the process of loading the entire model list and dragging and dropping models to create model instances. For example, the final oil field scenario through drag and drop looks like this:

In a 3D scene, you need to adjust the position, rotation Angle and zoom of the 3D model through the properties panel:

You can also use the 3D editing function to adjust the mark of the model directly in the 3D scene. To use the editing function, you only need to add the following line of code:

 const editInteraction = new mono.EditInteraction(network);
    editInteraction.setScaleable(false);
    editInteraction.setRotateable(false);
    editInteraction.setTranslateable(true);
    editInteraction.setDefaultMode(' ');

    network.setInteractions([...network.getInteractions(), editInteraction]);
Copy the code

The EditInteraction class is used to adjust the position, rotation, and scaling of the model. The keyboard allows you to adjust EditInteraction to which attribute is currently being adjusted:

case82: // r Toggle to rotate when element is selectedif(this.network.getIsMonoElement(this.network.currComponent)) { const editInteraction = this.network.getInteractions()[2];  editInteraction.setScaleable(false);
            editInteraction.setRotateable(true);
            editInteraction.setTranslateable(false);
          }
          break;
        case84: // t Toggle to move when element is selectedif(this.network.getIsMonoElement(this.network.currComponent)) { const editInteraction = this.network.getInteractions()[2];  editInteraction.setScaleable(false);
            editInteraction.setRotateable(false);
            editInteraction.setTranslateable(true);
          }
          break;
        case89: // y Toggle to zoom when element is selectedif(this.network.getIsMonoElement(this.network.currComponent)) { const editInteraction = this.network.getInteractions()[2];  editInteraction.setScaleable(true);
            editInteraction.setRotateable(false);
            editInteraction.setTranslateable(false);
          }
          break;
Copy the code

R switch to rotation Angle adjustment:

T key switch to position adjustment:

Y switch to zoom adjustment:

After dragging and dropping to create a scene, each object can also be docked with real-time data, and the result presented after docked is as follows:

After completing the creation of the scene and data docking, the scene can be published. Click the preview button in the toolbar to complete the release and preview of the scene. The last final release is as follows:

If you are interested in obtaining the editor, please email: [email protected]

Welcome to the public account “ITman Biao Shu”.