How to convert vector3 to vector2 in a way that scales?

   562   7   2
User Avatar
Member
108 posts
Joined: 8月 2017
オフライン
It's been bugging me all weekend. For the record, I know how to do it in general in a rather clunky way.
The way I do it right now is I have an attribute and I create a second attribute of a different name, like this:
u@uv2 = set(v@uv1.x, v@uv1.y);
So, now I have two attributes. And the old attribute has the name that I'd like the new attribute to use. Let's imagine we have 5-10 attributes to convert. This technique does not scale unless we introduce an elaborate setup that manages everything.
What I wish was possible:
u@uv = set(v@uv.x, v@uv.y);

I also tried to do this with SOP tools, I looked at things like Attribute Cast or Attribute Create, but couldnt figure anything out.

The end goal is to turn vector3 into vector2 and keep the original name on the vector2. Kind of like Attribute Promote's "Delete Original" checkbox.
User Avatar
Member
247 posts
Joined: 5月 2017
オフライン
I guess it is not possible to resize the same object at runtime. You can throw it from memory and recreate with the new size and old identifier.

That works for me:

wrangle 1
v@attrib = set(1, 2, 3);
u@tmp = vector2(@attrib);
removepointattrib(0, "attrib");

wrangle 2
u@attrib = @tmp;
removepointattrib(0, "tmp");
Edited by vikus - 2025年10月27日 09:47:26
User Avatar
Member
108 posts
Joined: 8月 2017
オフライン
@vikus Ooh okay! vector2() is so much easier to type, how did I miss this one for so long

Your solution is very good. Thank you so much!

I was experimenting with different ideas in the meantime, so how about this for a bit more SOP-based solution: First Attribute Swap to add a _tmp suffix to my attribs, then use vector2() in a wrangle to re-create their names, then delete all attribs with *_tmp suffix.

Attachments:
sop-based-batch-convert.png (177.1 KB)

User Avatar
Member
247 posts
Joined: 5月 2017
オフライン
Still remains a vector(3) as defined at first place. Changing the attribute type prefix afterwards has no effect. You can also try vops "vectovec2" uv* will remain a vec3.

I would try the method mentioned above or break the geo stream by passing the old uv in to new uv (vec2) stream as removing attributes in VEX can get expensive.
User Avatar
Member
247 posts
Joined: 5月 2017
オフライン
expanded your example here:
Image Not Found

Attachments:
vectovec2.hiplc (92.9 KB)

User Avatar
Member
108 posts
Joined: 8月 2017
オフライン
@vikus What do you mean it remains a vector3? It's vector2 in your hipfile as well as when trying your original VEX technique. And it can't not be vector2 since we create a new attribute.

One thing that I noticed about the new detail wrangle is that it produces different values than all previous methods (check geo spreadsheet). Not sure yet why. Btw if you set Attribute Swap method to "Move" the attribdelete2 node is no longer needed.
User Avatar
Member
247 posts
Joined: 5月 2017
オフライン
Yes I missmove method...

produces different values than all previous methods
in the left wrangle the type prefix is missed, set it back then it should work.
u@uv0 = vector2(v@tmp_uv0);
u@uv1 = vector2(v@tmp_uv1);
User Avatar
Member
9337 posts
Joined: 7月 2007
オフライン
alternatively you can delete all desired attribs from the geo, append Vertex Wrangle and plug the original geo to second input
which saves few extra steps of wrangling temporary attribs
string attrib_mask = chs("attribs");  // pattern that matches attribs to convert, like uv*

string attribs[] = detailintrinsic( 1, "vertexattributes" );
foreach( string attrib; attribs ){
    if ( !match( attrib_mask, attrib ) ) continue;
    
    vector2 value = vertex( 1, attrib, @vtxnum );
    string type = attribtypeinfo( 1, "vertex", attrib );
    setvertexattrib( 0, attrib, @vtxnum, -1, value);
    setattribtypeinfo( 0, "vertex", attrib, type );
}

Attachments:
ts_sop_convert_vertex_attribs_vec3_to_vec2.hipnc (95.7 KB)

Tomas Slancik
CG Supervisor
Framestore, NY
  • Quick Links