SCIRun User Mailing List

Text archives Help


Re: [SCIRUN-USERS] Questions about BioMesh3D


Chronological Thread 
  • From: Brett Burton <zaracay@gmail.com>
  • To: Nima Maftoon <n_maftoon@yahoo.com>
  • Cc: Brett Burton <zaracay@gmail.com>, Jess Tate <jess@sci.utah.edu>, "scirun-users@sci.utah.edu" <scirun-users@sci.utah.edu>
  • Subject: Re: [SCIRUN-USERS] Questions about BioMesh3D
  • Date: Wed, 10 Jun 2015 21:50:42 -0600

Nima,
 I'm just going to respond within the text of the email below.


On Jun 10, 2015, at 9:16 AM, Nima Maftoon <n_maftoon@yahoo.com> wrote:

Dear Jess and Brett,

Thanks for your great explanations. Let me go back to the itemized format again.

1) I don't seem to find the relevant document pages about mesh conversion. Could you please point me there?


The Field format is not well documented.  There are high level descriptions with in the documentation (http://www.sci.utah.edu/devbuilds/scirun_docs/UserGuide.pdf), but if you are looking for a way to crack into the format, you probably won't be able to find an adequate description (http://scirundocwiki.sci.utah.edu/SCIRunDocs/index.php5/CIBC:Documentation:SCIRun:FAQDraft).  If you would like to convert a mesh that you have into a SCIRun field, you will have to get it into one of the several input formats that SCIRun recognizes.  It will be converted into fld format as soon as you load the file.  If you want to convert a mesh that you generated in SCIRun into a different format, you can choose one of the many output formats in the drop down menu of the WriteField module.

2 & 3)
(a) "You will need to transform it back into the original coordinate system (can be done is scirun). You can also use SCIRun to extract the surfaces from the tet mesh." How?
Transform to original coord space - Biomesh produces a .tf file, which is the transformation file that you need to convert back to the original coordinate space.  Unfortunately, the file is not readable by any SCIRun module.  In order to convert, using the file, you will need to make calls to TransformFieldWithTransform to get it to re-orient your data.  I have attached a new version of the Stage 2 python script in which the .tf file is called to convert the tight.fld files back into the original space.  The comments "### New Command" indicate where those changes were inserted in case you wanted to propagate those changes to other stages of the pipeline.

#!/usr/bin/env python
#  
#  For more information, please see: http://software.sci.utah.edu
#  
#  The MIT License
#  
#  Copyright (c) 2009 Scientific Computing and Imaging Institute,
#  University of Utah.
#   
#  
#  Permission is hereby granted, free of charge, to any person obtaining a
#  copy of this software and associated documentation files (the "Software"),
#  to deal in the Software without restriction, including without limitation
#  the rights to use, copy, modify, merge, publish, distribute, sublicense,
#  and/or sell copies of the Software, and to permit persons to whom the
#  Software is furnished to do so, subject to the following conditions:
#  
#  The above copyright notice and this permission notice shall be included
#  in all copies or substantial portions of the Software.
#  
#  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
#  OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
#  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
#  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
#  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
#  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
#  DEALINGS IN THE SOFTWARE.
#  
#    Author : Martin Cole

import string
from sys import argv
import sys
import subprocess
import re
import os
import time
import glob

if sys.version_info[0] < 3 :
    from thread import start_new_thread
else :
    from _thread import start_new_thread

from math import fabs

import Utils

maxval_re = re.compile("max: ([\d\.\d]+)")
axsizes_re = re.compile("sizes: (\d+) (\d+) (\d+)")
#space directions: (-0.671875,0,-0) (0,0.671875,0) (-0,0,5)
tri = "\(([\-\d\.]+),([\-\d\.]+),([\-\d\.]+)\)\s?"
spc_re = re.compile("space directions: %s%s%s" % (tri, tri, tri))

maxval = 0
axsizes = ()
spacing = None
print_only = False
use_shell = True
if sys.platform == "win32" :
    use_shell = False
	

def transform_with_transform(tet_file) :

	assert_exists(tet_file)
	transformed_fname = "%s_transformed.fld" % tet_file[:-4]
	transf = "%s_pad_transform.tf" % model_input_file[:-5]
	dummy,filename = os.path.split(transf)
	transf = os.path.join(model_output_path,filename)
	print("Transforming %s" % tet_file)
	trans_cmmd = r'"%s" -input %s -transform "%s" -output %s' % (os.path.join(binary_path,"TransformFieldWithTransform"), tet_file, transf, transformed_fname)
	Utils.do_system(trans_cmmd,print_only,use_shell)
	
	########## New command start
	transformed_nrrd = "%s_transformed.nrrd" % tet_file[:-4]	
        field_to_nrrd_cmd = r'"%s" %s %s' % (os.path.join(binary_path,"ConvertFieldToNrrd"), transformed_fname, transformed_nrrd)
        print("Converting %s to %s" % (tet_file,transformed_nrrd))
        Utils.do_system(field_to_nrrd_cmd,print_only,use_shell)
	########## New command end
	

	print("Done Transforming")

