Important: Please read the installation page for details about how to install the toolboxes. $\newcommand{\dotp}[2]{\langle #1, #2 \rangle}$ $\newcommand{\enscond}[2]{\lbrace #1, #2 \rbrace}$ $\newcommand{\pd}[2]{ \frac{ \partial #1}{\partial #2} }$ $\newcommand{\umin}[1]{\underset{#1}{\min}\;}$ $\newcommand{\umax}[1]{\underset{#1}{\max}\;}$ $\newcommand{\umin}[1]{\underset{#1}{\min}\;}$ $\newcommand{\uargmin}[1]{\underset{#1}{argmin}\;}$ $\newcommand{\norm}[1]{\|#1\|}$ $\newcommand{\abs}[1]{\left|#1\right|}$ $\newcommand{\choice}[1]{ \left\{ \begin{array}{l} #1 \end{array} \right. }$ $\newcommand{\pa}[1]{\left(#1\right)}$ $\newcommand{\diag}[1]{{diag}\left( #1 \right)}$ $\newcommand{\qandq}{\quad\text{and}\quad}$ $\newcommand{\qwhereq}{\quad\text{where}\quad}$ $\newcommand{\qifq}{ \quad \text{if} \quad }$ $\newcommand{\qarrq}{ \quad \Longrightarrow \quad }$ $\newcommand{\ZZ}{\mathbb{Z}}$ $\newcommand{\CC}{\mathbb{C}}$ $\newcommand{\RR}{\mathbb{R}}$ $\newcommand{\EE}{\mathbb{E}}$ $\newcommand{\Zz}{\mathcal{Z}}$ $\newcommand{\Ww}{\mathcal{W}}$ $\newcommand{\Vv}{\mathcal{V}}$ $\newcommand{\Nn}{\mathcal{N}}$ $\newcommand{\NN}{\mathcal{N}}$ $\newcommand{\Hh}{\mathcal{H}}$ $\newcommand{\Bb}{\mathcal{B}}$ $\newcommand{\Ee}{\mathcal{E}}$ $\newcommand{\Cc}{\mathcal{C}}$ $\newcommand{\Gg}{\mathcal{G}}$ $\newcommand{\Ss}{\mathcal{S}}$ $\newcommand{\Pp}{\mathcal{P}}$ $\newcommand{\Ff}{\mathcal{F}}$ $\newcommand{\Xx}{\mathcal{X}}$ $\newcommand{\Mm}{\mathcal{M}}$ $\newcommand{\Ii}{\mathcal{I}}$ $\newcommand{\Dd}{\mathcal{D}}$ $\newcommand{\Ll}{\mathcal{L}}$ $\newcommand{\Tt}{\mathcal{T}}$ $\newcommand{\si}{\sigma}$ $\newcommand{\al}{\alpha}$ $\newcommand{\la}{\lambda}$ $\newcommand{\ga}{\gamma}$ $\newcommand{\Ga}{\Gamma}$ $\newcommand{\La}{\Lambda}$ $\newcommand{\si}{\sigma}$ $\newcommand{\Si}{\Sigma}$ $\newcommand{\be}{\beta}$ $\newcommand{\de}{\delta}$ $\newcommand{\De}{\Delta}$ $\newcommand{\phi}{\varphi}$ $\newcommand{\th}{\theta}$ $\newcommand{\om}{\omega}$ $\newcommand{\Om}{\Omega}$
This tour explores deformation of 2D mesh using Laplacian interpolation. The dense deformation field is obtained from a sparse set of displaced anchor point by computing harmonic interpolation.
from __future__ import division
import nt_toolbox as nt
from nt_solutions import meshdeform_5_deformation as solutions
%matplotlib inline
%load_ext autoreload
%autoreload 2
p = 150
[Y, X] = meshgrid(linspace(-1, 1, p), linspace(-1, 1, p))
vertex0 = [X(: )'; Y(: )'; zeros(1, p^2)]
n = size(vertex0, 2)
We generate a triangulation of a square.
I = reshape(1: p^2, p, p)
a = I(1: p-1, 1: p-1); b = I(2: p, 1: p-1); c = I(1: p-1, 2: p)
d = I(2: p, 1: p-1); e = I(2: p, 2: p); f = I(1: p-1, 2: p)
faces = cat(1, [a(: ) b(: ) c(: )], [d(: ) e(: ) f(: )])'
Width and height of the bumps.
sigma = .03
h = .35
q = 8
Elevate the surface using bumps.
t = linspace(-1, 1, q + 2); t([1 length(t)]) = []
vertex = vertex0
for i in 1: q:
for j in 1: q:
d = (X(: )'-t(i)).^2 + (Y(: )'-t(j)).^2
vertex(3, : ) = vertex(3, : ) + h * exp(-d/ (2*sigma^2))
Display the surface.
plot_mesh(vertex, faces)
view(3)
Compute its geometric (cotan) Laplacian
W = sparse(n, n)
for i in 1: 3:
i1 = mod(i-1, 3) + 1
i2 = mod(i , 3) + 1
i3 = mod(i + 1, 3) + 1
pp = vertex(: , faces(i2, : )) - vertex(: , faces(i1, : ))
qq = vertex(: , faces(i3, : )) - vertex(: , faces(i1, : ))
% normalize the vectors
pp = pp ./ repmat(sqrt(sum(pp.^2, 1)), [3 1])
qq = qq ./ repmat(sqrt(sum(qq.^2, 1)), [3 1])
% compute angles
ang = acos(sum(pp.*qq, 1))
u = cot(ang)
u = clamp(u, 0.01, 100)
W = W + sparse(faces(i2, : ), faces(i3, : ), u, n, n)
W = W + sparse(faces(i3, : ), faces(i2, : ), u, n, n)
Compute the symmetric Laplacian matrix.
d = full(sum(W, 1))
D = spdiags(d(: ), 0, n, n)
L = D - W
I = find(abs(X(: )) = =1 | abs(Y(: )) = =1)
Compute the deformation field (zeros outsize the handle, proportional to the normal otherwise).
Delta0 = zeros(3, n)
d = (vertex(1, I) + vertex(2, I)) / 2
Delta0(3, I) = sign(d) .* abs(d).^3
Modify the Laplacian to take into account the fixed handles.
L1 = L
L1(I, : ) = 0
L1(I + (I-1)*n) = 1
Compute the full deformation by solving for Laplacian=0 on each coordinate.
Delta = (L1 \ Delta0')'
Compute the deformed mesh.
vertex1 = vertex + Delta
Display it.
plot_mesh(vertex1, faces)
view(-100, 15)
Exercise 1
Perform a more complicated deformation of the boundary. eform isplay it.
solutions.exo1()
## Insert your code here.
Exercise 2
Move both the inside and the boundary.
aplacian eform isplay it.
solutions.exo2()
## Insert your code here.
Exercise 3
Apply the mesh deformation method to a real mesh, with both large scale and fine scale details.
solutions.exo3()
## Insert your code here.
Linear methods give poor results for large deformation.
It is possible to obtain better result by applying the linear deformation only to a low pass version of the mesh (coarse scale modifications). The remaining details are then added in the direction of the normal, in a local frame that is rotated to match the deformation of the coarse surface.
Exercise 4
Apply the deformation to the coarse mesh |vertex0| to obtain |vertex1|. Important: you need to compute and use the cotan Laplacian of the coarse mesh, not of the original mesh! ompute laplacian
aplacian eform isplay it.
solutions.exo4()
## Insert your code here.
Compute the residual vector contribution along the normal (which is vertical).
normal = compute_normal(vertex0, faces)
d = repmat(sum(normal .* (vertex-vertex0)), [3 1])
Exercise 5
Add the normal contribution |d.*normal| to |vertex1|, but after replacing the normal of |vertex0| by the normal of |vertex1|. isplay it.
solutions.exo5()
## Insert your code here.
Exercise 6
Try on other surfaces. How can you compute |vertex0| for an arbitrary surface ?
solutions.exo6()
## Insert your code here.
To take into account the bending of the surface, one can use higher order derivative to interpolate the deformation field.
The bi-laplacian |LL| corresponds to 4th order derivatives. It is the square of the Laplacian |LL=L*L|.
Exercise 7
Compute the bi-laplacian deformation of the coarse shape |vertex0| by using |LL| instead of |L|. What do you observe ? eform isplay it.
solutions.exo7()
## Insert your code here.
Exercise 8
Compute the deformation obtained by moving from the Laplacian to the bi-laplacian, i.e. with |tL+(1-t)LL| for varying t.
solutions.exo8()
## Insert your code here.
Exercise 9
Apply the full model (Laplacian, bi-Laplacian and non-linear deformation) to the deformation of a complicated mesh.
solutions.exo9()
## Insert your code here.