Jump to content
slayerk

[SOLVED] Wrangle Node. Vex Problem with importing attribute.

Recommended Posts

How can i import attribute to geoself() geometry from second input of wrangle node if i don't know type of this attribute.

I write function:

parameters:

native_input  = 0 (first input of wrangle node)

sample_input = 1 (second input of wrangle node)

attribs = string like "attrib1 attrib2 attrib3"

native_ptnum = number of point in current geometry where i want create attributes like in second input

sampled_ptnum = number of point from second input where i want sample attribute.

but cannon import any array attributes like "Cd" and etc...

This function correctly worked only if attribute is not array (type = 0 or 1 or 2) :(((

void sampleattribs(int native_input; int sample_input; string attribs; int native_ptnum; int sampled_ptnum ) {
    foreach(string aname; split(strip(attribs), " ")) {
        aname = strip(aname);
        if ( haspointattrib(sample_input, aname) ) {
            
            int atype = attribtype(sample_input, "point", aname);
            
            if (atype==0) {
                addpointattrib(native_input, aname, int(0));
                int value = point(sample_input, aname, sampled_ptnum);
                setpointattrib(native_input, aname, native_ptnum, value);
            };
            if (atype==1) {
                addpointattrib(native_input, aname, float(0));
                float value = point(sample_input, aname, sampled_ptnum);
                setpointattrib(native_input, aname, native_ptnum, value);
            };
            if (atype==2) {
                addpointattrib(native_input, aname, "");
                string value = point(sample_input, aname, sampled_ptnum);
                setpointattrib(native_input, aname, native_ptnum, value);
            };
            if (atype==3) {
                int def_value[];
                addpointattrib(native_input, aname, def_value);
                int value[] = point(sample_input, aname, sampled_ptnum);
                setpointattrib(native_input, aname, native_ptnum, value);
            };
            if (atype==4) {
                int size = pointattribsize(sample_input, aname);
                string typeinfo = attribtypeinfo(sample_input, "point", aname);
	                float def_value[] = {};
                for(int i=0; i<size; i++) append(def_value, 0.);
	                addpointattrib(native_input, aname, def_value);
                setattribtypeinfo(native_input, "point", aname, typeinfo);
                
                
                
                float value[];
                resize(value, size);
                int success = -1;
                
                //value = point(sample_input, aname, sampled_ptnum);
                //printf("%d\n", sampled_ptnum);
                
                //foreach(float v; value)  { printf("%f", v); };
                
                setpointattrib(native_input, aname, native_ptnum, value);
            };
            if (atype==5) {
                string def_value[]={};
                addpointattrib(native_input, aname, def_value);
                string value[] = point(sample_input, aname, sampled_ptnum);
                setpointattrib(native_input, aname, native_ptnum, value);
            };
        };
    };
};
Edited by slayerk

Share this post


Link to post
Share on other sites

you read the code i'm attach above?

6th string is:

int atype = attribtype(sample_input, "point", aname);

problem is:

how to operate and create attributes of type: 3, 4, 5 (int, float, string arrays). code in my function doesn't work.

for example in array (type 3):

if (atype==3) {
                int def_value[];
                addpointattrib(native_input, aname, def_value);
                int value[] = point(sample_input, aname, sampled_ptnum);
                setpointattrib(native_input, aname, native_ptnum, value);
            };

simply creates int array with 1 element, independent to size of reference attribute array.

 

Share this post


Link to post
Share on other sites

Sorry about that. Thought i read through it all. Kind of hard to read black text on grey background. :)
Do you have a sample file you can upload that shows the problem? Or a call statement to your function with a sample of the data your passing in?
Or you could use Attribute Copy and set "Attribute Name" to asterix. That will basically do the same thing as your function is doing.

-b

Share this post


Link to post
Share on other sites

If I read the docs correctly, then the setpointattrib() function does not have an overloaded version which works on arrays. So I suppose you will have to iterate over the source entries and push them to the destination array.

Share this post


Link to post
Share on other sites

You did everything right, except misunderstanding about array and vector types. Cd is a float type with size of 3, not float array. Float array types are arrays of single floats as well as arrays of vectors or matrices.

attribute_copy.hipnc

Here I'm trying to be robust. With a bit more complex macro, it can be expanded to all types of geometry. You will see the current VEX limitations right in the code. I also simplified the code, so, you will need to wrap it in function and foreach loop again.

// Point wrangle.

// Testing variable set.
string name = "attrib";
int dst = geoself();
int dst_pt = @ptnum;
int src = 1;
int src_pt = dst_pt;

// Function body.
int type = pointattribtype(src, name);
int size = pointattribsize(src, name);
string info = pointattribtypeinfo(src, name);

#define ADDSETATTRIB(declaration)                \
{                                                \
    declaration = point(src, name, -1);          \
    addpointattrib(dst, name, defvalue, info);   \
    defvalue = point(src, name, src_pt);         \
    setpointattrib(dst, name, dst_pt, defvalue); \
}

// Any of it indicates attribute not exist on source.
if (type == -1 || size == 0 || info == "")
    error("Attribute not found");

// Integer.
else if (type == 0 && size == 1)
    ADDSETATTRIB(int defvalue)

// Float.
else if (type == 1 && size == 1)
    ADDSETATTRIB(float defvalue)

// 2-float vector.
else if (type == 1 && size == 2)
    ADDSETATTRIB(vector2 defvalue)

// 3-float vector.
else if (type == 1 && size == 3)
    ADDSETATTRIB(vector defvalue)

// 4-float vector or 2x2 matrix. Both are [4f] by default.
else if (type == 1 && size == 4)
    ADDSETATTRIB(vector4 defvalue)

// 3x3 matrix.
else if (type == 1 && size == 9)
    ADDSETATTRIB(matrix3 defvalue)

// 4x4 matrix.
else if (type == 1 && size == 16)
    ADDSETATTRIB(matrix defvalue)

// String.
else if (type == 2 && size == 1)
    ADDSETATTRIB(string defvalue)

// Integer array.
else if (type == 3 && size == 1)
    ADDSETATTRIB(int defvalue[])

// Float array.
else if (type == 4 && size == 1)
    ADDSETATTRIB(float defvalue[])

// String array.
else if (type == 5 && size == 1)
    ADDSETATTRIB(string defvalue[])

// Integer vectors.
else if (type == 0 && size > 1)
    error("Can't add %d-integer vector (Houdini 15.5)", size);

// Float vectors with arbitrary size.
else if (type == 1 && size != 2
                   && size != 3
                   && size != 4
                   && size != 9
                   && size != 16)
    error("Can't add %d-float vector (Houdini 15.5)", size);

// String vectors. Can be created by promoting varmap only.
else if (type == 2 && size > 1)
    error("Can't add %d-string vector (Houdini 15.5)", size);

// Integer vector arrays.
else if (type == 3 && size > 1)
    error("Can't add %d-integer vector array (Houdini 15.5)", size);

// Vector and matrix arrays.
else if (type == 4 && size > 1)
    error("Can't add %d-float vector array (Houdini 15.5)", size);

// We forgot something.
else
    error("Non-implemented for this kind of attributes");

// Impossible to get default attribute values in VEX in Houdini 15.5.
// We will stick to what point(input, attribute_name, -1) returns.
// And maybe in future it will return proper defaults, instead of zeros.
warning("Default values cannot be copied, if any. (Houdini 15.5)");
Edited by f1480187
  • Like 2

Share this post


Link to post
Share on other sites

Wow!!! Thanks!!!

More than anything, I'm afraid that for each type of data (returned by tipeinfo() function and each size of it) in Houdini would have to do a separate condition: (( No other, more simpler ways?

 

Share this post


Link to post
Share on other sites

yes, yes you right.

I mean I'm lazy and afraid that for each returned value of attribtypeinfo *(multiply) each size of attrib i must write separate if construction in code. :(((

I was hoping that there was an easier way.

Share this post


Link to post
Share on other sites

Could you post a working sample of VEX code implementing such separation? I think you don't have to do it at all. Type info is just a string passed into addpointattrib function, and it don't care about attribute size and even about actual type. Most of attributes have "none".

Edited by f1480187

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

×