Threejs: Geometry vertices not updated when exported to stl - javascript

I'm trying to export an stl from Threejs using this stl exporter
https://gist.github.com/paulkaplan/6513707
When I open the model in meshlab the vertex positions don't seem to keep their rotations from the parent mesh.
The rotations are applied to the mesh, not the geometry. Is there any flag I need to set in order to update the vertex positions?
Here's the code Im using (CS):
geometry = new THREE.CubeGeometry( 10, 10, 10)
mesh = new THREE.Mesh(geometry)
mesh.position.set(10, 10, 10)
mesh.lookAt new THREE.Vector3
scene.add mesh
saveSTL(geometry, 'mesh')

You need to apply a transform to the geometry directly (instead of the mesh), in order for the exporter you are using to work as you intend.
geometry.applyMatrix( new THREE.Matrix4().makeRotationX( - Math.PI / 2 ) );
Look in Matrix4.js for the other transforms you can construct.
three.js r.62

Related

three.js map mesh.geometry.attributes.uv

I am currently working on a 3D configurator.
So I should be able to import a logo on a FBX object, which normally already have UV coordinates.
The problem is : I am struggling since 3 days ago, trying to import a texture on a mesh but I can't map it using his UVs coordinates.
So, I have a texture with a logo.
When I map it on a simple Cube, no problem, it is working :
But when I try to apply the same texture to my mesh :
The texture is cropped.
So I've been looking inside the mesh json tree and I found it :
So there are uv coordinates, but it seems different from my cube because, when I look to his json, I don't find the same tree which is (on the cube) :
And finally, this is my code :
if(myMesh.name == 'Logo'){
// Texture
var texture = new THREE.TextureLoader().load('img/logoTesla_Verre_green.jpg', function(){
texture.needUpdate = true;
// Material
var material = new THREE.MeshLambertMaterial( {map: texture, morphTargets: true} );
material.needUpdate = true;
// Geometry Cube
var geometry = new THREE.BoxGeometry( 40, 40, 40 );
// Cube
var cube = new THREE.Mesh( geometry, material);
scene.add(cube);
// Duplicate logo mesh for testing
var newGeometry = myMesh.geometry;
var newMesh = new THREE.Mesh( newGeometry, material);
newMesh.position.y = 100;
newMesh.geometry.uvsNeedUpdate = true;
scene.add(newMesh);
});
}
My question is : Should I use the geometry.attributes.uv object to map my texture ? If yes, how to do that ?
Or should I convert these UV coordinates to a geometry.faceVertexUvs ???
Please, help me, I am totally lost :)
Nevermind, it has been solved by exporting the .fbx again.
Now the mapping is working fine !
But I don't know why...
Thank you for your question and answer. I was having the same problem where my custom FBX I imported was only taking the bottom left pixel of the canvas as the color for the whole mesh. (I was using texture = new THREE.CanvasTexture(ctx.canvas); to get my texture).
The issue for me was that the FBX had no UV mapping! How I solved it was I imported the fbx to maya, opened up the UV editor (under the modeling menu mode got to UV->UV editor ) then in the UV editor there was a Create section and I hit one of those options (i chose cylinder) and then exported it with the default fbx settings. I am very grateful this worked.
You can see the result of using a canvas context as a custom FBX texture here:
www.algorat.club/sweater

Invert material image of sphere in three.js

I'm using a plugin that implements 360 / VR video into our video player. It does this by using Three.js to create a sphere and taking the video itself and making it the material the sphere is created out of. The viewport is then set inside of the sphere to give it the 360 view.
The problem I'm running into is that the material is placed on the sphere using THREE.DoubleSide (THREE.BackSide would also work since we're only viewing it from the inside of the sphere), but the image is inverted since we are viewing it from the inside.
Is there a way to invert the image material that is placed on the sphere?
One way to create a spherical panorama, that is not inverted, is to use this pattern:
var geometry = new THREE.SphereBufferGeometry( 100, 32, 16 );
var material = new THREE.MeshBasicMaterial( { map: texture } );
var mesh = new THREE.Mesh( geometry, material );
mesh.scale.set( - 1, 1, 1 );
scene.add( mesh );
It is generally not advisable to set negative scale values in three.js, but in this case, since you are using MeshBasicMaterial which does not utilize normals, it is OK to do so.
three.js r.75

Using three.js, how do I determine which plane my mesh is facing?

