Iso2Mesh Node creation issues

39 views
Skip to first unread message

Kamran Ali Ahmed

unread,
Sep 20, 2024, 12:03:08 AM9/20/24
to iso2mesh-users
Hello Prof Fang,

I am encountering a small but consistent issue where the mesh generated by Iso2Mesh has node coordinates slightly extending beyond the expected boundaries of my grid. I am working with a TPMS structure and defining the grid as follows:

  • Grid dimensions, gridSize: 30 x 30 x 30
  • Grid range: The grid is defined using linspace(-1, 1, gridSize) in all three directions (X, Y, Z), which is later rescaled to a range of 0 to 30.

The grid generation works as expected, and the initial coordinates fall within the correct range of 0 to 30. However, after applying Iso2Mesh to generate a mesh, I observe that the node coordinates extend slightly outside this range:

  • X coordinates: Min = -0.38851, Max = 30.3887
  • Y coordinates: Min = -0.3888, Max = 30.3888
  • Z coordinates: Min = -0.38869, Max = 30.3891

This small deviation occurs consistently and is outside the expected [0, 30] range. I suspect that the meshing process might be applying some transformations or automatic adjustments that are shifting the node coordinates slightly beyond the grid boundary.

Here are some additional details about my meshing setup:

  • I am using opt.radbound = 0.5 and opt.autoregion = 1 as part of the mesh generation options.
  • No deliberate scaling or translation is being applied to the grid after mesh generation.
  • I also suspect that smoothing or boundary adjustments might be responsible for the coordinate shift, but I am unsure how to prevent this.
I am sharing the mesh setting as a reference as well. 

opt.radbound = 0.5;
opt.autoregion = 0.5;
opt.distbound = 0.1;
for k = 1:structure_count
hollow_structure = all_structures(k).hollow_structure;
mesh_file_name = sprintf('mesh_%d', k);
[node, element, face] = v2m(hollow_structure, 1, opt, 0.5, 'cgalsurf');
clear mode
element(element(:,5)~=mode(element(:,5)),:)=[]; % Keep region of interest
element(:, [1,2,3,4]) = element(:, [1,2,4,3]); % Reorder element nodes to avoid negative volume
vol=elemvolume(node(:,1:3),element(:,1:4)); % Calculate element volume
total_volume = sum(vol); % Compute total volume
all_structures(k).total_volume = total_volume; % Total volume of the tpms unit cell
cube_volume = gridSize^3; % Total Cube Cell volume
relative_density = total_volume / cube_volume; % Compute relative density
all_structures(k).relative_density = relative_density; % Store relative density for future use

Could you please provide insight into why this boundary extension might be happening? Additionally, are there specific settings in Iso2Mesh that can help me constrain the node coordinates strictly within the grid range [0, 30] or avoid this minor shift? 

This shift is causing an overestimation of relative density (volume of the tpms unit cell divided by the cube volume)and shooting the values beyond 1 which is physically impossible. 

Thanks,
Kamran

Qianqian Fang

unread,
Sep 20, 2024, 1:25:57 PM9/20/24
to iso2mes...@googlegroups.com, Kamran Ali Ahmed

hi Kamran,

you can set opt.distbound to a smaller value - say 0.1 (default is 1, allowing ), then, the deviation of the surface will become less, but it still won't be perfectly flat.


newer CGAL libraries added capability to define "sharp features" in the domain. see

https://doc.cgal.org/latest/Mesh_3/index.html#title21

I am not sure the new "domain.detect_features()" API can get the exact bounding box coordinates. regardless, it is not supported in the iso2mesh included cgal utilities.


one workaround we do in the past is to perform a surfboolean(node1,face1, 'and', bbxno, bbxfc) for the cgalsurf extracted mesh (node1/face1) with a bounding box mesh (bbxno, bbxfc) generated using meshabox().


this cuts the exterior surface back to a perfectly flat bounding box mesh.

see an example


vol=zeros(60,60,60);
vol(21:40,21:40,21:40)=1;
[xi, yi, zi]=meshgrid(1:60,1:60,1:60);
dist2=(xi-20).*(xi-20) + (yi-20).*(yi-20) + (zi-20).*(zi-20);
vol(dist2<15*15)=0;
[no, fc]=v2s(vol, 0.5, 1);
plotmesh(no, fc)
[bbxno, bbxfc]=meshabox([20, 20, 20]+0.5, [40, 40, 40]-0.5, 3);
[newno, newfc]=surfboolean(no, fc, 'and', bbxno, bbxfc);
plotmesh(newno, newfc)


see the output screenshot.


here I recessed the bounding box (bbx) by 0.5 voxel in all sides, you could also slightly inflate your mesh (no, fc) by a small fraction, and then cut it at the expected bounding box.

--
You received this message because you are subscribed to the Google Groups "iso2mesh-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to iso2mesh-user...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/iso2mesh-users/63a90ef1-4bc3-41ba-b02f-0058871d70aen%40googlegroups.com.
mesh_boolean.png

Kamran Ali Ahmed

unread,
Sep 22, 2024, 11:00:12 PM9/22/24
to iso2mesh-users
Hello Prof Fang;

I am attempting to create a bounding box as you suggested, in order to eliminate nodes that lie outside the defined grid. However, I am encountering a significant issue: the process changes the total number of nodes, which results in a mismatch with the elements generated when I run v2m before the surfboolean operation. My current workflow involves initially using v2m to mesh the volume, followed by v2s for the surfboolean operation. While the surfboolean correctly restricts the nodes to those within the grid, it inadvertently disrupts the elements since the necessary nodes for element connectivity are no longer available.

Additionally, I have tried an alternative approach where I mesh the surface using v2s, perform the surfboolean operation, and then use surf2mesh to create a volume mesh. Unfortunately, this method results in a poor-quality mesh (comparison of both meshes attached as figures).

Could you please suggest a way to navigate these issues?


Mesh settings for surf2mesh: 

[no, fc] = v2s(hollow_structure, 0.5, 1);
[bbxno, bbxfc]=meshabox([0 0 0]+0.5, [30 30 30]-0.5, 3);
[node, face]= surfboolean(no, fc,'and', bbxno, bbxfc);
plotmesh(node, face)
[node, element, face] = surf2mesh(node, face, [0,0,0], [30,30,30], 0.1, 0.5);
plotmesh(node,face(:,1:3));
axis equal;
clear mode
element(element(:,5)~=mode(element(:,5)),:)=[]; % Keep region of interest
element(:, [1,2,3,4]) = element(:, [1,2,4,3]); % Reorder element nodes to avoid negative volume
vol=elemvolume(node(:,1:3),element(:,1:4)); % Calculate element volume
total_volume = sum(vol); % Compute total volume
all_structures(k).total_volume = total_volume; % Total volume of the tpms cell
unitcell_volume = gridSize^3; % Total Unit Cell volume
relative_density = total_volume / unitcell_volume; % Compute relative density
all_structures(k).relative_density = relative_density; % Store relative density for future use

Iso2mesh: v2m (left) vs surf2mesh (right)





v2m.pngsurf2mesh.png


Qianqian Fang

unread,
Sep 23, 2024, 10:51:36 AM9/23/24
to iso2mes...@googlegroups.com, Kamran Ali Ahmed

if you have restrictions on node number/connectivity to the tet mesh, then the only way to do it is your alternative approach. i am supprised that it did not get what you want.

feel free to send me your test data offline, I am happy to play with it.

Reply all
Reply to author
Forward
0 new messages