Points that recolor each other with one that remains unchanged

   1239   2   0
User Avatar
Member
48 posts
Joined: Feb. 2018
Offline
Hi,

I have a point cloud with 2 different colors. If at least 2 red dots come too close, one of them should turn green. I work with pcfind. However, both become green in the process. Well, they are also within the mutual selection radius.
I tried to filter in my script, but I'm stuck.

It should be the case that the points are processed one after the other? Finally, one point of the “dense point group” should remain, since the others have already turned green and can no longer select it…

Help would be great.



@Cd = 0;

float seed = chf("seed");
float prob = chf("prob");
float r = rand(seed+@ptnum);
@Cd = set( prob > r, prob < r,0 );

float rad = 0.5;

if (@Cd.r == 1) {
    i[]@pclouds = pcfind(0,"P",@P,rad,15);
    removeindex(i[]@pclouds,0);     
}


foreach (int i; i[]@pclouds) {
    
    if (@Cd.r == 1) {
        setpointattrib(0,"Cd",i,set(0,1,0));
    }

}
User Avatar
Member
4516 posts
Joined: Feb. 2012
Online
If you don't wanna affect both, just compare their @ptnum and only affect the one with the smaller or bigger @ptnum.
Senior FX TD @ Industrial Light & Magic
Get to the NEXT level in Houdini & VEX with Pragmatic VEX! [www.pragmatic-vfx.com]

youtube.com/@pragmaticvfx | patreon.com/animatrix | animatrix2k7.gumroad.com
User Avatar
Member
48 posts
Joined: Feb. 2018
Offline
That's not exactly what I meant.
Now I've found the problem, too.

The structure should be:

In the first loop, based on the first array (the points that the surrounding search and store in another array).

In the second loop, the second array is used. On the basis of the second array, the points are examined and checked whether they are red. If so, they turn green.

Finally, another if statement should ensure that all points that turn green lose their arrays (and are therefore no longer able to recolor other points).

This should leave the last red dot of an intersecting group of dots.
But he doesn't. The wrangler doesn't realize the new green points.


However, it works again when the last if statement appears in a new wrangler.
But that's the problem. Then it is outside the loop.


Is all this normal? And how can I achieve my desired effect?


@Cd = 0;

float seed = chf("seed");
float prob = chf("prob");
float r = rand(seed+@ptnum);
@Cd = set( prob > r, prob < r,0 );

float rad = 0.5;

if (@Cd.r == 1) {
    setpointgroup(0,"a",@ptnum,1);
    
    i[]@pclouds = pcfind(0,"P",@P,rad,15);
    removeindex(i[]@pclouds,0);
    i[]@pclouds = sort(i[]@pclouds);
    
}

i[]@reds = expandpointgroup(0,"a");

for (int j = 0; j < chi("iter"); j++) {
int i = i[]@reds[j];

if (@ptnum == i) {

for (int k = 0; k < chi("iter2"); k++) {
int l = i[]@pclouds[k];

if (@Cd.r == 1) {

setpointattrib(0,"Cd",l,set(0,1,0));
}

if (@Cd.g == 1) {

resize(i[]@pclouds,0);
}
}
}
}


is a weird situation because this loop works:

for (int i = 0; i < chi("iter"); i++) {
    
    if (@Cd.r == 1) {
    
        if (@P.y == 2) {
            @P.y += 1;
        }
    
        if (@P.y == 1) {
            @P.y += 1;
        }
    
        if (@P.y == 0) {
            @P.y += 1;
        }
    }
}


So the problem is the function setpointattrib():
It just doesn't work.

for (int i = 0; i < chi("iter"); i++) {

if (@Cd.g == 1) {
@P.y ++;
}

if (@Cd.r == 1) {
setpointattrib(0,"Cd",@ptnum,set(0,1,0));
}

}

But I need that when each point has its own array.

What works: All points have the same array:
@ptnum == a; a can be read.

Which doesn't work: All points have different arrays:
@ptnum == b; b cannot be read. there is no result. probably because of different values.
Unless you use setpointattrib().

- - - - - - - -

I just remembered something else:
if i use a maximum iteration with the function len() it seems to use only the points which store the arrays (in this case from i@pclouds). So not the value for all points.

If I just enter the value by hand, all points go up.
Is that normal? There is nothing of this in the function documentation.

int len2 = len(i[]@pclouds);
i@len2 = len2;

for (int k = 0; k < len2 /* or 14 */; k++) {
int l = i[]@pclouds[k];
i@l = l;

@P.y = @P.y + .5;
}
Edited by Christoph_H_ - July 9, 2018 06:44:50

Attachments:
loop_questions.hiplc (165.0 KB)

  • Quick Links