def assert_exists(file):
    if not(os.path.exists(file)):
        print("2 No such file %s. Perhaps you need to run a previous stage."%file)
        sys.exit(-1)

param_lines = []

if __name__ == "__main__" :

# Check that we got the right arguments......
    if len(argv) < 2 or not(os.path.exists(argv[1])):
        print('Usage: %s [model_config] [binary_path]' % argv[0])
        exit(1)

    model_config = argv[1]
    exec(open(model_config).read())
    
    model_path, dummy = os.path.split(model_config)
    
    if not(os.path.isabs(model_input_file)) :
      model_input_file = os.path.normpath(os.path.join(model_path, model_input_file))

    if not(os.path.isabs(model_output_path)) :
      model_output_path = os.path.normpath(os.path.join(model_path, model_output_path))
   
    
    if len(argv) > 2:
        binary_path = argv[2]
    else:
        binary_path = ""  

# Done checking arguments

    if not(os.path.exists(model_output_path)):
        os.makedirs(model_output_path)

    Utils.output_path = model_output_path
    Utils.current_stage = 2

    curr_work_dir = os.getcwd()
    os.chdir(model_output_path)

    Utils.delete_complete_log()
    Utils.delete_error_log()
    Utils.rec_running_log()
    
    start_time = time.time()

    isosurface_ts_file_names = []

    idx = 0    
    for i in mats :
        n = Utils.extract_root_matname(mat_names[idx])
        #convert the nrrd to a latvol.
        print("Working on material: %s" % n)
        nrrd_filename = "%s.tight.nrrd" % n
        assert_exists(nrrd_filename)
        field_filename = "%s.tight.fld" % n
        nrrd_to_field_cmd = r'"%s" %s %s' % (os.path.join(binary_path,"ConvertNrrdToField"), nrrd_filename, field_filename)
        print("Converting %s to %s" % (nrrd_filename,field_filename))
        Utils.do_system(nrrd_to_field_cmd,print_only,use_shell)
        isosurf_prefix = "%s_isosurface.ts" % n
        isosurface_ts_file_names.append(isosurf_prefix + ".fld")
        isosurf_cmd = r'"%s" %s %s.fld %s' % (os.path.join(binary_path,"ExtractIsosurface"), field_filename, isosurf_prefix, 0)
        print("Isosurfacing %s" % field_filename)
        Utils.do_system(isosurf_cmd,print_only,use_shell)
	##### New Transform
	transform_with_transform(field_filename) 
	#####
        idx = idx + 1

    join_fields_cmmd = r'"%s" -indexdata isosurface-all.ts.fld %s' % (os.path.join(binary_path,"JoinFields"), " ".join(isosurface_ts_file_names)) # isosurface-all is called when displaying (-d flag)
    #print(join_fields_cmmd)
    Utils.do_system(join_fields_cmmd,print_only,use_shell) 


    stop_time = time.time()
    f = open("compute-material-boundary-runtime.txt","w")
    f.write("%lf" % (stop_time-start_time))
    f.close()

    Utils.rec_completed_log()
    os.chdir(curr_work_dir)

Which module does that?

Extract surfaces - Use the GetFieldBoundary module to extract the surface mesh.
Can a part of a surface be selected to make an element group for applying boundary conditions?
Can you provide an example of what you mean by selecting a part of the surface to get the boundary from?

(b) By "transformed "tight" files" do you mean that they are transformed to the correct coordinate system? Are "tight" files the surface mesh files?
Tight files are surface meshes and will look like something like "air.tight.nrrd" in the top level directory of your Biomesh output.  These files are not transformed.  If you replace your ComputeMaterialBoundary.py file in the FEMesher directory with the one I sent you, you will get transformed tight files: air.tight_transformed.nrrd or air.tight_transformed.fld

(c) "there is a problem doing mix type meshes.  BioMesh/SCIRun does not support mixed mesh type, so they would have to be all surfaces or all volumes.  Additionally,  BioMesh (and almost all meshing software) has problems with thin features." I understand this. FE meshers are perfectly happy with surface meshes and mixing them with volume meshes. This mixing job can be done there. A very thin structure is usually represented by one open line in segmentation because as you implied capturing the thickness is usually very hard if not impossible. Triangulation of these open lines across slices provides the 3D model of that structure. An example of such a structure is the tympanic membrane. In such a structure the segmentation essentially lacks volume information.
4) Does specifying the max volume size, have any effect on the surface element and edge sizes as well?

