Identifying Vector 4 or Matrix 2 Attributes in VEX

   1693   13   1
User Avatar
Member
143 posts
Joined: May 2017
Offline
Hello everyone,
Is there a way to find out in VEX whether an attribute is a vector 4 or a matrix 2?

I use the attribtype [www.sidefx.com] and attribsize [www.sidefx.com] functions to determine the data type. The first returns the type, in the case of a vector or a matrix it is always float, then I can read out the size of the components, but for a vector 4 and matrix 2, the size is 4. Therefore it is not possible to separate these from each other - at least I have no solution. I could, for example, use the ident() function to cause an error when assigning it to a vector4, but VEX is not Python - I can't just bypass such an error.
Edited by viklc - Oct. 24, 2023 07:41:39
User Avatar
Member
2042 posts
Joined: Sept. 2015
Offline
viklc
then I can read out the size of the components, but for a vector 4 and matrix 2, the size is 4. Therefore it is not possible to separate these from each other

You don't have to - They are the same data wise. Unless of course have you had any function 'complain' when one is provided yet it asks for the other by 'name', rather than looking at the data it provides?
User Avatar
Member
143 posts
Joined: May 2017
Offline
Hey BabaJ,

BabaJ
Unless of course have you had any function 'complain' when one is provided yet it asks for the other by 'name', rather than looking at the data it provides?

Yes exactly, that's the point 😊

I'm working on a tool, or rather a sub-tool, that makes it easier to work with attributes and to interact with them more flexible. For example, if the user provides a vector, the program can dynamically interact with it and provide user interface elements such as position or color components, similar to a vector 4 euler parms for normals rotation. For a matrix xform parameters or the matrix itself.

BabaJ
They are the same data wise.
At least that's what it looks like in Spreedsheat - and yes they are float at the end. But you can't access a matrix with square brackets, you use postfixes like .xx, yz and so on. And the getComp function is not too flexible either. And if it's purely a matter of fictionality, you quickly run into errors. For example, I can't assign an identity matrix to a vector 4, you wouldn't want to, but the programme can't tell the difference from the current point.
The same applies to the matrix operation - the results would be different.

I've tried this in Python as well, but run into the same problem - especially if you also want to separate array types, they are not returned as nested lists/tuples, but as a single tuple.

What works is filtering with the function attribtypeinfo. However, this additional information must be given, which only happens automatically if attributes are set with the AtttribCreate SOP, otherwise it must be set manually - which again makes the function useless in this case.
Edited by viklc - Oct. 24, 2023 11:23:09
User Avatar
Member
4521 posts
Joined: Feb. 2012
Offline
viklc
Hey BabaJ,

BabaJ
Unless of course have you had any function 'complain' when one is provided yet it asks for the other by 'name', rather than looking at the data it provides?

Yes exactly, that's the point 😊

I'm working on a tool, or rather a sub-tool, that makes it easier to work with attributes and to interact with them more flexible. For example, if the user provides a vector, the program can dynamically interact with it and provide user interface elements such as position or color components, similar to a vector 4 euler parms for normals rotation. For a matrix xform parameters or the matrix itself.

BabaJ
They are the same data wise.
At least that's what it looks like in Spreedsheat - and yes they are float at the end. But you can't access a matrix with square brackets, you use postfixes like .xx, yz and so on. And the getComp function is not too flexible either. And if it's purely a matter of fictionality, you quickly run into errors. For example, I can't assign an identity matrix to a vector 4, you wouldn't want to, but the programme can't tell the difference from the current point.
The same applies to the matrix operation - the results would be different.

I've tried this in Python as well, but run into the same problem - especially if you also want to separate array types, they are not returned as nested lists/tuples, but as a single tuple.

What works is filtering with the function attribtypeinfo. However, this additional information must be given, which only happens automatically if attributes are set with the AtttribCreate SOP, otherwise it must be set manually - which again makes the function useless in this case.

Without Attribute Type Info metadata, you can't know. Because a vector can be a vector, or a normal, or a position, or a color, or an array of numbers, etc. I think the best way is to provide a menu dropdown based on the number of elements in the attribute.
Senior FX TD @ Industrial Light & Magic
Get to the NEXT level in Houdini & VEX with Pragmatic VEX! [www.pragmatic-vfx.com]

youtube.com/@pragmaticvfx | patreon.com/animatrix | pragmaticvfx.gumroad.com
User Avatar
Member
2042 posts
Joined: Sept. 2015
Offline
viklc
I'm working on a tool, or rather a sub-tool, that makes it easier to work with attributes and to interact with them more flexible. For example, if the user provides a vector, the program can dynamically interact with it and provide user interface elements such as position or color components, similar to a vector 4 euler parms for normals rotation. For a matrix xform parameters or the matrix itself.
So you can maybe just put in an RFE for identifying attributes more specifically than what attribtype can give you.

