Posts
Houdini - Separate Pieces
We want to manipulate every face individually, so we have to “break up” the mesh into individual primitive pieces.
Use a facet operator, with “unique point” turned on. Then, use a primitive operator to do stuff, like scaling, which will get us:
Add a point to the center of each primitive Run a Wrangle SOP over primitives and simply add a point at each position:
int pt = addpoint(0, @P); setpointgroup(0, "centroids", pt, 1); // group just in case Which gives us this:
Posts
Houdini - Selecting With Bounding Box
Use the relbbox function in a Group Expression to select points at the “extremities” of a geo’s bounding box.
E.g. the “front facing” points here are +1 on the z-axis:
relbbox(0, @P).z == 1 And the “back facing” ones would be z == 0.
The “top” points are +1 on the y-axis:
relbbox(0, @P).y == 1 Using the same expression lets us also conveniently select the “topmost” point on a sphere:
Posts
Houdini - A solver is a reduce function
A solver is essentially a reduce function. It’s passed, as its first argument, the result of the previous loop’s evaluation.
A reduce function in Javascript:
const array1 = [1, 2, 3, 4]; function reducer(accumulator, currentValue) { return accumulator + currentValue } ; result = array1.reduce(reducer) //=> 10 Inside a solver:
As an example, we create a network with a single attribute @num = 0 and pass it into the solver.
Posts
Houdini - Solver as an Accumulator
The idea: Use a solver to accumulate boxes from each frame of a “simulation”.
E.g. we’re creating a reduce function that looks like this:
func accumulate(boxes []box, currBox box) { boxes = append(boxes, currBox) return boxes } To get started, we create one point on a grid on each frame.
We then copy a randomly colored box to each of those points, on each frame e.g. the box is given a different color on each frame, and then copied to the new point on that frame.
Posts
Houdini - Using a solver to persist attribute transfer
Here we have a bunch of curves that change color over time and transfers their @Cd to the grid when they come into contact with it.
When a frame cooks, Houdini evaluates the contact only on that frame, it has no “memory” as to whether they’ve touched before.
So how do we persist the color?
We do the attribute transfer inside a solver node, which will allow us to “accumulate” the paint just as we did with boxes.
Posts
FFMPEG - Apply a 3D LUT to an image
Assuming the LUT is a *.cube file:
ffmpeg -i "${FILEIN}.jpg" -vf lut3d="{lut}.cube" -q:v 1 -y "${FILEOUT}.jpg"
Posts
FFMPEG - Burn in frame number
Burn an arbitrary frame number into a video.
ffmpeg -i "${FILEIN}" -vf "drawtext=fontfile=InputMono-Regular.ttf: text='%{frame_num}': start_number=1000: x=20:y=h-120: fontcolor=white: fontsize=100: box=1: boxcolor=black: boxborderw=5" "${FILEOUT}" To write out image files, change $FILEOUT to outfile.%04d.jpg.
Input Mono is a nice font for this.
Posts
FFMPEG - ffprobe and JSON
Get metadata from ffprobe in JSON output:
ffprobe -v quiet -print_format json -show_format -show_streams "${FILEIN}"
Posts
FFMPEG - Merge one mono channel to stereo
Assuming we have video in 0:0 and only one audio stream in 0:1:
ffmpeg -i ${FILEIN} -filter_complex "[0:1][0:1]amerge,channelmap=channel_layout=stereo[st]" -map 0:0 -map "[st]" -c:v copy -c:a pcm_s16le -ar 48k ${FILEOUT}
Posts
Houdini - Pattern Matching
Delete every attribute except This is a gotcha, an Attribute Delete SOP doesn’t have an “invert” option:
Above, delete every attribute except @P @b @c
* ^[Pbc] See Pattern Matching