algorithmic modeling for Rhino
Hi,
I'm trying to write a component which has a background thread, a timer, that will move a point in a circular path in the Rhino Document every 100ms while the component itself won't get stuck and also will respond to parameters changes in it's SolveInstance function.
I've been using Rhino.RhinoDoc.ActiveDoc's AddPoint function in the background thread.
The problem is that Rhino always crashes when i touch the view while the background timer moving the point.
The background thread does the following algorithm:
- my_active_doc.AddPoint(circle_points[i])
- my_active_doc.Sleep(100ms)
- my_active_doc.PurgePoint(circle_points[i])
- i += 1
- my_active_doc.Views.Redraw()
I've placed my_active_doc with RhinoDoc.ActiveDoc only once in the component class constructor (i did it because there's a warning in the ActiveDoc documentation that says you either use the given DocObject which refers to written Rhino Plugins or use only the first instance you get from ActiveDoc)
I even tried locking with a static locker object each call to the my_active_doc and that did not help.
I'd like to hear any suggestions, maybe i'm using it wrong and that's not the way to change the active rhino document in the background.
Now i know it IS possible because i've seen many GrassHopper components that simulate a motion of an object while the grasshopper component is still responsive and there isn't output parameter - so they're probably not using ExpireSolution every 100ms
Thanks,
H.
Tags:
Much safer would be to use gh timer component instead of system.timer.
The gh timer component expires the solution with the given iterval.
To draw something without the output parameter you have to read more about drawviewportwires and drawviewportmeshes
You cannot do anything which affects the UI from any thread other than the main application thread. Never. Ever. Instant Crash.
Here are your solutions:
I'm not sure which of these suits your needs the best, though I suspect it's #1.
Another thing to keep in mind is that timers that run on different threads can start to raise overlapping events. If it somehow takes longer than 100ms to execute your iteration (for example because something else that is computationally expensive is already happening) then you start to collect timer events faster than you can handle them. Ideally you'd disable/suspend the timer once you get an tick event, then restart the timer when you're done doing whatever it is you're doing.
--
David Rutten
david@mcneel.com
Hi,
Thanks for the quick reply :)
I just tried using System.Windows.Form.Timer that seemed to work very good, though i'll give it some more heavy testing.
I'm wondering about the #1 solution you suggested - How can i invoke a method on the main UI thread?
Thanks!
RhinoWindow.Invoke() is probably the best option. If the Grasshopper window is always loaded while your code runs, then you can also use the Invoke methods on Grasshopper.Instances.DocumentEditor.
--
David Rutten
david@mcneel.com
Welcome to
Grasshopper
Added by Parametric House 0 Comments 0 Likes
Added by Parametric House 0 Comments 0 Likes
Added by Parametric House 0 Comments 0 Likes
Added by Parametric House 0 Comments 0 Likes
© 2024 Created by Scott Davidson. Powered by