You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

185 lines
6.0 KiB

%--------------------------
% @Author: Jingqiao Hu
% @Date: 2022-01-21 10:22:36
% @LastEditTime: 2022-01-29 15:24:37
% WHAT I NEED for each v-cell:
% 1. pnt-poly, for intersection with MMC
% c_polyPnts: vertex of each polytope
% c_polyMesh: triangulation surface of each polytope
% 2. nodes, tets, for simulation
% 3. segments, for initializing MMC
% 4. polygon of each faces, for building Bezier surface
%--------------------------
function [c_polyMesh, c_node, c_tet, c_segs, c_polygon] = ...
generateMesh(seeds, nelx, nely, nelz, microx, optDesign)
path0 = "data/" + optDesign + "/";
npnts = size(seeds, 1);
ncvt = npnts;
globalx = nelx * microx;
globaly = nely * microx;
globalz = nelz * microx;
if strcmp(optDesign,'cantilever_hole')
[c_segs, c_norms] = mexVD_info_file(seeds, int32(1:npnts)', globalx, globaly, globalz);
else
[c_segs, c_norms] = mexVD_info(seeds, int32(1:npnts)', globalx, globaly, globalz);
end
c_polyMesh = cell(ncvt, 1);
c_node = cell(ncvt, 1);
c_tet = cell(ncvt, 1);
c_polygon = cell(ncvt, 1);
figure;
% merge colinear segs
for i = 1 : ncvt
segs = c_segs{i}; % [m,6]
norms = c_norms{i};
pnts = reshape(segs', 3, [])'; % [n,3]
pntsFiltered = uniquetol(pnts, 1e-5, 'ByRows', true );
faces = int32(convhull(pntsFiltered(:,1), pntsFiltered(:,2), pntsFiltered(:,3),'Simplify',true));
vert1 = pntsFiltered(faces(:,1),:);
vert2 = pntsFiltered(faces(:,2),:);
vert3 = pntsFiltered(faces(:,3),:);
c_polyMesh{i} = [vert1, vert2, vert3]; % for the following intersection
clf;
scatter3(vert1(:,1), vert1(:,2), vert1(:,3), 'filled'); axis equal; hold on;
scatter3(vert2(:,1), vert2(:,2), vert2(:,3), 'filled'); axis equal; hold on;
scatter3(vert3(:,1), vert3(:,2), vert3(:,3), 'filled'); axis equal; hold on;
[nodes, tets] = read_tet(path0, i-1);
c_node{i} = nodes;
c_tet{i} = tets;
[segsPerFace, ~] = build_polygon_surface(segs, norms);
c_polygon{i} = segsPerFace;
end
end
function [segsPerFace, faceID] = build_polygon_surface(segs, norms)
% 1. detect all fnorms to find nfaces
% 2. for each fnorm: find corresponding segs
% 3. order these segs
fn0 = reshape(norms', 3, [])'; % n,6
fn1 = uniquetol(fn0, 1e-5, 'ByRows', true );
nface = size(fn1, 1);
nsegs = size(segs, 1);
faceID = zeros(nsegs, 2); % each seg belongs to 2 faces
segsPerFace = cell(nface, 1); % all segs belong to this face
for i = 1 : nsegs
f1 = fn0(2*i-1, :);
f2 = fn0(2*i, :);
[idx1, ~] = find(abs(fn1(:, 1) - f1(1)) < 1e-5 & ...
abs(fn1(:, 2) - f1(2)) < 1e-5 & ...
abs(fn1(:, 3) - f1(3)) < 1e-5);
[idx2, ~] = find(abs(fn1(:, 1) - f2(1)) < 1e-5 & ...
abs(fn1(:, 2) - f2(2)) < 1e-5 & ...
abs(fn1(:, 3) - f2(3)) < 1e-5);
faceID(i, :) = [idx1, idx2];
segsPerFace{idx1} = [segsPerFace{idx1}; segs(i, :)];
segsPerFace{idx2} = [segsPerFace{idx2}; segs(i, :)];
end
% figure(1); clf;
tol = 1e-2;
% reorder segs
for i = 1 : nface
%% 1. reorder segs as end by end
s0 = segsPerFace{i};
s1 = zeros(size(s0));
s1(1,:) = s0(1,:);
for j = 1 : size(s0, 1) - 1
p1 = s1(j, 1:3);
p2 = s1(j, 4:6);
% find seg in s0: pi != p1 && pj = p2
[idx1, ~] = find(abs(s0(:,1) - p2(1)) < tol & ...
abs(s0(:,2) - p2(2)) < tol & ...
abs(s0(:,3) - p2(3)) < tol & ...
(abs(s0(:,4) - p1(1)) > tol | ...
abs(s0(:,5) - p1(2)) > tol | ...
abs(s0(:,6) - p1(3)) > tol) );
if ~isempty(idx1)
s1(j+1, :) = s0(idx1, :);
end
[idx2, ~] = find((abs(s0(:,1) - p1(1)) > tol | ...
abs(s0(:,2) - p1(2)) > tol | ...
abs(s0(:,3) - p1(3)) > tol ) & ...
abs(s0(:,4) - p2(1)) < tol & ...
abs(s0(:,5) - p2(2)) < tol & ...
abs(s0(:,6) - p2(3)) < tol );
if ~isempty(idx2)
s1(j+1, :) = s0(idx2, [4:6, 1:3]);
end
if isempty(idx2) && isempty(idx1)
error("here!");
end
end
%% 2. detect the clockwise
fi = fn1(i, :); % norms of this face
v1 = s1(1, 4:6) - s1(1, 1:3);
v2 = s1(2, 4:6) - s1(2, 1:3);
fv = cross(v1, v2);
fv = fv ./ norm(fv);
if abs(fi(1)-fv(1)) < tol && abs(fi(2)-fv(2)) < tol && abs(fi(3)-fv(3)) < tol
else
s2 = zeros(size(s1));
for j = 1:size(s1, 1)
jj = size(s1, 1) - j + 1;
s2(j, :) = [s1(jj, 4:6), s1(jj, 1:3)];
end
s1 = s2;
end
segsPerFace{i} = s1;
end
% x = segs(:,[1,4]);
% y = segs(:,[2,5]);
% z = segs(:,[3,6]);
% figure(1); clf; plot3(x',y',z','LineWidth',2); hold on;
end
% tet file
% 1. Number of vertex, tet: n1, n2
% vertex: n * 3
% tet: m * 4
function [nodes, valid_tets] = read_tet(path0, i)
datapath = [path0+'tet'+num2str(i)+'.txt'];
fileID = fopen(datapath, 'r');
info = fscanf(fileID, '%f');
npnts = info(1);
ntets = info(2);
nodes = reshape(info(3 : 3 + npnts*3 - 1), 3, [])'; % all nodes coodinates of cdt
tets = reshape(info(3 + npnts*3 : end), 4, [])' + 1;
fclose(fileID);
[valid_tets] = checkValid_tetmesh(nodes, tets);
% DT = triangulation(valid_tets, nodes(:,1), nodes(:,2), nodes(:,3));
% figure; tetramesh(DT,'FaceAlpha',0.3);
end