Jump to content

Create a Landscape from Irregular Points using Multivariate Interpolation


konstantin magnus

Recommended Posts

This is an example for building landscapes from irregular points using SciPy.

fit_plane_through_points.thumb.jpg.67674d94c5e655ac06b0629eb3a011bb.jpg

import numpy as np
from scipy.interpolate import griddata

# FIRST INPUT: REGULAR GRID
node = hou.pwd()
geo1 = node.geometry()

grid_x = np.array(geo1.pointFloatAttribValues("px"))
grid_y = np.array(geo1.pointFloatAttribValues("py"))
grid_z = np.array(geo1.pointFloatAttribValues("pz"))

# SECOND INPUT: RANDOM POINTS
inputs = node.inputs()
geo2 = inputs[1].geometry()

val_x = np.array(geo2.pointFloatAttribValues("px"))
val_y = np.array(geo2.pointFloatAttribValues("py"))
val_z = np.array(geo2.pointFloatAttribValues("pz"))

# MULTIVARIATE INTERPOLATION
grid_y = griddata( (val_x, val_z), val_y, (grid_x, grid_z), fill_value=0.0, method='cubic' ) # methods: nearest, cubic, linear

# NEW HEIGHT POSITIONS ON GRID
geo1.setPointFloatAttribValuesFromString("py",grid_y.astype(np.float32))

scipy_grid_to_points.hiplc

Edited by konstantin magnus
  • Like 2
  • Thanks 1
Link to comment
Share on other sites

I just found out about the radial basis function (RBF) in Scipy.interpolate, which does an even better job at interpolating between irregular points. As it does not use delaunay, it also lost the trianglish appearance it had before. RBF looks way smoother than what you´d get from Attribute Transfer SOP, too.

interpolate_rbf.png.36775930a97ef7427f055603cedaf71f.png

 

Btw: Does someone know, how to make the same code work with vector arrays in NumPy?

I tried it in the commented lines, but currently I have to use three separate arrays for each color channel and therefore call each function three times, as well : (

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'))

color_r = np.array(geo2.pointFloatAttribValues('cr')) 
color_g = np.array(geo2.pointFloatAttribValues('cg')) 
color_b = np.array(geo2.pointFloatAttribValues('cb')) 
#color = np.array(geo2.pointFloatAttribValues('Cd'))
#np.reshape(color, (30, 3))

pos_x = np.array(geo2.pointFloatAttribValues('px'))
pos_z = np.array(geo2.pointFloatAttribValues('pz'))

rbf_red = interp.Rbf(pos_x, pos_z, color_r, function=method_str)
rbf_green = interp.Rbf(pos_x, pos_z, color_g, function=method_str)
rbf_blue = interp.Rbf(pos_x, pos_z, color_b, function=method_str)
#rbf_color = interp.Rbf(pos_x, pos_z, color, function=method_str)

smooth_rbf_red = rbf_red(grid_x, grid_z)
smooth_rbf_green = rbf_green(grid_x, grid_z)
smooth_rbf_blue = rbf_blue(grid_x, grid_z)
#smooth_rbf_color = rbf_color(grid_x, grid_z)

geo1.setPointFloatAttribValuesFromString("clr_r", smooth_rbf_red.astype(np.float32))
geo1.setPointFloatAttribValuesFromString("clr_g", smooth_rbf_green.astype(np.float32))
geo1.setPointFloatAttribValuesFromString("clr_b", smooth_rbf_blue.astype(np.float32))
#geo1.setPointFloatAttribValuesFromString("Cd", smooth_rbf_color.astype(np.float32))

 

scipy_grid_to_color_points.hiplc

  • Like 7
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...