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