Friday, 10 April 2026

how to match geo based on path attribute and delete non matching (or keep) primitives

This is quite a specific script.. I got chatgpt to make them for me!

TWO SCRIPTS - they compare input 0 and 1's path attritbutes. Firstly, they strip away (deleting) the primitives that don't match. 
Use case-  you have two mostly identical alembic files of a house. One has UVs you want to transfer to another, but maybe one has some excess geo that you haven't processed yet, or forgot to delete. This will get the two alembics having the same geo (based on path attributes!), so you could do a clean transfer.

 // Get this primitive's path

string my_path = prim(0, "path", @primnum);


// Flag to track match

int match_found = 0;


// Loop over all primitives in input 1

int nprims1 = nprimitives(1);

for (int i = 0; i < nprims1; i++)

{

    string other_path = prim(1, "path", i);

    

    if (my_path == other_path)

    {

        match_found = 1;

        break;

    }

}


// Remove primitive if no match

if (!match_found)

{

    removeprim(0, @primnum, 1); // 1 = delete associated points if unused

}



AND THE REVERSE - KEEPING ONLY THE NON MATCHING STUFF, so you can merge that back into the matching stuff after transferring UVs or whatever.



// Get this primitive's path

string my_path = prim(0, "path", @primnum);


// Flag to track match

int match_found = 0;


// Loop over all primitives in input 1

int nprims1 = nprimitives(1);

for (int i = 0; i < nprims1; i++)

{

    string other_path = prim(1, "path", i);

    

    if (my_path == other_path)

    {

        match_found = 1;

        break;

    }

}


// Remove primitive if a match IS found (reverse logic)

if (match_found)

{

    removeprim(0, @primnum, 1);

}

replacing strings

can't remember if i've written about the "Replace" function. Replacing a given string with nothing, eg "" is a *another* way to remove parts of an existing string!


string tempo=s@path;

tempo=replace(tempo, "/ppHeroBuilding_forTexture/","");

@path=tempo;

Wednesday, 1 April 2026

stop shadow catcher from receiving shadows

Use the Light Linker, but switch the Link Type to Shadow Mask.
Now select your light sources and remove the shadow catcher from the Shadow Casters list.
This will prevent complex objects with detail from casting unwanted shadows on themselves (even though you've unticked self-casting on their object!)

like this- 



Thursday, 20 November 2025

copying a weave onto uv

you need a weave pattern that is positioned between positive 0 and 1 , on the XY plane

you also need an object with good UVs.

The weave goes into input 0 and the target object is input 1.


Here's the wrangle.

 vector uvpos = set(@P.x, @P.z, 0);

vector pos = uvsample(1, "P", "uv", uvpos);

vector normal = uvsample(1, "N", "uv", uvpos);

@P = pos+(normal*@P.y*1);


Wednesday, 8 October 2025

sweep node, spiral / wrap a curve around a curve

 I always forget how to do this ,so here we are.
This creates a spiral loop around a provided curve (no need to add cross section)
Important bits - Round Tube surface shape, Columns surface type, control the twists in the rotation section.


random vellum rest length in houdini core

 To randomise the stretch rest length value on initialisation (not dynamic, it can't be animated like this). make a primitive wrangle between the vellum hair constraint and the solver.

I've used a connectivity node set to Primitives and changed the "class" attrib to "hairID". Here we affect the restlength value by multiplying it by some remapped randomness.

f@restlength*=fit01(chramp("remap",rand(@hairID)),chf("min"),chf("max"));



remap "probability" of random CHANDOM

rand(@ptnum) will give you a distribution between 0 and 1.
fit01 will let you remap this random value between a given minimum and maximum.

But what if you want to have more of the larger values, or mostly small values.. or even just the values inbetween?

We can remap the initial rand(@ptnum) using a chramp.

eg. chramp("remap",rand(@ptnum);

displaying the ramp will let us draw a curve and affect the values.
So below, we will have very few small values and mostly large ones. 
The code is - f@restlength*=fit01(chramp("remap",rand(@hairID)),chf("min"),chf("max"));
Pay attention to the brackets.