0

So, I am trying to add TextGeometry to the viewer with Three.js. I am wondering if it is possible to do this, and how you would go about doing it.

I have looked on the docs, but none of their solutions seem to be working since the Forge viewer uses R71, and they are far past that now with three.js. I have also tried downloading the R71 examples from Github, but I get an error saying that one of the fonts is not existent even when I have included them with script tags in the html.

So, are you able to add TextGeometry to the viewer? And if so, could someone give me an example of how to do this.

I have also considered layering a 2D canvas over the viewer, but because the scene is bigger than the viewer canvas, it makes for a weird setup that I am not technically sure of how to fix.

The goal of this is to be able to add text to the viewer via javascript, meaning the user will have no control over the textbox, the script will spawn it.

Sam Curry
  • 445
  • 2
  • 11

1 Answers1

0

It is rather straightforward to import features from later versions of Three.js even if the Viewer version is behind. I used the threejs-full-es6 package which allows to import only what's needed from the version of Three.js, just so you don't bloat your app with two versions of the lib and also prevents namespace collision. It is using r89 at the moment, another good news!

Here is a simple ES6 extension I created that wraps the TextGeometry creation:

import { Font, TextGeometry } from 'threejs-full-es6'
import FontJson from './helvetiker_bold.typeface.json'

export default class TestExtension
  extends Autodesk.Viewing.Extension {

  constructor (viewer, options) {

    super()

    this.viewer = viewer
  }

  load () {

    return true
  }

  unload () {

    return true
  }

  /////////////////////////////////////////////////////////
  // Adds a color material to the viewer
  //
  /////////////////////////////////////////////////////////
  createColorMaterial (color) {

    const material = new THREE.MeshPhongMaterial({
      specular: new THREE.Color(color),
      side: THREE.DoubleSide,
      reflectivity: 0.0,
      color
    })

    const materials = this.viewer.impl.getMaterials()

    materials.addMaterial(
      color.toString(),
      material,
      true)

    return material
  }

  /////////////////////////////////////////////////////////
  // Wraps TextGeometry object and adds a new mesh to  
  // the scene
  /////////////////////////////////////////////////////////
  createText (params) {

    const geometry = new TextGeometry(params.text,
      Object.assign({}, {
        font: new Font(FontJson),
        params
      }))

    const material = this.createColorMaterial(
      params.color)

    const text = new THREE.Mesh(
      geometry , material)

    text.position.set(
      params.position.x,
      params.position.y,
      params.position.z)

    this.viewer.impl.scene.add(text)

    this.viewer.impl.sceneUpdated(true)
  }
}

Autodesk.Viewing.theExtensionManager.registerExtension(
  'Viewing.Extension.Test', TestExtension)

To use it, simply load the extension and invoke createText method:

import './Viewing.Extension.Test'

// ...

viewer.loadExtension('Viewing.Extension.Test').then((extension) => {

    extension.createText({
      position: {x: -150, y: 50, z: 0},
      bevelEnabled: true,
      curveSegments: 24,
      bevelThickness: 1,
      color: 0xFFA500,
      text: 'Forge!',
      bevelSize: 1,
      height: 1,
      size: 1
    })
})

enter image description here

Sweet! ;)

Felipe
  • 4,325
  • 1
  • 14
  • 19
  • This is awesome! I thought about pulling in a newer version, but I wasn't sure if it would work. What are you using to transpile this code? Just curious, I am considering using webpack since chrome doesn't appear to like ES6 imports. – Sam Curry Jan 21 '18 at 07:46
  • Webpack + babel-loader, most flexible/powerful configuration as far as I know. I created a Forge React Boiler if you are into React: https://github.com/Autodesk-Forge/forge-react-boiler.nodejs. This contains all the setup you need to start quickly with ES6, Webpack, Babel and Forge Viewer (you could also use that without React btw) – Felipe Jan 21 '18 at 10:20
  • This works great! The only problem I have is that when I change the size property in the object, it doesn't change the size at all. Have you tried this? – Sam Curry Jan 24 '18 at 22:34
  • Yeah I'm not sure what's the matter with TextGeometry, I didn't test if the behavior was different in a plain r89 three.js application. One thing that should work is to set the scale on the mesh object that was added to the scene. – Felipe Jan 25 '18 at 15:49
  • Changing the mesh still doesn't work for me. Would you suggest going back a version to R88? – Sam Curry Jan 25 '18 at 16:40
  • Setting scale on the mesh definitely works for me: mesh.scale.set(0.1, 0.1, 0.1) – Felipe Jan 26 '18 at 11:08
  • You are right. I wasn't changing it enough to notice the change. – Sam Curry Jan 26 '18 at 17:53
  • Is this still the best way to display text in the Autodesk Viewer? The [threejs-full-es6](https://www.npmjs.com/package/threejs-full-es6) package is now deprecated. – ChrisR Oct 06 '20 at 12:25
  • deprecated doesn't mean it is not working, keep in mind the forge viewer is using an antique version of three.js (to say the least, r71). So most of the non-deprecated packages of three.js you have out there might not be compatible with that relic. I can't tell for sure it's still the best way but it's a way that works, you are welcome to suggest a better way if you find one. – Felipe Oct 06 '20 at 16:01
  • Tested it with latest three package and it's not working. Using the deprecated threejs-full-es6 was the only way to get it to work. – Duzmac Mar 11 '21 at 03:46
  • yep just because of what I said above, forge viewer is using a very ageing three.js version which makes it uneasy to work with current three.js packages. Otherwise you would need to get your hands dirty and dig into the code to find out what you need to adjust, sometimes it's just few changes but some other it's more involved. – Felipe Mar 11 '21 at 12:45