For Each on 2 objects

   633   7   1
User Avatar
Member
30 posts
Joined: Feb. 2008
Offline
So I have 2 objects that contains a bunch of “Pieces” sharing an attribute “name” and I want to copy some attributes from one object to the next. The problem is that the order of the pieces don't match, so I can't simply use and Attribute Wrangle to copy data from one to the next because point order don't match. So I want to use a For Each loop to iterate through all the pieces to isolate each matching pieces so I can copy the data piece by piece.

For Each loops on the first object by it's “name” attribute, but I can't figure out the most efficient way to extract the same piece on the second mesh.

The only way I was able to make this work is by creating groups and merge the 2 objects to then separate them using a Blast inside the For Each loop. Merging and Blasting don't feel like a very optimized way of working though. There must be a more efficient way to do this !?

I tried using an expression on a Blast node plugged on the second object to fetch the Metadata value from the iteration to isolate the matching piece, but I get some very inconsistent results. I thought maybe a Fetch Input would do the trick, but no such luck there either. There must be a better way to do this !?

Any suggestion on how I can match 2 pieces from 2 different meshes in a For Each loop (other then the group/merge/blast technique explained earlier)?
User Avatar
Member
518 posts
Joined: May 2006
Offline
Using findattribval might be a better way.

You ask it ‘give me the point of the other object that matches @name’, then lookup attributes on that point.

Attachments:
findattribval.hip (215.0 KB)

http://www.tokeru.com/cgwiki [tokeru.com]
User Avatar
Member
518 posts
Joined: May 2006
Offline
Dur, realised just after I posted that an attribcopy sop is the easiest way; tell it what attribute to match on (name in this case), it does the same as the wrangle.

I did a for loop version too for completeness.

Attachments:
findattribval2.hip (235.3 KB)

http://www.tokeru.com/cgwiki [tokeru.com]
User Avatar
Member
30 posts
Joined: Feb. 2008
Offline
Yes, this works… but now I face a different situation where this approach does not work. I'm trying to pointdeform piece by piece while I have overlapping pieces :

This is the hi res mesh…


Whose name attribute match the lo res animation…


But if I simply do a pointdeform of the whole thing…


I'll get some stretching because of the overlapping pieces at their rest state…


So I need to use a for each loop to pointdeform the mesh piece by piece…


And that gives me a proper deformation…



But I'm not sure the group/merge/blast workflow is the optimal way of doing this. I feel like I'm taking up a lot of extra memory when all I need is to reference to the matching piece of the second geometry inside the loop. This is a simple example with just 2 meshes, but I have hundreds, maybe even thousands of pieces to process in my set-up and I'm trying to figure out the most optimal way of doing something like this.

Attachments:
1 - HiRes overlap.JPG (28.5 KB)
2 - LoRes animated.JPG (34.7 KB)
3 - pointdeform.JPG (22.5 KB)
4 - stretching deformation.JPG (35.2 KB)
5 - for each pointdeform.JPG (37.8 KB)
6 - proper deform.JPG (33.8 KB)
pointdeform by name.hip (358.1 KB)

User Avatar
Member
518 posts
Joined: May 2006
Offline
the for each loop seems like a reasonable approach here. if your production scene is like this (in terms of pieces are moving, but not deforming), I'd look into a packed geo approach which would be faster still and wouldn't require a point deform.
http://www.tokeru.com/cgwiki [tokeru.com]
User Avatar
Member
30 posts
Joined: Feb. 2008
Offline
They are deforming. I just simplified the example.

I also believe the for each loop is unavoidable, but what I'm wondering is if there's a better way to loop through 2 or more objects by name without having to group and merge before entering the loop and splitting each piece up inside the loop. That's the part that feels wrong to me. It feels like I'm taking up extra processing power and extra memory to do this. I'm wondering if there's not a way to simply loop through the first object and inside that loop, call the second (and/or more) object(s) and tell it to isolate the piece that's matching the first object's name inside the loop… but maybe that's not possible? I don't know. That's why I'm asking.
User Avatar
Member
60 posts
Joined: March 2014
Offline
MathieuLeclaire
I'm wondering if there's not a way to simply loop through the first object and inside that loop, call the second (and/or more) object(s) and tell it to isolate the piece that's matching the first object's name inside the loop… but maybe that's not possible? I don't know. That's why I'm asking.
In this scenario I'd say you'll want to work with two “streams”: the object that you loop over (1) and all the other objects (2) that you want to match to the loop. I wouldn't merge (1) and (2) together, but I assume that all the objects in (2) are merged together.

For (2) I'd avoid grouping because it's slower than using attributes and instead give them an attribute that identifies the object. So you'd have:
(1) For the loop object -> name attribute
(2) For the other objects -> name attribute, objectid attribute

Then you'll have to take (2) into the loop and extract the elements you're interested in, e.g. via a Wrangle inside the loop. (2) into input 0, (1) into input 1:
string nameToMatch = prim(1, “name”, 0);
if (s@name != nameToMatch)
removeprim(0, i@elemnum, 1);

And if you further need to differentiate between individual objects of (2) you'll have to do a loop within a loop. I don't think there's a better way. Look into Compile Blocks, they can speed up your loops significantly. Also, there's a video on Vimeo that explains how to use OpenCL for this kind of geometry manipulation, the performance of that seemed ridiculous to me when I saw it, it's much faster than even a Wrangle node.
Edited by GoetzingerC - Jan. 4, 2018 17:31:35
User Avatar
Member
30 posts
Joined: Feb. 2008
Offline
That's great. Thank you. It's what I was looking for.
  • Quick Links