Multivariate interpolation with RBF

calendar_today

19.06.2022

label

Python, VEX, Environment

mouse

Houdini 19.0

Description

Making a grid flow through guide points using multivariate interpolation with the Python module Numpy / Scipy.

1 Initialization

The f@height attribute is going to be interpolated based on common X and Z positions between the grid and the guide points.

CPP
        // Grid
f@px = v@P.x;
f@pz = v@P.z;

f@height = 0.0;
    
CPP
        // Guide points
f@px = v@P.x;
f@pz = v@P.z;

f@height = v@P.y;
    

2 Interpolation

Python's NumPy/SciPy library offers multivariate interpolation. It's making sure the grid will always flow smoothly through our guide points even if they are positioned irregularily.

There are various interpolation methodes provided: multiquadric, inverse multiquadric, gaussian, linear, cubic, quintic and thinplate.

PYTHON
        import numpy as np
from scipy.interpolate import griddata
import scipy.interpolate as interp

node = hou.pwd()
geo1 = node.geometry()
inputs = node.inputs()
geo2 = inputs[1].geometry()

method_nr = node.evalParm('method')
method_names = 'multiquadric,inverse_multiquadric,gaussian,linear,cubic,quintic,thin_plate'.split(',')
method_str = method_names[method_nr]

grid_x = np.array(geo1.pointFloatAttribValues('px'))
grid_z = np.array(geo1.pointFloatAttribValues('pz'))
pos_x = np.array(geo2.pointFloatAttribValues('px'))
pos_z = np.array(geo2.pointFloatAttribValues('pz'))
height = np.array(geo2.pointFloatAttribValues('height'))

rbf_height = interp.Rbf(pos_x, pos_z, height, function=method_str)
smooth_rbf_height = rbf_height(grid_x, grid_z)

geo1.setPointFloatAttribValuesFromString("height", smooth_rbf_height.astype(np.float32))
    
C
        v@P.y = f@height;
    

3 Conclusion

The radial basis function (RBF) in Scipy.interpolate does an excellent job at interpolating between irregular points. RBF looks smoother than what we´d get from the Attribute Transfer SOP, too.

4 Contribution

Adrian Pan contributed a corresponding example file that works directly with heightfields.

5 VEX version

rbf.hip contains a simplified VEX version of multivariate interpolation using radial basis functions. The screenshot compares the attribute transfer node's result (left) with RBF.

C
        int mode = chi('mode');
float k = chf('radius');

float w    = 0.0;
vector clr = 0.0;

for(int i = 0; i < npoints(1); i++){
    vector pos = point(1, 'P', i);
    float d = distance2(v@P, pos);
    vector clr_pt = point(1, 'Cd', i);
    
    float weight = 0.0;
    if     (mode == 0) weight = 1.0 / sqrt(d);                // inverse multiquadratic
    else if(mode == 1) weight = pow(1.0 + (d * d), -0.5) / d; // multiquadric
    else if(mode == 2) weight = exp(-d / (2.0 * k * k));      // gaussian
    else if(mode == 3) weight = 1.0 / (d * d * d);            // cubic
    w += weight; 
    
    clr += clr_pt * weight;
}

v@Cd = clr / w;
    
download

Downloads

smart_display

Videos

Height Field Modeling with Guide Points – Houdini Tutorial

link

Related articles

favorite

167

label

Python

Neural Network SDFs

favorite

262

label

PythonAutomation

Batch processing files with Python

favorite

255

label

ModelingPython

Clipping tools using Python verbs

favorite

213

label

VEXPythonRendering

Convert Meshes to Vector Graphics

favorite

199

label

VEXPythonRendering

Lighting 2D triangles from a 3D mesh

favorite

347

label

VEX

Attribute to match across inputs