Hazoc Posted December 1, 2015 Share Posted December 1, 2015 (edited) 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 December 1, 2015 by Hazoc Quote Link to comment Share on other sites More sharing options...
Atom Posted December 1, 2015 Share Posted December 1, 2015 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); Quote Link to comment Share on other sites More sharing options...
Hazoc Posted December 1, 2015 Author Share Posted December 1, 2015 Thanks! Yeah maybe I smuggle the the strings in and the split them into an array. string foo = "S F E C"; string fooArray[] = split(foo); But this page still makes me believe there is an array type for strings: http://www.sidefx.com/docs/houdini15.0/vex/functions/detailattribtype Quote Link to comment Share on other sites More sharing options...
goldleaf Posted December 2, 2015 Share Posted December 2, 2015 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. Quote Link to comment Share on other sites More sharing options...
Hazoc Posted December 3, 2015 Author Share Posted December 3, 2015 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 Quote Link to comment Share on other sites More sharing options...
mestela Posted December 3, 2015 Share Posted December 3, 2015 the syntax for string array attributes in wrangles is s[]@name. s[]@test={'one','two','three'}; And to read it back: string read[] = s[]@test; s@a = read[0]; s@b = read[1]; s@c = read[2]; 2 Quote Link to comment Share on other sites More sharing options...
Hazoc Posted December 3, 2015 Author Share Posted December 3, 2015 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. Quote Link to comment Share on other sites More sharing options...
mestela Posted December 3, 2015 Share Posted December 3, 2015 (edited) 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. Edited December 3, 2015 by mestela 1 Quote Link to comment Share on other sites More sharing options...
Hazoc Posted December 3, 2015 Author Share Posted December 3, 2015 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. Quote Link to comment Share on other sites More sharing options...
goldleaf Posted December 3, 2015 Share Posted December 3, 2015 It does sound like there might be a bug here. Have you submitted a bug? The description has a link to the bug submit page. Quote Link to comment Share on other sites More sharing options...
Hazoc Posted December 3, 2015 Author Share Posted December 3, 2015 Have you submitted a bug? Not yet. First I needed to exclude the "stupid user" error I'll send a ticket. Quote Link to comment Share on other sites More sharing options...
Hazoc Posted December 14, 2015 Author Share Posted December 14, 2015 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); Quote Link to comment Share on other sites More sharing options...
eistan Posted July 4, 2017 Share Posted July 4, 2017 (edited) 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 July 4, 2017 by eistan Quote Link to comment Share on other sites More sharing options...
f1480187 Posted July 4, 2017 Share Posted July 4, 2017 (edited) @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 July 4, 2017 by f1480187 1 Quote Link to comment Share on other sites More sharing options...
eistan Posted July 5, 2017 Share Posted July 5, 2017 @f1480187 thank u ! this is it! Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.