Update vertices of mesh object based on another object


(Qtov) #1

Hello,

How would one approach the task of writing a python script that can bring the vertices (the ones outlined in blue) of separated meshes towards a NURBS object with the same shape.

sphere_question

(I have cut the original NURBS sphere in two just for illustration purposes).

  1. Is it possible to accomplish this without having to guide the script, so it would have to go through each mesh object and shoot up from any vertex to find the corresponding NURBS?

  2. What happens if a blue vertex is not a welded vertex and there are actually two vertices in that place (like where the green and yellow objects meet)? What if there are three?

Any pointers how I can approach this idea greatly appreciated :slight_smile:


(Pascal Golay) #2

Hello - probably the easiest is to pull (Brep.ClosestPoint()) all the vertices to the surface then replace the mesh with one that has the new vertex locations.

import scriptcontext as sc
import Rhino
import rhinoscriptsyntax as rs


def test():
    
    meshId = rs.GetObject("Select a mesh.", 32, preselect=True)
    if not meshId: return
    
    srfId = rs.GetObject("Select a surface.", 8)
    if not srfId: return
    
    
    mesh = rs.coercemesh(meshId)
    brep = rs.coercebrep(srfId)
    
    pts = mesh.Vertices
    
    pulledPts = [brep.ClosestPoint(pt) for pt in pts]
    
    pts.Clear()
    
    for pt in pulledPts:
        pts.Add(pt)
        
    sc.doc.Objects.Replace(meshId, mesh)
    
    sc.doc.Views.Redraw()
    pass
    
    
test()

Something like that? I guess you could also use SetVertex() on each vertex.

    pts = mesh.Vertices
    
    for i in range (pts.Count):
        pts.SetVertex(i, brep.ClosestPoint(pts[i]))

Probably also want to mesh.RebuildNormals() before replacing the original.

-Pascal


(Qtov) #3

Hello Pascal,

This is perfect! Thank you very much for writing this.

I can make the script iterate through different meshes and execute the code you wrote.
Although I have no idea how to approach it so that after a mesh is selected a corresponding NURBS surface to be found.

Do you have any ideas how this can be done?

I am thinking of taking a random vertex from the mesh and somehow detecting the nearest NURBS object, or subobject of an object, is something like this doable?

The end goal would be so that iterating through each mesh the script can find the corresponding surface on its own for more complex cases than this example scenario.

Thank you


(Pascal Golay) #4

I think I’d compare bounding boxes - see which ones overlap.
Pascal