-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathgenerateNodeElemMeshes.m
88 lines (67 loc) · 2.39 KB
/
generateNodeElemMeshes.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
function generateNodeElemMeshes(data, outPath, rE, rN)
% Generate and save truss meshes suitable for rendering
% Input
% data: struct with fields Node and Elem
% outPath: path (including filename) for saving the output meshes
% rE: radius of the cylindrical elements
% rN: radius of the spherical nodes
%
% Output
% Visualizes the mesh and saves two OBJ files:
% <outPath>_nodes.obj, <outPath>_elem.obj
%
% WARNING: These meshes are only suitable for rendering.
% Use gptoolbox's wire_mesh function to generate a boolean'd manifold mesh
nodePath = [outPath, '_nodes.obj'];
elemPath = [outPath, '_elems.obj'];
node = data.Node;
elem = data.Elem;
[sV, sF] = readOBJ('./util_meshes/sphere_8_5.obj');
[cV, cF] = readOBJ('./util_meshes/cylinder_6.obj');
nsV = size(sV, 1);
nsF = size(sF, 1);
ncV = size(cV, 1);
ncF = size(cF, 1);
sV = [sV, ones(nsV, 1)];
cV = [cV, ones(ncV, 1)];
[node, SVI, ~] = remove_unreferenced(node, elem);
elem = SVI(elem);
n = size(node, 1);
m = size(elem, 1);
nodeF = zeros(nsF*n, 3);
nodeV = zeros(nsV*n, 4);
elemF = zeros(ncF*m, 3);
elemV = zeros(ncV*m, 4);
for i=1:n
S = diag([rN rN rN 1])';
T = [[eye(3); ones(1, 3)], [node(i, :)'; 1]]';
nodeV((i-1)*nsV + (1:nsV), :) = sV*S*T;
nodeF((i-1)*nsF + (1:nsF), :) = sF + (i-1)*nsV;
end
eVec = node(elem(:, 1), :) - node(elem(:, 2), :);
eLen = sqrt(sum(eVec.^2, 2));
eVec = eVec./eLen;
vec2 = cross(eVec, repmat([0 1 0], m, 1));
yIdx = sum(vec2.^2, 2) < 1e-6;
vec2(yIdx, :) = cross(eVec(yIdx, :), repmat([0 0 1], sum(yIdx), 1));
vec2 = vec2./sqrt(sum(vec2.^2, 2));
vec3 = cross(eVec, vec2);
vec3 = vec3./sqrt(sum(vec3.^2, 2));
ePos = (node(elem(:, 1), :) + node(elem(:, 2), :))/2;
for i=1:m
S = diag([eLen(i) rE rE 1])';
T = [[eye(3); ones(1, 3)], [ePos(i, :)'; 1]]';
R = [[eVec(i, :), 0]; [vec2(i, :), 0]; [vec3(i, :), 0]; [0 0 0 1]];
elemV((i-1)*ncV + (1:ncV), :) = cV*S*R*T;
elemF((i-1)*ncF + (1:ncF), :) = cF + (i-1)*ncV;
end
figure
tsurf(nodeF, nodeV(:, 1:3), 'FaceColor', [203, 109, 81]/255, 'EdgeAlpha', 0);
hold on
tsurf(elemF, elemV(:, 1:3), 'FaceColor', [201, 192, 187]/255, 'EdgeAlpha', 0);
hold off
axis equal
light
writeOBJ(nodePath, nodeV(:, 1:3), nodeF);
writeOBJ(elemPath, elemV(:, 1:3), elemF);
end