three.js Cube Geometry - how to update parameters? - javascript

Possibly dumb question but here goes. Three.js geometries have 'parameter' feilds associated with them, see the box geometry here...
box Geometry parameters
I am trying to update these parameters like this...
var nodeSize = 10;
var geometry = new THREE.CubeGeometry(nodeSize, nodeSize, nodeSize);
mesh = new THREE.Mesh(geometry, new THREE.MeshNormalMaterial({side:THREE.DoubleSide}));
scene.add(mesh);
mesh.geometry.parameters.depth=20;
But of course, the geometry remains unchanged. Is there a way of updating the geometry by editing these parameters?
fiddle here https://jsfiddle.net/kn3owveg/2/
Any help appreciated!

parameters.depth is only used at geometry construction time. it has no effect when modifying it. you can think of it as read only.
Use the example at BoxGeometry and the gui on the right to see how to achieve what you want.

Gaitat is totally right, you can't change geometry with changing of parameters.
And there can be another solution. With scaling of your cube.
function setSize( myMesh, xSize, ySize, zSize){
scaleFactorX = xSize / myMesh.geometry.parameters.width;
scaleFactorY = ySize / myMesh.geometry.parameters.height;
scaleFactorZ = zSize / myMesh.geometry.parameters.depth;
myMesh.scale.set( scaleFactorX, scaleFactorY, scaleFactorZ );
}
...
setSize(mesh, 10, 10, 20);
jsfiddle example

Technically, scaling only creates the illusion of an updated geometry. I would say a better approach would be to reassign the geometry value of your mesh to a new geometry.
mesh.geometry = new THREE.CubeGeometry(newSize, newSize, newSize)
With this approach you can update any aspect of the geometry including depth segments for example. This is especially useful when working with non cube geometries like cylinders or spheres.
Here is a full rework of your original code using this approach, really only the last line has changed:
var nodeSize = 10;
var geometry = new THREE.CubeGeometry(nodeSize, nodeSize, nodeSize);
mesh = new THREE.Mesh(geometry, new THREE.MeshNormalMaterial({side:THREE.DoubleSide}));
scene.add(mesh);
mesh.geometry = new THREE.CubeGeometry(nodeSize, nodeSize, 20);

Related

Drawing custom shapes with THREE BufferGeometry - shape is see through depending on angle

I am working with THREE.js and BufferGeometry to create a view of a set of points based on an image. Currently, I have the following:
As can be seen, the "object" that I have constructed has faces that can only be viewed from the opposite side as intended.
I have constructed my BufferGeometry with the a set of points with a corresponding array of normals, implemented like so (assuming that verts and norms are valid):
vertices = Float32Array.from(verts)
normals = Float32Array.from(norms)
// Make new geometry
geometry = new THREE.BufferGeometry();
geometry.setAttribute('position', new THREE.BufferAttribute(vertices, 3))
geometry.setAttribute('normal', new THREE.BufferAttribute(normals, 3))
material = new THREE.MeshPhongMaterial({color: 0xffffff})
mesh = new THREE.Mesh(geometry, material)
geometry.computeVertexNormals()
scene.add(mesh)
As you can see from trying to add the array of normals, I have tried adding normals in which all are (0,1,0). Without geometry.computeVertexNormals(), this still results in none of the faces being solid/behaving correctly. With such, the result in the image is generated.
What could be causing the solid to behave as such?

Overlaying texture onto STL loaded mesh

I'm looking for an efficient method of overlaying a texture to cover a mesh. I'm not an expert, more a novice, when it comes to 3 dimensional mapping/objects. Below shows how I would like the end product to look.
When attempting to apply texture with the following code, the end result looks similar to below. I have not done any UV mapping, I believe my answer may be lay here. As you can see from the below image it roughly takes the general shade of the picture but I get the impression that the texture is being drawn between each vertice of the model rather than across the entirity.
var textureLoader = new THREE.TextureLoader();
var texture = textureLoader.load('resource/images/materials/Mahogany.jpg');
var STLLoader = new THREE.STLLoader();
STLLoader.load( 'test.stl', function ( geometry1 ) {
var meshMaterial = new THREE.MeshBasicMaterial({map:texture});
var mesh = new THREE.Mesh( geometry1, meshMaterial );
mesh.scale.set(1, 1, 1);
mesh.position.set(5, 20, 80);
scene.add(mesh);
});
The cube has the correct texturing, whereas my STL loaded mesh does not.
Please ignore the rotation of the object in the above picture, I will move to unioning my objects together once I have fixed my texturing issues.
Fairly new at asking questions on here so please do comment to help me expand my question if it's too general or not percise enough. Thank you.
You may use
THREE.MeshPhongMaterial()
instead of
THREE.MeshBasicMaterial()
THREE.MeshPhongMaterial() will wrap the material outside the object and we can get curved material as per the object.

