update indices of a bufferGeometry in three.js - three.js

I have updated vertices of a BufferGeometry in Three.js. However, after that update, the indices of that bufferGeometry also need to be updated in my case. I just use geometry.setIndex(newIndicesArray) command without success. I am not sure if I need to enable any update flag for index. Thank you.

You want to update the indices of your indexed-BufferGeometry after the geometry has been rendered.
To do so, you cannot reassign a new index array -- you can only change the values of the existing array.
Consequently, you must use this pattern:
mesh.geometry.index.array[ 0 ] = 10;
mesh.geometry.index.needsUpdate = true;
For how to update vertices, see this related answer.
three.js r.84

Related

How to get updated buffer attributes in Threejs

When i apply a matrix to a buffergeometry
I want to get the updated position attributes fast , i am dealing with 1000000+ vertex .
I have tried Matrix4.applyToBufferAttribute() , but the buffer attribute is still the same
What is the most proper way to perform this ?
I have tried Matrix4.applyToBufferAttribute() , but the buffer attribute is still the same
Then it seems you are doing something wrong in your application. Matrix4.applyToBufferAttribute() does apply the matrix to the given attribute. The method is used multiple times in the core of three.js for example in BufferGeometry.applyMatrix():
https://github.com/mrdoob/three.js/blob/9f7f38b543c8a51d5614b72c04d657a4cfad68da/src/core/BufferGeometry.js#L141-L142
Ensure to set BufferAttribute.needsUpdate to true after the method invocation. And yes, it's the intended way to apply a 4x4 transformation matrix to a buffer attribute.

Paraview rotate fields

I am using Paraview 5.0.1. If any solution requires updating, I can try.
I want to programmatically obtain field plots (and corresponding PlotOverLine) of displacements and stresses in rotated coordinate systems.
What are appropriate/convenient/possible ways of doing this?
So far, I have created one Calculator filter for each component of displacements and stresses.
For instance, I used Calculators in 2D with results
(displacement.iHat)*cos(0.7853981625)+(displacement.jHat)*sin(0.7853981625)
(stress_3-stress_0)*sin(45.0*3.14159265/180)*cos(45.0*3.14159265/180)+stress_1*((cos(45.0*3.14159265/180))^2-(sin(45.0*3.14159265/180))^2)
It works fine, but it is quite cumbersome, in several aspects:
Creating them (one filter per component).
Plotting several of them in a single XY plot
Exporting them (one export per component).
Is there a simple way to do this?
PS: The Transform filter does not accomplish this. It rotates the view, not the fields.
Two solutions:
Ugly, inneficient solution
Use Transform and check "Transform All Input vectors"
Add a calculator and add a dummy array
Use transform the other way around, without checking "Transform All Input vectors"
Correct solution :
Compute the transformation yourself in a programmable filter
input = self.GetUnstructuredGridInput();
output = self.GetUnstructuredGridOutput();
output.ShallowCopy(input)
data = input.GetPointData().GetArray("YourArray")
vec = vtk.vtkDoubleArray();
vec.SetNumberOfComponents(3);
vec.SetName("TransformedVectors");
numPoints = input.GetNumberOfPoints()
for i in xrange(0, numPoints):
tuple = data.GetTuple(i)
transform(tuple) # implement the transform in python
vec.InsertNextTuple(tuple)
output.GetPointData().AddArray(vec)

Get index of an SKPoint in an SKPath

I'm not seeing an IndexOf or FindIndex method for SKPath.Points. I need to be able to get neighbouring points on both sides of a specified point. Path.Iterator only has .Next, so I am looking for using the index of the SKPoint instead.
With IndexOf or FindIndex seemingly missing, I am thinking of inheriting and maintaining a 2nd dataset in the background for getting the index.
Am I missing something obvious? How are others getting the index, so far?
This post helped. Calling IndexOf directly on Array works. Just need to make sure your SKPoint X and Y are unique from other SKPoints stored in the SKPath.Points. It is doing the check based on the SKPoint's position, so if you have multiple SKPoints at (0, 0), for example, it will return the first one at that position.
Luckily, I should never be in the situation for my use case.

How to copy faces and preserve transformation in Sketchup Ruby

