Help: speed smooth a mesh as fast as -Smooth

I am trying to smooth a mesh X number of times, but if I loop it in Rhino Common then it is much slower than Rhino’s Smooth command, why is that, and can I improve it?

import rhinoscriptsyntax as rs
import Rhino
import scriptcontext as sc
import time

SmoothNr = 1000
mesh_id = rs.GetObject("mesh to smooth",rs.filter.mesh,preselect=True)
if mesh_id:
    
    startTime=time.time()
    mesh = rs.coercemesh(mesh_id)
    coordinateSystem = Rhino.Geometry.SmoothingCoordinateSystem(2)
    plane = Rhino.Geometry.Plane.WorldXY
    for i in range(SmoothNr):
        mesh.Smooth(1,True,True,True,True, coordinateSystem, plane)
    sc.doc.Objects.AddMesh(mesh)
    print round(time.time()-startTime,2)
    
    
    ### Setting up smooth with out taking time
    rs.Command("_MeshBox 0 1 1 1 Enter SelLast Delete")
    rs.Command("_-Smooth SmoothFactor=1 CoordinateSystem=World X=Yes Y=Yes Z=Yes FixBoundaries=Yes Steps="+str(SmoothNr)+" Enter",False)
    rs.Command("_undo",False)
    
    ### Running the test
    rs.EnableRedraw(False)
    rs.SelectObject(mesh_id)
    startTime=time.time()
    rs.Command("_-Smooth Enter",False)
    print round(time.time()-startTime,2)
    rs.EnableRedraw(True)

With this I get the results 2.8 sec versus 0.5 sec…
So -Smooth is a whopping 5.6 times faster.

Here is a mesh to try it on:
mesh smooth dummy.3dm (263.9 KB)

I forgot to tag some brains.
@trav is this for you?

(Thanks for the edit @wim!)

Hi @Holo,

The both run thru the same code, so I’m not sure why one would be faster/slower than the other.

– Dale

I am not sure that the second one smooths with the same settings. After a first trial i got similar times as @Holo but once i’ve entered the values manually using _Smooth, there was only a small difference between runtimes. Still the Rhino command seems to be twice as fast.

_
c.

Thanks for testing, I don’t fully understand what you mean, because -smooth should remember it’s settings. That’s why I made a mesh box first and sat the values there, and then ran it with out setting the settings again on the real mesh. Did you find something else than that, that made it run only twice as fast?

I noticed that. On my first run i got values like these:

2.54
0.04

Then when i did start the _Smooth command after running your example, i saw that the Steps value was still set at 30. Once i changed it to 1000 and smoothed your part (without running the script part which changes the option values) i got the results:

2.61
1.33

so it got only faster using the _Smooth command but not the Python part.
_
c.

Hey @Holo

Keep in mind that mesh smoothing is iterative, so it takes longer each step since it has to go through the previous iterations.

Here you have a very simple definition in C# (still easy to understand). It has a Laplacian and Centroidal smoothing.
Smooth

Simplified SmoothMesh.gh (8.9 KB)

Hi Demifish, thanks for the info, fun to see the Centroidal version.
But this is about why the command version is faster than the scripted version running Rhino Common. I have a tool that I would like to smooth a mesh x times as fast as possible, that’s all :slight_smile:

Hi Clement, I use the -_Smooth version first to set the variables, but a bug got in there I think.

Please try this on the file:


import rhinoscriptsyntax as rs
import Rhino
import scriptcontext as sc
import time

SmoothNr = 1000
mesh_id = rs.GetObject("mesh to smooth",rs.filter.mesh,preselect=True)
if mesh_id:
    
    startTime=time.time()
    mesh = rs.coercemesh(mesh_id)
    coordinateSystem = Rhino.Geometry.SmoothingCoordinateSystem(2)
    plane = Rhino.Geometry.Plane.WorldXY
    for i in range(SmoothNr):
        mesh.Smooth(1,True,True,True,True, coordinateSystem, plane)
    newMesh=sc.doc.Objects.AddMesh(mesh)
    print round(time.time()-startTime,2)
    
    
    ### Setting up smooth with out taking time
    rs.Command("_MeshBox 0 1 1 1 Enter SelLast")
    rs.UnselectObject(newMesh) ### the newMesh is selected by the SelLast command, so I unselect it first
    rs.Command("_-Smooth SmoothFactor=1 CoordinateSystem=World X=Yes Y=Yes Z=Yes FixBoundaries=Yes Steps="+str(SmoothNr)+" Enter",False)
    rs.Command("_Delete",False) ### Deleting the smoothed dummy mesh
    
    
    ### Running the Rhino command to compare times
    rs.EnableRedraw(False)
    rs.SelectObject(mesh_id)
    startTime=time.time()
    rs.Command("_-Smooth Enter",False)
    print round(time.time()-startTime,2)
    rs.EnableRedraw(True)
    
    ### Now select the smoothed mesh and see that there are two similar meshes, one from each test

I see that if the SmoothNr is low then the script is faster, but if it is high like 1000 then the Rhino command is faster. And I want it faaaaast :wink: ((without using the command and messing up users settings))

Hi @Holo, with the second script i get this output:

2.4
0.4

me too, especially on larger meshes. But it seems that’s all you can get from python.

_
c.

1 Like

Thanks for testing. @dale are there anything you could do? Or I could do?

Well, the iterative code that is supposed to do the smoothing doesn’t yield anything remotely similar to the -_Smooth command.

Anyway, a quick peek at the code teaches me that using the Smooth() method on the mesh creates and deletes 1000 times a mesh, which is going to be much slower than the _-Smooth command since it doesn’t do that.

Ok, thanks.
So my only hope is wishing for an iterative smooth command in Common? Or to build my own?

Logging a couple of bugs:

RH-71529 Mesh.Smooth does not yield same results as Smooth command

RH-71530 Mesh.Smooth is slow when used in a loop

1 Like