Otherwise I think what you need to do is reconsider your tool and think about what to do upstream for the initial providing of data by the user - in which you know what is what. Like what animatrix is saying - a drop down menu for the user enter. And based on what they choose,i.e. vector4 or matrix2, you decide how to handle it.
User Avatar
Member
143 posts
Joined: May 2017
Offline
Hey animatrix_,

animatrix_
Without Attribute Type Info metadata, you can't know. Because a vector can be a vector, or a normal, or a position, or a color, or an array of numbers, etc. I think the best way is to provide a menu dropdown based on the number of elements in the attribute.

Yes, but at least you can filter the data types per se.

And for the Vector 2 and Matrix 2 problem, I have a nasty solution:

As an example, @att is an attribute of any data type, which can be filtered with attribtype and attribsize. However, if @att is a Matrix 2 or Vector 4, the result is always the same. Here is an approach how to determine the difference:

In a vector 4 array you can pass a vector 4 as well as a matrix 2 with the set function, but the elements are set differently. While a vector 4 sets all elements of the array, the matrix 2 does not.
vector4 tmp[];

// - att set to a vector4
p@att = {1,2,3,4};
tmp = set(@att); // {{1,1,1,1}, {2,2,2,2}, {3,3,3,3}, {4,4,4,4}} 

// - att set to a matrix2
2@att = {1,2,3,4};
tmp = set(@att); //{1,2,0,0}, {3,4,0,0}, {0,0,1,0}, {0,0,0,1}}

The simplest form of the query would be:
string data_type = (tmp[0].w == 0) ? "matrix2" : "vector4";

You could make the query a bit more complex in case the given vector is 0 by querying the array for tmp.z for 1 or zero.

But well, this seems really nasty
Edited by viklc - Oct. 24, 2023 12:46:33
User Avatar
Member
2042 posts
Joined: Sept. 2015
Offline
viklc
Yes, but at least you can filter the data types per se.

Why not 'pre filter' - when the user provides data, have them specify with a drop down menu - what type it is going to be.
Then you can create a detail attribute that keeps/stores that information - So all you have to do anywhere downstream is look at the specified type chosen and deal with that accordingly.
User Avatar
Member
143 posts
Joined: May 2017
Offline
BabaJ
Why not 'pre filter' - when the user provides data, have them specify with a drop down menu - what type it is going to be.
Then you can create a detail attribute that keeps/stores that information - So all you have to do anywhere downstream is look at the specified type chosen and deal with that accordingly.
Hey,
the main goal is to automate these processes and save the user from clicking around or build extra nodes and code for a simple task - so increasing usability is one of the goals.

I've put the whole thing in a gif:

The parameters automatically adapt to the data type, whether it's color or normal for a Vector3 is up to the user.
Another feature is the direct declaration of attributes - both declaration and existing attributes are supported in the same string input. A meta-dictionary is then generated, which can then be processed as desired, for example to change the parameter layout or trigger certain functions for the appropriate data type.

The whole thing is an abstract construct - a tool to build tools easier.
Edited by viklc - Oct. 24, 2023 15:22:16

Attachments:
houdinifx_LTECIjaBVq.gif (459.9 KB)

User Avatar
Member
143 posts
Joined: May 2017
Offline
BabaJ
So you can maybe just put in an RFE for identifying attributes more specifically than what attribtype can give you.

I will do it eventually. But first I want to see how far it will take me - and whether the additional reading of the attribute types will not affect the performance too much.
I think in general what you both say is right - just let the user decide for himself which type the respective attribute has, but I think especially for attributes that already exist, such information should be readily available to be able to automate certain things. But so far I have a solution for all that.

And a REF for matrix square brackets / index operators wouldn't be wrong either.

Thank you for the feedback.
Edited by viklc - Oct. 25, 2023 09:32:55
User Avatar
Member
143 posts
Joined: May 2017
Offline
Okey, after a few attempts it doesn't really seems possible to keep these two types apart.
For example, if you try to retrieve a Matrix2 attribute with getattrib() and don't explicitly refer to the data type, Houdini sees it as Vector4 - what BabaJ mentioned above. It can also be proved by adding a matrix2 to a dictionary, it will indeed say "vector4" as the type. So the "solution" above does not work in the end.
Edited by viklc - Oct. 26, 2023 20:04:37
User Avatar
Member
2042 posts
Joined: Sept. 2015
Offline
viklc
Okey, after a few attempts it doesn't really seems possible to keep these two types apart.
For example, if you try to retrieve a Matrix2 attribute with getattrib() and don't explicitly refer to the data type, Houdini sees it as Vector4 - what BabaJ mentioned above. It can also be proved by adding a matrix2 to a dictionary, it will indeed say "vector4" as the type. So the "solution" above does not work in the end.

