Monday 25 September 2023

resolving intersections between multiple closed objects (like cushions)

to summarise - convert to vdb, do a volume point sample. multiply the normal of the geo by the volume sample and then add back to the original position. It should push in -or out- for a packed cushiony effect.

nicely demo'd here by Emīls Geršinskis - Ješinskis
https://www.youtube.com/watch?v=2yGxLHSYf8I

Tuesday 28 March 2023

fusing geo using uv attribute (eg. separated head from neck)

Lets say you've separated the head geo from the body for rigging purposes or otherwise.
How do you glue it back together reliably, without resorting to many individual vertex pair selections and fusing each?
UV's! As long as your mesh has good non overlapping UV's (which existed before you chopped it), you can promote them from vertex to point (might as well give it a new name, and keep the originals for actual texture use) then specify this new attribute at the Match Attribute (see below). Turn off Snap Distance, as the UV data is what will snap vertices/points together (in this case I've called it fuse_uv). I've left everything else in the Fuse node as default.
This is super handy especially if your model's point count is not fixed (eg you're not sure where you're cutting the model yet)


Thursday 9 March 2023

Wednesday 8 March 2023

padzero in vex - sprintf %04d

s@name = sprintf('%04d',@primnum);
padzero doesn't work in vex, so you have to use sprintf and the `%04d` method - don't forget those little backticks

Thursday 2 March 2023

curl curves with vex

VEX code taken from this forum post, by user F1 -
Curling hair curves with VEX - General Houdini Questions - od|forum (odforce.net)

Very hand bit of code that can curl up your curves for hairstyles, bits of fluff or any other curly things you might imagine. 

If you're going to use a path deform SOP after this (eg, you're using the curves to deform a bunch of snakes) you'll want to Attribute Delete the Normal "N" attribute that this script creates. Otherwise your geo might come out a bit flat/squashed/wrong in places.


 // Primitive wrangle.

#define TWO_PI 6.2831852

addpointattrib(0, "N", {0, 0, 0});
int pts[] = primpoints(0, @primnum);
int npt = len(pts);

// Loop variables.
vector rest = point(0, "P", pts[0]);
vector prev_pos = rest;
matrix3 frame = ident();

for (int i = 0; i < npt; i++)
{
    vector pos = point(0, "P", pts[i]);
    vector delta = pos - rest;
    rest = pos;

    // Make normal. Point normals could be used instead.
    vector normal = normalize(cross(cross({0, 1, 0}, delta), delta));
    if (length(normal) == 0)
    {
        normal = {0, 0, 1};
    }

    // Drive a shape with ramps and multipliers.
    vector axis;
    float ramp, angle;

    // Twist the bend axis.
    axis = normalize(delta);
    ramp = chramp("twist_profile", (float) i / npt);
    angle = fit01(ramp, -TWO_PI, TWO_PI) * ch("twist") / (npt - 1);
    rotate(frame, angle, axis);

    // Bend the curve.
    axis = normalize(cross(normal, delta));
    ramp = chramp("bend_profile", (float) i / npt);
    angle = fit01(ramp, -TWO_PI, TWO_PI) * ch("bend") / (npt - 1);
    rotate(frame, angle, axis);

    // Compute new position and normal.
    vector new_pos = delta * frame + prev_pos;
    prev_pos = new_pos;
    setpointattrib(0, "P", pts[i], new_pos);
    setpointattrib(0, "N", pts[i], normal * frame);
}




// Primitive wrangle.

int pts[] = primpoints(0, @primnum);

vector rest = point(0, "P", pts[0]);
vector prev_pos = rest;
matrix3 frame = ident();

for (int i = 0; i < len(pts); i++)
{
    vector pos = point(0, "P", pts[i]);
    rotate(frame, 0.1, {0, 0, 1});
    vector new_pos = (pos - rest) * frame + prev_pos;
    rest = pos;
    prev_pos = new_pos;
    setpointattrib(0, "P", pts[i], new_pos);
}

Wednesday 1 March 2023

primitive number as an attribute - enumerate

 use case - you have a bunch of curves and want to give them individual point colours - but you want the points to all use the same id.

an Enumerate sop node will let you store the number value in each point or primitive. Lets use the primitive option, then attribute promote it to points so that each curve's points all contain the same identifiable attribute.


It can also be used to name "pieces", which might be useful



Friday 17 February 2023

decent kinefx primer youtube playlist

 More of a reminder for myself... Quite a good primer on Kine FX, full body IK, posing and animation
https://youtu.be/S4Bzhnepovk

Tuesday 31 January 2023

exporting custom attributes in Alembic to Blender

We use the setattribtypeinfo function to force an attribute to be a color type. Just like Cd usually is.

This will probably streamlined and not necessary in future versions of Blender, but it seems like it is still necessary atm (Jan 2023)

using a point wrangle, set to detail (so it only runs once)

 setattribtypeinfo(0,"point","attributename","color");


here I'm forcing an attribute called attributename to be recognised as a color type & not just 3 floats.
I'm using the rop_alembic output to write the abc file.

Friday 6 January 2023

doing things to for each sop loops

 

How to get information about the current loop

Sometimes you need to use the current loop or the current piece number in an expression on one of the nodes in the same loop. You can get this information with a  Block Begin SOP node that uses the Fetch Metadata method.

  1. Set up a looping block using the instructions above.

  2. Select the  Block Begin SOP node, and then in the Parameter Editor click Create Meta Import Node.

    This button adds a second Block Begin SOP node to the side of the existing one. This node is set up to generate an empty geometry with some detail attributes.

    The detail attributes are as follows:

    numiterations

    The expected total number of iterations, taking into account the Max Iterations and Single Pass parameters on the  Block End SOP node of the loop.

    iteration

    The current iteration number, always starting at 0 and increasing by 1 each loop.

    value

    In piecewise loops, this is the current value of the attribute. For example, the piece integer or name string, or if there is no attribute, the current point or primitive number.

    In simple repetition loops, this is a floating point value starting at the Block End SOP’s Start Value and increasing by the specified Increment each loop.

    ivalue

    In simple repetition, this is an integer version of value. This can be useful if the value is naturally an integer (for example, starts at 1 and increments by 2) and/or if values are over 24 million (where floating point numbers lose precision).

  3. To grab the value of these attributes in a node inside the loop, do the following: