Bug? mesh.Smooth() it is controlled by SMOOTH command settings

Hi guys, I have a script where I use

coordinateSystem = Rhino.Geometry.SmoothingCoordinateSystem(2)
plane = Rhino.Geometry.Plane.WorldXY
mesh.Smooth(grips,1,True,True,True,False, coordinateSystem, plane)

And I see that if I have ran the Smooth command in Rhino first and changed it’s setting to exclude some directions, then that affects the mesh.Smooth() too…

(to sum it up: The command Smooth’s settings overrides the mesh.Smooth() setttings)

I presume that is not as intended.

Hi @Holo,

Can you provide a full python code sample, plus a sample mesh, that isn’t smoothing?

Thanks,

– Dale

Hi Dale, sure,
This is the backbone of our most important internal script right now, so to me it is top priority, so here is a custom script made just for you :slight_smile:

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

mesh_id = rs.GetObject("mesh to smooth", rs.filter.mesh, preselect=True)
if mesh_id:
    ### Make a mesh to smooth
    mesh = rs.coercemesh(mesh_id)
    ### make a list for vertice indicators
    vertexIndices = []
    ### add them all
    nrV = len(mesh.Vertices)
    for i in range(nrV):
        vertexIndices.append(i)
    ### setup the variables to smooth 100% in all directions according to world
    smoothFactor = 1
    bXSmooth = True
    bYSmooth = True
    bZSmooth = True
    bFixBoundaries = True
    coordinateSystem = Rhino.Geometry.SmoothingCoordinateSystem(0)
    plane = rs.WorldXYPlane()
    ### Set up timers for feedback
    runTime = time.time()
    startTime = time.time()
    ### Set it up to smooth 1/10 of the number of vertices
    nrPasses = int(nrV/10)
    ### Make sure it smooths at least 10 times
    if nrPasses < 10:
        nrPasses = 10
    ###
    ### Smooth the mesh
    ###
    for i in range(nrPasses):
        mesh.Smooth(vertexIndices, 1, bXSmooth, bYSmooth, bZSmooth, bFixBoundaries, coordinateSystem, plane)
        
        ###
        ### Make the script escapable and give feedback 
        ###
        if sc.escape_test(False):
            print "ESC pressed"
            break
        ### Update the user how it is going on because blank screens are horrible
        if time.time()-runTime > 0.5:
            rs.Prompt("Smoothing pass "+str(i)+" of "+str(nrPasses)+" - Press ESC to terminate" )
            runTime = time.time()
    
    ### Add the mesh, update the view and give feedback
    sc.doc.Objects.AddMesh(mesh)
    sc.doc.Views.Redraw()
    print "Completed in "+str(round(time.time()-startTime,2))+" sec"

And here is a super simple mesh to test it on:

mesh.Smooth bug.3dm (60.4 KB)

Now here is what I want you to test:
1 the all is good test:
Run the command SMOOTH on the mesh in Rhino, make sure XYZ are all on.
Undo and run the script on the same mesh. (ALL IS GOOD!)

2 this is the problem test:
Undo and now Run the command SMOOTH with ONLY Z on.
Undo and run the script and now see that X and Y is ignored now as well, even if it says True in the script.

So for some strange reason the SMOOTH command overrides the script settings.

(And an OT question: Why is running the command SMOOTH much faster on say 500 smoothings than if I do the same in the script? To see this you would need a larger mesh, so please make a 100x100 mesh heightfield from image to test it, if you need it. And IMO it would be great if the mesh.Smooth could have a “number of passes” option to it so I don’t need to put it in a loop)

Here you can see an example of how we use mesh.Smooth:
I have made a script that takes input curves as a boundrycurve + breaklines + holes and then pulls points from these + populates within the boundrycurve with points (minus the holes minus a given distance to all curves) then builds a mesh of all of this, and then gets all the “inbetween” vertices and smoothes those.
Then it builds the edgemesh and give it thickness and groups it all, all in one go.

And the latest revision now tags the curves and the mesh with data so I can adjust them, select the group and hit the same button for the command to automatically update the geometry (I use replace so materials, layers etc are kept) And I can remove curves and add new ones, or retag them so I can change a hole to a breakline etc.

It’s the most complex thing I have made so far, but it’s robust and fast, and not impossible to maintain either… yeah, I have finally learned to use definitions and to annotate so the future me can understand what I did :wink:

The input is just boundry and the light curves as breaklines.

And I have another script to pull the top off the mesh and make height curves from those.
Here shown with transparency, I love that “hidden option” for curves.
And another script that tags it with IFC data, gives it materials and puts it on layers.

So having control over how the smoothing works would be great.

Hi @Holo,

Thanks for providing the sample. There is a pretty obvious typo in the internal SDK function, clearly my fault. A fix should be available in next week’s Rhino 7 SR18 RC.

https://mcneel.myjetbrains.com/youtrack/issue/RH-67886

Thanks for reporting,

– Dale

Awesome! Thanks for handling this so fast Dale!

And a million thanks for your incredible stamina regarding all my noob questions during the last decade, you have really changed my life in many ways. And thanks to everybody else who have contributed too of course (and all our partners who endure periods of time with absentmindedness due to single tracked, problem solving man-cave-attributes :wink: )

2 Likes