In several instances I ran into a problem where I need to change some of the Advanced Options via script during script runtime (and then restore them). Based on @stevebaer’s sample, the setting can be changed like this:
import Rhino
settings = Rhino.PlugIns.PlugIn.GetPluginSettings(Rhino.RhinoApp.CurrentRhinoId, False)
s = settings.GetChild("Options").GetChild("General")
s.SetBool("MiddleMouseViewManipulationMode",False)
The problem is, this only works after the script ends and I really need to make it work while the script is still running. Otherwise it kind of defeats the purpose of being able to access it.
I have tried using SaveSettings() or RaiseOnPlugInSettingsSavedEvent() but I can’t make it work.
Any suggestions how to effectively have these settings changed and updated while the script code is running ?
I do not know Python well. but in csharp I sometimes encounter this phenomenon.
This is often because it runs on different threads or on different stacks of events (it must be the same thing in python.)
I resolve this either with a RhinoApp.Wait () or with a function executed via RhinoApp.InvokeOnUiThread
But I do not know the correspondence with python, I hope it can help.
-jmv
thanks for the insight. I have tried both but it doesn’t seem to help. Either I do it wrong, or there is something else that controls the Advanced Options to refresh. I really hope there is a way to do this as I have several of them that would be super helpful to be able to toggle during script runtime.
Here is the sample of how I tried to use your suggestions (please note, to actually see the difference in that setting changing to 3, you need to have SkylightShadows ON, and the shadows quality in current display mode set to very low - then, once setting is switchted to 3, Skylight shadows become very grainy…). Just a tip how to visually test if it worked.
import Rhino
import rhinoscriptsyntax as rs
def setdegradation(intDegLevel):
print "setting to 3"
settings = Rhino.PlugIns.PlugIn.GetPluginSettings(Rhino.RhinoApp.CurrentRhinoId, False)
s = settings.GetChild("Options").GetChild("OpenGL")
s.SetInteger("SkylightShadowResolutionScale", intDegLevel)
Rhino.PlugIns.PlugIn.SavePluginSettings(Rhino.RhinoApp.CurrentRhinoId)
Rhino.RhinoApp.Wait()
rs.Sleep(1000)
Rhino.RhinoApp.InvokeOnUiThread(setdegradation(3))
print "setting to 1"
settings = Rhino.PlugIns.PlugIn.GetPluginSettings(Rhino.RhinoApp.CurrentRhinoId, False)
s = settings.GetChild("Options").GetChild("OpenGL")
s.SetInteger("SkylightShadowResolutionScale", 1)
Rhino.PlugIns.PlugIn.SavePluginSettings(Rhino.RhinoApp.CurrentRhinoId)
Rhino.RhinoApp.Wait()
rs.Sleep(1000)
Oh,
I think Rhino.PlugIns.PlugIn.SavePluginSettings write the settings to the disk and it does not update the settings … (I guess) Yes GetChild return a Rhino.PersistentSettings you have no effect because you work on disk.
@Jarek why you don’t use Rhino.ApplicationSettings.OpenGLSettings ?
Now that I see what we use only saved on disc, it makes sense that it doesn’t update, but it all does right after the script ends. So something is forcing it to update. I am looking for that “something” to trigger it while the script runs.
As I mentioned in the first post,I was also trying SaveSettings or RaiseOnPlugInSettingsSavedEvent () but no luck.
Yeah, a while ago regarding this question and ability to update from script he wrote:
But I am clinging to the “Probably” part… also if this is not possible, wouldn’t it be nice if it was? Otherwise why bother being able to change these settings within the script. I ran into this on several separate issues I am trying to solve and would be really helpful if we could do that.
@kitjmv - that works! thanks for your persistence
Looks like the rs.sleep(1000) is also needed (or at least 400 over here) for the saved settings to ‘register’, otherwise it doesn’t work. So it is a combo of a few methods to make it update.
Great, I will test the other Advanced Options I had problems in the past as well. The Skylight Shadows degradation works well:
And here is the test code:
import Rhino
import rhinoscriptsyntax as rs
def setdegradation(level):
settings = Rhino.PlugIns.PlugIn.GetPluginSettings(Rhino.RhinoApp.CurrentRhinoId, False)
s = settings.GetChild("Options").GetChild("OpenGL")
s.SetInteger("SkylightShadowResolutionScale", level)
Rhino.PlugIns.PlugIn.SavePluginSettings( Rhino.RhinoApp.CurrentRhinoId)
rs.Sleep(1000)
print "Degradation set to 3"
setdegradation(3)
Rhino.PlugIns.PlugIn.RaiseOnPlugInSettingsSavedEvent()
Rhino.RhinoDoc.ActiveDoc.Views.Redraw()
rs.Command("_TestMaxSpeed _Enter")
print "Degradation set to 2"
setdegradation(2)
Rhino.PlugIns.PlugIn.RaiseOnPlugInSettingsSavedEvent()
Rhino.RhinoDoc.ActiveDoc.Views.Redraw()
rs.Command("_TestMaxSpeed _Enter")
print "Degradation set to 1"
setdegradation(1)
Rhino.PlugIns.PlugIn.RaiseOnPlugInSettingsSavedEvent()
Rhino.RhinoDoc.ActiveDoc.Views.Redraw()
rs.Command("_TestMaxSpeed _Enter")
Well, we were lucky and your question relates to my current personal projects. But happy if it helped you.
Just to understand.
The problem is still in the queue of events (here the parameters queue changed)
and what helped me is the documentation of RaiseOnPlugInSettingsSavedEvent:
# Raise any pending OnPlugInSettingsSaved events, the events are normally
# queued while a command is running and and fired while Rhino is in an
# idle state. Calling this method will raise any pending changed events
# regardless of Rhino's current idle state or if a command is running.
So all that forces Rhino to go in Idle “should work”.
However, it seems that Python integration has a strange behavior with the Idle event (or RaiseOnPlugInSettingsSavedEvent).
Test this code
import Rhino
import rhinoscriptsyntax as rs
def setdegradation(level):
settings = Rhino.PlugIns.PlugIn.GetPluginSettings(Rhino.RhinoApp.CurrentRhinoId, False)
s = settings.GetChild("Options").GetChild("OpenGL")
s.SetInteger("AntialiasMode", level)
Rhino.PlugIns.PlugIn.SavePluginSettings( Rhino.RhinoApp.CurrentRhinoId)
Rhino.PlugIns.PlugIn.RaiseOnPlugInSettingsSavedEvent()
print ">> -6"
setdegradation(-6)
print "<< -6"
for i in range(0, 5000000):
n = i
rs.Sleep(1000); print "Now work"
# or
# rs.Sleep(0);
# Rhino.RhinoApp.Wait();
print ">> -6"
setdegradation(-6)
print "<< -6"
for i in range(0, 5000000):
n = i
print ">> 3"
setdegradation(3)
print "<< 3"
for i in range(0, 5000000):
n = i
print "end"
As long as Python does not leave its thread at least once, no call to RaiseOnPlugInSettingsSavedEvent will work
…?
-jmv
(finally, Rhino.RhinoDoc.ActiveDoc.Views.Redraw () is useless)
So RaiseOnPlugInSettingsSavedEvent, (despite misleading documentation). it need to raise a Idle to work.
but why just one time ? why the other calls of RaiseOnPlugInSettingsSavedEvent work after ?
On my end, unless I have rs.Sleep(600) at least, it does not work, I mean the first attempt does not, then later in the script the sleep can be very short. I don’t see any difference with using the Rhino.RhinoApp.Wait() in that behavior.
Ideally I would have the change happen instaneniously and not force wait ~1s.
How would I need to modify the code I posted last to make it work quick from the get-go? I am wondering if at least on your end you can avoid the initial wait for the change to be picked up.