2

I would like to get the THREE.Mesh object of an element in Autodesk Forge Viewer. Here is the code:

var dbId;   // geometry node Id of an element
var viewer; // GuiViewer3D
var mesh = viewer.impl.getRenderProxy(viewer.model, dbId);

The return mesh object is a THREE.Mesh object but with null Geometry and Material, so it is useless. How can I get the real THREE.Mesh object?

Thank you.

Khoa Ho
  • 87
  • 2
  • 13

1 Answers1

2

It depends what you want to do with the mesh: if you want to change the render style, you need to get the renderProxy, if you want to transform the component position or rotation, you need to get the fragmentProxy.

Those methods take as input the fragment ids not the dbId.

Find examples for both at:

Viewing.Extension.Material

Viewing.Extension.Transform

You get the fragment Ids for a given dbId either from the selection event, as illustrated in the above samples, or by using enumNodeFragments:

 var instanceTree = model.getData().instanceTree

 var fragIds = []

 instanceTree.enumNodeFragments(dbId, function(fragId){
     fragIds.push(fragId)
 })

 // to change material or transform, need to iterate all
 // fragments of a given dbId and apply same material/transform

 fragIds.forEach(function(fragId) {

     var renderProxy = viewer.impl.getRenderProxy(viewer.model, fragId)

     var fragmentproxy = viewer.impl.getFragmentProxy(viewer.model, fragId)
 })
Khoa Ho
  • 87
  • 2
  • 13
Felipe
  • 4,325
  • 1
  • 14
  • 19
  • Can you please explain the difference between node element (dbId) and fragment (fragId). I know one dbId can map to many fragIds, and one fragId can map to many dbIds. What are they visually in the Forge viewer? – Khoa Ho Dec 20 '16 at 15:42
  • To be exact, I would like to get the real THREE.Mesh object with full geometry and material of an object dbId on click in Forge viewer. The renderProxy = viewer.impl.getRenderProxy(viewer.model, fragId) does not have the real geometry. It has null or zero boundary box and sphere even after executing THREE.BufferGeometry.computeBoundingBox() or .computeBoundingSphere() – Khoa Ho Dec 20 '16 at 16:46
  • Since the Forge viewer geometry.boundingBox is empty. I have to run fragmentList.getWorldBounds(fragId, fragBox) to manually calculate it. – Khoa Ho Dec 21 '16 at 16:34
  • A dbId represent the id of a single component that you can see in the model structure (parent or children) or can select visually in the viewer, so one dbId can map to 0 or several fragIds, this is correct. However a fragId cannot map to several dbIds, a fragId lets you access a specific fragment, which is separated into renderProxy and fragmentProxy, so it's not 100% equivalent to THREE.mesh. If you want to transform the fragment, you need the fragmentProxy, if you want to change the rendering style, you need the renderProxy. The examples I pointed out above illustrate both. – Felipe Dec 22 '16 at 01:28
  • Concerning the bounding boxes, I already replied to your request in this thread http://stackoverflow.com/questions/41248260/how-autodesk-forge-viewer-manages-multiple-scenes-to-select-multiple-elements. Combined approaches should let you access or modify any element in the viewer. – Felipe Dec 22 '16 at 01:29
  • That helps me to understand component dbId vs fragment Id. The proxy is the simplified THREE.Mesh. Thank you. – Khoa Ho Dec 22 '16 at 19:15
  • Does this mean that the mesh's geometric point-cloud and face-table are not readable via the Forge API? – Jack Jun 14 '17 at 20:35