LOPs - AW - filtering & culling


// === Parameters ===
string primvar_name = chs("primvarName");
string primvar_attr = "primvars:" + primvar_name;
string primvar_values = chs("primvarValues");
float seed = chf("seed");
float prune_amt = chf("prune_amt");

// === Fetch data from Input 0 ===
int nums = usd_attriblen(0, @primpath, "positions");
vector positions[] = usd_attrib(0, @primpath, "positions");
int primvar_ids[] = usd_attrib(0, @primpath, primvar_attr);

// === Parse primvar values into set ===
string primvar_values_arr[] = split(primvar_values, ",");
int primvar_values_set[];
foreach (string value; primvar_values_arr) {
int primval = atoi(strip(value));
primvar_values_set[primval] = 1;
}

// === Hardcode cube prim path in Input 1 ===
// Replace with actual prim path to your cube
string cube_primpath = chs("cullingPrimPath"); // <-- Change this

// === Get cube bounding box in world space ===
vector extent[] = usd_attrib(1, cube_primpath, "extent");
matrix xform = usd_localtransform(1, cube_primpath);
vector bbmin = extent[0] * xform;
vector bbmax = extent[1] * xform;

// Make sure bbox min/max are correct
vector cube_bbmin = min(bbmin, bbmax);
vector cube_bbmax = max(bbmin, bbmax);

// === Test positions ===
int invisible[];
for (int i = 0; i < nums; ++i) {
vector pos = positions[i];
int prim_id = i < len(primvar_ids) ? primvar_ids[i] : -1;
int is_in_values = primvar_values_set[prim_id];

int inside_cube = (
pos.x >= cube_bbmin.x && pos.x <= cube_bbmax.x &&
pos.y >= cube_bbmin.y && pos.y <= cube_bbmax.y &&
pos.z >= cube_bbmin.z && pos.z <= cube_bbmax.z
);

if (inside_cube || is_in_values || rand(i + seed) < prune_amt) {
append(invisible, i);
}
}

// === Output result ===
i[]@invisibleIds = invisible;