-
Notifications
You must be signed in to change notification settings - Fork 73
/
extractloops.m
79 lines (77 loc) · 2.46 KB
/
extractloops.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
function loops = extractloops(edges)
%
% loops=extractloops(edges)
%
% extract individual loop or polyline segment from a collection of edges
%
% author: Qianqian Fang, <q.fang at neu.edu>
% date: 2007/11/21
%
% input:
% edges: two column matrix recording the starting/ending
% points of all edge segments
%
% output:
% loops: output, a single vector separated by NaN, each segment
% is a 3D polyline or loop consisted of node IDs
%
% example:
% edges=[1 2;2 3;1 4;3 4;7 3;1 9;5 6;6 7;10 9; 8 10;1 8;9 3;11 11;11 12];
% loops=extractloops(edges)
%
% -- this function is part of iso2mesh toolbox (http://iso2mesh.sf.net)
%
loops = [];
edges(edges(:, 1) == edges(:, 2), :) = []; % remove degenerated edges
loops = [loops, edges(1, :)];
loophead = edges(1, 1);
loopend = edges(1, end);
edges(1, :) = [];
while (~isempty(edges))
idx = [find(edges(:, 1) == loopend)', find(edges(:, 2) == loopend)'];
if (length(idx) > 1) % when a node with multiple connection found
idx = idx(1); % take the first connection and continue
end
if (isempty(idx)) % when an open-line segment gets to one end
% when both open ends are found
if (isempty([find(edges(:, 1) == loophead)', find(edges(:, 2) == loophead)']))
loops = [loops, nan];
loops = [loops, edges(1, :)];
loophead = edges(1, 1);
loopend = edges(1, end);
edges(1, :) = [];
else % only the first open end is found, flip and trace the other
[loophead, loopend] = deal(loopend, loophead);
lp = fliplr(loops);
seg = find(isnan(lp), 1);
if (isempty(seg))
loops = lp;
else
loops = [loops(1:end - seg(1) + 1) lp(1:seg(1) - 1)];
end
end
continue
end
if (length(idx) == 1) % tracing along a single line thread
idx = idx(1);
ed = edges(idx, :);
ed(ed == loopend) = [];
newend = ed(1);
if (newend == loophead) % when a loop is found
loops = [loops loophead nan];
edges(idx, :) = [];
if (size(edges, 1) == 0)
break
end
loops = [loops, edges(1, :)];
loophead = edges(1, 1);
loopend = edges(1, end);
edges(1, :) = [];
continue
else
loops = [loops, newend];
end
loopend = newend;
edges(idx, :) = [];
end
end