What solution are you referring too?

If you do the pre setup like mentioned before - Have user define the type and save that info as an attribute:

Then use the version of getcomp()that suites the attribute type.

https://www.sidefx.com/docs/houdini/vex/functions/getcomp.html [www.sidefx.com]

Or

If the user is just going to type in the attribute in a string edit box like in your gif - Then why not just do a parsing routine over the string to identify the attribute type,e.g. it's easy to parse for p@My_4linear_floats as being different to 2@My_PairOf_Floats - You have both spaces(since in your example you are separating attributes as such) and the '@' to be able to determine each attribute type specifically entered.
Edited by BabaJ - Oct. 27, 2023 09:16:01
User Avatar
Member
143 posts
Joined: May 2017
Offline
Hey,
BabaJ
What solution are you referring too?

this here,
viklc
The simplest form of the query would be:
string data_type = (tmp.w == 0) ? "matrix2" : "vector4";
but it doesn't work if the attirbute is queried outside the wragler.

2@att;
printf(attribtype(getattrib(0, ... "att"...))); // vector 4

only if

matrix2 att = getattrib(0, ... "att"...);

it is again a matrix2, which makes dynamic parsing of the type impossible.

BabaJ
If you do the pre setup like mentioned before - Have user define the type and save that info as an attribute:
The don't necessarily have to be generated somewhere in „runtime“, they could also come from a cache / imported geometry (whitout meta infos about the type) In such a case, the user should simply select or enter the attribute, but without the indication of what type it is, which would also be misleading, since the type has already been determined.

A simple example would be, the user uses some tool that includes automatic data type analysis as a component. The user works in 2D space and would like to make a 2D transformation with his existing attributes. He could now create a new matrix2, but one already exists from a previous process (or so) and he would like to continue using these values. Well, he now selects it from the dropdown menu, but the program tells him this is a vector4, here are the parameters associated with it, that would be for example RGBA component, but not a 2D xform to actually perform a transformation. And in this case, the user must now explicitly add the attribute tag with the type manually. In addition, the programme must also query whether the attribute already exists. Since this *@ syntax is actually intended for the declaration. Of course, you could add any other indicator here or differ from it completely, but that is not the point.

The thing is that for the return of the type, there are functions that return all types, including all array types, just not the matrix2. And my attempt was to work around this, which simply doesn't work without explicit hints.
Edited by viklc - Oct. 27, 2023 11:00:57
User Avatar
Member
2042 posts
Joined: Sept. 2015
Offline
viklc
they could also come from a cache / imported geometry........ the user should simply select or enter the attribute, but without the indication of what type it is,
If the user has to type or enter anyway - might as well 'force' the user to define what it is they are entering, e.g. drop down menu selection or string entered with full type attribute spelt out for parsing.

Otherwise if you really want a more streamlined operation -- either wait that many others want the same (filed a RFE) feature for a function or addendum to existing function -- OR -- perhaps dig into the HDK and do it with C++, if that's possible there, idk.
Edited by BabaJ - Oct. 27, 2023 11:04:43
User Avatar
Member
143 posts
Joined: May 2017
Offline
BabaJ
If the user has to type or enter anyway - might as well 'force' the user to define what it is they are entering, e.g. drop down menu selection or string entered with full type attribute spelt out for parsing.
Yes, for example the dropdown menu shows the same attribute two times but with different hints for the type. Or generally the option, Force one of both - this as said abstract and can then be determined depending on the tool. It also supports filter options that I have implemented in the meantime. So it is not a big deal, since transformation is usually done with a Matrxi3/4 and a RFE would possibly go beyond the scope. And such a restructuring would simply not justify it. As I said, I was more curious if there was a way around it.

BabaJ
Otherwise if you really want a more streamlined operation -- either wait that many others want the same (filed a RFE) feature for a function or addendum to existing function -- OR -- perhaps dig into the HDK and do it with C++, if that's possible there, idk.
That would probably be a solution, but I have hardly any experience with C++, I'm glad that Python/HOM is going ahead. So for now, everything is fine.
Edited by viklc - Oct. 27, 2023 11:36:30
  • Quick Links