-
Notifications
You must be signed in to change notification settings - Fork 7
/
meshParallelSimp.m
144 lines (117 loc) · 4.73 KB
/
meshParallelSimp.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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
function [vertices2,faces2] = meshParallelSimp(vertices1, tol)
% MESHPARALLELSIMP
%
% Function to simplify a surface mesh. The function will detect parallels
% in the shape, and take only the vertices of each of the longest vector in
% the parallel (i.e. the parallel's extremities) as output
%
% Inputs:
% - vertices1: list of nx3 coordinates of mesh free boundary vertices. The
% mesh should already be a planar surface (cf. roof detection)
% - tol: tolerance for parallelism. The closer the value to 0, the better
% the original mesh shape is preserved (but the lesser the size reduction)
%
% Outputs:
% - vertices2: list of nx3 coordinates of the simplified mesh
% - faces2: triangular faces of vertices2 resulting froma a Delaunay
% triangulation
%
% (c) Arnadi Murtiyoso (INSA Strasbourg - ICube-TRIO UMR 7357)
% input points
pts=vertices1;
[numPts,~]=size(pts);
indexList=zeros(numPts,1);
for i=1:numPts
indexList(i,1)=i;
end
% list all possible vector combinations
VectorList=nchoosek(indexList,2);
[nbCombinations,~]=size(VectorList);
% create a list: columns 1 and 2 are the vector points; colums 3 to 5 the
% xyz non-normalised vector
for i=1:nbCombinations
index1=VectorList(i,1);
index2=VectorList(i,2);
VectorList(i,3)=pts(index1,1)-pts(index2,1);
VectorList(i,4)=pts(index1,2)-pts(index2,2);
VectorList(i,5)=pts(index1,3)-pts(index2,3);
end
%% Check for parallel vectors
i=1;
VectorListRef=VectorList;
% keep looping until the VectorList is empty of 'seeds'
while ~isempty(VectorList)
parallelName = strcat('Parallel',string(i));
% 'seed' vector
v1 = [VectorList(1,3) VectorList(1,4) VectorList(1,5)];
[~, index]=ismember(VectorListRef(:,3:5),v1,'rows');
indexv1=find(index,1);
% normalise the seed vector (v1)
v1 = normalizeVector3d(v1);
% number of pairs to check the parallelism
[pairsToCheck,~]=size(VectorList);
% add this seed to the parallel's list of vectors
listParallel = indexv1;
ListToDelete=[];
for j=2:pairsToCheck
% second vector (to be checked against v1)
v2 = [VectorList(j,3) VectorList(j,4) VectorList(j,5)];
[~, index2]=ismember(VectorListRef(:,3:5),v2,'rows');
indexv2=find(index2,1);
% normalise v2
v2 = normalizeVector3d(v2);
% check the disparity between the two vectors.
disparity=abs(v1-v2);
% magDisparity should be 0 if they are parallel
magDisparity=sqrt(disparity(1)^2+disparity(2)^2+disparity(3)^2);
% set parallelism tolerance here
if magDisparity < tol
listParallel=vertcat(listParallel,indexv2);
ListToDelete = vertcat(ListToDelete,j);
end
end
% sanity check. don't delete anything if there is nothing to delete
if ~isempty(ListToDelete)
VectorList(ListToDelete,:) = [];
end
VectorList(1,:)=[];
% store the vector indices belonging to the same parallel to a struct
Struct.(parallelName).VectorIndices=listParallel;
% moving on...
i=i+1;
end
%% compute parallel vector distances
nbFields=length(fieldnames(Struct));
verticesSimp = [];
for i=1:nbFields
parallelName = strcat('Parallel',string(i));
[nbVectors,~]=size(Struct.(parallelName).VectorIndices);
for j=1:nbVectors
thisVectorIndex=Struct.(parallelName).VectorIndices(j,1);
v=[VectorListRef(thisVectorIndex,3) VectorListRef(thisVectorIndex,4) VectorListRef(thisVectorIndex,5)];
distance = sqrt(v(1)^2+v(2)^2+v(3)^2);
Struct.(parallelName).Distances(j,1)=distance;
end
% determine the longest vector in a parallel
[M,I] = max(Struct.(parallelName).Distances);
Struct.(parallelName).LongestVecMag = M;
Struct.(parallelName).LongestVecInd = Struct.(parallelName).VectorIndices(I,1);
VectorIndex = Struct.(parallelName).VectorIndices(I,1);
% extract the corresponding vertices
point1Index = VectorListRef(VectorIndex,1);
point2Index = VectorListRef(VectorIndex,2);
coordPoint1 = pts(point1Index,:);
coordPoint2 = pts(point2Index,:);
Struct.(parallelName).ExtremePts = vertcat(coordPoint1,coordPoint2);
dummy = Struct.(parallelName).ExtremePts;
verticesSimp = vertcat(verticesSimp,dummy);
end
% delete doubles
verticesSimp = unique (verticesSimp,'rows');
%% delaunay triangulation
TR = delaunayTriangulation(verticesSimp(:,1),verticesSimp(:,2),verticesSimp(:,3));
[faces2,vertices2] = freeBoundary(TR);
[numPts2,~] = size(vertices2);
gain=(abs(numPts2-numPts)/numPts)*100;
%disp(strcat('Heyo! Vertices reduced by:',num2str(gain),'%'));
end