Visualisation

Messing with meshes

A researcher has recently been trying to get to grips with meshes where they have scanned in some materials and would like to model this within COMSOL (multi-physics modelling package). There are a range of software which can be used to manipulate and display meshes. After some searching we found Gmsh seems to be very flexible and available on many platforms.

Using Gmsh

Gmsh is a very flexible and allows to perform pre/post-processing of data. In this case we had a binary STL file. We therefore opened this in Gmsh, due to its size this can take a while. We wanted to create an animation of the mesh to show people.

Animating in Gmsh

Gmsh has a programming language which can be used to merge instructions onto other files. We created a file which contained the instructions to Gmsh how we wanted to manipulate the mesh in the window. The file contained:

General.Trackball = 0;
General.RotationX = 0;
General.RotationY = 0;
General.RotationX = 0;
General.GraphicsWidth = General.MenuWidth + 640;
General.GraphicsHeight = 480;

For i In {0:180}
  General.RotationX = 4*i;
  General.RotationZ = 2*i;
  Sleep 0.1;
  Draw;
  Print Sprintf("box-%03g.gif",i);
EndFor

We then within Gmsh merged these instructions with the loaded file (under File -> Merge). This created a directory full of *.gif files. Using ImageMagick we then converted the series of GIF files to an animated GIF file using:

$ convert box-???.gif -set delay 5 -loop 0 animate.gif

After viewing this file we decided some colour was needed.

Gmsh and colours

It seems Gmsh cannot colour different parts of the mesh if the mesh is not divided into different volumes. Therefore after looking through the documentation we decided to output the STL file into a MSH file which is an ASCII text format of the mesh which allows us to add further information to the mesh, including values to nodes that Gmsh will then plot. We wrote some Perl (see below) to do this which read in the MSH file and output another file with the extra information, since the file had layers we wanted to take the coordinate value where the layer was constant.

#!/usr/bin/env perl

use warnings;
use strict;

# Store value for each node we want to give it.
my @nodevalues;
# Store number of nodes in file.
my $numnodes = 0;
# Are we within the node section of the file.
my $node_flag = 0;

# Open output file.
open(my $fh, ">", "output.msh")
    or die "cannot open > output.msh: $!";

# Read input file from command-line.
while() {
  my $line = $_;
  # Set node_flag to detect whether we start reading node information.
  $node_flag = 1 if ($line =~ /\$Nodes/ and $node_flag == 0);
  $node_flag = 0 if ($line =~ /\$EndNodes/ and $node_flag == 1);

  if ( $node_flag ) {
    # If just one number on line this is the number of nodes.
    if ($line =~ /^\s*([0-9]+)\s*$/) {
      $numnodes = $1;
    }
    # If line does not begin with $ then its a node coordinate.
    elsif ($line !~ /^\s*\$/) {
      # Create array from line.
      my @nodedata = split(/\s+/,$line);
      # Store the coordinate we want to set a the colour value.
      push(@nodevalues, $nodedata[2]);
    }
  }
  # Print out line.
  print $fh "$line";
}

# Print some sanity checking.
print "DEBUG: numnodes = $numnodes\n";
print "DEBUG: size of nodevalues = ", scalar(@nodevalues), "\n";

# Check we have consistent view of file.
if ($numnodes != scalar(@nodevalues)) {
  die "Inconsistent number of nodes."
}

# Now print out new section.
print $fh "\$NodeData\n";
print $fh "1\n";
print $fh "\"$ARGV\"\n";
print $fh "1\n";
print $fh "0.0\n";
print $fh "3\n";
print $fh "0\n";
print $fh "1\n";
print $fh "$numnodes\n";
for my $i (1 .. $numnodes) {
  my $value = $nodevalues[$i-1];
  print $fh "$i $value\n";
}
print $fh "\$EndNodeData\n";

# Close file.
close($fh);

Then run the Perl script by:

$ add_nodedata.pl input.msh

This then creates a new MSH file which can be read into Gmsh and it will display the colours as well.

Final animation

Once we have all the data we make sure we turn off the mesh visibility so the only thing in Gmsh being displayed is the post-processing view of the values we have given the nodes. This can be done either from

  • the Options button at bottom of script and goto “Mesh visibility” and turn off all features. Or,
  • the “Tools -> Options” menu and then “Mesh -> Visibility” tab.

We then merge the instructions to rotate and create the animation and end up with an animation.

Summary

There are many tools out there but finding a tool flexible enough to do many jobs then it can be useful to learn some tricks with it. The MSH file format is easy enough to adapt for specific needs and with some further reading of the documentation the functionality can probably be found to do this all within Gmsh itself.

Comments

No comments.

Leave a Reply

Your email address will not be published. Required fields are marked *