Forum

VL - first go - connect all

As a simple exercise I’m trying to recreate the famous ‘connect all’ plugin in VL. Am I right in thinking that this isn’t a candidate for making a datatype as we don’t need to store data about objects - we’re just processing a spread of positions and want to output a spread of position pairs?

Anyway, I got this far - (see attached)

I have the nested foreach loops but I’m not sure how to build the spread resulting from the distance checkconnect all VL.zip (5.2 KB)

the EdgeSplit operation in this example does what you want:

you start with an empty Spread or SpreadBuilder that you input as an accumulator and then use the Add node whenever you have a new element. when the loop is finished the accumulator output of the loop will contain the Spread with all elements…

ok. Is what I should be adding using the add (spread) a custom type that contains a pair of vector3s?

it could make sense to make a type called Edge or LineSegment to also store stuff like brighness/color whatever, but you could also go oldschool and use two Add nodes directly after each other (or select the Add node and press CTRL + ‘+’ to add more inputs) so that you know two successive vectors are one Edge…

connect all VL 0.2.zip (8.0 KB)

Ok I went for the new school option. Attached is as far as I’ve got. I think it’s basically done but I don’t know how to specify the input type should be a spread of vec3

right click the input and choose “configure” or middle click it, click the ‘Type’ field and input Spread<Vector3> to set the type annotation.

just for reference: https://discourse.vvvv.org/t/vl-sandboxing-connectall-from-node13

Thanks Joreg. gregsn’s VL connect all is broken unfortunately.

Tonfilm - I think there are still a fair few things wrong with my patch. I don’t suppose you could take a look?

my bad i should have checked that before. i uploaded a version fixed for b35 in that thread.

Thanks Joreg

ok, here we go:

there are a few details: first, the type annotation on the input was somehow wrong. the name of a type is a unique identifier, that means that it needs an exact character sequence to find it: Spread<Vector3> no spaces and case sensitive. it seems you typed that in differently.

your type LinePair was set to ‘Class’ which is probably not what you want in this case. instances of classes are not actually passed around like values (vectors, numbers) which have a solid link. instances of classes sit somewhere in a fixed memory location and you only pass around a reference to them which is indicated by a dashed link. i would change LinePair be a ‘Record’, so that you don’t have to think about this indirection while patching.

the VL spread is also a record, this means that as soon as you change it you have a new spread, same as in vvvv. this requires you to pass it thru every accumulator of every region. but here it comes: you stumbled over a bug we haven’t seen before. for some reason you can’t connect the LinePair spread to the accumulator input of the if region as long as it is a class. our fault, sorry!

but you can fix that with CTRL + click to force the link to the accumulator input, or simply change LinePair to Record.

then the loop that gets the A/B position has two issues:

same as above, the empty spread that you put in will be the same empty spread for each iteration of the loop. this is as if you would put in a number. it will always be the same number. if you want to increment the number on every iteration of the loop, you need to pass the new result on to the next iteration. so you have to input it as accumulator (instead of linking it directly into the loop) in order to get the new result from the last iteration of the loop.
same is true for the spread, you need to pass the new spread with one added element on to the next iteration of the loop by outputting it with an accumulator and input it with an accumulator.

second issue is, it does not need empty spreads to fill up at all, because you don’t want to output a spread with different size than the input spread, just one slice for each input LinePair. so simply use splicers there:

the rest should be easy… only one thing to consider, if you add a line for each pair that is closer together than the threshold, you will add the same line twice, because the loop in loop construct gives you each position pair twice, for each position you will get all other positions, you you will have AB and BA. but that’s not VL related…

1 Like

here is a version that is improved a little. i’ve also changed some names to stick to our naming conventions:
connect all VL optimized.zip (12.0 KB)

it solves the double lines by only calculating something in the inner loop by checking whether the index is greater than the index of the outer loop:

Thanks! So useful. Accumulators making sense now

I don’t see how checking the loop indices that way has fixed the double line issue but I’m sure I’ll work it out

no problem, we know that there are concepts we have to explain. so don’t worry about bothering us here. it helps us to understand where people run into problems.

the nested loops are very similar to the Cross (2d) node in vvvv that has the same I (Spread) on both inputs. it can be viewed as a big square with all pairings. by checking InnerIndex != OuterIndex you cast out the middle diagonal of the pairings. by checking InnerIndex > OuterIndex you get only the upper triangle of pairings without the diagonal. InnerIndex < OuterIndex the lower triangele. both would work in that case because it does not matter whether you check AB or BA.

Graphical descriptions to the rescue!

Yep that makes total sense with the cross. Really nice way to visualise it. And if you wanted the ‘diagonals’ you would use either >= or <=

I was just drawing this… :)

fixed in latest alpha.

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.