3D-Models

Adding a 3D Model (Digital Twin) to GRID

4 minute read

Video Tutorial

See how easy it is to create and link a 3D model to a MOTORCORTEX application:

Introduction

The GRID 3D widget supports 3D models in GLTF format. GLTF is an open 3D format maintained by the Khronos Group. More information on the format can be found here: https://www.khronos.org/gltf/.

A lot of 3D modeling and CAD tools support exporting a model in GLTF format natively and these models can be use in the 3D widget directly.

A couple of guidelines are important to make the 3D model work properly:

  1. Binary output format (.glb) is preferred because of more efficient storage and smaller file sizes.
  2. Model size should be below 10 MB for optimal performance on lower end devices like tablets.
  3. Enabling shadows are expensive (cost a lot of computing power), especially when using complex scenes.
  4. Make sure your model has the Z-axis pointing up, also make sure the exporter keeps the z-axis up (some exporters make the y-axis point up). The 3D widgets camera navigation relies on this “z is up” convention to function properly.

Creating 3D models with Blender

Blender is an extremely capable open-source 3D modeler that is ideal for creating 3D models for use in GRID. You can download Blender for your favorite platform from the Blender website: https://www.blender.org/. Here you can also find excellent modeling tutorials that help you get started.

When modeling a Digital Twin in Blender there are some important guidelines:

  1. The GLTF exporter currently silently renames objects that contain spaces or other special character (like period (".")). This is a problem for objects that you want to link later to motorcortex parameters. Especially avoid putting spaces in Object names, since this will have unexpected results in the 3D view. Periods are okay, but you need to know that they are removed in the GLTF export; “Cube.001” will become Cube001 in the GLTF file.
  2. In GRID all transforms are done in the object’s local axis frame.
  3. You can connect your objects together by “parenting” them, the child has then a local axis frame that moves together with its parent object.
  4. Make sure your object Origin is located at the desired rotation point. One way to change an objects origin in Blender is to first position the 3D Cursor at the desired location and then “Origin to 3D Cursor” from the Object menu.
  5. Also make sure to “Apply Rotation” and “Apply Scale” to all your moving objects to avoid some strange behavior later.
  6. When exporting to GLTF from Blender, make sure the “+Y Up” in the “Transform” section of the exporter settings is Off.
  7. If you are using Object Modifiers, make sure you select “Apply Modifiers” in the “Geometry” section of the GLTF Exporter.

Using a GLTF file in GRID

To use a GLTF file in the GRID 3D Widget the following steps are required:

  1. Upload your GLTF file(s) in either .gltf or .glb format to your project. You can place you models in a subfolder if that is preferred.
  2. Create a new JSON configuration file, specifying some additional properties of the objects and linking object properties to MOTORCORTEX parameters. See below for an example. You can download the JSON schema here v-3d-schema.json. In the JSON you can add references to your model files that should be loaded by the 3D widget.
  3. In GRID, add a 3D widget to your canvas and in the “model” property select the JSON file.

Here is an example of a minimalistic JSON file:

{
  "files": [
    {
      "file": "cube.glb"
    }
  ],
  "objects": [
    {
      "name": "Cube",
      "links": [
        {
          "link": "root/Control/dummyDouble",
          "axis": "rz"
        }
      ]
    }
  ]
}

An example of a more complex JSON file:

{
  "files": [
    {
      "file": "scenery.glb",
      "name": "scenery"
    },
    {
      "file": "robot.glb",
      "name": "robot"
    }
  ],
  "camera": "Camera",
  "cameraLookAt": {
    "x": 0.0,
    "y": 0.0,
    "z": 0.5
  }
  "hemisphereLight": {
    "intensity": 0.8
  },
  "spotLight": {
    "x": 1,
    "y": 1,
    "z": 5.8,
    "castShadow": true,
    "angle": 0.5,
    "intensity": 0.2,
    "penumbra": 1.5
  },
  "traceLine": [
    {
      "link": "root/Control/actualToolCoordinates",
      "channel": 0,
      "axis": "x"
    },
    {
      "link": "root/Control/actualToolCoordinates",
      "channel": 1,
      "axis": "y"
    },
    {
      "link": "root/Control/actualToolCoordinates",
      "channel": 2,
      "axis": "z"
    }
  ],
  "objects": [
    {
      "name": "Floor",
      "receiveShadow": true,
      "castShadow": false
    },
    {
      "name": "Base",
      "receiveShadow": false,
      "castShadow": true
    },
    {
      "name": "Link1",
      "castShadow": true,
      "links": [
        {
          "link": "root/Control/dummyDoubleArray6",
          "channel": 0,
          "axis": "rz"
        },
        {
          "link": "root/Control/dummyDoubleArray6",
          "channel": 4,
          "axis": "opacity",
          "gain": 1,
          "value": 1
        },
        {
          "link": "root/Control/dummyBool",
          "axis": "visible"
        }
      ]
    },
    {
      "name": "Link2",
      "links": [
        {
          "link": "root/Control/dummyDoubleArray6",
          "channel": 1,
          "axis": "rz"
        }
      ],
      "castShadow": true
    }
  ]
}
Last modified March 23, 2021: Restructured GRID (44d0658)