Loop through inputs attributes in VEX

   11719   8   4
User Avatar
Member
65 posts
Joined: March 2017
Offline
Hi,

I have a node connected to an attributeWrangle with these attributes :
- weight1,weight2,weight3
- nWeights=3

How can I loop through the 3 weights to get their values inside the wrangle node ?

Thanks,

Julien
VFX Supervisor @ MPC London
User Avatar
Member
2040 posts
Joined: Sept. 2015
Offline
Could you post your file? I don't use attributewrangle so I'm not sure what you have, in terms of contex.

But I loop through ‘stuff’ I've created all the time in wrangle nodes; Might be able to help you.
User Avatar
Member
897 posts
Joined: July 2018
Offline
Sounds like you can put the attributes in a string with a chs() expression, split that to an array, loop over the attributes:
foreach (string attribName; splitArray){
point (0, attribName, @ptnum)
}

Edit: missed the nWeight attribute.

Do a for loop instead.
for (int i =1; i <nWeight+1;i++){
point (0,“weight”+itoa (i), @ptnum)
}
Edited by kahuna031 - April 4, 2017 16:01:13
B.Henriksson, DICE
User Avatar
Member
23 posts
Joined: Oct. 2015
Offline
This computes the normalized sum and colors the points by the normalized weights for visualization, given multiple attributes called attrib0, attrib1 …. attribn. It sorts through all your attribs so no need to hard code anything besides the name prefix.

Hope this helps, it'd be nice if the paint weights node code also work on arbitrary attribs or allow you to create them by painting multiple new attrib regions. Bone capture weights are a unique kind of packed data that could be engineered to work but it requires captured bones to setup.

string ats[] = detailintrinsic(0,"pointattributes");

float wts[];
vector cds[];

float sum = 0;

//create attrib array and compute the sum

for(int i = 0; i < len(ats); i++){

string s = ats[i];

if(startswith(s,"attrib")){

float val = point(0,s,@ptnum);

append(wts,val);
append(cds,rand(i));

sum += val;

}

}

//normalize weights & color

@Cd = 0;

for(int i = 0; i < len(wts); i++){

float normVal = wts[i] / sum;

vector normCd = cds[i] * normVal;

@Cd += normCd;

wts[i] = normVal;

}
Tighe Rzankowski

trzankofx@gmail.com
User Avatar
Member
3 posts
Joined: April 2016
Offline
string ats = detailintrinsic(0,“pointattributes”);

Brilliant! I have been looking for this for days!
Couldn't not figure it out…quite obscur if you ask me
I was expecting something like listPointAttributes or something more obvious!

Thanks a lot!
User Avatar
Member
1743 posts
Joined: March 2012
Offline
For future reference, you can find what all of the detail intrinsics are, either by going to the Geometry Spreadsheet, going to the detail tab, then checking the Intrinsics drop-down, or by (in a somewhat meta way), reading the globaltokensdetail string array intrinsic. All of them can be read from VEX using the detailintrinsicfunction. You can do a similar thing with primitive intrinsics on the primitive tab, or using the primitivetokensprimitive string array intrinsic, and the primintrinsicVEX function.
Writing code for fun and profit since... 2005? Wow, I'm getting old.
https://www.youtube.com/channel/UC_HFmdvpe9U2G3OMNViKMEQ [www.youtube.com]
User Avatar
Member
10 posts
Joined: May 2020
Offline
kahuna031
Sounds like you can put the attributes in a string with a chs() expression, split that to an array, loop over the attributes:
foreach (string attribName; splitArray){
point (0, attribName, @ptnum)
}

Edit: missed the nWeight attribute.

Do a for loop instead.
for (int i =1; i <nWeight+1;i++){
point (0,“weight”+itoa (i), @ptnum)
}

Hello, I have a similar problem, since I am quite new to vex language, would you mid be more specific? Like I have 200 columns in geometry spreadsheet as attributes, and I want to take each column with name “water_conc0”,“water_conc1”,“water_conc2”… and fit each data into range 0 - 1 using fit01() function, so that I could get 200 columns of 0 - 1 data.
But I don't know how to use the for loop to achieve this.
Thanks in advance!

This iterated code could illustrate what I want to achieve~
Edited by jingyukan - June 8, 2020 17:05:06

Attachments:
Screenshot (69).png (812.7 KB)

User Avatar
Member
1738 posts
Joined: May 2006
Offline
Looking at your screenshot there, this is one way to convert that into a loop:

string src, dest, prefix, newprefix;
int range;
float value, min, max;

prefix = 'water_conc';
newprefix = 'waterCd';
range = 8;
min = 264;
max = 142;

for (int i=0; i<=range; i++) {
    src = prefix+itoa(i);                // construct the source attribute name
    dest = newprefix+itoa(i);            // construct the destination attribute name
    value = point(0,src,@ptnum);         // read the value
    value= fit(value, min,max,0,1);      // fit
    setpointattrib(0,dest,@ptnum,value); // set the value
}
http://www.tokeru.com/cgwiki [www.tokeru.com]
https://www.patreon.com/mattestela [www.patreon.com]
User Avatar
Member
10 posts
Joined: May 2020
Offline
mestela
Looking at your screenshot there, this is one way to convert that into a loop:

string src, dest, prefix, newprefix;
int range;
float value, min, max;

prefix = 'water_conc';
newprefix = 'waterCd';
range = 8;
min = 264;
max = 142;

for (int i=0; i<=range; i++) {
    src = prefix+itoa(i);                // construct the source attribute name
    dest = newprefix+itoa(i);            // construct the destination attribute name
    value = point(0,src,@ptnum);         // read the value
    value= fit(value, min,max,0,1);      // fit
    setpointattrib(0,dest,@ptnum,value); // set the value
}

Thanks so much!!
  • Quick Links