Attribute Wrange - Run over Numbers

   5959   12   3
User Avatar
Member
74 posts
Joined: March 2016
Offline
I understand what “Run over Numbers” is meant to achieve but not how it works. I have a simple network where I'm looking to find the high and low value of a point array on the x, y or z and the majority of the work is done via two Attribute Wrangles running in Detail Mode, meaning they're being run single threaded.

This is what the code looks like:

Wrangle 1
for (int i = 0; i < npoints(0); i++) {
vector p = point(0, "P", i);
f[]@attribute[i] = p.y;
}

Wrangle 2

@max = f[]@attribute[0];
@min = f[]@attribute[0];
for (int i = 0 ; i < len (f[]@attribute); i++) {
    if (@min > f[]@attribute[i]) {
        @min = f[]@attribute[i];
        @ptmin = idtopoint(0, i);
        
        }
        
    if (@max < f[]@attribute[i]) {
        @max = f[]@attribute[i];
        @ptmax = idtopoint( 0, i);
        
        }
}
resize(f[]@attribute, 0);

I get the result I want in a test case of 100K points scattered over a Mountain Sop deformed Grid. My worry is that this solution won't scale very well so I've been investigating “Run over Numbers” but I can't get the Wrangles to write the array info to Detail attributes in the same manner as running the Wrangles in “Run over Detail(once only)” mode.

I'd ideally like to suss this out as it seems a perfect opportunity for splitting the job up to multiple threads so the solution will scale better, but there's no usage documentation anywhere other than the cryptic tooltips and associated help card info.

Any guidance would be most appreciated.
User Avatar
Member
8506 posts
Joined: July 2007
Online
- any reason you can't use Attibute Promote for that?
- as well idtopoint() ? not sure you really want that there unless you want your ptmin/ptmax to be point whose “id” attribute is the same as @ptnum of the point that is actually lowest/highest, but ptmin/ptmax points will not necessarily be lowest/highest if you have “id” attribute present and it's not the same as @ptnum

- but to the main question, just use setdetailattrib(), there you can choose the mode, which for arrays the most useful is “append” which will append resulting arrays of each “number” into final array
- then as well use min/max modes to get min and max float result from all “numbers”
Edited by tamte - March 15, 2017 12:36:30
Tomas Slancik
FX Supervisor
Method Studios, NY
User Avatar
Member
2523 posts
Joined: June 2008
Offline
Here is my take on this. You really don't need two wrangles, you can do it in one running over points so you get multi-threaded performance. The result ends up in the detail attributes column of the geometry spreadsheet.
int success_flag = 0;
// NOTE: You can use the detail area of the geometry spreadsheet to hold "global" variables.
// but you must make sure the attributes exist before you operate upon them.
float min_Y = detailattrib(geoself(), "last_min_Y", 0, success_flag);
if (success_flag == 0) {
    // The detail attribute does not exist yet, time to create it.
    adddetailattrib(geoself(), "last_min_Y", 100000.0);
}
float max_Y = detailattrib(geoself(), "last_max_Y", 0, success_flag);
if (success_flag == 0) {
    // The detail attribute does not exist yet, time to create it.
    adddetailattrib(geoself(), "last_max_Y", -100000.0);
}
float temp = detailattrib(geoself(), "ptmin", 0, success_flag);
if (success_flag == 0) {
    // The detail attribute does not exist yet, time to create it.
    adddetailattrib(geoself(), "ptmin", -1);
}
temp = detailattrib(geoself(), "ptmax", 0, success_flag);
if (success_flag == 0) {
    // The detail attribute does not exist yet, time to create it.
    adddetailattrib(geoself(), "ptmax", -1);
}
// Now that we can gaurantee that the detail attributes exists, we can operate upon them.
if (v@P.y < min_Y) {
        setdetailattrib(geoself(),"last_min_Y", v@P.y,"set");
        setdetailattrib(geoself(),"ptmin", @ptnum,"set");
}
if (v@P.y > max_Y) {
        setdetailattrib(geoself(),"last_max_Y", v@P.y,"set");
        setdetailattrib(geoself(),"ptmax", @ptnum,"set");
}
Edited by Enivob - March 15, 2017 12:46:42

Attachments:
Untitled-1.jpg (309.5 KB)
ap_min_max_point_IDs.hiplc (102.7 KB)

Using Houdini Indie 20.0
Ubuntu 64GB Ryzen 16 core.
nVidia 3050RTX 8BG RAM.
User Avatar
Member
74 posts
Joined: March 2016
Offline
Thanks for your reply Tomas. I do use Attribute Promote on the next step of the tree.

