Jump to content

Reading a detail attribute array of strings in Vex


Hazoc

Recommended Posts

Hello

 

Have you ever tried to read array based detail attributes in VEX?

 

I have this simple setup where I create a global array attribute of strings using Python.

Later I try to read its' string elements with a  Attribute Wrangle using VEX.

 

Vex says that the length of the array is 1 which it should not be after I set 4 elements in the Python SOP. it also tells me that the type is "none". Should be "String Array type" ?

 

The Python SOP:

node = hou.pwd()
geo = node.geometry()

#A bunch of 4 strings
d = ("S", "F", "E", "C")

#Set as detail attribute "Strings"
geo.addAttrib(hou.attribType.Global, "Strings", d, False, True)
geo.setGlobalAttribValue("Strings", d)

And the Attribute Wrangle:

//Maybe the cause of all bad
string a[] = array(s@Strings);

//Prints the size of 1 instead of 4
int len = len(a);
printf("%g", len);

//Prints the type "none". Should be "String Array type"?
string type = detailattribtypeinfo(0, "Strings");
printf("%c", type);

What am I doing wrong?

Edited by Hazoc
Link to comment
Share on other sites

If you take a look at the help you will see that you can not store an array in the geometry spreadsheet, as far as I know. There is no array type for string attributes. The arrays that are supported are only for color or vectors. So VEX is telling you the truth. There is only one character from your string stored at the attribute.

 

If you are determined to treat the geometry spreadsheet like a database you will have to come up with some kind of pack/unpack data scheme using a single string and some delimiter.

string a = s@Strings[0];

printf("%s\n",a);

post-12295-0-84044300-1448979182_thumb.j

Link to comment
Share on other sites

There is an array type for strings that you can bind as an attribute to geometry. I believe the issue here is proper array attribute support wasn't implemented until 15.0.305, and the methods used are different from the regular attribute methods. The methods for accessing array attributes as a list are called stringListAttribValue(), intListAttribValue(), floatListAttribValue(). Otherwise, it seems Python just sees VEX arrays as strings, not Python lists...

 

Give that a try, you'll need to use build 305 or later to get access to those functions.

Link to comment
Share on other sites

Nice, thanks! I truly am now able to set string arrays in Python. But reading those attributes in VEX is still a mystery.

 

I attached the .hip file. (requires 15.0.305)

 

Python now:

node = hou.pwd()
geo = node.geometry()

#A bunch of 4 strings
d = ("S", "F", "E", "C")

#Set as detail attribute "Strings"
geo.addAttrib(hou.attribType.Global, "Strings", d, False)
geo.setGlobalAttribValue("Strings", d)

#Works!
print "Array list set through Hou: " + str(geo.stringListAttribValue("Strings"))


Vex now:

//Maybe the cause of all bad
string array[] = array(s@Strings);

//Prints nothing for any other than [0] element of the array
printf("Value in VEX: " + "%c\n", array[0]);

//Prints the size of 1 instead of 4
int length = len(array);
printf("Length: " + "%g\n", length);

//Prints the type "none"
string type = detailattribtypeinfo(0, "Strings");
printf("Type: " + "%c\n", type);

detailStringListArray.hip

Link to comment
Share on other sites

Hmm I see, that works in VEX. But still I'm unable to read an existing string array.

I checked the extended operator info and found something interesting. Your array gets typed as a "stringarray" but the one coming from Python operator is just a string. I'm getting confused.

 

post-1686-0-07287600-1449140631_thumb.jp

Link to comment
Share on other sites

I got rapped on the knuckles a few times by a workmate when learning houdini; 'if you don't keep a geometry spreadsheet open at all times with houdini, you don't know what you're doing.'.   :)

 

Loading your example scene with a geo spreadsheet open, you can see straight away on the python sop that you're not creating an array of name string, but rather 4 strings named string[0], string[1], string[2], string[3]. 

 

Compare that to creating the array with vex, and you can see its a single attribute with the values in an array.

 

I had a skim of how to create a string array attribute with python, couldn't see one. Use vex. :)

 

post-7292-0-19089900-1449147391_thumb.jp

Edited by mestela
  • Like 1
Link to comment
Share on other sites

I had a skim of how to create a string array attribute with python, couldn't see one. Use vex. :)

 

 

I need to combine this with XML parsing. If nothing works then I just pack everything into one single long string attribute in Python and convert it into an array in VEX. So dirty.

print geo.stringListAttribValue("Strings")[0]

returns correct values (S, F, E or C) for given indexes 0-3 so it has to be some sort of an array? I really hope the developers can clear this out.

Link to comment
Share on other sites

  • 2 weeks later...

Allright! Got a reply from SESI and here's how you can get it working. I guess this could be an obvious way but couple of confusing things simultaneously made it all appear a bit messy.

 

Python still the same:

node = hou.pwd()
geo = node.geometry()

#A bunch of 4 strings
d = ("S", "F", "E", "C")

#Set as detail attribute "Strings"
geo.addAttrib(hou.attribType.Global, "Strings", d, False)
geo.setGlobalAttribValue("Strings", d)

Vex now:

string A[] = detail(0, 'Strings');

for(int i=0; i<len(A);i++)
{
    printf("A = " + "%c\n", A[i]);
}

And here's the explanation:

 

Our developers say:

 

When you define an attribute binding, like @Strings, it must have the same type everywhere in the snippet. So it is wrong to have

 

s@Strings

and

s[]@Strings

 

This is creating the compiler error on #2.

 

It is a subtle point that the thing created by the Python code upstream is *not* a string array. It is a string tuple of size 4. There is currently no auto-promotion of string tuples to string arrays when binding attributes. Thus, s@Strings binds to the first element of the tuple (just like a f@bar would bind to the first element of a vector3), and s[]@Strings doesn't bind at all.

 

detailattribtyepinfo() returns None because that is the extended type info, not the raw type. This reports things like Vector vs Normal. The detailattribtype() will give the type and return 2 for string tuple, as opposed to 5 for string arrays.

 

To read and write to string tuples you can use the detail/setdetail methods which do support implicit promotion between arrays and tuples:

 

For example:

 

string C[] = detail(0, 'Strings');

 

s[]@bar = C;

string test[] = { 'hello', 'goodbye' };

setdetailattrib(0, 'Strings', test);

 

 

Link to comment
Share on other sites

  • 1 year later...

hi everyone,

im trying almost the same thing in inline

i have string for example a = "54 65 76 23", and i want to add color for every atribute with this number, but i dont know how, now ive got this code, and its not working

string a[] = split($id);
    foreach(int x , a){
        if ($udim == atoi(x)){
        $color = 1;
}}

 

Edited by eistan
Link to comment
Share on other sites

@eistan, array "a" is a string type, and member type must be a string too. Foreach also expects semicolon as a separator.

foreach (string $string_pt; split($pts))
{
    if ($value_to_check == atoi($string_pt))
    {
        $color = {1, 1, 1};
    }
}

 

Edited by f1480187
  • Like 1
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...