Ok, then I have done it the right way.
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.)
Thanks again.
Ok, then I have done it the right way.
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.)
Thanks again.
Rhinoscript has ReplaceObject()
Sorry should be:
Rhino.ReplaceGeometry (strTarget, strSource [, blnDelete])
-Willem
Ah, superb, thanks, I’ll test it out right away.
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()
–Mitch
[1]: http://4.rhino3d.com/5/rhinocommon/
Hi Jorgen,
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.
I would like to edit the mesh vertex colors in the same manner, and I am trying to figure out how to get info about stuf like this, but all I find is:
http://4.rhino3d.com/5/rhinocommon/html/AllMembers_T_Rhino_Geometry_Mesh.htm
And that doesn’t make too much sense to me.
Can I add something like “vertex.Color=(0,0,255)”
And where can I find info about what values “vertex” has, like .X, .Y and .Z
Does it have a color value?
And the same about SetVertex. How can I find out what I can add?
Hi Jorgen
a little short in time at the moment but here goes:
For me it’s a lot of trail and error runs, here’s how I’d get to finding how to set the colors for a mesh
(instead of the vertices)
EDIT for some reason the image do not scale automatically, try CTRL and + to zoom in
HTH
-Willem
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?
I’m working in RhinoScript for Rhino 5…
thanks, Tobias
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.
Oh… ok. Thanks a lot. Now I get it
makes perfect sense
In Rhino.Geometry.Collections under MeshVertexList there is the method SetVertex that says you can directly modify a vertex in the geometry of a mesh.
SetVertex(self: MeshVertexList, index: int, vertex: Point3f) -> bool
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:
from scriptcontext import doc
from Rhino.Geometry import Point3f
def getGeo(id):
obj = doc.Objects.Find(id)
return obj.Geometry
meshGeo = getGeo(mesh)
meshGeo.Vertices.SetVertex(index, Point3f(x,y,z))
doc.Objects.Replace(mesh, meshGeo)
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.
Thanks Terry, but I am on RhinoScript. Your code looks like RhinoCommon…?
And btw generate a new mesh and replacing the old one works perfectly.
Maybe I got it wrong, but doesn’t this also create a new mesh with the modified vertices and replace the original?
I agree.
I think this is the way Rhino works
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 …
Yes I have also duplicated meshes by separately copying the faces and vertices with good results. But it takes more coding. And may be slower to execute.
There is RhinoScript code that will do the same thing as the RhinoCommon code I showed.
Your mileage may vary depending upon what you want to do with the mesh. If you want to see the modified mesh then you of course have to replace the geometry attached to the displayed ID. But if you want the geometey itself then using SetVertex method could be quick and simple. I do a lot of these geometry-only type of operations with meshes that are large (20M faces) and so need to be efficient in order to avoid hour-long execution times that some methods take (try doing .Contains on the whole mesh to check which points are inside and outside of a closed curve - you will regret it especially when this can be done in under 30 sec with more contemplative code).