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
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
|
|
|