Grasshopper

algorithmic modeling for Rhino

I have timer inside component:

protected override void AfterSolveInstance()
{
//boolean toggle input false 
if (Running == false || count2 > frameRange.T1 )
return;


GH_Document gH_Document = base.OnPingDocument();

if (gH_Document == null)
return;

GH_Document.GH_ScheduleDelegate gH_ScheduleDelegate = new GH_Document.GH_ScheduleDelegate(this.ScheduleCallback);
gH_Document.ScheduleSolution(1000, gH_ScheduleDelegate);

}

private void ScheduleCallback(GH_Document doc)
{
this.ExpireSolution(false);
}

I added boolean condition in solve instance, if some condition is meet do not output anything , expecting that component connected to this one would not be updated. But it does.

Is there anyway having timer inside a component, but not affecting connected components while running  under some if some boolean condition is false?

protected override void SolveInstance(IGH_DataAccess DA)
{

  ....

  if (some boolean condition) {

    DA.SetData(0, count2);
    DA.SetData(1, a);
  }

}

Views: 2274

Attachments:

Replies to This Discussion

If you do not want a recomputation, you must not expire the component. Thus, the logic which decides whether or not to update must be inside the ScheduleCallback method.

I think you might find the IGH_DataAccess.AbortComponentSolution method an interesting option in your case, which you can call from the SolveInstance DA argument.

Anything inside SolveInstance is called well after the expiration shockwave has made its way through the network and thus cannot be used to prevent a recalculation. It's simply too late at this point. The only way to stop components from recollecting and recalculating and keep their old data, is to not call ExpireSolution(bool).

Is there a way to do the following then:

I am checking if render is finished  (from vray sdk), if it is finished I would like to recompute the solution. But if I just add this boolean property it just checks once, so I thought it would be good to check constantly and not to expire solution if it is still rendering. But it seems that after expire solution I cannot stop anything.

(for animations I check if render is finished, if it is finished recompute solution to update grasshopper definition) 

Yes, your best solution is to use a regular timer (provided by .NET framework, System.threading namespace). Have this timer fire events every half a second or so (or however often you feel is reasonable). Every time the timer fires you check the completeness of the rendering. If it completed, you then expire everything you need to expire and trigger a new solution. If it's just a single component, then comp.Expiresolution(true) is the best way to do this.

BUT BE CAREFUL!!!! Timer events will be raised on a separate thread. You cannot start new solutions on anything except the Grasshopper/Rhino UI thread. This means you must Invoke the relevant methods via the UI thread. If you don't know how to do this, I can set up an example.

In the end it is all related to one single component made.

If you could show me an example about timer events raised on a separate thread I would be very thankful:) 

See attached. It contains a C# component with a custom timer which fires every quarter second. However it only triggers an update if the current minute is different from the minute the previous solution ran in.

There's no smarts there at all to disable the timer if the document goes inactive or is unloaded, you'll have to add that sort of bookkeeping.

Attachments:

Yes I added this in visual studio and it works as a charm:

private void TimerElapsed(object sender, EventArgs e)
{
// First check to see if the current minute is the same as the previous minute.
DateTime now = DateTime.Now;
// if (_minute == now.Minute) return;
if(Running == false || count2 > frameRange.T1 || VRayInterface.HasRenderFinished() == false)
return;

// If not, invoke the ExpireSolution method on the UI thread.
// To do so, we must get access to a UI control. On Rhino6 you can use Rhino.RhinoApp.InvokeOnUiThread().
System.Windows.Forms.Control control = Grasshopper.Instances.ActiveCanvas;
if (control == null)
return;

Action<bool> action = new Action<bool>(base.ExpireSolution);
control.Invoke(action, true);
}

Thank you very very much:)

Regarding:

"There's no smarts there at all to disable the timer if the document goes inactive or is unloaded, you'll have to add that sort of bookkeeping."

Do you mean if grasshopper crashes or I simply close rhino?

What would be the way to turn it off? Should I add some sort of boolean if current grasshopper document is open?

Do you mean if grasshopper crashes or I simply close rhino?

No in those cases the timer will be properly destroyed as well. I mean when the grasshopper document that contains the timer is closed (but Grasshopper remains active) or when the document is deactivated (because a different document is loaded into the canvas) or when the component is deleted.

It sort of depends on whether your timer needs to keep checking stuff even if the document is inactive. But if the document is unloaded or if the component is deleted you definitely want to disable and dispose the timer.

In those cases when grasshopper is unloaded, component is deleted and if document is inactive is there an easy way to check this and dispose the timer?

 

 

RSS

About

Translate

Search

Videos

  • Add Videos
  • View All

© 2024   Created by Scott Davidson.   Powered by

Badges  |  Report an Issue  |  Terms of Service