Jump to content

VEX - Using a point attribute from an array in a foreach loop


Recommended Posts

Hello everyone,

this is my first post on this forum so thank you for welcoming me and please be indulgent if I'm not posting on the correct channel.
I've been trying to wrap my head around an issue that I'm facing with VEX for a couple of days but I'm really stuck.

My goal was to iterate through each points of a input and to create a Polyline between two points if there are close enough from each other

Problem is that if point 1 is close from point 6, it will create a Polyline (so far, so good) but when my VEX script reach point 6, the invert is also true. So VEX will create a second line from point#6 to point#1...

I'm trying to add some line in my script to raise a flag if a point has already been "activated" (used if you prefer) to use that as a check before creating anything.
From my understanding VEX scripts are running on each points sequentially so I tried to create an attribute called "active" that I can raise to 1 every time this point has been going through my script.

When I'm trying to get my attribute "active" from my foreach loop, it returns 0 if "active" has been initialized on the same VEX wrangle node but it's returning the right value if it has been set in a previous node.

What am I missing here ?

Thanks

float radius = chf('radius');
int ptArray[] = nearpoints(0,@P,radius, 2);
@active = set(1);
i[]@array = ptArray;

    foreach(int pointNum; ptArray)
    {
        int activated = point(geoself(),'active',pointNum);
        printf("activated = {%g}", activated);
        if(pointNum != @ptnum && activated != 1){
            int line = addprim(0,"polyline");
            addvertex(0, line, @ptnum);
            addvertex(0, line, pointNum);
            setpointattrib(0,"active",pointNum,1,"set");
            }
        } 



image.thumb.png.a10fd2507647993d4adf8dc70920276b.png

Link to comment
Share on other sites

That's a good idea @Fenolis that I followed and I find this wrangle SOP into "Connect Adjacent Pieces"
The part that is interesting for me seems to be located at the end under this last condition.

Quote

    // Don't create connections to multiple points on the same piece, or
    // to other points on our piece.
    // Only search in the direction of the point normal.
    if (s@__piecename != other_piecename && dot(other_P - @P, @N) >= 0)

I'm not really interested by the check for the normal direction but more about the first part of the condition when they are checking if s@__piecename != other_piecename. The problem is that there is no variable s@__piecename define in the script prior to this line.

What does this formulation mean ?
Thanks

The full VEX script:

float search_radius = chf("../searchradius");
int max_pts = chi("../maxsearchpoints");
int max_connections = chi("../maxconnections");
string piece_attrib = chs("../pieceattrib");

int use_cluster = chi("../useclusterattrib");
string cluster_attrib = chs("../clusterattrib");
int cluster_attribtype = -1;
int my_cluster_i;
string my_cluster_s;
if (use_cluster)
{
    cluster_attribtype = pointattribtype(0, cluster_attrib);
    if (cluster_attribtype == 2)
        my_cluster_s = point(0, cluster_attrib, @ptnum);
    else
        my_cluster_i = point(0, cluster_attrib, @ptnum);
}

string known_pieces[];
int num_connections = 0;

for (int other_pt : nearpoints(0, @P, search_radius, max_pts))
{
    if (use_cluster)
    {
        if (cluster_attribtype == 2)
        {
            string other_cluster = point(0, cluster_attrib, other_pt);
            if (my_cluster_s == other_cluster)
                continue;
        }
        else
        {
            int other_cluster = point(0, cluster_attrib, other_pt);
            if (my_cluster_i == other_cluster)
                continue;
        }
    }

    string other_piecename = point(0, piece_attrib, other_pt);
    vector other_P = point(0, "P", other_pt);

    // Don't create connections to multiple points on the same piece, or
    // to other points on our piece.
    // Only search in the direction of the point normal.
    if (s@__piecename != other_piecename && dot(other_P - @P, @N) >= 0)
    {
        if (find(known_pieces, other_piecename) < 0)
        {
            int other_anchor = point(0, "__anchorpt", other_pt);
            addprim(0, "polyline", i@__anchorpt, other_anchor);
            ++num_connections;

            if (num_connections >= max_connections)
                break;

            append(known_pieces, other_piecename);
        }
    }
}

 

Link to comment
Share on other sites

There is a Switch-If upstream that tries to initialize the __piecename attribute on points - you may have to initialize this properly using a Connectivity SOP/Attribute Wrangle to see how it flows.

s@__piecename is shorthand - what it's doing is looking for a string @ttribute on the incoming points called __piecename, to be compared with other_piecename. If such an attribute is not found, it returns a result of 0.

Link to comment
Share on other sites

51 minutes ago, animatrix said:

Hi,

When you create polylines, you can check if the current point number is greater than the target point number, or the opposite to avoid duplicates:


if ( @ptnum > targetpt )
    addprim()

 

Elegance.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...