-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathskeletonCanonicalForm.m
50 lines (43 loc) · 1.26 KB
/
skeletonCanonicalForm.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
function mesh = skeletonCanonicalForm(mesh)
% mesh = skeletonCanonicalForm(mesh)
% Computes a canonical form of a mesh using its skeleton.
%
% David Pickup 2015
mesh = normaliseMesh(mesh,100);
% MDS options.
options.rtol = 0.001;
options.iter = 100;
options.method = 'smacof';
options.dim = 3;
% Extract skeleton from mesh.
Skel = AuSkeleton(mesh);
Skel.TBA = triangleBoneAssignment(Skel, mesh);
% Make sure the skeleton is fully connected.
D = boneLengths(Skel);
D = graphallshortestpaths(D);
if numel(find(isinf(D))) > 0
while numel(find(isinf(D))) > 0
DE = allPairsEuclideanMesh(Skel);
DE(~isinf(D)) = Inf;
[I,J] = find(DE==min(DE(:)));
Skel.E(end+1,:) = [I(1) J(1)];
D = boneLengths(Skel);
D = allPairsDijkstra(D);
end
%Skel = mergeJunctions(Skel,mesh);
Skel = AuEmbeddingRefinement(Skel, mesh);
Skel.TBA = triangleBoneAssignment(Skel, mesh);
D = boneLengths(Skel);
D = graphallshortestpaths(D);
end
% Perform MDS on the skeleton.
verts = [Skel.X Skel.Y Skel.Z];
options.X0 = verts;
X = mds(D,options);
% Compute the mesh deformation based on the transformed skeleton.
Skel2 = Skel;
Skel2.X = X(:,1);
Skel2.Y = X(:,2);
Skel2.Z = X(:,3);
mesh = YanSkeletonDrivenMeshDeformation(mesh, Skel, Skel2);
return;