Simstim

Houdini

Smoothing point clouds with pcopen

Relax noisy scans and scatters in one Point Wrangle, and understand what pcopen and pcfilter actually do.

· 2 min read · houdini · vex · point clouds

Scans, fluid surfaces and scattered points all come in noisy. The fix is almost always the same move: nudge each point toward the average of its neighbours. In VEX that takes four lines.

The wrangle

Drop a Point Wrangle after your points and add three parameters with the button next to the code editor: radius, maxpts and amount.

// Point Wrangle, run over Points
int handle = pcopen(0, "P", @P, chf("radius"), chi("maxpts"));
vector avg = pcfilter(handle, "P");
@P = lerp(@P, avg, chf("amount"));
pcclose(handle);

Start with a radius about three times your average point spacing, maxpts around 20, and amount at 0.5.

What each line does

  1. pcopen builds a query around the current point: up to maxpts of the nearest points within radius, looking at the P attribute of input 0.
  2. pcfilter returns a distance-weighted average of any attribute over those points. Nearer points count for more, so the result is smoother than a plain mean.
  3. lerp blends from the original position toward that average.
  4. pcclose releases the handle. Houdini would clean up for you, but closing makes the intent obvious.

Because every point reads the input geometry rather than its already-moved neighbours, the result doesn't depend on point order. That is what you want in a wrangle.

Going further

  • More smoothing: put the wrangle inside a For-Loop with Feedback and set a few iterations, rather than raising the radius. (A For-Each loop won't do it. In Houdini 22.0.368, a For-Each whose piece attribute is missing warns and outputs no points. For-Each Point runs once per point, but then pcopen finds only the point itself, so nothing moves.) Large radii flatten detail you want to keep.
  • Protect edges: multiply amount by a mask, such as curvature or a painted attribute, so sharp features survive.
  • Smooth anything: swap "P" in pcfilter for "Cd", "N" or "v" to blur colour, normals or velocity with the same neighbourhood.
  • Count, don't average: pcnumfound(handle) gives you local density, which makes a great mask on its own.

The pcopen entry in the dictionary has this wrangle and a density example ready to copy, along with its other signatures.