Hi, I am trying to use the hand manipulations of a point in a curve to manipulate the position of all the points below it (highlighted in yellow).
For this, I planned to use the track taps to identify when a sphere is moved, its index, and the new position to alter all the neighboring spheres. However, when I try to connect the tap trigger to the function that generates the spheres, I get a “Recursive loop”, which makes sense since I am trying to modify the same object I am tracking but then, is there a way to do this?
Thanks for getting in touch. I think the simplest way to approach this would be to have a button that updates - that way it wouldn’t execute on release, but instead you could make multiple moves and then press a button in the menu to trigger the update.
Global variables have a ‘fetch’ feature that let you do this - when a component immediately downstream updates the global variable will pull the latest value. In this case inserting a stream gate acts as a simple shim.
In this sense you get recursion but it requires a step in between to trigger it.
However we are looking into a direct manipulation loop where moving one object enabled updating others in the same collection. There is not a simple way for us to specify some objects that are touchable and some that are just updating all can be touched and update others and we don’t want a button because this would interrupt the flow of the user.
Is there a way to detect the end of a drag event to trigger what the button would do otherwise?
Thank you for the suggestion. Do you know how I could connect the Track State component to the gate to emulate the behavior or a button so it clicks every time the state is ‘Release’?
Also, I was using the track taps component because it enabled me to access the specific item that was selected and released. Is there a way to do this with the state component, or do I have to keep a local collection of the points in my script to know which one was updated?
I created a script that checks if any of the strings in the state array is ‘Release’ and connected it to the gate. Then I used the taps component to check which element was selected. I use this to move all the objects near that object.
There are a few issues with this…The Track State component will trigger with any user interaction, so I am unsure if it’s actually dragging something. I am also getting some repeating motions that I am unsure are due to the state triggering multiple times.
You can see the update in the position that gets triggered multiple times in this video
Is there a way to better detect the click on a single object or know that an object was clicked without the recursive loop?
A good way of doing this (where you want to update the geometry you are clicking on) is to use the Rhino document as a ‘cache’ - bake geometry (with names if references/sorting is needed) and import it in as necessary - though note you still have to be careful with recursion if you are listening to document changes!
Thank you!. That approach to the state gate release looks cleaner than what I did.
I am not sure I understand your suggestion for baking. Forgive me, I may be too inexperienced with Grasshopper still, to bake the geometry I would have to manually right-click it and hit bake, and then import it? but what I need is to detect as soon as the State Gate is triggered which object was released (if any), is there a way to do this programmatically? For example, can I create two global variables one for the cache and one for the updated geometry?
You can see in my example I tried to use the Taps component, but I am not sure when it is triggering (with respect to the gate), and when I tried to recreate what I did in the example Grasshopper you sent, I got this error:
Geometry is not synchronized. Plug in the output of a Sync Object component.
Solution exception:Object reference not set to an instance of an object.
I have been trying to work around this issue of only triggering movement or change when the user taps and moves a sphere, not at any point that the screen is released.
I tried manually detecting the collision between the finger and the spheres but it only works when the movement is starting and I can’t preserve the variable (index) so that when the screen is released I can check if the index is a number or is null.