threejs cannot parse material in json object - json

Dear all I am using angular 2.4.10 and three js 0.85.0. After downloading a JSON file from the server, I have at my disposal the following JSON object:
https://drive.google.com/file/d/0B7IcIHZN137RdmVRTXpLZmlPaDg/view?usp=sharing
I am trying to load the object without using the loader URL using the following code suggested in another StackOverflow post:
loadModel(aJSONObject) {
console.log(aJSONObject);
let loader = new THREE.ObjectLoader();
let model = loader.parse( aJSONObject );
console.log(model);
.....
}
and it's working but it is not getting the materials. How can I get the material from the JSON file?

I tried to load your model and the unique material got imported correctly.
However, there is no texture nor color defined for this material in the JSON model. So the object will look white, the default color used for three.js materials.
Fiddle here.
To see your model in three.js make sure to scale it appropriately based on you camera position (I had to scale it down).Moreover, as the model is using a THREE.MeshPhongMaterial, don't forget to add some lights.
By the way, there are some X, Y and Z individual attributes defined in your model that increase its size uselessly (three.js won't use them).

Related

Import Shapes of Custom Library from Draw.io in mxGraph

I'm currently working with the mxGraph library in javascript and I'm trying to create my own shapes in draw.io, to export them, then to reuse them as much as I want in my own program using the mxGraph library.
So far, I have tried to create a custom library, which contains all my shapes. I have exported it in XML which gives me a half-encoded XML file. Then, I'd like to import that mxLibrary in my own app so I can reuse these shapes for creating my own diagrams. I have no idea how to deal with that XML file.
I have also tried taking the XML from Extras -> Edit Diagram and reimport it with the codec, then with mxGraph#addCells but the shapes aren't grouped anymore, and I can't seem to find how to clone them.
My goal would literally to have my list of shapes/cells somewhere, which I can reuse whenever I want.
If this is not possible, how may I do that instead? I have also looked up how to create my own shapes (with redrawPath and the style thing), but it looks really long and boring.
Here's an example of what the XML looks like. The shape is a simple double square.
<mxlibrary>[{"xml":"xVNBbsIwEHyN78EugjOhcOqpLzDJgi05XstZSPJ7trFbiAqCqpV6sLQ7O2N7xrJQZdNvow7mDWtwQr0KVUZESlXTl+CckIWthVoLKQteQm7uTGfjtAg6gqdnBDIJTtodISEJaGlwGThEPIZMg0jQT46q0HuoSO8+6cX3K4zUfP4WsAGKA1M6W5NJjGVWGbAHQ1NMt/keX8qLHy6ypdv21GN7nbEE70FXH33HDyHUylDDO65nXOo2sD1u9rYH3nV1N4lrx/LfHL/8veO9da5Eh5Exjx5+GUIWzJNgmHRXAS1uBLT4eUDcXn7TOJt8tjM=","w":80,"h":80,"aspect":"fixed","title":"custom_shape_1"}]</mxlibrary>
Thank you in advance!
There are 2 ways I know, to do it, depending on your needs.
Embed draw.IO as an iframe in your app, and create a plugin that adds your own palette of icon on the side bar. you can watch the p1 plugin code, and replicate it plugin list in draw.io, look for the p1 plugin
. code example of how to integrate draw.io in your app
hint: if pulgins are not loaded, check the plugin folder link.
If you add the vertices on you own app, create your own style, and reuse it when creating.
updateStyles()
{
var style = new Object();
style[(<any>window).mxConstants.STYLE_SHAPE] =
(<any>window).mxConstants.SHAPE_IMAGE;
style[(<any>window).mxConstants.STYLE_PERIMETER] =
(<any>window).mxPerimeter.RectanglePerimeter;
style[(<any>window).mxConstants.STYLE_IMAGE] =
'../assets/transformer.png';
style[(<any>window).mxConstants.STYLE_FONTCOLOR] = '#000000';
style[(<any>window).mxConstants.STYLE_WHITE_SPACE] = 'wrap';
style[(<any>window).mxConstants.STYLE_VERTICAL_ALIGN] = 'bottom';
this.graph.getStylesheet().putCellStyle('transformer', style);
}
reuse this style whenever creating a vertex using insertVertex function.
try {
const parent = this.graph.getDefaultParent();
this.graph.getModel().beginUpdate();
const vertex = this.graph.insertVertex(parent, uuid.v4(), node, 40, 40, 80, 40, 'transformer');
} finally {
this.graph.getModel().endUpdate();
}

Autodesk Forge Viewer: Change Texture in IFC Model

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.

Blender-exported JSON model shows wrong animations in THREE.js

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!

THREE.js - morphTargetInfluences on an imported JSON mesh not getting results

I have a basic three.js scene in which I am attempting to get objects exported from Blender (as JSON files with embedded morphs) to function and update their shapes with user input.
Here is a test scene
http://onthez.com/temphosting/three-js-morph-test/morph-test.html
The slab is being resized without morphs by simply scaling a box, which is working just fine.
I must be missing something fundamental with the little monument on top. It has 3 morphs (width, depth, height) that are intended to allow it to resize.
I am using this code to implement the morph based on users dat.gui input.
folder1.add( params, 'width', 12, 100 ).step(1).name("Width").onChange( function () {
updateFoundation();
building.morphTargetInfluences['width'] = params.width/100;
roofL.morphTargetInfluences['width'] = params.width/100;
roofR.morphTargetInfluences['width'] = params.width/100;
building.updateMorphs();
});
The materials for building, roofL, and roofR each have morphTargets set as true.
I've been going over the three.js examples here:
http://threejs.org/examples/?q=morph#webgl_morphtargets_human
as well as #webgl_morphtargets and #webgl_morphtargets_horse
Any thoughts or input would be much appreciated!
I believe I've reached a solution for my question I was under the impression that the JSON loader was preserving the morph target names to be used in place of an index number with morphTargetInfluences
something like morphTargetInfluences['myMorphTargetName']
but, after closer inspection in the console it seems like they should be referred to by number like morphTargetInfluences[0]
Not the most intuitive, but I can work with it.

WebGL - change mapAmbient material property in Three.js

I'm trying to update an image in a material of a pre-loaded .js model - i want it to have the same properties, whereas only the image is changed.
Was trying to use this post as a reference, but in the .js model file, the map appears as the "mapAmbient" property. I was thinking of somehow using the THREE.ImageUtils.loadTexture() function, but couldn't find where exactly it should be placed.
Moreover, the texture should be loaded using an Image() object generated using another canvas. Any help would be appriciated
*Edit:
Wasn't able to find actual way to change that property in runtime, but was able to change the image using base64 encoding:
//img is base64 encoded image
var tex = new THREE.ImageUtils.loadTexture(img);
currentMesh.material.materials[1].map = tex;