I am working on a script that makes a road based on a spline, on a mesh terrain.
I could not find a move vertices function, so the only way I found to do this was to make a new mesh based on the unchanged and changed vertices.
It works ok, but is there a move vertices function that I could use instead, so I don’t have to duplicate the object properties? (material, unweld value, display modes etc.)
Is there a fast way to duplicate all the object settings? Or do I have to read out all those settings manually (Layer, material, mapping, display mode etc.)
I could not use or find that, and I could not find any info about it either, neither in help or on web. Could you help me out on where to find info about it?
This hasn’t yet been implemented in Python rhinoscriptsyntax. For RhinoCommon base methods look in the [SDK][1] under ObjectTable.Replace Method. This can be addressed via scriptcontext.Objects.Replace()
I was curious and did some testing for myself.
Below is a script to create an animated waving mesh. It manipulates the vertices of a mesh object and than sets the manipulated mesh via doc.Objects.Replace
test file with a plane mesh:wavemesh.3dm (66.8 KB)
import rhinoscriptsyntax as rs
import scriptcontext as sc
import math
def DirectMeshVertexSet():
#get mesh object
mesh_id = rs.GetObject("select mesh",rs.filter.mesh)
if (mesh_id == None) : return
#get mesh object in document
mesh_obj = rs.coercemesh(mesh_id)
#direct link to the vertex list of the object
vertices = mesh_obj.Vertices
#create a set of frames
for frame in range(100):
#for each frame loop through the vertices and set the Z value accordingly
for index, vertex in enumerate(vertices):
vertex.Z = math.sin((vertex.X**2+vertex.Y**2)**0.5-frame/5)
# set the new vertex
vertices.SetVertex(index,vertex)
#clearing Previous Normals
mesh_obj.Normals.Clear()
mesh_obj.FaceNormals.Clear()
#replace intial mesh with the edited mesh object
sc.doc.Objects.Replace(mesh_id,mesh_obj)
#Sleep to catch view manipulations
rs.Sleep(0)
#Redraw the viewports
rs.Redraw()
DirectMeshVertexSet()
Thanks, your curiosity is great!
Because I would never have figured that out by my self
I managed to implement what you did into my script and it works.
Hi Dale, Jørgen, Willem,
I encountered the very same problem as the OP… how to move mesh vertices with a script. As usual I first searched discourse and found this post. I see Dale’s list of steps but I get stuck on point 3:
I just cannot find a way to modify the coordinates of a vertex.
Can anyone of you point me in the right direction?
Well, as the first posts in the thread covered, you cannot directly modify yhe vertices of a mesh. You need to modify the point locations and then recreate an entirely new mesh based on the new vertex locations and the original face list.
Working backwards, to add a new mesh it wants this:
The first two arguments are required, the last three are optional. All 5 can be gotten via Rhinoscript for an existing mesh if you look at the Rhinoscript methods.
So, for your existing mesh, get at least MeshVertices and MeshFaceVertices.
Then, you are going to need to change the point coordinates of each the mesh vertices you want to modify, but without changing the index at which the mesh vertex is stored in the array.
Then you can re-create a new mesh with the modified array of mesh vertices and the existing array of face vertices, plus any of the other three optional arguments that you want to transfer over from the original mesh.
Sets or adds a vertex to the Vertex List. If [index] is less than
[Count], the existing vertex at [index] will be modified.If [index] equals
[Count], a new vertex is appended to the end of the vertex list.If [index] is
larger than [Count], the function will return false.
You do need to know the index of the vertex that you want to modify. If you have a mesh ID and the index (an integer) you could use SetVertex like this:
Maybe SetVertex is in Rhino 6 and not Rhino5? I tested this in Rhino 6 and it works. You will have to test it in Rhino 5. But in Rhino 6 there is no need to define a whole new mesh just to modify some vertices.
RhinoObject.Geometry gives you a duplicate of the object’s geometry
and ObjectTable.Replace() replaces the original geometry with what you provide.
EDIT
Actually the docs say that what the object receives from ObjectTable.Replace() is a duplicate of the mesh you give to the method.
Then I think we cannot edit a mesh (or any other geometry) in a RhinoObject without duplicating it twice …