The smaller the volume, the shorter the edges have to be.  By changing the tetgen flags called by the model_config file (tetgen_joined_vol_flags = "zpAAqa10"  #default)  you can get shorter edges on your elements.  Proceed with caution, however, this will affect all of your elements, and not just those found on the surface.  For example, if you use the flag -aa0.1, you will constrain the max element size to 0.1 everywhere, including the surface.

Jess also mentioned the sizing field parameter.  You can multiply your sizing field by a value < 1 to get finer elements as well, or you can translate and scale the values in the sizing field as needed by opening the sizing field nrrd, piping it into a CalculateFieldData module, and applying your translation (+/-) and scaling (*) parameters.  If you need an example, I can get you one.


Thanks
Nima


From: Jess Tate <jess@sci.utah.edu>
To:
Cc: Nima Maftoon <n_maftoon@yahoo.com>; "scirun-users@sci.utah.edu" <scirun-users@sci.utah.edu>
Sent: Tuesday, June 9, 2015 4:40 PM
Subject: Re: [SCIRUN-USERS] Questions about BioMesh3D

Hi Nima,

To add what Brett provided, generating surfaces should be fine, but there is a problem doing mix type meshes.  BioMesh/SCIRun does not support mixed mesh type, so they would have to be all surfaces or all volumes.  Additionally,  BioMesh (and almost all meshing software) has problems with thin features.  Your sampling resolution for your input segmentation will need to be high enough to accurately represent the boundaries, which takes more time.  In terms of thin structures,  If Biomesh can generate a surface mesh, it can usually generate a volume mesh.

cheers,
Jess





On Jun 9, 2015, at 2:29 PM, Brett Burton <zaracay@gmail.com> wrote:

Nima,

Surfaces are generated, but BioMesh transforms the images into a different coordinate space during its initial stage.  It is not transformed back until the final stage.  So, pulling files like particle-union.ts.fld or the tissue1.tight.fld, which are surface meshes, will ultimately be in the wrong space, but (like Jess said) they can be transformed back in SCIRun.  

I have also altered the original python scripts to give the transformed "tight" files if you would like to have those files automatically generated.  I have not created the python scripts for the particle-union files, though it wouldn't take much time to do so if you need them.  I can check those changes in, or send you the scripts that you can use to replace your old python scripts.

Brett

On Jun 9, 2015, at 12:00 PM, Nima Maftoon <n_maftoon@yahoo.com> wrote:

Thanks Jess!

About Question #3: shell elements are essentially surface elements. I am wondering why this should be difficult? I thought in one of the intermediate stages surface elements are generated.

Nima


From: Jess Tate <jess@sci.utah.edu>
To:
Cc: scirun-users@sci.utah.edu; Nima_Maftoon@MEEI.HARVARD.EDU; n_maftoon@yahoo.com
Sent: Tuesday, June 9, 2015 1:52 PM
Subject: Re: [SCIRUN-USERS] Questions about BioMesh3D

Hi Nima,

here are some answers to your question:

1)  The output of BioMesh3D is a scirun field file (.fld)  This is the native format for SCIRun, with which Biomesh is distributed.  You can use SCIRun to convert the fld file into other formats.  vtk and stl formats are supported as are several others.  Please refer to the SCIRun website (scirun.org) and documentation for more information.  

2)  There are several intermediate steps that save out files.  These are left so that you can rerun BioMesh from later stages if desired.  Also, you can use them to take advantage of the interactive mode  and visualize the results of the various stages.  The surface file is saved out as particle-union.ts.fld.  You will need to transform it back into the original coordinate system (can be done is scirun).  You can also use SCIRun to extract the surfaces from the tet mesh.    

3) This is not supported.

4) You can set the max volume of the tet elements with the tetgen flags in the model_config.py file (see http://wias-berlin.de/software/tetgen/).  You can also play with the sizing field variables in the config file.  

Hope that helps,
Jess






On Jun 9, 2015, at 11:26 AM, Elizabeth Jurrus <liz@sci.utah.edu> wrote:

A few questions for the mailing list...
- liz


-------- Forwarded Message --------
Subject: Questions about BioMesh3D
Date: Tue, 9 Jun 2015 15:58:08 +0000
From: Maftoon, Nima <Nima_Maftoon@MEEI.HARVARD.EDU>
To: liz@sci.utah.edu <liz@sci.utah.edu>

I have few quick questions. I played with the Mickey example and I think I got the ideas to some degree. What I don't understand yet are the followings:

1) Is the final mesh file, the binary .fld file in the "junctions" directory? What kind of format does it have? Which software reads this mesh format? Is it possible to have the mesh in a more general format like .unv, vtk or even stl format to be more accessible? med is a good new format as well (http://www.salome-platform.org/user-section/about/med).

2) I see that some intermediate node, face, ele and pts files are generated. What are these? If I just need the surface mesh information which files can give me that? A user may prefer to generate my volume elements myself in another meshing software.

3) It is said that 3D tetrahedral elements are generated. Is it also possible to generate 3D shell or plate elements for thin structures like membranes?

4) Is it possible to control the element size in the mesher?

I really appreciate your answers to these questions.

Nima Maftoon, PhD

Massachusetts Eye and Ear Infirmary
Harvard Medical School
243 Charles St
Boston, MA 02114
617 981 2638













Archive powered by MHonArc 2.6.18.

Top of page