I recently discovered a strange behaviour using the autodesk forge viewer.
While viewing a model, i executed following code to add a red cube into my scene:
const mat = new THREE.MeshBasicMaterial({color: 0xff0000});
const geom = new THREE.BoxGeometry(50,50,50);
const cube = new THREE.Mesh(geom, mat);
NOP_VIEWER.impl.createOverlayScene('testOverlay', mat, mat);
NOP_VIEWER.impl.addOverlay('testOverlay', cube);
Regularly, the result would look as intended like this:
Adding a colored cube as intended
However, in the application I'm working in, the option setDisplayEdges is set to true as standard.
This seems to have the effect that any custom material used within the viewer is displayed as white, as seen in this example:
The same cube turned white without any change to the code itself
I was able to reproduce this in multiple models.
Glad to report that this has been fixed with the latest version 7.18
Related
I would like to link between elements from the 2D sheet and 3D model, so when I select the element from 2D it should reflect and select (isolate) in the 3D also if I change the color it does the same on both e.g. and the other way around.
so I can use the document browser extensions to open the 2d sheet on 1st viewer and the 3d model on the 2nd viewer:
const firstModel = new Autodesk.Viewing.Private.GuiViewer3D(document.getElementById('MyViewerDiv1'));
const secondModel = new Autodesk.Viewing.Private.GuiViewer3D(document.getElementById('MyViewerDiv2'));
Autodesk.Viewing.Initializer(options1, function() {
viewer1.start();
viewer1.load(...);
});
Autodesk.Viewing.Initializer(options2, function() {
viewer2.start();
viewer2.load(...);
});
if the example above is correct I am still missing how to links both viewers.
I hope someone could help me with this issue
Note that we have a viewer extension that might already give you what you're looking for: https://github.com/Autodesk-Forge/forge-extensions/blob/master/public/extensions/NestedViewerExtension/README.md.
If you want to implement the cross-selection between two viewer instances yourself, you can. Just subscribe to the SELECTION_CHANGED event in one of the viewers, get the selected IDs, and select the same IDs in the other viewer using the usual viewer.select([...]); method.
Btw. regarding your code snippet:
the Autodesk.Viewing.Initializer only needs to be called once per the entire webpage
the Autodesk.Viewing.Private.GuiViewer3D instances should be created after the initializer has done its work
we run a webapplication using Autodesk Forge. In the webapplication we'd like to change surface apperances. Therefore we use the following Audodesk functions
...
event.fragIdsArray.forEach(frag => {
const model = this.viewer.model;
model.getFragmentList().setMaterial(frag, this.material)
var object = this.viewer.impl.getFragmentProxy(this.viewer.impl.model, frag)
object.updateAnimTransform()
}
The code works fine for Autodesk Revit imported model. Using imported IFC models does not work as expected. Both models were imported to the AD Forge viewer by ADs model derivate api.
To geht our expected results we tried to use MeshBasicMaterial and MeshPhongMaterial. Both with the same result: Revit model is fine, IFC model aint so.
In Order to lookup for some workaround we tried to copy the fragment meshes and creating overlays with the same mashes and changed materials. Code was like
...
var obj = this.viewer.impl.getRenderProxy(this.viewer.impl.model, frag)
var meshProxy = new THREE.Mesh(obj.geometry, this.material);
meshProxy.matrix.copy(obj.matrixWorld);
meshProxy.matrixWorldNeedsUpdate = true;
meshProxy.matrixAutoUpdate = false;
meshProxy.frustumCulled = false;
this.viewer.impl.addOverlay("parkett", meshProxy);
...
The result is shown in the image (right side is the expected result):
Somehow it looks like the image texture is not shown "detailed" enough...
Thanks in advance for any suggestion!
From the question I'm not entirely sure what the problem is. Are there no visible changes when applying a custom material to IFC models? Or is the custom material applied, but in a "wrong way"?
If the custom material is not applied at all, make sure that the model is not consolidated. You can ensure that using viewer.model.unconsolidate();.
If the custom material is applied but its texture doesn't look correct, it could be because the geoemtries in the IFC model do not include proper texture coordinates. In that case you would have to map the texture yourself, for example, using a custom shader: https://github.com/petrbroz/forge-basic-app/blob/custom-texture-mapping/public/CustomTextureExtension.js.
I have an issue with a material on a second facemesh not showing in app but they do show up in spark AR.
I am super new with Spark (As in started today) and I did some face distortion in Blender and created a new Face mesh. This works fine however I also wanted to try creating freckles. I added a new face mesh for that and added a material and custom texture. This shows up in Spark AR but when I try it out in IG and FB only the face distortion and skin smoothing show up. Anyone know what I am doing incorrectly?
I already tried creating a new facemesh, creating a canvas and rectangle and connecting the mesh to that but it does not work.
As the freckles show up in SPARK AR i expect them to show up in app too, but this is not the case.
We are currently making the client retrieve the object states when the page loads (which will cause the 'pending' objects in the model to turn into different colors). Then we poll for changes to update the coloring (Firstly: pending object gets colored when the viewer loads, and then we keep polling to check and change state again, to make Forge render those in a different color and store their old color/material. When the polling received a change that an object should no longer be colored, it tells Forge to use the old color/material again.
The problem:
We've found out what the problem is, but we couldn't find out how to fix it. The problem is that changing materials in Forge doesn't work after startup anymore, it only works in the first ~3 seconds or so (the materials were used to show the colors).
However, setting overlays works even after the first ~3 seconds, (showing overlays instead of materials to show the colors).
This is not what we want to achieve. This looks unoptimized, because overlays will be shown through everything.
The materials, however, seem to be 'locked', as in, they cannot be changed anymore after the first ~3 seconds. It seems like they aren't refreshed or something
In the examples, we found they used viewer.impl.invalidate(true) to refresh the Forge viewer, but that doesn't do anything after ~3 seconds.
We've also tried every combination of viewer.impl.invalidate(true, true, true) as well as setting material.needsUpdate to true, as well as trying to re-render the entire scene.
We also found this: https://github.com/mrdoob/three.js/issues/790, but we couldn't find a good way to do that in Forge, we tried viewer.requestSilentRender() but that didn't do anything either.
Anyway, we've tried everything we could come up with and could find online to make the materials work, but nothing made a difference.
We are looking to find someone that's more experienced with how Forge works that can see what the material code is doing wrong.
As for the content, here is all the code you will need to understand what is happening:
DROPBOX LINK
And here is a small part of the "index.html" file that sets the color:
try
{
viewer.restoreAllColorOverlays(); //for materials instead of overlays: viewer.restoreAllColorMaterials();
$.each(colors, function(color, selectionIds)
{
viewer.setColorOverlay(selectionIds, color); //for materials instead of overlays: viewer.setColorMaterial(selectionIds, color);
});
}
catch(error)
{
console.error(error);
}
I have no idea how you implement your app, so I only tell what I found in your codes. If you want to resolve the issue you addressed, you can consider providing a reproducible case demonstrating that, I will gladly pass it to our dev team. Those following items should be in the reproducible case:
A short exact description of what you are trying to achieve. The behavior you observe versus what you expect, and why this is a problem.
A complete yet minimal sample source model to run a test in.
A complete yet minimal Forge app that can be run and debugged with a simple procedure to analyze its behavior lives in the sample model.
A complete yet minimal pure three.js app that can be run and demonstrated the shader effect you want. Note. Forge Viewer is using r71 three.js.
Detailed step-by-step instructions for reproducing the issue, e.g. which element to pick, what command to launch etc.
If your reproducible case could not be posted here publicly, please send it to the forge.help#autodesk.com and remove sensitive data or information before you send.
=== Something I found in your codes:
I found here are some wrong types and missing actions in your ColorMaterial extension. The color property of an material should the a type of the THREE.Color. Here is my modification:
Autodesk.Viewing.Viewer3D.prototype.setColorMaterial = function(objectIds, color)
{
if( !(color instanceof THREE.Color) ) throw 'Invalid argument: Color';
var material = new THREE.MeshPhongMaterial
({
color: color,
opacity: 0.8,
transparent: true
});
viewer.impl.matman().addMaterial( 'ColorMaterial-' + new Date().getTime(), material, true );
// ...........
};
Its' result is here:
In the ColorOverlay extension, The type of material color property is also wrong, it should be a type of THREE.Color, too. Changing it into THREE.Color should work fine. In addition, overlay is covers on 3D objects, so you should call viewer.hide() with your setColorOverlay() together. Otherwise, it won't look like a transparent object.
Without hidding 3D object of the wall:
hide 3D object of the wall:
I have a basic walk animation in Blender that I´m trying to export to THREE.js. It looks nice in Blender playback:
Now, after being exported with the THREE.js exporter, it looks like this on the browser:
The geometry is broken, not in all the body parts, but certainly has some problems. I´m not sure what to do now, I tried exporting with several options checked/unchecked, with no luck.
I also read the explanations in this posts, I think I followed all the required steps but still getting this weird animations:
http://unboring.net/workflows/animation.html#preview
https://github.com/mrdoob/three.js/pull/8412#issuecomment-210675561
https://github.com/mrdoob/three.js/issues/6050
The code I´m currently using to load the JSON model/animations is like this:
var loader = new THREE.JSONLoader();
var action = {}, mixer;
loader.load(path + '/dino.json', function (geometry, materials) {
materials.forEach(function (material) {
material.skinning = true;
});
character = new THREE.SkinnedMesh(
geometry,
new THREE.MeshFaceMaterial(materials)
);
scene.add(character);
/* ANIMATION */
mixer = new THREE.AnimationMixer(character);
action.walk = mixer.clipAction(geometry.animations[ 3 ]);
action.walk.setEffectiveWeight(1);
action.walk.enabled = true;
/* Update/render functions */
onUpdateFcts.push(function(delta, now){
mixer.update(delta);
});
action.walk.play();
});
I´m using Blender 2.78c and THREE.js r84, with the Blender exporter tool including in this revision.
I found some interesting links about similar animation problems:
Model with bones animation (blender export) animating incorrectly in three.js
http://dev.mothteeth.com/2012/10/threejs-blender-exporting-skeletal-animations/
Blender exports a three.js animation - bones rotate strangely
After reading all of these advices, I had successfully exported the animated mesh without visual artifacts following this workflow:
Create the armature bone by bone around the mesh. When done and in object mode, select first the mesh, then the armature, press CTRL+P > With automatic weights. This generates an armature modifier on the mesh. Against what I read, the armature modifier doesn´t need to be deleted before exporting.
You must have a default pose like the rest position. This must be the one selected on Blender. Also, the playback frame 0 must be selected in that default pose.
I created keyframes at the start and end of every pose for all the bones involved, this seems important.
You must unselect everything and only select the mesh, not the armature. This must be done in object mode.
My export settings:
Note: I must say that this is the same workflow I was following with no luck. This time the difference was that I first deleted every vertex group, also the armature modifier (not the armature itself) and recreated all the steps from the first one. Now, once exported the animated mesh worked fine enough!