Undo in Rhino while Grasshopper is running?

I’m working on a script that continuously runs in the background with conditional content cache updates (e.g. whenever I draw a curve on a particular layer, GH adds the attributes for me). However, when I want to undo while drafting, I have to disable the Grasshopper Solver first, because each undo only affects Grasshopper.

Surely there’s another way to tackle this?

1 Like

For example, the Grasshopper solution could be paired with manual edits in grouped undo steps. Krita does this for brush strokes, where any operation that happens within x ms from the next CAN be treated as one undo step.

Hi @Intuos,

I tested with something like this and is working as expected.

Every time an object is added Grasshopper changes its color without creating a new UNDO operation.

Are you using a Trigger?
Can you share a small sample of how you are using this?

Thanks,

Hey @kike, right now, my script is this :sweat_smile::


Most of the script is manual trimming and matching of curves to make it much faster than region union.

What I’m doing is offsetting wall centrelines based on User Text Attributes and processing the offsets to create walls. Whenever I make a modification to the centreline layers (orange lines) or their attributes, the offset curves are pushed into the document (the white lines). So it’s not just geometry modification.

I’m not using any trigger components.

May it be that any of these unconnected groups of components trigger with a change another group of components?

Yes they do, each of the ‘lines’ (large groups) of the script feeds into another. So for example, the first adds the attributes, the second processes the attributes for the facades and the third then uses the facade walls to create the interior rooms.

This is why then.

Grasshopper can’t expire an input while the solution is being solved.
Your changes on the model triggers group A that pushes something. But group B was already solved when this started.
The solution finishes and changes done by group A trigger group B this starts a new UNDO record to push changes of group B.

I could solve group B right after A is done in the same UNDO operation but then if A and B create a circular dependency this would not be cancelable from the UI.

Joining those UNDO operations after based on the elapsed time between them is not something that the Rhino UNDO system allows right now.

Yeah, I understand that. It’s a semi-loop after all. Is there something else that could be done? In this case, I’d wait for Grasshopper to complete the computation from start to end before I move on.
But I do need to push the interim steps, because I can use the wall outlines to create windows with, for instance. Having the wall outlines in Rhino means I can use snaps or use attributes. And it serves as a way to avoid loops in Grasshopper.

If you were able to connect in a meaningful way group A with group B then both changes will occur on the same UNDO operation.

For instance I guess you use same layer to push in A and to query in B.

If you flatten Result of A and then do a List Length convert it to bool and use this bool as an argument of a Gate connected to the query on B that expires it.

1 Like

So in other words: make sure to push geometry only at the end of the script (when the script finishes) and hook up interim results between groups. I didn’t know that UNDO was already accounted for with attribute changes, so that’s worth a try, I guess.
Thanks!

E: I see you edited your comment while I wrote this. Makes sense to use gates and booleans like that.

You can push several times if the code is more clear to you.
As long as you convert the two disconnected groups A and B into a bigger one you are ok.

1 Like

Okay, so what I find is that I can keep adding line segments, change their attributes and UNDO just fine. Removing lines is where the issue is at, by disabling the groups, I found that the issue stems from the automatic push logic.


This logic activates the push when the number of curves or their length change differs between what’s referenced from Rhino and what’s recomputed in Grasshopper (basically pushing the wall outlines whenever I change any of the centrelines or their properties).


So now I am wondering if there is another method I could use, because as I mentioned, I want the wall outlines to update so I can draw my windows and doors with snaps.

I would assume a datadam to delay the push might work, but I can only really undo when I mash the undo button as fast as I can (as indicated by the line colour faintly flickering).

Here’s a test file in which I am trying to figure out how to limit the data pushes and the Undos that result from them:

Attribute changes on the other hand undo just fine:

Push and undo.gh (14.6 KB)

:slight_smile:

I’m sure this is a joke, but I did just post the problematic part of the script that messes up the undo. That is because I push data as soon as I edit it, so when I Undo, I make changes and the script thus pushes again. I would need some Undo flag/ exception, I think.

Sorry, I know it can be difficult to come up with a simple and small example to replicate a problem…

@martinsiegrist :point_up:

1 Like