The only safe way to Update Sliders in GhPython

ghpython
python
slider

(Giulio Piacentino) #1

Over the years, there have been lots of threads here and on the old Grasshopper forum that deal with setting slider values in Grasshopper. They all have some advantages and disadvantages, but they have something in common: they too often end up breaking the Grasshopper SDK rule “never edit values while the definition is running”.

This thread shows a way of fixing that. This is a Rhino-6-only possibility, because this feature is new in Rhino 6. By overriding the Component Context menu, we can set the values outside of the solution, in a very Grasshopper-classic way.

Like this definition by Anders Holden Deleuran on the old Grasshopper forum, this uses the logic of searching sliders by name. You can however adapt it to using slider InstanceGuids, so that they can be renamed.

image

Here is the code:

"""
Reset named sliders.
Right-click on the component and choose "Update Sliders!" to update their values.
    Inputs:
        Sliders: (strings) A list with names of sliders
        Values: (numbers) A list with values of sliders
    Remarks: This component does not retuns any values.
 """

from ghpythonlib.componentbase import executingcomponent as component
import Grasshopper, GhPython
import System
import Rhino
import rhinoscriptsyntax as rs

class UpdateSliders(component):
    
    def RunScript(self, Sliders, Values):
        if not Sliders or not Values:
            Sliders = None
            Values = None
            return
        self.Sliders = Sliders
        self.Values = Values
        if len(Sliders) != len(Values):
            raise Exception("Different lenghts of sliders and values")
        self.Component = ghenv.Component
        self.GhDef = None
        if self.Component: self.GhDef = self.Component.OnPingDocument()
        
        
    def AppendAdditionalComponentMenuItems(self, menu):
        item = Grasshopper.Kernel.GH_Component.Menu_AppendGenericMenuItem(
            menu, "Update Sliders!", self.OnClicked, self.Icon_24x24, None, True, False);
        item.ToolTipText = "Update the sliders now";
        
        
    def OnClicked(self, obj, args):
        try:
            self.UpdateValues(obj, args)
        except Exception, ex:
            System.Windows.Forms.MessageBox.Show(str(ex))
            
    def UpdateValues(self, obj, args):
        if not self.GhDef: return
        if not self.Sliders or not self.Values: return
        
        ghObjects = self.GhDef.Objects # Get to the GH objects
        
        # Iterate the GH objects
        for obj in ghObjects:
            # Set the named slider values
            if type(obj) is Grasshopper.Kernel.Special.GH_NumberSlider and \
                obj.NickName in self.Sliders:
                
                # Set min/max
                #obj.Slider.Minimum = 0
                #obj.Slider.Maximum = 10
                
                # Set value
                obj.Slider.Value = self.Values[self.Sliders.index(obj.NickName)]
                
                # Update slider
                obj.ExpireSolution(True)

Have a look and see if it helps!
Thanks,

Giulio


Giulio Piacentino
for Robert McNeel & Associates
giulio@mcneel.com


Dynamic input of min/max range of sliders?
Problem Controlling Range of Sliders with Python
Manipulate slider values via code
Pulling % values from total Square Footage to Equal 100%
Deleting Rhino objects during solution time
In "Grasshopper", the way moving slider and automatically baking
Accessing GH canvas componens from Python (outside of GH)
Building a value list based on values in sc.sticky or other non-GH storage space
Using same slider variables in few custom componets [Solved]
(IVELIN PEYCHEV) #3

Maybe this is pointless, because it slows the solution, but if the only safest way is to update the sliders manually by a button then how is galapagos doing it?

How can I get access to sliders inside galapagos’ gene pool?


#4

Hi, it seems to me that Galapagos, is only able to update the tick of the sliders without been able to read again the values, is basically for esthetic reasons. There are other discusions on this forum about how to create that dinamic effect but it is basically not useful for anything else. So Galapagos is not really using the data of the sliders, they are generated internally.


(IVELIN PEYCHEV) #5

Yeah, I know it’s not reading the values from the sliders, they are used only for visualization, the random values are created inside galapagos code, but it is updating them while computing, and according to Giulio that’s unsafe.

I made a script doing pretty much the same but I get errors. If I have to do it with a button I’m losing the effect. And how I’m doing it is unsafe. I don’t understand then how is Galapagos doing it.


#6

Yeah, Galapagos is updating the values on slider but it’s not using the values of the input, doing that cause all sorts of problems with the behavior of the slider and the Solution Expires. So there is not real feedback. You can modify Giulio’s Script for doing the same thing that Galapagos does.


(Giulio Piacentino) #7

Galapagos is not updating the sliders from the solution. It is doing it from a button that is invoked outside the solution mechanics.

Problems start if your script that computes the solution also calls for sliders to be recomputed.


(IVELIN PEYCHEV) #8

So:

  1. Updating sliders from outside the class in gh_python?
    or
  2. updating from a separate gh_python, not the one defining their values?

(Giulio Piacentino) #9

It’s not a problem of class. It’s a problem of invocation chain (thread call stack).

The easiest way to fix it always is by doing what I mention above.


(IVELIN PEYCHEV) #10

Yeah but I don’t want user interaction to update them I want it to happen automatically.


(Giulio Piacentino) #11

Nothing forbids you, from the button above, to request the computation of 7 different solutions, or even an infinite loop (might not be smart, though).


(IVELIN PEYCHEV) #12

Hmm, how? Using boolean sticky variable to toggle it?

:smiley: about that I get slapped everytime I try to use While loops. Every single time if I forget to use try: except: I crash Rhino.


(Giulio Piacentino) #13

For example, by having:

try:
    for i in range(10):
        self.UpdateValues(obj, args)

in place of:

try:
    self.UpdateValues(obj, args)

Or in any other common way loops work.


(Giulio Piacentino) #14

2 posts were split to a new topic: Deleting Rhino objects during solution time


(Charles) #15

How do I get the menu object to run AppendAdditionalComponentMenuItems?


(Giulio Piacentino) #16

@charles2, what are you meaning here? The method is called by Grasshopper.