I'm trying to build a simple game that shoots stuff out of a barrel of a gun. So far I have a simple group with a cube and a cylinder added as the barrel. When I rotate the group (90 degrees at a time) the barrel moves around facing different directions and that all fine.
My problem is that I cannot for the life of me figure out a way to determine which way the barrel of my gun is pointing. I need to know how to identify the face of the cube that the barrel is attached to and to what part of the 3D world it is facing..either X+, Y+, Z+, X-, Y-, Z-. Forgive me if my lexicon is all wrong in describing this. I have not posted any of my attempts because they are not working at all.
Please take a look at this CodePen for an example of what I'm trying to do...
... and here's some code just because I can't post this on SO w/o it.
var geometry = new THREE.BoxGeometry( 50, 50, 50 );
var material = new THREE.MeshNormalMaterial();
var cube = new THREE.Mesh( geometry, material );
var cylgeo = new THREE.CylinderGeometry( 10, 5, 100, 32 );
var cylmesh = new THREE.Mesh( cylgeo, material );
cylmesh.rotateZ(Math.PI/2);
cylmesh.translateY(35);
var group = new THREE.Group();
group.add( cube );
group.add( cylmesh );
scene.add(group);
First, construct your "gun" so the barrel, by default, points up the positive-z axis by modifying your code like so:
cylmesh.rotateX( Math.PI / 2 );
Add a helper axis to your scene so your can see what you are doing:
scene.add( new THREE.AxisHelper( 100 ) );
In this configuration, when the parent group has rotation zero, the barrel of the gun points up the positive-z axis.
If the parent group is rotated, you can get the direction the group (and hence the barrel) is looking like so:
var vector = new THREE.Vector3(); // create once an reuse
...
group.getWorldDirection( vector );
The returned value of vector will be unit-length vector pointing in the same direction as the barrel.
three.js r.75

My object isn't reflects the light in Three.js

I have some CubeGeometry based mesh in a three.js scene, and all of them reflects the PointLight what I'm using globally. But one of them, which made by "hand" with just THREE.Geometry (add vertices and faces by code) is not reflected. Even it has no color, I only can set color for this, if I set a THREE.Color to "emissive" key on the MeshPhongMaterial.
The geometry made by a JS function dinamically. I'm using this litghs:
pointLight = new THREE.PointLight(0xFFFEF0, 1, 100000)
pointLight.position = camera.position;
scene.add(
pointLight
);
And I'm creating the mentioned mesh with this code:
var floor = new THREE.Mesh(
ShelfArchitect.Utils.getFloorGeometry(walls),
new THREE.MeshPhongMaterial(materialParams)
);
I should add something on materialParams? Or what is the problem?
It sounds like the geometry made by "hand" is missing, or has incorrect, vertex normals.
You can do this:
geometry.computeFaceNormals();
geometry.computeVertexNormals();

Custom shapes in Three.js

In my project the shapes I created were spheres and I used an image as texture for material...
How can I make a custom shape (not sphere, rectangle, etc.)? For example, how can I create a halfsphere?
My code for now:
// create a texture
texture = THREE.ImageUtils.loadTexture('red.png');
// create a sphere shape
geometry = new THREE.SphereGeometry(50, 16, 16);
// give it a shape red color
material = new THREE.MeshLambertMaterial({map: texture});
// create an object
mesh = new THREE.Mesh( geometry, material);
There are multiple ways to use geometry in Three.js, from exporting models via a 3D editor (like Blender, for which a nice Three.js exporter already exists), to creating geometry from scratch.
One way would by to create instance of THREE.Geometry and add vertices, and then work out how those connect to add face indices, but this not an easy way to do it.
I would suggest starting with the existing geometries (found in the extras/geometries package) like THREE.CubeGeometry, THREE.CylinderGeometry, THREE.IcosahedronGeometry, THREE.OctahedronGeometry, etc.)
Additionally there are some really nice classes that allow you to generate extrusions (THREE.ExtrudeGeometry) and lathes(THREE.LatheGeometry). For extrusions, see this example.
You mentioned creating half a sphere. That's an ideal candidate for using LatheGeometry.
All you need to do is create a half-circle path (as an array of Vector3 instances) and pass that to the lathe so it revolves the half-circle into 3D - a halfsphere.
Here's an example:
var pts = [];//points array - the path profile points will be stored here
var detail = .1;//half-circle detail - how many angle increments will be used to generate points
var radius = 200;//radius for half_sphere
for(var angle = 0.0; angle < Math.PI ; angle+= detail)//loop from 0.0 radians to PI (0 - 180 degrees)
pts.push(new THREE.Vector3(Math.cos(angle) * radius,0,Math.sin(angle) * radius));//angle/radius to x,z
geometry = new THREE.LatheGeometry( pts, 12 );//create the lathe with 12 radial repetitions of the profile
Plug that geometry into your mesh and Bob’s your uncle!
Optionally, you can centre the mesh/pivot using GeometryUtils:
THREE.GeometryUtils.center(geometry);

Categories