How to Change a Box's dimensions/size after creation?

One can easily create a THREE.BoxGeometry where you have to pass arguments when creating as three separated arguments for width, height, and depth.
I would like to create any and all THREE[types]() with no parameters and set the values after that.
Is there a way to set the dimensions/size of the box geometry after creation (possibly buried in a Mesh already too)? other then scaling etc.
I couldn't find this in the documentation if so, otherwise maybe a major feature request if not a bug there. Any thoughts on how to classify this? maybe just a documentation change.
If you want to scale a mesh, you have two choices: scale the mesh
mesh.scale.set( x, y, z );
or scale the mesh's geometry
mesh.geometry.scale( x, y, z );
The first method modifies the mesh's matrix transform.
The second method modifies the vertices of the geometry.
Look at the source code so you understand what each scale method is doing.
three.js r.73
When you instantiate a BoxGeometry object, or any other geometry for that matter, the vertices and such buffers are created on the spot using the parameters provided. As such, it is not possible to simply change a property of the geometry and have the vertices update; the entire object must be re-instantiated.
You will need to create your geometries as you have the parameters for them available. You can however create meshes without geometries, add them to a scene, and update the mesh's geometry property once you have enough information to instantiate the object. If not that, you could also set a default value at first and then scale to reach your target.
Technically, scaling only creates the illusion of an updated geometry and the question did say (other then scaling). So, I would say a better approach would be to reassign the geometry property of your mesh to a new geometry.
mesh.geometry = new THREE.BoxGeometry(newSize, newSize, newSize)
With this approach you can update any aspect of the geometry including width segments for example. This is especially useful when working with non box geometries like cylinders or spheres.
Here is a full working example using this approach:
let size = 10
let newSize = 20
// Create a blank geometry and make a mesh from it.
let geometry = new THREE.BoxGeometry()
let material = new THREE.MeshNormalMaterial()
let mesh = new THREE.Mesh(geometry, material)
// Adding this mesh to the scene won't display anything because ...
// the geometry has no parameters yet.
scene.add(mesh)
// Unless you intend to reuse your old geometry dispose of it...
// this will significantly reduce memory footprint.
mesh.geometry.dispose()
// Update the mesh geometry to a new geometry with whatever parameters you desire.
// You will now see these changes reflected in the scene.
mesh.geometry = new THREE.BoxGeometry(size, size, size)
// You can update the geometry as many times as you like.
// This can be done before or after adding the mesh to the scene.
mesh.geometry = new THREE.BoxGeometry(newSize, newSize, newSize)

Three.js: wrong BoundingBox after scaling a geometry

In my scene I have a simple cube:
var test = new THREE.Mesh(new THREE.CubeGeometry(10,10,10), new THREE.MeshBasicMaterial());
scene.add(test);
This cube is getting traversed/scaled through the user with THREE.TransformControls. What I need is the boundingbox of the cube after these interactions. So I'm doing
test.geometry.computeBoundingBox();
var bb = test.geometry.boundingBox;
bb.translate(test.localToWorld( new THREE.Vector3()));
But I always get a wrong boundingbox! The translation is computed correct, but not the scale. The width and heigth of the boundingbox is always 10 ...
Is this a bug or feature? How do I get the correct boundingbox of my cube?
You can compute the world-axis-aligned bounding box of an object (including its children) like so:
var box = new THREE.Box3();
box.setFromObject( object );
Have a look at the source code so you understand what it is doing.
three.js. r.60

How to access the each element individually in Three.js

I have created mesh and rendered " 10 " 3d objects using three.js?
how to access each object to perform scaling , rotation & all stuffs so there is a
need to get the div object individually?
help me to solve this issue ?
thanks !
You do not seem to be asking a real question. But rather asking for someone to teach you something. In the 'startup code' a SphereGeometry object is combined with a MeshBasicMaterial object in order to create the Mesh object which is your 3d object that you can then use to access/set the objects position, rotation, etc. Here are the lines of code I am referring to:
var geometry = new THREE.SphereGeometry( 75, 20, 10 );
var material = new THREE.MeshBasicMaterial( { color: 0xffffff, wireframe: true } );
var mesh = new THREE.Mesh( geometry, material );
Once you create mesh objects you need to add them to the scene with a call to scene.add(mesh). At this point you can set or get the rotation or position as such
mesh.position.x = 50;
mesh.rotation.z = Math.PI / 2 // rotations are in radians

Categories

Resources