DonRomano Posted July 8, 2020 Share Posted July 8, 2020 (edited) Hey guys, I started writing a deformer using rbf (Radial Basis Function) with python, my aim is to reproduce the one made by Artem Smirnov in his reel : https://vimeo.com/338885866 Currently I try to get it working on geometry and then I'll implement it for volumes I'm experiencing an issue and I don't really know from where it's coming : the deformation is kind of inverted on the other side of the geometry, where the geometry should not move and stay where it is, and I don't know what causes this. Input 1 is the mesh, Input 2 is the rest lattice and Input 3 is the deformed lattice Here's the code : import numpy as np node = hou.pwd() inputs = node.inputs() geo1 = node.geometry() geo2 = inputs[1].geometry() geo3 = inputs[2].geometry() radius_parm = float(node.evalParm("radius")) kernel_parm = node.evalParm("kernels") kernel_names = "gaussian,thinPlateSpline,linear".split(",") kernel = kernel_names[kernel_parm] ##################################################### #distance calculation def ext_arrs(A,B, precision="float64"): nA,dim = A.shape A_ext = np.ones((nA,dim*3),dtype=precision) A_ext[:,dim:2*dim] = A A_ext[:,2*dim:] = A**2 nB = B.shape[0] B_ext = np.ones((dim*3,nB),dtype=precision) B_ext[:dim] = (B**2).T B_ext[dim:2*dim] = -2.0*B.T return A_ext, B_ext def pdist_squareformed(a, b): A_ext, B_ext = ext_arrs(a, b) dist = A_ext.dot(B_ext) np.fill_diagonal(dist,0) return dist def thinPlateSpline(x, r): arg = x / r result = arg * arg result = np.where(arg > 0, result * np.log(arg), result) return result def gaussianSpline(x, r): result = np.exp(-(x * x) / (r * r)) return result def linear(x, r): result = x / r return result def rbf(x, kernel, radius): if kernel == "gaussian": result = gaussianSpline(x, radius) if kernel == "thinPlateSpline": result = thinPlateSpline(x, radius) if kernel == "linear": result = linear(x, radius) return result ##################################################### #SETUP GEO POSITIONS MATRICES numpt1 = len(geo1.iterPoints()) matrixQ1 = np.zeros((numpt1, 3)) numpt2 = len(geo2.iterPoints()) matrixQ2 = np.zeros((numpt2, 3)) numpt3 = len(geo3.iterPoints()) matrixQ3 = np.zeros((numpt3, 3)) #geo i = 0; for p1 in geo1.points(): matrixQ1[i, 0] = p1.position()[0] matrixQ1[i, 1] = p1.position()[1] matrixQ1[i, 2] = p1.position()[2] i += 1 #lattice j = 0; for p2 in geo2.points(): matrixQ2[j, 0] = p2.position()[0] matrixQ2[j, 1] = p2.position()[1] matrixQ2[j, 2] = p2.position()[2] j += 1 #deformed lattice k = 0; for p3 in geo3.points(): matrixQ3[k, 0] = p3.position()[0] matrixQ3[k, 1] = p3.position()[1] matrixQ3[k, 2] = p3.position()[2] k += 1 ##################################################### #CALCULATE WEIGHTS npts, dim = matrixQ2.shape H = np.zeros((npts + 3 + 1, npts + 3 + 1)) H[:npts, :npts] = rbf(np.sqrt(pdist_squareformed(matrixQ2, matrixQ2)), kernel, radius_parm) H[npts, :npts] = 1.0 H[:npts, npts] = 1.0 H[:npts, -3:] = matrixQ2 H[-3:, :npts] = matrixQ2.T RH = np.zeros((npts + 3 + 1, dim)) RH[:npts, :] = matrixQ3 weights = np.linalg.solve(H, RH) ##################################################### #DEFORMATION npts2, dim2 = matrixQ1.shape G = np.zeros((npts2, npts + 3 + 1)) G[:, :npts] = rbf(np.sqrt(pdist_squareformed(matrixQ1, matrixQ2)), kernel, radius_parm) G[:, :npts] = 1.0 G[:, -3:] = matrixQ1 new_pos = np.asarray(np.dot(G, weights)) ##################################################### #SET POS s = 0; for p in geo1.points(): newX = new_pos[s, 0] newY = new_pos[s, 1] newZ = new_pos[s, 2] p.setPosition((newX, newY, newZ)) s += 1 Edited July 8, 2020 by DonRomano Quote Link to comment Share on other sites More sharing options...
nithish24 Posted April 9, 2022 Share Posted April 9, 2022 Hey, I'm also in the same process trying to understand RBF interpolation. were you able to achieve the effect ? Quote Link to comment Share on other sites More sharing options...
Librarian Posted April 9, 2022 Share Posted April 9, 2022 @niteshift maybe Try with Vex.. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.