-
Notifications
You must be signed in to change notification settings - Fork 326
/
perform_faces_reorientation.m
119 lines (107 loc) · 2.8 KB
/
perform_faces_reorientation.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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
function faces = perform_faces_reorientation(vertex,faces, options)
% perform_faces_reorientation - reorient the faces with respect to the center of the mesh
%
% faces = perform_faces_reorientation(vertex,faces, options);
%
% try to find a consistant reorientation for faces of a mesh.
%
% if options.method = 'fast', then use a fast non accurate method
% if options.method = 'slow', then use a slow exact method
%
% Copyright (c) 2007 Gabriel Peyre
options.null = 0;
method = getoptions(options, 'method', 'fast');
verb = getoptions(options, 'verb', 1);
[vertex,faces] = check_face_vertex(vertex,faces);
n = size(vertex,2);
m = size(faces,2);
if strcmp(method, 'fast')
% compute the center of mass of the mesh
G = mean(vertex,2);
% center of faces
Cf = (vertex(:,faces(1,:)) + vertex(:,faces(2,:)) + vertex(:,faces(3,:)))/3;
Cf = Cf - repmat(G,[1 m]);
% normal to the faces
V1 = vertex(:,faces(2,:))-vertex(:,faces(1,:));
V2 = vertex(:,faces(3,:))-vertex(:,faces(1,:));
N = [V1(2,:).*V2(3,:) - V1(3,:).*V2(2,:) ; ...
-V1(1,:).*V2(3,:) + V1(3,:).*V2(1,:) ; ...
V1(1,:).*V2(2,:) - V1(2,:).*V2(1,:) ];
% dot product
s = sign(sum(N.*Cf));
% reverse faces
I = find(s>0);
faces(:,I) = faces(3:-1:1,I);
return
end
options.method = 'fast';
faces = perform_faces_reorientation(vertex,faces, options);
fring = compute_face_ring(faces);
tag = zeros(m,1)-1;
heap = 1;
for i=1:m
if m>100 & verb==1
progressbar(i,m);
end
if isempty(heap)
I = find(tag==-1);
if isempty(I)
error('Problem');
end
heap = I(1);
end
f = heap(end); heap(end) = [];
if tag(f)==1
warning('Problem');
end
tag(f) = 1; % computed
fr = fring{f};
fr = fr(tag(fr)==-1);
tag(fr)=0;
heap = [heap fr];
for k=fr(:)'
% see if re-orientation is needed
if check_orientation(faces(:,k), faces(:,f))==1
faces(1:2,k) = faces(2:-1:1,k);
end
end
end
if not(isempty(heap)) || not(isempty(find(tag<1)))
warning('Problem');
end
% try to see if face are facing in the correct direction
[normal,normalf] = compute_normal(vertex,faces);
a = mean(vertex,2);
a = repmat(a, [1 n]);
dp = sign(sum(normal.*a,1));
if sum(dp>0)<sum(dp<0)
faces(1:2,:) = faces(2:-1:1,:);
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function o = check_orientation(f1,f2)
i1 = 0; j1 = 0;
for i=1:3
for j=1:3
if f1(i)==f2(j)
i1 = i; j1 = j;
break;
end
end
if i1~=0
break;
end
end
if i1==0
error('Problem.');
end
ia = mod(i1,3)+1;
ja = mod(j1,3)+1;
ib = mod(i1-2,3)+1;
jb = mod(j1-2,3)+1;
if f1(ia)==f2(ja) || f1(ib)==f2(jb)
o=1;
else
o = -1;
end