Jump to content
ingersoll

array amnesia -- losing values or my mind

Recommended Posts

Hi all, I have an arrays-in-loops puzzle. I thought of a shortcut to do a thing, it doesn't seem to work, and I should move on -- except I would like to understand why it doesn't work.

Minimal background: I've got some point data, I've polywired it together using Connect Adjacent Pieces, and gotten a restlength on the primitives from that. I need to set a pscale on the points before moving on to my next step. Half the distance to the nearest neighbor is good enough for now. I could use nearpoints() to figure that out (and it seems to work!), but I thought, "hey, I already have restlengths; why not just look up the shortest restlength and use that?" That turns out not to work, or at least not as I think it should. Where have I gone wrong?

After my connect step, each point ends up connected to 4-20 other points by primitives with restlengths between .9 and 3.9. My first stab at this was:

  1. use pointprims() to get an array of primitives associate with each point;
  2. create an empty float array to hold the restlengths;
  3. foreach loop over the primitives, read the restlength with primattrib(), and push the result onto the lengths array;
  4. sort() the lengths array into a new array;
  5. read out the shortest length and use that to calculate a pscale.

Here's the actual code:

int myprims[] = pointprims(0, @ptnum);
float mylens[] = {};
foreach (int myndx; myprims) {
    float mytmp = primattrib(0, "restlength", myprims[myndx], 0);
    // f@checktmp = mytemp;
    push(mylens, mytmp);
    // f@checkrslt = mylens[myndx];
}
float lensort[] = sort(mylens);
float shortest = lensort[0];
f@pscale = shortest/2;

 

I think it's failing at the push statement. If I write out mytmp as a point attribute just before I push it, I get a reasonable number (commented code). If I check the stored value right after the push, I get either zero or the restlength of prim zero. If I check after the foreach loop completes, I get restlength of prim zero. So the push doesn't work. Looks like example code in the docs, but I'm missing something. 

Any thoughts?

 

Share this post


Link to post
Share on other sites

You are supplying a 0 for the final parameter of the primattrib. This is actually a return value and I am not sure if providing a constant is the best way to go. Try supplying an int based variable instead and actually examine the variable after primattrib executes to see if it was successful. You should only push if it is successful. Also try using append instead of push, docs say they are the same. Maybe append works better...?

Edited by Atom

Share this post


Link to post
Share on other sites

Thanks Atom! The syntax of the docs was confusing to me there. If I modify my foreach section to create a success variable and test for it, it runs without errors ... and still gives the same result, as does append. It still seems likely I'm flubbing the code somehow, as there's limited example code to crib from. What I've got now is:

foreach (int myndx; myprims) {
    int success;
    float mytmp = primattrib(0, "restlength", myprims[myndx], success);
    if(success == 1) {
        push(mylens, mytmp);
    }
}

Share this post


Link to post
Share on other sites

The problem might be that your success is always zero. Thus pscale will always be zero.

Try this modification and examine the @error attribute in the spreadsheet.

int success;
int myprims[] = pointprims(0, @ptnum);
if (len(myprims)>0) {
    float mylens[];
    foreach (int myndx; myprims) {
        float mytmp = primattrib(0, "restlength", myprims[myndx], success);
        if (success==1) {
            push(mylens, mytmp);
        } else {
            f@error = -1.0;
        }
    }
    float lensort[] = sort(mylens);
    float shortest = lensort[0];
    f@pscale = lensort[0]; 
} else {
    f@pscale = -1.0;
}

 

Share this post


Link to post
Share on other sites

What about this. You have source points then construct primitives from those points. So the points you are running over are the constructed points, not the source points. Instead run over the source points but fetch from the second input of the wrangle the constructed points/primitives...?

Then success is 1 and error is zero and you can fetch from the sorted array.

untitled-1.jpg

ap_prim_array_issue.hiplc

Share this post


Link to post
Share on other sites

Thanks for the sample file! It looks like it's not the code, it's my data -- if I load my point data into your file and pipe it through your code, it fails the same way my code fails. 

I think that qualifies as "garbage in..." -- I'll see if I can clean the data or change my initial processing steps. 

Thanks again!

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×