I am new to Sketchup Ruby and am blown away this is not more simple but here goes...
I would like to copy all the groups matching a certain layer name to a new temporary group. I have basically given up on trying to copy the whole group because that appears to be fraught with peril and Bugsplats if not done in some super-anal retentive way that considers context, immediate exploding of objects, etc...
So, I have resorted to trying to loop through all matching groups entities and copying faces instead, which seems much more straight-forward. My goal here is not to become a Ruby wizard but just accomplish this one script.
I have been able to copy faces BUT the faces lose their transformation on copy and just end up at some random size at the origin rather than wherever they were at the model.
Here is the code:
SKETCHUP_CONSOLE.clear
mod = Sketchup.active_model # Open model
ent = mod.entities # All entities in model
temp_wall_primitives = ent.add_group #create a new empty temporary group
mod.definitions.each{|d|
next if d.image? || d.group? || d.name!="WALL"
d.entities.each{ |wall_primative_group|
if wall_primative_group.layer.name == "WALL_PRIMITIVES"
wall_primative_group.entities.each{ |wall_primative_group_entity|
if wall_primative_group_entity.is_a? Sketchup::Face
new_face = temp_wall_primitives.entities.add_face(wall_primative_group_entity.vertices)
end
}
end
}
}
I believe I need to somehow get the transformation of each face and apply it to the new faces as they are created?
Instead of trying to copy the entities from an instance to another one, place a new instance;
# Lets say we have a group.
source_group = model.entities.grep(Sketchup::Group)
# We can "copy" this to another group by fetching it'd definition and adding a new one:
new_group = model.entities.add_group
new_group.entities.add_instance(source_group.definition, source_group.transformation)
In your current solution, where you re-create each face, the reason for the transformation being lost is that vertex positions are relative to their parent. You pass in the vertices you copy from directly: temp_wall_primitives.entities.add_face(wall_primative_group_entity.vertices)
But you need to apply the transformation for the instance they relate to as well.
Additionally your current solution doesn't seem to take into account nested instances. And that faces can have holes in them - in which case face.vertices would not form a valid single loop. Manually recreating faces quickly gets complicated. If you want the whole content of a group or component instance, just make a copy of the instance itself. You can explode the new instance if you want.
But I would question why you have a temporary group in the first place. (Often this turns out to not be necessary. It would help if you explained the higher level task you are trying to perform here.)

THREE.js Migration r60 to r70: now cannot write: mesh.position = myVector3()

I am migrating a THREE.js app from r60 to r70. Amongst other changes I notice that r60 constructs of the following form no longer work in r70.
mesh.position.set(0,0,0);
myVector3 = new THREE.Vector3 (100,200,300);
mesh.position = myVector3;
This applies to meshes, pointLights, presumably to all Object3D's but I havent tested further.
In the above example the mesh.position x,y,z values remain unchanged at (0,0,0). For illustration see this JSFiddle and compare lines 70 and 73.
//...The next line DOES NOT update Sphere_mesh.position.x
Sphere_mesh.position = NewPos_vector3;//...
//...The next line DOES update Sphere_mesh.position.x
Sphere_mesh.position.x = NewPos_vector3.x
In a debugger no console warning is given during execution that the assignment has not worked. In the very brief THREE.js migration notes for (r68 --> r69) I see something about an Object3D's position no longer being immutable but I don't know what that means.
Anyway, my question
Is there a standard THREE construct or function I can use to copy x,y,z values from a Vector3 object to the x,y,z values of a mesh.position rather than the effective, but verbose, form such as
mesh.position.x = myVector3.x;
mesh.position.y = myVector3.y;
mesh.position.z = myVector3.z; ?
e.g. something such as
mesh.position = F_Get_Object3DPosition_from_Vector3(myVector3); ?
I know it would be easy to write my own function but a standard THREE function would be more likely to evolve smoothly with future versions of THREE.
position beeing immutable means that the position property can not be changed.
so
mesh.position = anything;
won't work (but you already discovered this)
what you can do is not change the position, but you have to change position values.
in your case, the easiest way is
mesh.position.copy (myVector3);
I think you meant myVector3 not myVector3() in the last line... Anyway, I though that would work too but the thing is, you are applying a Vector to something that supposed to be a point/Vertex. Even if that worked in my opinion it wasn't the right way to do it. How about using a simple array:
mesh.position.set(0,0,0);
new_position = [100,200,300]
mesh.position.fromArray(new_position,0)
in which 0 is the starting index. So you can have multiple position sets in one array

Resources