I think my problem was that I was expecting the detail attribute to be written automatically in the same manner as when the Wrangle is set to ‘Run over Detail’. With the documentation mentioning that "no attributes will be bound, except read only Detail attributes I thought I could run the same snippet without amendment. SetDetailAttrib certainly sounds like it will do what I want in Numbers mode. I'll report back ref how I get on.



The purpose of the scene was strictly research as I've never used the ‘Run Over Numbers’ mode since it was introduced in 15.5 and I wanted to find a better way of wrangling point clouds in the multi million range seeing as Detail mode is single threaded.
Edited by Jonathan Moore2 - March 15, 2017 13:03:01
User Avatar
Member
74 posts
Joined: March 2016
Offline
Thanks too Enivob.

Liking the look of that. Why take two wrangles when one will do the job.

I'll have a play and report back on both approaches.

I don't come from a programing background but have taught myself what I can of VEX off the back of previous experience of Python and Processing (and funnily enough, it's my knowledge of Processing that has more helpful in trying to get to grips with VEX). I hate the idea of having to learn a C like language to get more out of Houdini, especially when I mainly only use wrangles. But Houdini seems to becoming more and more Vex focussed with every release so I may have to bite the bullet.
User Avatar
Member
74 posts
Joined: March 2016
Offline
@Enivob, had a play with your single Wrangle approach and the good news is that it works and it's lightning fast but the result it provides isn't the true min and max as you can see here. I'll try and debug it myself as I'm sure it's something simple but any thoughts from your end will be appreciated too,

User Avatar
Member
2523 posts
Joined: June 2008
Offline
Hmm.. maybe you have an object level transformation in play? Try setting top level transformation to 0,0,0 and scale to 1,1,1.
Using Houdini Indie 20.0
Ubuntu 64GB Ryzen 16 core.
nVidia 3050RTX 8BG RAM.
User Avatar
Member
74 posts
Joined: March 2016
Offline
Enivob
Hmm.. maybe you have an object level transformation in play? Try setting top level transformation to 0,0,0 and scale to 1,1,1.

No object level transforms or scaling. Thanks for the suggestion anyway.

I've been drawn into other things and won't be able to investigate further till this evening. The approach you've laid out has opened my eyes to more efficient ways of working and I'm sure I'll figure out what's going on here.
User Avatar
Member
603 posts
Joined: July 2013
Offline
H calculates an intrinsic bbox for you automatically, which will give you min/max in all 3 axes.
Houdini Indie
Karma/Redshift 3D
User Avatar
Member
74 posts
Joined: March 2016
Offline
Daryl Dunlap
H calculates an intrinsic bbox for you automatically, which will give you min/max in all 3 axes.

Aware of that Daryl. What I'm looking for is the exact point position within any arbitrary point cloud (the mountain distorted grid is just a measurable test case). My original wrangle code works as it should but it's single threaded because it's running in details mode (see image below). My original request was to get a better idea of how to utilize the wrangle in Numbers mode (introduced in 15.5). This allows you to explicitly tell Houdini how many threads you want the job to use (whilst still working at Detail level).

Tamte's original reply should answer my needs but I haven't had a chance to test it as I've got a deadline looming.

User Avatar
Member
74 posts
Joined: March 2016
Offline
Just wanted to report back that in this instance @tamte's response gave me what I wanted (an ability to set detail attribute values in ‘Run over Numbers’ mode). But @Enivob's response taught me a few tricks ref setting detail attributes whilst running a Wrangle over Points.

So good day at the office to all concerned.
User Avatar
Member
1 posts
Joined: March 2018
Offline
You really don't need two wrangles, you can do it in one running over points so you get multi-threaded performance.

This does not work. Do not waste your time like I did.

Judging from detail data in the screenshot and point data from attached file, this has never worked before as well.
Instead of getting the last stored value, detailattrib always gives the value set in adddetailattrib.
Since last_min_y and last_max_y were set as 0, all this code does is check P.y against 0.

min_y does not give the minimum value. Instead it gives the last value less than zero.
True min y value is -.24915. Meanwhile the value it outputs is -.113051.

max_y gives the maximum value, but that is a happy coincidence, as it is the last point with y bigger than zero.
User Avatar
Member
8506 posts
Joined: July 2007
Online
Saintana
You really don't need two wrangles, you can do it in one running over points so you get multi-threaded performance.
This does not work. Do not waste your time like I did.

not sure about that other code, but you can still do it in a single wrangle if you need to
Point Wrangle:
adddetailattrib(0, "min", 1e10);
adddetailattrib(0, "max", -1e10);
setdetailattrib(0,"min", v@P.y, "min");
setdetailattrib(0,"max", v@P.y, "max");
Tomas Slancik
FX Supervisor
Method Studios, NY
  • Quick Links