[MOAB-dev] r2653 - MOAB/trunk/tools

kraftche at cae.wisc.edu kraftche at cae.wisc.edu
Tue Feb 24 10:35:31 CST 2009


Author: kraftche
Date: 2009-02-24 10:35:31 -0600 (Tue, 24 Feb 2009)
New Revision: 2653

Added:
   MOAB/trunk/tools/README.hexmodops
   MOAB/trunk/tools/README.mbsize
   MOAB/trunk/tools/README.mbtagprop
   MOAB/trunk/tools/README.mvconvert
   MOAB/trunk/tools/README.skin
   MOAB/trunk/tools/README.spheredecomp
   MOAB/trunk/tools/README.surfplot
   MOAB/trunk/tools/SphereDecomp.cpp
   MOAB/trunk/tools/SphereDecomp.hpp
   MOAB/trunk/tools/convert.cpp
   MOAB/trunk/tools/gsets.cc
   MOAB/trunk/tools/main.cpp
   MOAB/trunk/tools/makeops.cpp
   MOAB/trunk/tools/mbconvert.man
   MOAB/trunk/tools/measure.cpp
   MOAB/trunk/tools/measure.hpp
   MOAB/trunk/tools/parse.cpp
   MOAB/trunk/tools/parse.hpp
   MOAB/trunk/tools/propagate_tags.cpp
   MOAB/trunk/tools/size.cpp
   MOAB/trunk/tools/skin.cpp
   MOAB/trunk/tools/surfplot.cpp
Removed:
   MOAB/trunk/tools/converter/
   MOAB/trunk/tools/gsets/
   MOAB/trunk/tools/hexmodops/
   MOAB/trunk/tools/size/
   MOAB/trunk/tools/skin/
   MOAB/trunk/tools/spheredecomp/
   MOAB/trunk/tools/surfplot/
   MOAB/trunk/tools/tagprop/
Modified:
   MOAB/trunk/tools/Makefile.am
Log:
get rid of subdirectories for simple tools

Modified: MOAB/trunk/tools/Makefile.am
===================================================================
--- MOAB/trunk/tools/Makefile.am	2009-02-23 18:04:07 UTC (rev 2652)
+++ MOAB/trunk/tools/Makefile.am	2009-02-24 16:35:31 UTC (rev 2653)
@@ -1,29 +1,61 @@
+AUTOMAKE_OPTIONS = foreign
+DEFS = $(DEFINES)
+INCLUDES += -I$(top_srcdir) -I$(top_builddir)
+LDADD = $(top_builddir)/libMOAB.la
+bin_PROGRAMS =
+dist_man1_MANS = 
+
 if ENABLE_mbconvert
-  converter_DIR = converter
-else
-  converter_DIR=
+  bin_PROGRAMS += mbconvert
+  dist_man1_MANS += mbconvert.man
 endif
 
 if ENABLE_hexmodops
-  hexmodops_DIR = hexmodops
-else
-  hexmodops_DIR=
+  bin_PROGRAMS += hexmodops
 endif
+
+if ENABLE_mbsize
+  bin_PROGRAMS += mbsize
+endif
+
+if ENABLE_mbskin
+  bin_PROGRAMS += mbskin
+endif
+
+if ENABLE_mbtagprop
+  bin_PROGRAMS += mbtagprop
+endif
+
+if ENABLE_spheredecomp
+  bin_PROGRAMS += spheredecomp
+endif
+
+if ENABLE_mbsurfplot
+  bin_PROGRAMS += mbsurfplot
+endif
+
+if ENABLE_gsets
+  bin_PROGRAMS += mbgsets
+endif 
+
 if ENABLE_mbperf
   mbperf_DIR = mbperf
 else
   mbperf_DIR =
 endif
+
 if ENABLE_mbchaco
   mbchaco_DIR = mbchaco
 else
   mbchaco_DIR=
 endif
+
 if ENABLE_mbcoupler
   mbcoupler_DIR = mbcoupler
 else
   mbcoupler_DIR=
 endif
+
 if ENABLE_mbzoltan
   mbzoltan_DIR = mbzoltan
 else
@@ -36,36 +68,6 @@
   qvdual_DIR=
 endif
 
-if ENABLE_mbsize
-  size_DIR = size
-else
-  size_DIR=
-endif
-
-if ENABLE_mbskin
-  skin_DIR = skin
-else
-  skin_DIR=
-endif
-
-if ENABLE_mbtagprop
-  tagprop_DIR = tagprop
-else
-  tagprop_DIR=
-endif
-
-if ENABLE_spheredecomp
-  spheredecomp_DIR = spheredecomp
-else
-  spheredecomp_DIR=
-endif
-
-if ENABLE_mbsurfplot
-  mbsurfplot_DIR = surfplot
-else
-  mbsurfplot_DIR=
-endif
-
 if ENABLE_mcnpmit
   mcnpmit_DIR = mcnpmit
 else
@@ -84,27 +86,37 @@
   imesh_DIR = 
 endif 
 
-if ENABLE_gsets
-  gsets_DIR = gsets
-else
-  gsets_DIR = 
-endif 
-
 SUBDIRS = $(imesh_DIR) \
-	  $(converter_DIR) \
-          $(hexmodops_DIR) \
           $(mbchaco_DIR) \
           $(mbcoupler_DIR) \
           $(mbzoltan_DIR) \
           $(mbperf_DIR) \
 	  $(mcnpmit_DIR) \
           $(qvdual_DIR) \
-          $(size_DIR) \
-          $(skin_DIR) \
-          $(tagprop_DIR) \
-          $(spheredecomp_DIR) \
-          $(mbsurfplot_DIR) \
-          $(dagmc_DIR) \
-          $(gsets_DIR)
+          $(dagmc_DIR)
 
 EXTRA_DIST = mbzoltan/README 
+
+mbconvert_SOURCES = convert.cpp
+mbconvert_DEPENDENCIES = $(top_builddir)/libMOAB.la
+
+mbgsets_SOURCES = gsets.cc
+mbgsets_DEPENDENCIES = $(top_builddir)/libMOAB.la
+
+hexmodops_SOURCES = makeops.cpp
+hexmodops_DEPENDENCIES = $(top_builddir)/libMOAB.la
+
+mbsize_SOURCES = measure.cpp measure.hpp size.cpp
+mbsize_DEPENDENCIES = $(top_builddir)/libMOAB.la
+
+mbskin_SOURCES = skin.cpp
+mbskin_DEPENDENCIES = $(top_builddir)/libMOAB.la
+
+spheredecomp_SOURCES = SphereDecomp.hpp SphereDecomp.cpp main.cpp
+spheredecomp_DEPENDENCIES = $(top_builddir)/libMOAB.la
+
+mbsurfplot_SOURCES = surfplot.cpp
+mbsurfplot_DEPENDENCIES = $(top_builddir)/libMOAB.la
+
+mbtagprop_SOURCES = parse.cpp parse.hpp propagate_tags.cpp
+mbtagprop_DEPENDENCIES = $(top_builddir)/libMOAB.la

Copied: MOAB/trunk/tools/README.hexmodops (from rev 2644, MOAB/trunk/tools/hexmodops/README)
===================================================================
--- MOAB/trunk/tools/README.hexmodops	                        (rev 0)
+++ MOAB/trunk/tools/README.hexmodops	2009-02-24 16:35:31 UTC (rev 2653)
@@ -0,0 +1,14 @@
+This utility constructs meshes indicating structure of local hex modification
+operations developed by Tautges.
+
+Usage: hexmodops [-h5m] [-vtk] {-ap | -foc | -fs | -cp | -tcp | -thp}
+
+-h5m: Output results to h5m file
+-vtk: Output results to vtk file
+
+-ap: Atomic pillow operation
+-foc: Face open-collapse operation
+-fs: Face shrink operation
+-cp: Chord push operation
+-tcp: Triple chord-push operation
+-thp: Triple hex-push operation


Property changes on: MOAB/trunk/tools/README.hexmodops
___________________________________________________________________
Name: svn:keywords
   + Author Date Id Revision
Name: svn:mergeinfo
   + 
Name: svn:eol-style
   + native

Copied: MOAB/trunk/tools/README.mbsize (from rev 2644, MOAB/trunk/tools/size/README)
===================================================================
--- MOAB/trunk/tools/README.mbsize	                        (rev 0)
+++ MOAB/trunk/tools/README.mbsize	2009-02-24 16:35:31 UTC (rev 2653)
@@ -0,0 +1,6 @@
+Print entity counts by geometric owner or block/boundary.
+
+Usage:
+size [-g] [-m] <mesh file list>
+  -g : print counts by geometric owner"
+  -m : print counts per block/boundary"


Property changes on: MOAB/trunk/tools/README.mbsize
___________________________________________________________________
Name: svn:keywords
   + Author Date Id Revision
Name: svn:mergeinfo
   + 
Name: svn:eol-style
   + native

Copied: MOAB/trunk/tools/README.mbtagprop (from rev 2644, MOAB/trunk/tools/tagprop/README)
===================================================================
--- MOAB/trunk/tools/README.mbtagprop	                        (rev 0)
+++ MOAB/trunk/tools/README.mbtagprop	2009-02-24 16:35:31 UTC (rev 2653)
@@ -0,0 +1,55 @@
+Usage:
+tagprop <options> <input_file> <output_file>
+Options:
+  -t <ident_tag>[=<value>]
+  -d <data_tag>[=<default>]
+  -c <data_tag=type:size>[=defult]
+  -w <write_tag>          
+  -n|-e                   
+
+At least one ident_tag must be specified.  This tag will be used to
+select entity sets to process.  If more than one ident_tag is
+specified, entity sets that match A\bAN\bNY\bY the specified tags will
+be selected (logical OR).  A tag value to match may optionally be
+specified for each ident_tag.
+
+The data_tag is the tag on the selected entity sets for which the
+value should be propogated to the contained mesn entities.  If no
+data_tag is specified, the value of the ident_tag will be used.  If
+multiple ident_tags are specified, the data_tag must be specified
+explicitly.  If the data tag is specified with the '-d' option, the
+tag must exist and the optional value will be set on any entiites for
+which the owning set doesn't have the data_tag defined.  If the
+data_tag is specified with the '-c' option, the tag will be created.
+
+If the write_tag is specified, the tag propogated to the mesh entities
+contained in the set will be given this name.  If no write_tag is
+specified, the data_tag will be used.
+
+If -\b-n\bn is specified, the tag values will be propogated only to
+nodes contained in the identified sets.  If -\b-e\be is specified, the
+tags will be propogated to the contained elements.  If neither is
+specified, the default is both.
+
+The syntax for specifying tag values is as follows: Tags are specified
+as <name>=[value], where the tag value is optional.  For opaque tags,
+a numeric value may be specified in hexadecimal with a '0x' prefix.
+If the value does not begin with the '0x' prefix, it will be treated
+as a string (not a numerical value) and padded with NULL characters to
+fit the tag size.
+
+For integral types (INTEGER, BIT, and HANDLE), values are parsed as
+integers with the standard 0x and 0 prefixes for hexidecimal and octal
+bases, respectively.
+
+DOUBLE types must be specified in base-10.  Exponential syntax (e) is
+accepted.
+
+If the tag is not opaque and is an array of values, the values must be
+specified as a comma-separated list w/out spaces.
+
+Tags are created with the form name=type:size[=default_value] where
+type is one of {int,double,opaque,handle,bit} and size is the number
+of values of the specified type, or the number of bytes if the type is
+'opaque', A default value for the tag make be specified.
+


Property changes on: MOAB/trunk/tools/README.mbtagprop
___________________________________________________________________
Name: svn:keywords
   + Author Date Id Revision
Name: svn:mergeinfo
   + 
Name: svn:eol-style
   + native

Copied: MOAB/trunk/tools/README.mvconvert (from rev 2644, MOAB/trunk/tools/converter/README)
===================================================================
--- MOAB/trunk/tools/README.mvconvert	                        (rev 0)
+++ MOAB/trunk/tools/README.mvconvert	2009-02-24 16:35:31 UTC (rev 2653)
@@ -0,0 +1 @@
+See mbconvert.man in this directory.


Property changes on: MOAB/trunk/tools/README.mvconvert
___________________________________________________________________
Name: svn:keywords
   + Author Date Id Revision
Name: svn:mergeinfo
   + 
Name: svn:eol-style
   + native

Copied: MOAB/trunk/tools/README.skin (from rev 2644, MOAB/trunk/tools/skin/README)
===================================================================
--- MOAB/trunk/tools/README.skin	                        (rev 0)
+++ MOAB/trunk/tools/README.skin	2009-02-24 16:35:31 UTC (rev 2653)
@@ -0,0 +1,15 @@
+This is a utility for generating input files for testing Mesquite
+(MESh QUality Improvement Toolkit).  The CL arguments to the utilty
+are a single input file and a single outpute file.  The utility
+does the following:
+  o Read input file
+  o Find the set of all elements of the highest dimension
+    (e.g. all volume elements if there are any, otherwise
+     all face elements.)
+  o Generate the skin of that set of elements.
+  o Create an integer tag named "fixed"
+  o Set the tag to zero on all interior vertices and one
+    on all vertices in the skin of the mesh
+  o Write out the set of elements
+
+ 


Property changes on: MOAB/trunk/tools/README.skin
___________________________________________________________________
Name: svn:keywords
   + Author Date Id Revision
Name: svn:mergeinfo
   + 
Name: svn:eol-style
   + native

Copied: MOAB/trunk/tools/README.spheredecomp (from rev 2644, MOAB/trunk/tools/spheredecomp/README)
===================================================================
--- MOAB/trunk/tools/README.spheredecomp	                        (rev 0)
+++ MOAB/trunk/tools/README.spheredecomp	2009-02-24 16:35:31 UTC (rev 2653)
@@ -0,0 +1,13 @@
+This tool constructs an all-hex mesh for a set of spheres embedded in
+a substrate.  The sphere locations and radii are specified as a set of
+vertices and tags on those vertices.  The vertices are triangulated
+with a tet mesh, then each tet is subdivided such that the spherical
+surface around each vertex is resolved.  The current subdivision
+method used is to split each corner region (the part inside the
+sphere) with four hexes, using a standard tetrahedron primitive, and
+to split the remaining "interstices" region using a midpoint
+subdivision on the tet with corner spheres removed.  This results in
+28 hexes per tetrahedron, with 16 of those inside the 4 sphere regions
+and 12 hexes in the interstices.
+
+


Property changes on: MOAB/trunk/tools/README.spheredecomp
___________________________________________________________________
Name: svn:keywords
   + Author Date Id Revision
Name: svn:mergeinfo
   + 
Name: svn:eol-style
   + native

Copied: MOAB/trunk/tools/README.surfplot (from rev 2644, MOAB/trunk/tools/surfplot/README)
===================================================================
--- MOAB/trunk/tools/README.surfplot	                        (rev 0)
+++ MOAB/trunk/tools/README.surfplot	2009-02-24 16:35:31 UTC (rev 2653)
@@ -0,0 +1,10 @@
+This utility plots the mesh of a single geometric surface projected to
+a plane.  The output file is written to stdout.
+
+Usage:
+surfplot [-g|-p] <Surface_ID> <input_file>
+-g           -  Write GNU Plot data file (default).
+-p           -  Write encapsulated postscript file
+-s           -  Write an SVG file                  
+<Surface_ID> -  ID of surface containing mesh to export.
+<input_file> -  Mesh file to read.


Property changes on: MOAB/trunk/tools/README.surfplot
___________________________________________________________________
Name: svn:keywords
   + Author Date Id Revision
Name: svn:mergeinfo
   + 
Name: svn:eol-style
   + native

Copied: MOAB/trunk/tools/SphereDecomp.cpp (from rev 2644, MOAB/trunk/tools/spheredecomp/SphereDecomp.cpp)
===================================================================
--- MOAB/trunk/tools/SphereDecomp.cpp	                        (rev 0)
+++ MOAB/trunk/tools/SphereDecomp.cpp	2009-02-24 16:35:31 UTC (rev 2653)
@@ -0,0 +1,476 @@
+#include "SphereDecomp.hpp"
+#include "MeshTopoUtil.hpp"
+#include "MBRange.hpp"
+#include "MBCN.hpp"
+#include <math.h>
+#include <assert.h>
+#include <iostream>
+
+#define RR if (MB_SUCCESS != result) return result
+
+const char *SUBDIV_VERTICES_TAG_NAME = "subdiv_vertices";
+
+SphereDecomp::SphereDecomp(MBInterface *impl) 
+{
+  mbImpl = impl;
+}
+
+MBErrorCode SphereDecomp::build_sphere_mesh(const char *sphere_radii_tag_name,
+                                            MBEntityHandle *hex_set) 
+{
+  MBErrorCode result = mbImpl->tag_get_handle(sphere_radii_tag_name, sphereRadiiTag); RR;
+
+    // need to make sure all interior edges and faces are created
+  MBRange all_verts;
+  result = mbImpl->get_entities_by_type(0, MBVERTEX, all_verts); RR;
+  MeshTopoUtil mtu(mbImpl);
+  result = mtu.construct_aentities(all_verts);
+  
+    // create tag to hold vertices
+  result = mbImpl->tag_create(SUBDIV_VERTICES_TAG_NAME, 9*sizeof(MBEntityHandle), 
+                           MB_TAG_DENSE, MB_TYPE_HANDLE, subdivVerticesTag, NULL); RR;
+
+    // compute nodal positions for each dimension element
+  result = compute_nodes(1); RR;
+  result = compute_nodes(2); RR;
+  result = compute_nodes(3); RR;
+  
+    // build hex elements
+  std::vector<MBEntityHandle> sphere_hexes, interstic_hexes;
+  result = build_hexes(sphere_hexes, interstic_hexes); 
+
+  result = mbImpl->tag_delete(subdivVerticesTag); RR;
+
+  if (NULL != hex_set) {
+    if (0 == *hex_set) {
+      MBEntityHandle this_set;
+        // make a new set
+      result = mbImpl->create_meshset(MESHSET_SET, this_set); RR;
+      *hex_set = this_set;
+    }
+    
+      // save all the hexes to this set
+    result = mbImpl->add_entities(*hex_set, &sphere_hexes[0], 
+                                  sphere_hexes.size()); RR;
+    result = mbImpl->add_entities(*hex_set, &interstic_hexes[0], 
+                                  interstic_hexes.size()); RR;
+  }
+      
+  return result;
+}
+
+MBErrorCode SphereDecomp::compute_nodes(const int dim) 
+{
+    // get facets of that dimension
+  MBRange these_ents;
+  const MBEntityType the_types[4] = {MBVERTEX, MBEDGE, MBTRI, MBTET};
+  
+  MBErrorCode result = mbImpl->get_entities_by_dimension(0, dim, these_ents); RR;
+  assert(mbImpl->type_from_handle(*these_ents.begin()) == the_types[dim] &&
+         mbImpl->type_from_handle(*these_ents.rbegin()) == the_types[dim]);
+  
+  MBEntityHandle subdiv_vertices[9];
+  MeshTopoUtil mtu(mbImpl);
+  double avg_pos[3], vert_pos[12], new_vert_pos[12], new_new_vert_pos[3];
+  double radii[4], unitv[3];
+  int num_verts = MBCN::VerticesPerEntity(the_types[dim]);
+  
+  for (MBRange::iterator rit = these_ents.begin(); rit != these_ents.end(); rit++) {
+    
+      // get vertices
+    const MBEntityHandle *connect;
+    int num_connect;
+    result = mbImpl->get_connectivity(*rit, connect, num_connect); RR;
+
+      // compute center
+    result = mtu.get_average_position(connect, num_connect, avg_pos); RR;
+
+      // create center vertex
+    result = mbImpl->create_vertex(avg_pos, subdiv_vertices[num_verts]); RR;
+    
+      // get coords of other vertices
+    result = mbImpl->get_coords(connect, num_connect, vert_pos); RR;
+    
+      // get radii associated with each vertex
+    result = mbImpl->tag_get_data(sphereRadiiTag, connect, num_connect, radii); RR;
+    
+      // compute subdiv vertex position for each vertex
+    for (int i = 0; i < num_verts; i++) {
+      for (int j = 0; j < 3; j++) unitv[j] = avg_pos[j] - vert_pos[3*i+j];
+      double vlength = sqrt(unitv[0]*unitv[0] + unitv[1]*unitv[1] + unitv[2]*unitv[2]);
+      if (vlength < radii[i]) {
+        std::cout << "Radius too large at vertex " << i << std::endl;
+        result = MB_FAILURE;
+        continue;
+      }
+      
+      
+      for (int j = 0; j < 3; j++) unitv[j] /= vlength;
+          
+      for (int j = 0; j < 3; j++)
+        new_vert_pos[3*i+j] = vert_pos[3*i+j] + radii[i] * unitv[j];
+
+      // create vertex at this position
+      MBErrorCode tmp_result = mbImpl->create_vertex(&new_vert_pos[3*i], subdiv_vertices[i]);
+      if (MB_SUCCESS != tmp_result) result = tmp_result;
+    }
+    
+    if (MB_SUCCESS != result) return result;
+    
+      // compute subdiv vertex positions for vertices inside spheres; just mid-pt between
+      // previous subdiv vertex and corner vertex
+    for (int i = 0; i < num_verts; i++) {
+      for (int j = 0; j < 3; j++) 
+        new_new_vert_pos[j] = .5 * (vert_pos[3*i+j] + new_vert_pos[3*i+j]);
+
+      result = mbImpl->create_vertex(new_new_vert_pos, subdiv_vertices[num_verts+1+i]);
+    }
+
+      // set the tag
+    result = mbImpl->tag_set_data(subdivVerticesTag, &(*rit), 1, subdiv_vertices); RR;
+  }
+  
+  return result;
+}
+
+MBErrorCode SphereDecomp::build_hexes(std::vector<MBEntityHandle> &sphere_hexes,
+                        std::vector<MBEntityHandle> &interstic_hexes) 
+{
+    // build hexes inside each tet element separately
+  MBRange tets;
+  MBErrorCode result = mbImpl->get_entities_by_type(0, MBTET, tets); RR;
+  
+  for (MBRange::iterator vit = tets.begin(); vit != tets.end(); vit++) {
+    result = subdivide_tet(*vit, sphere_hexes, interstic_hexes); RR;
+  }
+  
+  return MB_SUCCESS;
+}
+
+MBErrorCode SphereDecomp::subdivide_tet(MBEntityHandle tet, 
+                          std::vector<MBEntityHandle> &sphere_hexes,
+                          std::vector<MBEntityHandle> &interstic_hexes) 
+{
+    // 99: (#subdiv_verts/entity=9) * (#edges=6 + #faces=4 + 1=tet)
+  MBEntityHandle subdiv_verts[99];
+
+    // get tet connectivity
+  std::vector<MBEntityHandle> tet_conn;
+  MBErrorCode result = mbImpl->get_connectivity(&tet, 1, tet_conn); RR;
+  
+  for (int dim = 1; dim <= 3; dim++) {
+      // get entities of this dimension
+    std::vector<MBEntityHandle> ents;
+    if (dim != 3) {
+      result = mbImpl->get_adjacencies(&tet, 1, dim, false, ents); RR; 
+    }
+    else ents.push_back(tet);
+    
+      // for each, get subdiv verts & put into vector
+    for (std::vector<MBEntityHandle>::iterator vit = ents.begin(); vit != ents.end(); vit++) {
+      result = retrieve_subdiv_verts(tet, *vit, &tet_conn[0], dim, subdiv_verts); RR;
+    }
+  }
+
+    // ok, subdiv_verts are in canonical order; now create the hexes, using pre-computed templates
+
+    // Templates are specified in terms of the vertices making up each hex; vertices are specified 
+    // by specifying the facet index and type they resolve, and the index of that vertex in that facet's
+    // subdivision vertices list.
+
+    // Each facet is subdivided into:
+    // - a mid vertex
+    // - one vertex for each corner vertex on the facet (located on a line between the mid vertex and
+    //   the corresponding corner vertex, a distance equal to the sphere radius away from the corner
+    //   vertex)
+    // - one vertex midway between each corner vertex and the corresponding "sphere surface" vertex
+    // For edges, tris and tets this gives 5, 7 and 9 subdivision vertices, respectively.  Subdivision vertices
+    // appear in the list in the order: sphere surface vertices, mid vertex, sphere interior vertices.  In
+    // each of those sub lists, vertices are listed in the canonical order of the corresponding corner vertices
+    // for that facet.
+
+    // Subdivision vertices for facetes are indexed by listing the facet type they resolve (EDGE, FACE, TET), the index of
+    // that facet (integer = 0..5, 0..3, 0 for edges, tris, tet, resp), and subdivision index (AINDEX..EINDEX for
+    // edges, AINDEX..GINDEX for tris, AINDEX..IINDEX for tets).
+
+    // Subdivision vertices for all facets of a tet are stored in one subdivision vertex vector, in order of increasing
+    // facet dimension and index (index varies fastest).  The ESV, FSV, and TSV macros are used to compute the
+    // indices into that vector for various parameters.  The CV macro is used to index into the tet connectivity
+    // vector.
+
+    // Subdivision templates for splitting the tet into 28 hexes were derived by hand, and are listed below 
+    // (using the indexing scheme described above).
+
+#define EDGE 0
+#define FACE 1
+#define TET 2
+#define AINDEX 0
+#define BINDEX 1
+#define CINDEX 2
+#define DINDEX 3
+#define EINDEX 4
+#define FINDEX 5
+#define GINDEX 6
+#define HINDEX 7
+#define IINDEX 8
+#define V0INDEX 0
+#define V1INDEX 1
+#define V2INDEX 2
+#define V3INDEX 3
+#define CV(a) tet_conn[a]
+#define ESV(a,b) subdiv_verts[a*9+b]
+#define FSV(a,b) subdiv_verts[54+a*9+b]
+#define TSV(a,b) subdiv_verts[90+a*9+b]
+
+  MBEntityHandle this_connect[8], this_hex;
+
+    // first, interstices hexes, three per vertex/spherical surface
+// V0:
+  int i = 0;
+  this_connect[i++]=ESV(0,AINDEX); this_connect[i++]=ESV(0,CINDEX); this_connect[i++]=FSV(3,DINDEX); this_connect[i++]=FSV(3,AINDEX); 
+  this_connect[i++]=FSV(0,AINDEX); this_connect[i++]=FSV(0,DINDEX); this_connect[i++]=TSV(0,EINDEX); this_connect[i++]=TSV(0,AINDEX);
+  result = mbImpl->create_element(MBHEX, this_connect, 8, this_hex); RR;
+  interstic_hexes.push_back(this_hex);
+
+  i = 0;
+  this_connect[i++]=FSV(0,AINDEX); this_connect[i++]=FSV(0,DINDEX); this_connect[i++]=TSV(0,EINDEX); this_connect[i++]=TSV(0,AINDEX); 
+  this_connect[i++]=ESV(3,AINDEX); this_connect[i++]=ESV(3,CINDEX); this_connect[i++]=FSV(2,DINDEX); this_connect[i++]=FSV(2,AINDEX);
+  result = mbImpl->create_element(MBHEX, this_connect, 8, this_hex); RR;
+  interstic_hexes.push_back(this_hex);
+
+  i = 0;
+  this_connect[i++]=FSV(3,AINDEX); this_connect[i++]=FSV(3,DINDEX); this_connect[i++]=ESV(2,CINDEX); this_connect[i++]=ESV(2,BINDEX); 
+  this_connect[i++]=TSV(0,AINDEX); this_connect[i++]=TSV(0,EINDEX); this_connect[i++]=FSV(2,DINDEX); this_connect[i++]=FSV(2,AINDEX);
+  result = mbImpl->create_element(MBHEX, this_connect, 8, this_hex); RR;
+  interstic_hexes.push_back(this_hex);
+
+
+// V1:
+  i = 0;
+  this_connect[i++]=ESV(0,CINDEX); this_connect[i++]=ESV(0,BINDEX); this_connect[i++]=FSV(3,CINDEX); this_connect[i++]=FSV(3,DINDEX); 
+  this_connect[i++]=FSV(0,DINDEX); this_connect[i++]=FSV(0,BINDEX); this_connect[i++]=TSV(0,BINDEX); this_connect[i++]=TSV(0,EINDEX);
+  result = mbImpl->create_element(MBHEX, this_connect, 8, this_hex); RR;
+  interstic_hexes.push_back(this_hex);
+
+  i = 0;
+  this_connect[i++]=FSV(0,DINDEX); this_connect[i++]=FSV(0,BINDEX); this_connect[i++]=TSV(0,BINDEX); this_connect[i++]=TSV(0,EINDEX); 
+  this_connect[i++]=ESV(4,CINDEX); this_connect[i++]=ESV(4,AINDEX); this_connect[i++]=FSV(1,AINDEX); this_connect[i++]=FSV(1,DINDEX);
+  result = mbImpl->create_element(MBHEX, this_connect, 8, this_hex); RR;
+  interstic_hexes.push_back(this_hex);
+
+  i = 0;
+  this_connect[i++]=FSV(1,DINDEX); this_connect[i++]=FSV(1,AINDEX); this_connect[i++]=TSV(0,BINDEX); this_connect[i++]=TSV(0,EINDEX); 
+  this_connect[i++]=ESV(1,CINDEX); this_connect[i++]=ESV(1,AINDEX); this_connect[i++]=FSV(3,CINDEX); this_connect[i++]=FSV(3,DINDEX);
+  result = mbImpl->create_element(MBHEX, this_connect, 8, this_hex); RR;
+  interstic_hexes.push_back(this_hex);
+
+
+// V2:
+  i = 0;
+  this_connect[i++]=FSV(3,DINDEX); this_connect[i++]=ESV(1,CINDEX); this_connect[i++]=ESV(1,BINDEX); this_connect[i++]=FSV(3,BINDEX); 
+  this_connect[i++]=TSV(0,EINDEX); this_connect[i++]=FSV(1,DINDEX); this_connect[i++]=FSV(1,BINDEX); this_connect[i++]=TSV(0,CINDEX);
+  result = mbImpl->create_element(MBHEX, this_connect, 8, this_hex); RR;
+  interstic_hexes.push_back(this_hex);
+
+  i = 0;
+  this_connect[i++]=TSV(0,EINDEX); this_connect[i++]=FSV(1,DINDEX); this_connect[i++]=FSV(1,BINDEX); this_connect[i++]=TSV(0,CINDEX); 
+  this_connect[i++]=FSV(2,DINDEX); this_connect[i++]=ESV(5,CINDEX); this_connect[i++]=ESV(5,AINDEX); this_connect[i++]=FSV(2,CINDEX);
+  result = mbImpl->create_element(MBHEX, this_connect, 8, this_hex); RR;
+  interstic_hexes.push_back(this_hex);
+
+  i = 0;
+  this_connect[i++]=TSV(0,CINDEX); this_connect[i++]=FSV(2,CINDEX); this_connect[i++]=ESV(2,AINDEX); this_connect[i++]=FSV(3,BINDEX); 
+  this_connect[i++]=TSV(0,EINDEX); this_connect[i++]=FSV(2,DINDEX); this_connect[i++]=ESV(2,CINDEX); this_connect[i++]=FSV(3,DINDEX);
+  result = mbImpl->create_element(MBHEX, this_connect, 8, this_hex); RR;
+  interstic_hexes.push_back(this_hex);
+
+
+// V3:
+  i = 0;
+  this_connect[i++]=TSV(0,EINDEX); this_connect[i++]=FSV(1,DINDEX); this_connect[i++]=ESV(5,CINDEX); this_connect[i++]=FSV(2,DINDEX); 
+  this_connect[i++]=TSV(0,DINDEX); this_connect[i++]=FSV(1,CINDEX); this_connect[i++]=ESV(5,BINDEX); this_connect[i++]=FSV(2,BINDEX);
+  result = mbImpl->create_element(MBHEX, this_connect, 8, this_hex); RR;
+  interstic_hexes.push_back(this_hex);
+
+  i = 0;
+  this_connect[i++]=FSV(0,DINDEX); this_connect[i++]=ESV(4,CINDEX); this_connect[i++]=FSV(1,DINDEX); this_connect[i++]=TSV(0,EINDEX); 
+  this_connect[i++]=FSV(0,CINDEX); this_connect[i++]=ESV(4,BINDEX); this_connect[i++]=FSV(1,CINDEX); this_connect[i++]=TSV(0,DINDEX);
+  result = mbImpl->create_element(MBHEX, this_connect, 8, this_hex); RR;
+  interstic_hexes.push_back(this_hex);
+
+  i = 0;
+  this_connect[i++]=ESV(3,CINDEX); this_connect[i++]=FSV(0,DINDEX); this_connect[i++]=TSV(0,EINDEX); this_connect[i++]=FSV(2,DINDEX); 
+  this_connect[i++]=ESV(3,BINDEX); this_connect[i++]=FSV(0,CINDEX); this_connect[i++]=TSV(0,DINDEX); this_connect[i++]=FSV(2,BINDEX);
+  result = mbImpl->create_element(MBHEX, this_connect, 8, this_hex); RR;
+  interstic_hexes.push_back(this_hex);
+
+    // now, the sphere interiors, four hexes per vertex sphere
+
+// V0:
+  i = 0;
+  this_connect[i++]=CV(V0INDEX); this_connect[i++]=ESV(0,DINDEX); this_connect[i++]=FSV(3,EINDEX); this_connect[i++]=ESV(2,EINDEX); 
+  this_connect[i++]=ESV(3,DINDEX); this_connect[i++]=FSV(0,EINDEX); this_connect[i++]=TSV(0,FINDEX); this_connect[i++]=FSV(2,EINDEX);
+  result = mbImpl->create_element(MBHEX, this_connect, 8, this_hex); RR;
+  sphere_hexes.push_back(this_hex);
+
+  i = 0;
+  this_connect[i++]=ESV(0,DINDEX); this_connect[i++]=ESV(0,AINDEX); this_connect[i++]=FSV(3,AINDEX); this_connect[i++]=FSV(3,EINDEX); 
+  this_connect[i++]=FSV(0,EINDEX); this_connect[i++]=FSV(0,AINDEX); this_connect[i++]=TSV(0,AINDEX); this_connect[i++]=TSV(0,FINDEX);
+  result = mbImpl->create_element(MBHEX, this_connect, 8, this_hex); RR;
+  sphere_hexes.push_back(this_hex);
+
+  i = 0;
+  this_connect[i++]=FSV(3,EINDEX); this_connect[i++]=FSV(3,AINDEX); this_connect[i++]=ESV(2,BINDEX); this_connect[i++]=ESV(2,EINDEX); 
+  this_connect[i++]=TSV(0,FINDEX); this_connect[i++]=TSV(0,AINDEX); this_connect[i++]=FSV(2,AINDEX); this_connect[i++]=FSV(2,EINDEX);
+  result = mbImpl->create_element(MBHEX, this_connect, 8, this_hex); RR;
+  sphere_hexes.push_back(this_hex);
+
+  i = 0;
+  this_connect[i++]=TSV(0,FINDEX); this_connect[i++]=TSV(0,AINDEX); this_connect[i++]=FSV(2,AINDEX); this_connect[i++]=FSV(2,EINDEX); 
+  this_connect[i++]=FSV(0,EINDEX); this_connect[i++]=FSV(0,AINDEX); this_connect[i++]=ESV(3,AINDEX); this_connect[i++]=ESV(3,DINDEX);
+  result = mbImpl->create_element(MBHEX, this_connect, 8, this_hex); RR;
+  sphere_hexes.push_back(this_hex);
+
+
+// V1:
+  i = 0;
+  this_connect[i++]=CV(V1INDEX); this_connect[i++]=ESV(1,DINDEX); this_connect[i++]=FSV(3,GINDEX); this_connect[i++]=ESV(0,EINDEX); 
+  this_connect[i++]=ESV(4,DINDEX); this_connect[i++]=FSV(1,EINDEX); this_connect[i++]=TSV(0,GINDEX); this_connect[i++]=FSV(0,FINDEX);
+  result = mbImpl->create_element(MBHEX, this_connect, 8, this_hex); RR;
+  sphere_hexes.push_back(this_hex);
+
+  i = 0;
+  this_connect[i++]=FSV(3,GINDEX); this_connect[i++]=ESV(1,DINDEX); this_connect[i++]=ESV(1,AINDEX); this_connect[i++]=FSV(3,CINDEX); 
+  this_connect[i++]=TSV(0,GINDEX); this_connect[i++]=FSV(1,EINDEX); this_connect[i++]=FSV(1,AINDEX); this_connect[i++]=TSV(0,BINDEX);
+  result = mbImpl->create_element(MBHEX, this_connect, 8, this_hex); RR;
+  sphere_hexes.push_back(this_hex);
+
+  i = 0;
+  this_connect[i++]=TSV(0,GINDEX); this_connect[i++]=FSV(1,EINDEX); this_connect[i++]=FSV(1,AINDEX); this_connect[i++]=TSV(0,BINDEX); 
+  this_connect[i++]=FSV(0,FINDEX); this_connect[i++]=ESV(4,DINDEX); this_connect[i++]=ESV(4,AINDEX); this_connect[i++]=FSV(0,BINDEX);
+  result = mbImpl->create_element(MBHEX, this_connect, 8, this_hex); RR;
+  sphere_hexes.push_back(this_hex);
+
+  i = 0;
+  this_connect[i++]=ESV(0,BINDEX); this_connect[i++]=ESV(0,EINDEX); this_connect[i++]=FSV(3,GINDEX); this_connect[i++]=FSV(3,CINDEX); 
+  this_connect[i++]=FSV(0,BINDEX); this_connect[i++]=FSV(0,FINDEX); this_connect[i++]=TSV(0,GINDEX); this_connect[i++]=TSV(0,BINDEX);
+  result = mbImpl->create_element(MBHEX, this_connect, 8, this_hex); RR;
+  sphere_hexes.push_back(this_hex);
+
+
+// V2:
+  i = 0;
+  this_connect[i++]=ESV(1,BINDEX); this_connect[i++]=ESV(1,EINDEX); this_connect[i++]=FSV(3,FINDEX); this_connect[i++]=FSV(3,BINDEX); 
+  this_connect[i++]=FSV(1,BINDEX); this_connect[i++]=FSV(1,FINDEX); this_connect[i++]=TSV(0,HINDEX); this_connect[i++]=TSV(0,CINDEX);
+  result = mbImpl->create_element(MBHEX, this_connect, 8, this_hex); RR;
+  sphere_hexes.push_back(this_hex);
+
+  i = 0;
+  this_connect[i++]=FSV(3,FINDEX); this_connect[i++]=ESV(1,EINDEX); this_connect[i++]=CV(V2INDEX); this_connect[i++]=ESV(2,DINDEX); 
+  this_connect[i++]=TSV(0,HINDEX); this_connect[i++]=FSV(1,FINDEX); this_connect[i++]=ESV(5,DINDEX); this_connect[i++]=FSV(2,GINDEX);
+  result = mbImpl->create_element(MBHEX, this_connect, 8, this_hex); RR;
+  sphere_hexes.push_back(this_hex);
+
+  i = 0;
+  this_connect[i++]=TSV(0,HINDEX); this_connect[i++]=FSV(1,FINDEX); this_connect[i++]=ESV(5,DINDEX); this_connect[i++]=FSV(2,GINDEX); 
+  this_connect[i++]=TSV(0,CINDEX); this_connect[i++]=FSV(1,BINDEX); this_connect[i++]=ESV(5,AINDEX); this_connect[i++]=FSV(2,CINDEX);
+  result = mbImpl->create_element(MBHEX, this_connect, 8, this_hex); RR;
+  sphere_hexes.push_back(this_hex);
+
+  i = 0;
+  this_connect[i++]=FSV(3,BINDEX); this_connect[i++]=FSV(3,FINDEX); this_connect[i++]=ESV(2,DINDEX); this_connect[i++]=ESV(2,AINDEX); 
+  this_connect[i++]=TSV(0,CINDEX); this_connect[i++]=TSV(0,HINDEX); this_connect[i++]=FSV(2,GINDEX); this_connect[i++]=FSV(2,CINDEX);
+  result = mbImpl->create_element(MBHEX, this_connect, 8, this_hex); RR;
+  sphere_hexes.push_back(this_hex);
+
+
+// V3:
+  i = 0;
+  this_connect[i++]=FSV(0,CINDEX); this_connect[i++]=ESV(4,BINDEX); this_connect[i++]=FSV(1,CINDEX); this_connect[i++]=TSV(0,DINDEX); 
+  this_connect[i++]=FSV(0,GINDEX); this_connect[i++]=ESV(4,EINDEX); this_connect[i++]=FSV(1,GINDEX); this_connect[i++]=TSV(0,IINDEX);
+  result = mbImpl->create_element(MBHEX, this_connect, 8, this_hex); RR;
+  sphere_hexes.push_back(this_hex);
+
+  i = 0;
+  this_connect[i++]=ESV(3,BINDEX); this_connect[i++]=FSV(0,CINDEX); this_connect[i++]=TSV(0,DINDEX); this_connect[i++]=FSV(2,BINDEX); 
+  this_connect[i++]=ESV(3,EINDEX); this_connect[i++]=FSV(0,GINDEX); this_connect[i++]=TSV(0,IINDEX); this_connect[i++]=FSV(2,FINDEX);
+  result = mbImpl->create_element(MBHEX, this_connect, 8, this_hex); RR;
+  sphere_hexes.push_back(this_hex);
+
+  i = 0;
+  this_connect[i++]=TSV(0,DINDEX); this_connect[i++]=FSV(1,CINDEX); this_connect[i++]=ESV(5,BINDEX); this_connect[i++]=FSV(2,BINDEX); 
+  this_connect[i++]=TSV(0,IINDEX); this_connect[i++]=FSV(1,GINDEX); this_connect[i++]=ESV(5,EINDEX); this_connect[i++]=FSV(2,FINDEX);
+  result = mbImpl->create_element(MBHEX, this_connect, 8, this_hex); RR;
+  sphere_hexes.push_back(this_hex);
+
+  i = 0;
+  this_connect[i++]=FSV(0,GINDEX); this_connect[i++]=ESV(4,EINDEX); this_connect[i++]=FSV(1,GINDEX); this_connect[i++]=TSV(0,IINDEX); 
+  this_connect[i++]=ESV(3,EINDEX); this_connect[i++]=CV(V3INDEX); this_connect[i++]=ESV(5,EINDEX); this_connect[i++]=FSV(2,FINDEX);
+  result = mbImpl->create_element(MBHEX, this_connect, 8, this_hex); RR;
+  sphere_hexes.push_back(this_hex);
+
+  return result;
+}
+
+MBErrorCode SphereDecomp::retrieve_subdiv_verts(MBEntityHandle tet, MBEntityHandle this_ent,
+                                  const MBEntityHandle *tet_conn,
+                                  const int dim, MBEntityHandle *subdiv_verts) 
+{
+    // get the subdiv verts for this entity
+  MBErrorCode result;
+  
+    // if it's a tet, just put them on the end & return
+  if (tet == this_ent) {
+    result = mbImpl->tag_get_data(subdivVerticesTag, &this_ent, 1, &subdiv_verts[90]);
+    return MB_SUCCESS;
+  }
+  
+    // if it's a sub-entity, need to find index, relative orientation, and offset
+    // get connectivity of sub-entity
+  std::vector<MBEntityHandle> this_conn;
+  result = mbImpl->get_connectivity(&this_ent, 1, this_conn); RR;
+  
+    // get relative orientation
+  std::vector<int> conn_tet_indices(this_conn.size());
+  for (size_t i = 0; i < this_conn.size(); ++i)
+    conn_tet_indices[i] = std::find(tet_conn, tet_conn+4, this_conn[i]) - tet_conn;
+  int sense, side_no, offset;
+  int success = MBCN::SideNumber(MBTET, &conn_tet_indices[0],
+                                 this_conn.size(), dim, side_no, sense, offset);
+  if (-1 == success) return MB_FAILURE;
+  
+    // start of this entity's subdiv_verts; edges go first, then preceding sides, then this one;
+    // this assumes 6 edges/tet
+  MBEntityHandle *subdiv_start = &subdiv_verts[((dim-1)*6 + side_no) * 9];
+  
+    // get subdiv_verts and put them into proper place
+  result = mbImpl->tag_get_data(subdivVerticesTag, &this_ent, 1, subdiv_start);
+
+    // could probably do this more elegantly, but isn't worth it
+#define SWITCH(a,b) {MBEntityHandle tmp_handle = a; a = b; b = tmp_handle;}
+  switch (dim) {
+    case 1:
+      if (offset != 0 || sense == -1) {
+        SWITCH(subdiv_start[0], subdiv_start[1]);
+        SWITCH(subdiv_start[3], subdiv_start[4]);
+      }
+      break;
+    case 2:
+        // rotate first
+      if (0 != offset) {
+        std::rotate(subdiv_start, subdiv_start+offset, subdiv_start+3);
+        std::rotate(subdiv_start+4, subdiv_start+4+offset, subdiv_start+7);
+      }
+        // now flip, if necessary
+      if (-1 == sense) {
+        SWITCH(subdiv_start[1], subdiv_start[2]);
+        SWITCH(subdiv_start[5], subdiv_start[6]);
+      }
+      break;
+    default:
+      return MB_FAILURE;
+  }
+  
+    // ok, we're done
+  return MB_SUCCESS;
+}


Property changes on: MOAB/trunk/tools/SphereDecomp.cpp
___________________________________________________________________
Name: svn:keywords
   + Author Date Id Revision
Name: svn:mergeinfo
   + 
Name: svn:eol-style
   + native

Copied: MOAB/trunk/tools/SphereDecomp.hpp (from rev 2644, MOAB/trunk/tools/spheredecomp/SphereDecomp.hpp)
===================================================================
--- MOAB/trunk/tools/SphereDecomp.hpp	                        (rev 0)
+++ MOAB/trunk/tools/SphereDecomp.hpp	2009-02-24 16:35:31 UTC (rev 2653)
@@ -0,0 +1,45 @@
+#ifndef SPHERE_DECOMP_HPP
+#define SPHERE_DECOMP_HPP
+
+#include "MBInterface.hpp"
+
+class SphereDecomp 
+{
+public:
+  SphereDecomp(MBInterface *impl);
+
+  MBErrorCode build_sphere_mesh(const char *sphere_radii_tag_name, 
+                                MBEntityHandle *hex_set = NULL);
+  
+private:
+
+    //! compute subdivision vertices on entities of specified dimension
+  MBErrorCode compute_nodes(const int dim);
+
+    //! subdivide tets based on subdiv vertices, returning in lists according
+    //! to whether they're inside or outside spheres
+  MBErrorCode build_hexes(std::vector<MBEntityHandle> &sphere_hexes,
+                          std::vector<MBEntityHandle> &interstic_hexes);
+  
+    //! subdivide an individual tet
+  MBErrorCode subdivide_tet(MBEntityHandle tet, 
+                            std::vector<MBEntityHandle> &sphere_hexes,
+                            std::vector<MBEntityHandle> &interstic_hexes);
+  
+    //! retrieve the subdivision vertices for a given entity in a given tet,
+    //! placing them in the array oriented wrt the tet
+  MBErrorCode retrieve_subdiv_verts(MBEntityHandle tet, MBEntityHandle this_ent,
+                                    const MBEntityHandle *tet_conn,
+                                    const int dim, MBEntityHandle *subdiv_verts);
+  
+    //! tag used to hold sphere radii (assigned to vertices)
+  MBTag sphereRadiiTag;
+
+    //! used to store subdiv vertices for a given d>0 entity
+  MBTag subdivVerticesTag;
+  
+    //! MOAB interface ptr
+  MBInterface *mbImpl;
+  
+};
+#endif


Property changes on: MOAB/trunk/tools/SphereDecomp.hpp
___________________________________________________________________
Name: svn:keywords
   + Author Date Id Revision
Name: svn:mergeinfo
   + 
Name: svn:eol-style
   + native

Copied: MOAB/trunk/tools/convert.cpp (from rev 2644, MOAB/trunk/tools/converter/convert.cpp)
===================================================================
--- MOAB/trunk/tools/convert.cpp	                        (rev 0)
+++ MOAB/trunk/tools/convert.cpp	2009-02-24 16:35:31 UTC (rev 2653)
@@ -0,0 +1,773 @@
+/**
+ * MOAB, a Mesh-Oriented datABase, is a software component for creating,
+ * storing and accessing finite element mesh data.
+ * 
+ * Copyright 2004 Sandia Corporation.  Under the terms of Contract
+ * DE-AC04-94AL85000 with Sandia Coroporation, the U.S. Government
+ * retains certain rights in this software.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ */
+
+// If Microsoft compiler, then WIN32
+#if defined(_MSC_VER) || defined(__MINGW32__)
+#  ifndef WIN32
+#    define WIN32
+#  endif
+#endif
+
+#include "MBCore.hpp"
+#include "MBRange.hpp"
+#include "MBTagConventions.hpp"
+#include "MBReaderWriterSet.hpp"
+#include <iostream>
+#include <iomanip>
+#include <set>
+#include <cstdlib>
+#include <algorithm>
+#ifndef WIN32
+#  include <sys/times.h>
+#  include <limits.h>
+#  include <unistd.h>
+#endif
+#include <time.h>
+#ifdef USE_MPI
+#  include <mpi.h>
+#endif
+
+/* Exit values */
+#define USAGE_ERROR 1
+#define READ_ERROR 2
+#define WRITE_ERROR 3
+#define OTHER_ERROR 4
+#define ENT_NOT_FOUND 5
+
+/* Tag to control ACIS dump from .cub file reader */
+const char acis_dump_file_tag_name[] = "__ACISDumpFile";
+
+
+void print_usage( const char* name, std::ostream& stream )
+{
+  stream << "Usage: " << name << 
+    " [-a <sat_file>|-A] [-t] [subset options] [-f format] <input_file> <output_file>" << std::endl
+    << "\t-f <format>    - Specify output file format" << std::endl
+    << "\t-a <acis_file> - ACIS SAT file dumped by .cub reader (same as \"-o SAT_FILE=acis_file\"" << std::endl
+    << "\t-A             - .cub file reader should not dump a SAT file (depricated default)" << std::endl
+    << "\t-o option      - Specify write option." << std::endl
+    << "\t-O option      - Specify read option." << std::endl
+    << "\t-t             - Time read and write of files." << std::endl
+    << "\t-g             - Enable verbose/debug output." << std::endl
+    << "\t-h             - Print this help text and exit." << std::endl
+    << "\t-l             - List available file formats and exit." << std::endl
+    << "\t-I <dim>       - Generate internal entities of specified dimension." << std::endl
+#ifdef USE_MPI
+    << "\t-P             - Append processor ID to file name" << std::endl
+#endif
+    << "\t--             - treat all subsequent options as file names" << std::endl
+    << "\t                 (allows file names beginning with '-')" << std::endl
+    << "  subset options: " << std::endl
+    << "\tEach of the following options should be followed by " << std::endl
+    << "\ta list of ids.  IDs may be separated with commas.  " << std::endl
+    << "\tRanges of IDs may be specified with a '-' between " << std::endl
+    << "\ttwo values.  The list may not contain spaces." << std::endl
+    << "\t-v  - volume" << std::endl
+    << "\t-s  - surface" << std::endl
+    << "\t-c  - curve" << std::endl
+    << "\t-V  - vertex" << std::endl
+    << "\t-m  - material set (block)" << std::endl
+    << "\t-d  - Dirchlet set (nodeset)" << std::endl
+    << "\t-n  - Neumann set (sideset)" << std::endl
+    << "\tThe presence of one or more of the following flags limits " << std::endl
+    << "\tthe exported mesh to only elements of the corresponding " << std::endl
+    << "\tdimension.  Vertices are always exported." << std::endl
+    << "\t-1  - edges " << std::endl
+    << "\t-2  - tri, quad, polygon " << std::endl
+    << "\t-3  - tet, hex, prism, etc. " << std::endl
+    ;
+}
+
+void print_help( const char* name )
+{
+  std::cout << 
+  " This program can be used to convert between mesh file\n"
+  " formats, extract a subset of a mesh file to a separate\n"
+  " file, or both.  The type of file to write is determined\n"
+  " from the file extension (e.g. \".vtk\") protion of the\n"
+  " output file name.\n"
+  " \n"
+  " While MOAB strives to export and import all data from\n"
+  " each supported file format, most file formats do\n"
+  " not support MOAB's entire data model.  Thus MOAB cannot\n"
+  " guarantee lossless conversion for any file formats\n"
+  " other than the native HDF5 representation.\n"
+  "\n";
+  
+  print_usage( name, std::cout );
+  exit(0);
+}
+
+void usage_error( const char* name )
+{
+  print_usage( name, std::cerr );
+  exit(USAGE_ERROR);
+} 
+
+
+void list_formats( MBInterface* );
+bool parse_id_list( const char* string, std::set<int>&  );
+void print_id_list( const char*, std::ostream& stream, const std::set<int>& list );
+void reset_times();
+void write_times( std::ostream& stream );
+void remove_entities_from_sets( MBInterface* gMB, MBRange& dead_entities, MBRange& empty_sets );
+void remove_from_vector( std::vector<MBEntityHandle>& vect, const MBRange& ents_to_remove );
+bool make_opts_string( std::vector<std::string> options, std::string& result );
+
+int main(int argc, char* argv[])
+{
+  MBInterface* gMB;
+  MBErrorCode result;
+  MBRange range;
+
+  int proc_id = 0;
+  gMB = new MBCore();
+
+  bool append_rank = false;
+  int i, dim;
+  bool dims[4] = {false, false, false, false};
+  const char* format = NULL; // output file format
+  const char* in = NULL;    // input file name
+  const char* out = NULL;   // output file name
+  bool verbose = false;
+  std::set<int> geom[4], mesh[3];       // user-specified IDs 
+  std::vector<MBEntityHandle> set_list; // list of user-specified sets to write
+  std::vector<std::string> write_opts, read_opts;
+  const char* const mesh_tag_names[] = { DIRICHLET_SET_TAG_NAME,
+                                         NEUMANN_SET_TAG_NAME,
+                                         MATERIAL_SET_TAG_NAME };
+  const char* const geom_names[] = { "VERTEX",
+                                     "CURVE",
+                                     "SURFACE",
+                                     "VOLUME" };
+  
+    // scan arguments
+  bool do_flag = true;
+  bool print_times = false;
+  bool generate[] = { false, false, false };
+  bool pval;
+  for (i = 1; i < argc; i++)
+  {
+    if (!argv[i][0])
+      usage_error(argv[0]);
+      
+    if (do_flag && argv[i][0] == '-')
+    {
+      if (!argv[i][1] || argv[i][2])
+        usage_error(argv[0]);
+      
+      switch ( argv[i][1] )
+      {
+          // do flag arguments:
+        case '-': do_flag = false;       break;
+        case 'g': verbose = true;        break;
+        case 't': print_times = true;    break;
+        case 'A':                        break;
+        case 'h': 
+        case 'H': print_help( argv[0] ); break;
+        case 'l': list_formats( gMB );   break;
+#ifdef USE_MPI
+        case 'P': append_rank = true;    break;
+#endif
+        case '1': case '2': case '3':
+          dims[argv[i][1] - '0'] = true; break;
+          // do options that require additional args:
+        default: 
+          ++i;
+          if (i == argc || argv[i][0] == '-') {
+            std::cerr << "Expected argument following " << argv[i-1] << std::endl;
+            usage_error(argv[0]);
+          }
+          if (argv[i-1][1] == 'I') {
+            int dim = atoi( argv[i] );
+            if (dim < 1 || dim > 2) {
+              std::cerr << "Invalid dimension value following -I" << std::endl;
+              usage_error(argv[0]);
+            }
+            generate[dim] = true;
+            continue;
+          }
+          pval = false;
+          switch ( argv[i-1][1] )
+          {
+            case 'a': 
+              read_opts.push_back( std::string("SAT_FILE=") + argv[i] );
+              pval = true;
+              break;
+            case 'f': format = argv[i]; pval = true;              break;
+            case 'o': write_opts.push_back(argv[i]); pval = true; break;
+            case 'O':  read_opts.push_back(argv[i]); pval = true; break;
+            case 'v': pval = parse_id_list( argv[i], geom[3] ); break;
+            case 's': pval = parse_id_list( argv[i], geom[2] ); break;
+            case 'c': pval = parse_id_list( argv[i], geom[1] ); break;
+            case 'V': pval = parse_id_list( argv[i], geom[0] ); break;
+            case 'm': pval = parse_id_list( argv[i], mesh[2] ); break;
+            case 'n': pval = parse_id_list( argv[i], mesh[1] ); break;
+            case 'd': pval = parse_id_list( argv[i], mesh[0] ); break;
+            default: std::cerr << "Invalid option: " << argv[i] << std::endl;
+          }
+          
+          if (!pval) {
+            std::cerr << "Invalid flag or flag value: " << argv[i-1] << " " << argv[i] << std::endl;
+            usage_error(argv[0]);
+          }
+      }
+    }
+      // do file names
+    else if (!in)
+      in = argv[i];
+    else if (!out)
+      out = argv[i];
+    else  { // too many file names
+      std::cerr << "Unexpexed argument: " << argv[i] << std::endl;
+      usage_error(argv[0]);
+    }
+  }
+  if (!in || !out) {
+    std::cerr << "No output file name specified." << std::endl;
+    usage_error(argv[0]);
+  }
+    
+  std::string mod_out;
+  if (append_rank) {
+    char buffer[16];
+    sprintf(buffer,".%d",proc_id);
+    mod_out = out;
+    mod_out += buffer;
+    out = mod_out.c_str();
+  }
+
+    // construct options string from individual options
+  std::string read_options, write_options;
+  if (!make_opts_string(  read_opts,  read_options ) ||
+      !make_opts_string( write_opts, write_options ))
+    return USAGE_ERROR;
+  
+  
+    // Read the input file.
+  reset_times();
+  MBEntityHandle read_meshset;
+  result = gMB->load_file( in, read_meshset, read_options.c_str() );
+  if (MB_SUCCESS != result)
+  { 
+    std::cerr << "Failed to load \"" << in << "\"." << std::endl;
+    std::cerr  << "Error code: " << gMB->get_error_string(result) << " (" << result << ")" << std::endl;
+    std::string message;
+    if (MB_SUCCESS == gMB->get_last_error(message) && !message.empty())
+      std::cerr << "Error message: " << message << std::endl;
+    return READ_ERROR;
+  }
+  std::cerr << "Read \"" << in << "\"" << std::endl;
+  if (print_times) write_times( std::cerr );
+  
+    // Determine if the user has specified any geometry sets to write
+  bool have_geom = false;
+  for (dim = 0; dim <= 3; ++dim)
+  {
+    if (!geom[dim].empty())
+      have_geom = true;
+    if (verbose)
+      print_id_list( geom_names[dim], std::cout, geom[dim] );
+  }
+  
+    // True if the user has specified any sets to write
+  bool have_sets = have_geom;
+  
+    // Get geometry tags
+  MBTag dim_tag, id_tag;
+  if (have_geom) 
+  {
+    int size;
+    result = gMB->tag_get_handle( GLOBAL_ID_TAG_NAME, id_tag );
+    if (MB_SUCCESS != result) 
+    {
+      std::cerr << "No ID tag defined."  << std::endl;
+      have_geom = false;
+    }
+    else
+    {
+      result = gMB->tag_get_size( id_tag, size );
+      if (MB_SUCCESS != result || size != sizeof(int))
+      {
+        std::cerr << "ID tag is invalid." << std::endl;
+        have_geom = false;
+      }
+    }
+    result = gMB->tag_get_handle( GEOM_DIMENSION_TAG_NAME, dim_tag );
+    if (MB_SUCCESS != result) 
+    {
+      std::cerr << "No geometry tag defined."  << std::endl;
+      have_geom = false;
+    }
+    else
+    {
+      result = gMB->tag_get_size( dim_tag, size );
+      if (MB_SUCCESS != result || size != sizeof(int))
+      {
+        std::cerr << "Geometry tag is invalid." << std::endl;
+        have_geom = false;
+      }
+    }
+  }
+  
+    // Get geometry sets
+  if ( have_geom ) 
+  {
+    int id_val;
+    MBTag tags[] = { id_tag, dim_tag };
+    const void* vals[] = { &id_val, &dim };
+    for (dim = 0; dim <= 3; ++dim) 
+    {
+      int init_count = set_list.size();
+      for (std::set<int>::iterator iter = geom[dim].begin(); iter != geom[dim].end(); ++iter) 
+      {
+        id_val = *iter;
+        range.clear();
+        result = gMB->get_entities_by_type_and_tag( 0, MBENTITYSET, tags, vals, 2, range );
+        if (MB_SUCCESS != result || range.empty()) 
+        {
+          range.clear();
+          std::cerr << geom_names[dim] << " " << id_val << " not found.\n";
+        }
+        std::copy( range.begin(), range.end(), std::back_inserter(set_list) );
+      }
+      
+      if (verbose)
+        std::cout << "Found " << (set_list.size()-init_count) << ' '
+                  << geom_names[dim] << " sets" << std::endl;
+    }
+  }
+  
+    // Get mesh groupings
+  for (i = 0; i < 3; ++i) 
+  {
+    if (verbose)
+      print_id_list( mesh_tag_names[i], std::cout, mesh[i] );
+    
+    if (mesh[i].empty())
+      continue;
+    have_sets = true;
+    
+      // Get tag
+    MBTag tag;
+    result = gMB->tag_get_handle( mesh_tag_names[i], tag );
+    if (MB_SUCCESS != result) 
+    {
+      std::cerr << "Tag not found: " << mesh_tag_names[i] << std::endl;
+      continue;
+    }
+    int size;
+    result = gMB->tag_get_size( tag, size );
+    if (MB_SUCCESS != result || size != sizeof(int))
+    {
+      std::cerr << "Tag invalid: " << mesh_tag_names[i] << std::endl;
+      continue;
+    }
+
+      // get entity sets
+    int init_count = set_list.size();
+    for (std::set<int>::iterator iter = mesh[i].begin(); iter != mesh[i].end(); ++iter) 
+    {
+      range.clear();
+      const void* vals[] = { &*iter };
+      result = gMB->get_entities_by_type_and_tag( 0, MBENTITYSET, &tag, vals, 1, range );
+      if (MB_SUCCESS != result || range.empty()) 
+      {
+        range.clear();
+        std::cerr << mesh_tag_names[i] << " " << *iter << " not found.\n";
+      }
+      std::copy( range.begin(), range.end(), std::back_inserter(set_list) );
+    }
+      
+    if (verbose)
+      std::cout << "Found " << (set_list.size()-init_count) << ' '
+                << mesh_tag_names[i] << " sets" << std::endl;
+  }
+  
+    // Check if output is limited to certain dimensions of elements
+  bool bydim = false;
+  for (dim = 1; dim < 4; ++dim)
+    if (dims[dim])
+      bydim = true;
+  
+    // Check conflicting input
+  if (bydim) {
+    if (generate[1] && !dims[1]) {
+      std::cerr << "Warning: Request to generate 1D internal entities but not export them." << std::endl;
+      generate[1] = false;
+    } 
+     if (generate[2] && !dims[2]) {
+      std::cerr << "Warning: Request to generate 2D internal entities but not export them." << std::endl;
+      generate[2] = false;
+    } 
+  }
+ 
+    // Generate any internal entities
+  if (generate[1] || generate[2]) {
+    MBEntityHandle all_mesh = 0;
+    const MBEntityHandle* sets = &all_mesh;
+    int num_sets = 1;
+    if (have_sets) {
+      num_sets = set_list.size();
+      sets = &set_list[0];
+    }
+    for (i = 0; i < num_sets; ++i) {
+      MBRange dim3, dim2, adj;
+      gMB->get_entities_by_dimension( sets[i], 3, dim3, true );
+      if (generate[1]) {
+        gMB->get_entities_by_dimension( sets[i], 2, dim2, true );
+        gMB->get_adjacencies( dim3, 1, true, adj, MBInterface::UNION );
+        gMB->get_adjacencies( dim2, 1, true, adj, MBInterface::UNION );
+      }
+      if (generate[2]) {
+        gMB->get_adjacencies( dim3, 2, true, adj, MBInterface::UNION );
+      }
+      if (sets[i])
+        gMB->add_entities( sets[i], adj );
+    }
+  }
+      
+    // Delete any entities not of the dimensions to be exported
+  if (bydim) {
+      // Get list of dead elements
+    MBRange dead_entities , tmp_range;
+    for (dim = 1; dim <= 3; ++dim) {
+      if (dims[dim])
+        continue;
+      gMB->get_entities_by_dimension(0, dim, tmp_range );
+      dead_entities.merge( tmp_range );
+    }
+      // Remove dead entities from all sets, and add all 
+      // empty sets to list of dead entities.
+    MBRange empty_sets;
+    remove_entities_from_sets( gMB, dead_entities, empty_sets );
+    while (!empty_sets.empty()) {
+      if (!set_list.empty())
+        remove_from_vector( set_list, empty_sets );
+      dead_entities.merge( empty_sets );
+      MBRange tmp_range;
+      remove_entities_from_sets( gMB, empty_sets, tmp_range );
+      empty_sets = tmp_range.subtract( dead_entities );
+    }
+      // Destroy dead entities
+    result = gMB->delete_entities( dead_entities );
+  }
+  
+    // If user specified sets to write, but none were found, exit.
+  if (have_sets && set_list.empty())
+  {
+    std::cerr << "Nothing to write." << std::endl;
+    return ENT_NOT_FOUND;
+  }
+  
+  if (verbose)
+  {
+    if (have_sets)
+      std::cout << "Found " << set_list.size() 
+              << " specified sets to write (total)." << std::endl;  
+    else
+      std::cout << "No sets specifed.  Writing entire mesh." << std::endl; 
+  }  
+  
+    // Write the output file
+  reset_times();
+  if (have_sets) 
+    result = gMB->write_file( out, format, write_options.c_str(), &set_list[0], set_list.size() );
+  else
+    result = gMB->write_file( out, format, write_options.c_str() );
+  if (MB_SUCCESS != result)
+  { 
+    std::cerr << "Failed to write \"" << out << "\"." << std::endl; 
+    std::cerr  << "Error code: " << gMB->get_error_string(result) << " (" << result << ")" << std::endl;
+    std::string message;
+    if (MB_SUCCESS == gMB->get_last_error(message) && !message.empty())
+      std::cerr << "Error message: " << message << std::endl;
+    return WRITE_ERROR;
+  }
+  std::cerr << "Wrote \"" << out << "\"" << std::endl;
+  if (print_times) write_times( std::cerr );
+
+#ifdef USE_MPI
+  MPI_Finalize();
+#endif
+  return 0;
+}
+
+bool parse_id_list( const char* string, std::set<int>& results )
+{
+  bool okay = true;
+  char* mystr = strdup( string );
+  for (const char* ptr = strtok(mystr, ","); ptr; ptr = strtok(0,","))
+  {
+    char* endptr;
+    long val = strtol( ptr, &endptr, 0 );
+    if (endptr == ptr || val <= 0) {
+      std::cerr << "Not a valid id: " << ptr << std::endl;
+      okay = false;
+      break;
+    }
+    
+    long val2 = val;
+    if (*endptr == '-') {
+      const char* sptr = endptr+1;
+      val2 = strtol( sptr, &endptr, 0 );
+      if (endptr == sptr || val2 <= 0) {
+        std::cerr << "Not a valid id: " << sptr << std::endl;
+        okay = false;
+        break;
+      }
+      if (val2 < val) {
+        std::cerr << "Invalid id range: " << ptr << std::endl;
+        okay = false;
+        break;
+      }
+    }
+    
+    if (*endptr) {
+      std::cerr << "Unexpected character: " << *endptr << std::endl;
+      okay = false;
+      break;
+    }
+    
+    for (; val <= val2; ++val)
+      if (!results.insert( (int)val ).second) 
+        std::cerr << "Warning: duplicate Id: " << val << std::endl;
+
+  }
+  
+  free( mystr );
+  return okay;    
+}
+
+void print_id_list( const char* head, std::ostream& stream, const std::set<int>& list )
+{
+  stream << head << ": ";
+  
+  if (list.empty())
+  {
+    stream << "(none)" << std::endl;
+    return;
+  }
+  
+  int start, prev;
+  std::set<int>::const_iterator iter = list.begin();
+  start = prev = *(iter++);
+  for (;;)
+  {
+    if (iter == list.end() || *iter != 1+prev) {
+      stream << start;
+      if (prev != start)
+        stream << '-' << prev;
+      if (iter == list.end())
+        break;
+      stream << ", ";
+      start = *iter;
+    }
+    prev = *(iter++);
+  }
+  
+  stream << std::endl;
+}
+    
+    
+
+
+void print_time( int clk_per_sec, const char* prefix, clock_t ticks, std::ostream& stream )
+{
+  ticks *= clk_per_sec/100;
+  clock_t centi = ticks % 100;
+  clock_t seconds = ticks / 100;
+  if (seconds < 120)
+  {
+    stream << prefix << (ticks / 100) << "." << centi << "s" << std::endl;
+  }
+  else
+  {
+    clock_t minutes = (seconds / 60) % 60;
+    clock_t hours = (seconds / 3600);
+    seconds %= 60;
+    if (hours)
+      stream << hours << "h";
+    if (minutes)
+      stream << minutes << "m";
+    if (seconds || centi)
+      stream << seconds << "." << centi << "s";
+    stream << " (" << (ticks/100) << "." << centi << "s)" << std::endl;
+  }
+}
+
+clock_t usr_time, sys_time, abs_time;
+
+#ifdef WIN32
+
+void reset_times() 
+{
+  abs_time = clock();
+}
+
+
+void write_times( std::ostream& stream ) 
+{
+  clock_t abs_tm = clock();
+  print_time( CLOCKS_PER_SEC, "  ", abs_tm - abs_time, stream );
+  abs_time = abs_tm;
+}
+
+#else
+
+void reset_times()
+{
+  tms timebuf;
+  abs_time = times( &timebuf );
+  usr_time = timebuf.tms_utime;
+  sys_time = timebuf.tms_stime;
+}
+
+void write_times( std::ostream& stream )
+{
+  clock_t usr_tm, sys_tm, abs_tm;
+  tms timebuf;
+  abs_tm = times( &timebuf );
+  usr_tm = timebuf.tms_utime;
+  sys_tm = timebuf.tms_stime;
+  print_time( sysconf(_SC_CLK_TCK), "  real:   ", abs_tm - abs_time, stream );
+  print_time( sysconf(_SC_CLK_TCK), "  user:   ", usr_tm - usr_time, stream );
+  print_time( sysconf(_SC_CLK_TCK), "  system: ", sys_tm - sys_time, stream );
+  abs_time = abs_tm;
+  usr_time = usr_tm;
+  sys_time = sys_tm;
+}
+
+#endif
+
+bool make_opts_string( std::vector<std::string> options, std::string& opts )
+{
+  opts.clear();
+  if (options.empty())
+    return true;
+
+    // choose a separator character
+  std::vector<std::string>::const_iterator i;
+  char separator = '\0';
+  const char* alt_separators = ";+,:\t\n";
+  for (const char* sep_ptr = alt_separators; *sep_ptr; ++sep_ptr) {
+    bool seen = false;
+    for (i = options.begin(); i != options.end(); ++i)
+      if (i->find( *sep_ptr, 0 ) != std::string::npos) {
+        seen = true;
+        break;
+      }
+    if (!seen) {
+      separator = *sep_ptr;
+      break;
+    }
+  }
+  if (!separator) {
+    std::cerr << "Error: cannot find separator character for options string" << std::endl;
+    return false;
+  }
+  if (separator != ';') {
+    opts = ";";
+    opts += separator;
+  }
+  
+    // concatenate options
+  i = options.begin();
+  opts += *i;
+  for (++i; i != options.end(); ++i) {
+    opts += separator;
+    opts += *i;
+  }
+
+  return true;
+}
+
+
+void list_formats( MBInterface* gMB )
+{
+  const char iface_name[] = "MBReaderWriterSet";
+  MBErrorCode err;
+  void* void_ptr = 0;
+  MBReaderWriterSet* set;
+  MBReaderWriterSet::iterator i;
+  std::ostream& str = std::cout;
+    
+    // get MBReaderWriterSet
+  err = gMB->query_interface( iface_name, &void_ptr );
+  if (err != MB_SUCCESS || !void_ptr) {
+    std::cerr << "Internal error:  Interface \"" << iface_name 
+              << "\" not available.\n";
+    exit(OTHER_ERROR);
+  }
+  set = (MBReaderWriterSet*)void_ptr;
+  
+    // get field with for format description
+  size_t w = 0;
+  for (i = set->begin(); i != set->end(); ++i)
+    if (i->description().length() > w)
+      w = i->description().length();
+  
+    // write table header
+  str << "Format  " << std::setw(w) << std::left << "Description"
+      << "  Read  Write  File Name Suffixes\n"
+      << "------  " << std::setw(w) << std::setfill('-') << "" << std::setfill(' ')
+      << "  ----  -----  ------------------\n";
+      
+    // write table data
+  for (i = set->begin(); i != set->end(); ++i)
+  {
+    std::vector<std::string> ext;
+    i->get_extensions( ext );
+    str << std::setw(6) << i->name() << "  " 
+        << std::setw(w) << std::left << i->description() << "  "
+        << (i->have_reader() ?  " yes" :  "  no") << "  "
+        << (i->have_writer() ? "  yes" : "   no") << " ";
+    for (std::vector<std::string>::iterator j = ext.begin(); j != ext.end(); ++j)
+      str << " " << *j;
+    str << std::endl;
+  }
+  str << std::endl;
+  
+  gMB->release_interface( iface_name, void_ptr );
+  exit(0);
+}
+
+void remove_entities_from_sets( MBInterface* gMB, MBRange& dead_entities, MBRange& empty_sets )
+{
+  empty_sets.clear();
+  MBRange sets;
+  gMB->get_entities_by_type( 0, MBENTITYSET, sets );
+  for (MBRange::iterator i = sets.begin(); i != sets.end(); ++i) {
+    MBRange set_contents;
+    gMB->get_entities_by_handle( *i, set_contents, false );
+    set_contents = set_contents.intersect( dead_entities );
+    gMB->remove_entities( *i, set_contents );
+    set_contents.clear();
+    gMB->get_entities_by_handle( *i, set_contents, false );
+    if (set_contents.empty())
+      empty_sets.insert( *i );
+  }
+}
+
+void remove_from_vector( std::vector<MBEntityHandle>& vect, const MBRange& ents_to_remove )
+{
+  MBRange::const_iterator i;
+  std::vector<MBEntityHandle>::iterator j;
+  for (i = ents_to_remove.begin(); i != ents_to_remove.end(); ++i) {
+    j = std::find( vect.begin(), vect.end(), *i );
+    if (j != vect.end())
+      vect.erase( j );
+  }
+}


Property changes on: MOAB/trunk/tools/convert.cpp
___________________________________________________________________
Name: svn:keywords
   + Author Date Id Revision
Name: svn:mergeinfo
   + 
Name: svn:eol-style
   + native

Copied: MOAB/trunk/tools/gsets.cc (from rev 2644, MOAB/trunk/tools/gsets/gsets.cc)
===================================================================
--- MOAB/trunk/tools/gsets.cc	                        (rev 0)
+++ MOAB/trunk/tools/gsets.cc	2009-02-24 16:35:31 UTC (rev 2653)
@@ -0,0 +1,284 @@
+#include <iostream>
+#include <stdlib.h>
+#include "MBRange.hpp"
+#include "MBCore.hpp"
+#include "MBTagConventions.hpp"
+#include "GeomTopoTool.hpp"
+
+MBTag geomTag = 0;
+MBTag blockTag = 0;
+MBTag sideTag = 0;
+MBTag nodeTag = 0;
+MBTag nameTag = 0;
+MBTag idTag = 0;
+bool printAnonSets = false;
+bool printSVSense = false;
+
+MBCore mb;
+GeomTopoTool geomTool(&mb);
+
+void usage( const char* name, bool brief = true ) {
+  std::ostream& str = brief ? std::cerr : std::cout;
+  if (!brief)
+   str << name << ": A tool to export entity set parent/child relations" << std::endl
+       << "      for use as input to graphviz" << std::endl;
+  str << "Usage: " << name << " [-a | [-g] [-m] [-n] ] <input_file>" << std::endl
+      << "       " << name << " -h" << std::endl;
+  if (brief)
+    exit(1);
+  str << "  The default behavior is equivalent to \"-gmn\"." << std::endl
+      << "  If any of the following options are used to specify which " << std::endl
+      << "  sets to output, then there are no defaults.  Only the " << std::endl
+      << "  indicated sets will be output." << std::endl
+      << "  -a  : write all sets (default is only geom, mesh, and named)" << std::endl
+      << "  -g  : write geometric topology sets" << std::endl
+      << "  -m  : write material sets and boundary condition sets" << std::endl
+      << "  -n  : write named sets" << std::endl
+      << "  -s  : label surface-volume links with sense" << std::endl
+      << "  The default link behavior is to both child links" << std::endl
+      << "  and containment with solid lines." << std::endl
+      << "  -P  : do not write child links" << std::endl
+      << "  -p  : write child links with dashed lines" << std::endl
+      << "  -C  : do not write containment links" << std::endl
+      << "  -c  : write containment links with dashed lines" << std::endl;
+  exit(0);
+}
+
+enum Link { NONE = 0, SOLID, DASHED };
+void write_dot( Link contained, Link children );
+void dot_nodes( std::ostream& s, MBRange& sets_out );
+void dot_children( std::ostream& s, const MBRange& sets, bool dashed );
+void dot_contained( std::ostream& s, const MBRange& sets, bool dashed );
+
+int main( int argc, char* argv[] )
+{
+  Link children = SOLID, contained = SOLID;
+  bool printGeomSets = true;
+  bool printMeshSets = true;
+  bool printNamedSets = true;
+  const char* input_file = 0;
+  bool geom_flag = false, mesh_flag = false, name_flag = false, all_flag = false;
+  bool no_more_flags = false;
+  for (int i = 1; i < argc; ++i) {
+    if (no_more_flags || argv[i][0] != '-') {
+      if (input_file) 
+        usage(argv[0]);
+      input_file = argv[i];
+      continue;
+    }
+    for (int j = 1; argv[i][j]; ++j) {
+      switch (argv[i][j]) {
+        case 'a': all_flag = true; break;
+        case 'g': geom_flag = true; break;
+        case 'm': mesh_flag = true; break;
+        case 'n': name_flag = true; break;
+        case 's': printSVSense = true; break;
+        case 'P': children = NONE; break;
+        case 'p': children = DASHED; break;
+        case 'C': contained = NONE; break;
+        case 'c': contained = DASHED; break;
+        case '-': no_more_flags = true; break;
+        case 'h': usage(argv[0], false);
+        default:
+          std::cerr << "Unknown flag: '" << argv[i][j] << "'" << std::endl;
+          usage(argv[0]);
+      }
+    }
+  }
+  
+  if (!input_file) {
+    std::cerr << "No input file specified." << std::endl;
+    usage(argv[0]);
+  }
+  
+  if (all_flag) {
+    printGeomSets = printMeshSets = printNamedSets = printAnonSets = true;
+  }
+  else if (geom_flag || mesh_flag || name_flag) {
+    printGeomSets = geom_flag;
+    printMeshSets = mesh_flag;
+    printNamedSets = name_flag;
+  }
+  
+  if (MB_SUCCESS != mb.load_mesh( input_file )) {
+    std::cerr << input_file << ": file read failed." << std::endl;
+    return 1;
+  }
+
+  MBTag t;
+  if (printGeomSets) {
+    if (MB_SUCCESS == mb.tag_get_handle( GEOM_DIMENSION_TAG_NAME, t )) {
+      geomTag = t;
+    }
+  }
+  if (printMeshSets) {
+    if (MB_SUCCESS == mb.tag_get_handle( MATERIAL_SET_TAG_NAME, t )) {
+      blockTag = t;
+    }
+    if (MB_SUCCESS == mb.tag_get_handle( DIRICHLET_SET_TAG_NAME, t )) {
+      nodeTag = t;
+    }
+    if (MB_SUCCESS == mb.tag_get_handle( NEUMANN_SET_TAG_NAME, t )) {
+      sideTag = t;
+    }
+  }
+  if (printNamedSets) {
+    if (MB_SUCCESS == mb.tag_get_handle( NAME_TAG_NAME, t )) {
+      nameTag = t;
+    }
+  }
+  if (MB_SUCCESS == mb.tag_get_handle( GLOBAL_ID_TAG_NAME, t ))
+    idTag = t;
+  
+  write_dot( contained, children );
+  return 0;
+}
+      
+  
+void write_dot( Link contained, Link children )
+{
+  MBRange sets;
+  std::cout << "digraph {" << std::endl;
+  dot_nodes( std::cout, sets );
+  std::cout << std::endl;
+  if (contained)
+    dot_contained( std::cout, sets, contained == DASHED );
+  if (children)
+    dot_children( std::cout, sets, children == DASHED );
+  std::cout << "}" << std::endl;
+}
+
+void dot_get_sets( MBRange& curr_sets, MBRange& result_sets, 
+                   MBTag tag, void* tag_val = 0 )
+{
+  if (!tag)
+    return;
+    
+  result_sets.clear();
+  mb.get_entities_by_type_and_tag( 0, MBENTITYSET, &tag, &tag_val, 1, result_sets );
+  result_sets = result_sets.subtract( curr_sets );
+  curr_sets.merge( result_sets );
+}
+
+void dot_write_node( std::ostream& s, MBEntityHandle h, 
+                     const char* label, int* id = 0 )
+{
+  s << 's' << mb.id_from_handle(h) << " [label = \"" << label;
+  if (id)
+    s << ' ' << *id;
+  s << "\"];" << std::endl;
+}
+
+void dot_write_id_nodes( std::ostream& s,
+                         const MBRange& entites,
+                         MBTag id_tag,
+                         const char* type_name )
+{
+  int id;
+  for (MBRange::iterator i = entites.begin(); i != entites.end(); ++i)
+    if (MB_SUCCESS == mb.tag_get_data( id_tag, &*i, 1, &id )) 
+      dot_write_node( s, *i, type_name, &id );
+}
+
+void dot_nodes( std::ostream& s, MBRange& sets )
+{
+  MBRange vol_sets, surf_sets, curv_sets, vert_sets;
+  MBRange block_sets, side_sets, node_sets;
+  MBRange named_sets, other_sets;
+
+  dot_get_sets( sets, named_sets, nameTag );
+    
+  int dim = 3;
+  dot_get_sets( sets, vol_sets, geomTag, &dim );
+  dim = 2;
+  dot_get_sets( sets, surf_sets, geomTag, &dim );
+  dim = 1;
+  dot_get_sets( sets, curv_sets, geomTag, &dim );
+  dim = 0;
+  dot_get_sets( sets, vert_sets, geomTag, &dim );
+  
+  dot_get_sets( sets, block_sets, blockTag );
+  dot_get_sets( sets, side_sets, sideTag );
+  dot_get_sets( sets, node_sets, nodeTag );
+
+  if (printAnonSets) {
+    mb.get_entities_by_type( 0, MBENTITYSET, other_sets );
+    MBRange xsect = other_sets.subtract( sets );
+    sets.swap(other_sets);
+    other_sets.swap(xsect);
+  }
+  
+  dot_write_id_nodes( s, vol_sets , idTag, "Volume"  );
+  dot_write_id_nodes( s, surf_sets, idTag, "Surface" );
+  dot_write_id_nodes( s, curv_sets, idTag, "Curve"   );
+  dot_write_id_nodes( s, vert_sets, idTag, "Vertex"  );
+  dot_write_id_nodes( s, block_sets, blockTag, "Block" );
+  dot_write_id_nodes( s, side_sets, sideTag, "Neumann Set" );
+  dot_write_id_nodes( s, node_sets, nodeTag, "Dirichlet Set" );
+  
+  MBRange::iterator i;
+  char name[NAME_TAG_SIZE+1];
+  for (i = named_sets.begin(); i != named_sets.end(); ++i) {
+    if (MB_SUCCESS == mb.tag_get_data( nameTag, &*i, 1, name )) {
+      name[NAME_TAG_SIZE] = '\0';
+      dot_write_node( s, *i, name );
+    }
+  }
+  for (i = other_sets.begin(); i != other_sets.end(); ++i) {
+    int id = mb.id_from_handle(*i);
+    dot_write_node( s, *i, "EntitySet ", &id );
+  }
+}
+
+void dot_down_link( std::ostream& s,
+                    MBEntityHandle parent,
+                    MBEntityHandle child,
+                    bool dashed,
+                    const char* label = 0 )
+{
+  s << 's' << mb.id_from_handle(parent) << " -> "
+    << 's' << mb.id_from_handle(child);
+  if (dashed && label) 
+    s << " [style = dashed label = \"" << label << "\"]";
+  else if (dashed)
+    s << " [style = dashed]";
+  else if (label)
+    s << " [label = \"" << label << "\"]";
+  s << ';' << std::endl;
+}
+
+
+void dot_children( std::ostream& s, 
+                   const MBRange& sets,
+                   bool dashed )
+{
+  bool forward;
+  const char *fstr = "forward", *rstr = "reverse";
+  for (MBRange::iterator i = sets.begin(); i != sets.end(); ++i) {
+    MBRange parents;
+    mb.get_parent_meshsets( *i, parents );
+    parents = parents.intersect( sets );
+    
+    for (MBRange::iterator j = parents.begin(); j != parents.end(); ++j) {
+      const char* linklabel = 0;
+      if (printSVSense && MB_SUCCESS == geomTool.get_sense( *i, *j, forward ))
+        linklabel = forward ? fstr : rstr;
+      dot_down_link( s, *j, *i, dashed, linklabel);
+    }
+  }
+}
+
+
+void dot_contained( std::ostream& s, 
+                    const MBRange& sets,
+                    bool dashed )
+{
+  for (MBRange::iterator i = sets.begin(); i != sets.end(); ++i) {
+    MBRange contained;
+    mb.get_entities_by_type(*i, MBENTITYSET, contained );
+    contained = contained.intersect( sets );
+    
+    for (MBRange::iterator j = contained.begin(); j != contained.end(); ++j)
+      dot_down_link( s, *i, *j, dashed );
+  }
+}


Property changes on: MOAB/trunk/tools/gsets.cc
___________________________________________________________________
Name: svn:mergeinfo
   + 

Copied: MOAB/trunk/tools/main.cpp (from rev 2644, MOAB/trunk/tools/spheredecomp/main.cpp)
===================================================================
--- MOAB/trunk/tools/main.cpp	                        (rev 0)
+++ MOAB/trunk/tools/main.cpp	2009-02-24 16:35:31 UTC (rev 2653)
@@ -0,0 +1,52 @@
+/*
+ * Sphere decomp tool.  Meshes a group of spheres and the interstices between with
+ * hex elements, by triangulating the vertices corresponding to sphere centers
+ * and subdividing those tets.  For a description of the subdivision template used,
+ * see comments in the subdivide_tet function below.
+ */
+
+#include "MBCore.hpp"
+#include "SphereDecomp.hpp"
+#include <iostream>
+
+const char *SPHERE_RADII_TAG_NAME = "SPHERE_RADII";
+
+#define RR if (MB_SUCCESS != result) return result
+
+int main(int argc, char *argv[]) 
+{
+  if (argc < 3) {
+    std::cout << "Usage: " << argv[0] << " <input_mesh> <output_mesh>" << std::endl;
+    return 0;
+  }
+  
+    // create MOAB
+  MBInterface *mbImpl = new MBCore();
+  
+    // read in mesh
+  MBErrorCode result = mbImpl->load_mesh(argv[1]); 
+  if (MB_SUCCESS != result) {
+    std::cout << "Problems loading mesh." << std::endl;
+    return 1;
+  }
+
+  MBTag sphere_radii_tag = 0;
+  double dum_val = 0.1;
+  result = mbImpl->tag_create(SPHERE_RADII_TAG_NAME, sizeof(double), 
+                              MB_TAG_DENSE, MB_TYPE_DOUBLE, sphere_radii_tag, &dum_val); 
+  if (MB_SUCCESS != result && MB_ALREADY_ALLOCATED != result) {
+    std::cout << "Problem allocating SPHERE_RADII tag." << std::endl;
+    return 1;
+  }
+
+  SphereDecomp sd(mbImpl);
+
+  MBEntityHandle this_set = 0;
+  result = sd.build_sphere_mesh(SPHERE_RADII_TAG_NAME, &this_set); RR;
+  
+    // write mesh
+  result = mbImpl->write_mesh(argv[2], &this_set, 1); RR;
+  
+  return 0;
+}
+


Property changes on: MOAB/trunk/tools/main.cpp
___________________________________________________________________
Name: svn:keywords
   + Author Date Id Revision
Name: svn:mergeinfo
   + 
Name: svn:eol-style
   + native

Copied: MOAB/trunk/tools/makeops.cpp (from rev 2644, MOAB/trunk/tools/hexmodops/makeops.cpp)
===================================================================
--- MOAB/trunk/tools/makeops.cpp	                        (rev 0)
+++ MOAB/trunk/tools/makeops.cpp	2009-02-24 16:35:31 UTC (rev 2653)
@@ -0,0 +1,438 @@
+/*
+ * Program to make hex modification operation meshes
+ *
+ */
+
+#include "MBCore.hpp"
+#include "MBRange.hpp"
+#include <iostream>
+
+MBInterface *gMB = NULL;
+
+MBErrorCode make_atomic_pillow();
+MBErrorCode make_face_shrink();
+MBErrorCode make_face_open_collapse();
+MBErrorCode make_chord_push();
+MBErrorCode make_triple_chord_push();
+MBErrorCode make_triple_hex_push();
+
+enum OperationType {ATOMIC_PILLOW = 0, 
+                    FACE_OPEN_COLLAPSE, 
+                    FACE_SHRINK, 
+                    CHORD_PUSH, 
+                    TRIPLE_CHORD_PUSH, 
+                    TRIPLE_HEX_PUSH,
+                    UNDEFINED};
+
+const char *OperationNames[] = {"atomic_pillow", 
+                                "face_open_collapse", 
+                                "face_shrink", 
+                                "chord_push", 
+                                "triple_chord_push", 
+                                "triple_hex_push",
+                                "undefined"};
+
+int main(int argc, char **argv) 
+{
+  gMB = new MBCore();
+  const char *extensions[] = 
+    {
+      ".g",
+      ".h5m",
+      ".vtk"
+    };
+  int file_exten = 1;
+  
+  std::vector<OperationType> op_types;
+
+  if (argc < 2) {
+    std::cout << "Usage: " << argv[0] 
+              << " [-h5m] [-vtk] {-ap | -foc | -fs | -cp | -tcp | -thp}" 
+              << std::endl;
+    return 1;
+  }
+    
+  int current_arg = 1;
+  while (current_arg < argc) {
+    if (!strcmp("-g", argv[current_arg])) file_exten = 0;
+    else if (!strcmp("-h5m", argv[current_arg])) file_exten = 1;
+    else if (!strcmp("-vtk", argv[current_arg])) file_exten = 2;
+    else if (!strcmp("-ap", argv[current_arg])) 
+      op_types.push_back(ATOMIC_PILLOW);
+    else if (!strcmp("-foc", argv[current_arg])) 
+      op_types.push_back(FACE_OPEN_COLLAPSE);
+    else if (!strcmp("-fs", argv[current_arg])) 
+      op_types.push_back(FACE_SHRINK);
+    else if (!strcmp("-cp", argv[current_arg])) 
+      op_types.push_back(CHORD_PUSH);
+    else if (!strcmp("-tcp", argv[current_arg])) 
+      op_types.push_back(TRIPLE_CHORD_PUSH);
+    else if (!strcmp("-thp", argv[current_arg])) 
+      op_types.push_back(TRIPLE_HEX_PUSH);
+    current_arg++;
+  }
+  
+  MBErrorCode result = MB_SUCCESS, tmp_result = MB_FAILURE;
+
+  for (std::vector<OperationType>::iterator vit = op_types.begin(); 
+       vit != op_types.end(); vit++) {
+    if (*vit == ATOMIC_PILLOW) {
+      tmp_result = make_atomic_pillow();
+    }
+    else if (*vit == FACE_OPEN_COLLAPSE) {
+      tmp_result = make_face_open_collapse();
+    }
+    else if (*vit == CHORD_PUSH) {
+      tmp_result = make_chord_push();
+    }
+    else if (*vit == TRIPLE_CHORD_PUSH) {
+      tmp_result = make_triple_chord_push();
+    }
+
+    else if (*vit == TRIPLE_HEX_PUSH) {
+      tmp_result = make_triple_hex_push();
+    }
+    else if (*vit == FACE_SHRINK) {
+      tmp_result = make_face_shrink();
+    }
+    else {
+      std::cout << "Operation undefined." << std::endl;
+      return 1;
+    }
+  
+    // now write to a file
+    std::string filename(OperationNames[*vit]);
+    filename.append(extensions[file_exten]);
+    tmp_result = gMB->write_mesh(filename.c_str());
+    if (MB_SUCCESS != tmp_result) result = tmp_result;
+  }
+    
+  return (result == MB_SUCCESS ? 0 : 1);
+}
+
+MBErrorCode make_atomic_pillow() 
+{
+    // make atomic pillow configuration
+    // make all vertices
+  double vtx_coord[] = 
+    {
+      1.0, 1.0, 1.0, 
+      1.0, 0.0, 1.0, 
+      0.0, 0.0, 1.0, 
+      0.0, 1.0, 1.0, 
+      .75, .75, 1.0, 
+      .75, .25, 1.0, 
+      .25, .25, 1.0, 
+      .25, .75, 1.0
+    };
+
+  int connect[] = {
+    0, 1, 2, 3, 4, 5, 6, 7,
+    4, 5, 6, 7, 0, 1, 2, 3
+  };
+
+  MBErrorCode result;
+  MBEntityHandle vtx_handles[8];
+  
+  for (int i = 0; i < 8; i++) {
+    result = gMB->create_vertex(&vtx_coord[3*i], vtx_handles[i]);
+    if (MB_SUCCESS != result) return MB_FAILURE;
+  }
+  
+  MBEntityHandle conn[8], elems[4];
+
+    // make the two hexes
+  for (int i = 0; i < 8; i++)
+    conn[i] = vtx_handles[connect[i]];
+  result = gMB->create_element(MBHEX, conn, 8, elems[0]);
+  if (MB_SUCCESS != result) return MB_FAILURE;
+
+  for (int i = 0; i < 8; i++)
+    conn[i] = vtx_handles[connect[8+i]];
+  result = gMB->create_element(MBHEX, conn, 8, elems[1]);
+  if (MB_SUCCESS != result) return MB_FAILURE;
+
+    // make one of the end quads explicitly and bind to the first hex
+  for (int i = 0; i < 4; i++)
+    conn[i] = vtx_handles[connect[i]];
+  result = gMB->create_element(MBQUAD, conn, 4, elems[2]);
+  if (MB_SUCCESS != result) return MB_FAILURE;
+  
+  result = gMB->add_adjacencies(elems[2], elems, 1, false);
+  if (MB_SUCCESS != result) return MB_FAILURE;
+
+    // now the other one
+  result = gMB->create_element(MBQUAD, conn, 4, elems[3]);
+  if (MB_SUCCESS != result) return MB_FAILURE;
+  
+  result = gMB->add_adjacencies(elems[3], &elems[1], 1, false);
+  if (MB_SUCCESS != result) return MB_FAILURE;
+
+  return MB_SUCCESS;
+}
+
+MBErrorCode make_face_shrink() 
+{
+    // make face shrink configuration
+    // make all vertices
+  double vtx_coord[] = 
+    {
+      1.0, 1.0, 0.0, 
+      1.0, 0.0, 0.0, 
+      0.0, 0.0, 0.0, 
+      0.0, 1.0, 0.0, 
+      1.0, 1.0, 1.0, 
+      1.0, 0.0, 1.0, 
+      0.0, 0.0, 1.0, 
+      0.0, 1.0, 1.0, 
+      1.0, 1.0, 2.0, 
+      1.0, 0.0, 2.0, 
+      0.0, 0.0, 2.0, 
+      0.0, 1.0, 2.0, 
+      .75, .75, 1.0, 
+      .75, .25, 1.0, 
+      .25, .25, 1.0, 
+      .25, .75, 1.0
+    };
+
+  int connect[] = {
+    3, 7, 11, 15, 0, 4, 8, 12,
+    0, 4, 8, 12, 1, 5, 9, 13,
+    1, 5, 9, 13, 2, 6, 10, 14,
+    2, 6, 10, 14, 3, 7, 11, 15,
+    0, 3, 2, 1, 12, 15, 14, 13,
+    12, 15, 14, 13, 8, 11, 10, 9
+  };
+
+  MBErrorCode result;
+  MBEntityHandle vtx_handles[16];
+  
+  for (int i = 0; i < 16; i++) {
+    result = gMB->create_vertex(&vtx_coord[3*i], vtx_handles[i]);
+    if (MB_SUCCESS != result) return MB_FAILURE;
+  }
+  
+    // make all elements at once
+  MBEntityHandle conn[8], elems[6];
+
+  for (int j = 0; j < 6; j++) {
+    for (int i = 0; i < 8; i++)
+      conn[i] = vtx_handles[connect[j*8+i]];
+    
+    result = gMB->create_element(MBHEX, conn, 8, elems[j]);
+    if (MB_SUCCESS != result) return MB_FAILURE;
+  }
+  
+  return MB_SUCCESS;
+}
+
+MBErrorCode make_face_open_collapse() 
+{
+  return MB_FAILURE;
+}
+
+MBErrorCode make_chord_push() 
+{
+    // make chord push configuration
+    // make all vertices
+  double vtx_coord[] = 
+    {
+        // first layer
+      0.0, 0.0, 0.5,
+      0.0, 1.0, 0.0,
+      -1.0, 0.5, 0.0, 
+      -1.0, -0.5, 0.0,
+      0.0, -1.0, 0.0,
+      1.0, -0.5, 0.0,
+      1.0, 0.5, 0.0,
+        // second layer
+      0.0, 0.0, -1.5,
+      0.0, 1.0, -1.0,
+      -1.0, 0.5, -1.0, 
+      -1.0, -0.5, -1.0,
+      0.0, -1.0, -1.0,
+      1.0, -0.5, -1.0,
+      1.0, 0.5, -1.0,
+        // 2 extra vertices for chord push
+      0.0, -.333, 0.05,
+      0.0, -.667, 0.10
+    };
+
+  int connect[] = {
+      // 3 "normal" hexes first
+      // top hex
+    0, 2, 1, 6, 7, 9, 8, 13,
+      // bottom left
+    0, 4, 3, 2, 7, 11, 10, 9,
+      // bottom right
+    6, 5, 4, 0, 13, 12, 11, 7,
+      // front chord push hex
+    2, 0, 4, 3, 14, 6, 5, 15,
+      // back chord push hex
+    2, 14, 15, 3, 0, 6, 5, 4,
+      // front/rear quads a, b
+    2, 0, 4, 3, 6, 5, 4, 0,
+      // duplicate edges from chord push
+    0, 4,
+      // face between bottom 2 normal hexes (needed for explicit
+      // adjacency)
+    0, 4, 11, 7
+  };
+
+  MBErrorCode result;
+  MBEntityHandle vtx_handles[16];
+  
+  for (int i = 0; i < 16; i++) {
+    result = gMB->create_vertex(&vtx_coord[3*i], vtx_handles[i]);
+    if (MB_SUCCESS != result) return MB_FAILURE;
+  }
+  
+  MBEntityHandle conn[8], elems[12];
+
+    // make the five hexes
+  for (int i = 0; i < 5; i++) {
+    for (int j = 0; j < 8; j++)
+      conn[j] = vtx_handles[connect[8*i+j]];
+    result = gMB->create_element(MBHEX, conn, 8, elems[i]);
+    if (MB_SUCCESS != result) return MB_FAILURE;
+  }
+
+    // make the frontmost pair of quads and bind to the front degen hex
+  for (int i = 0; i < 2; i++) {
+    for (int j = 0; j < 4; j++)
+      conn[j] = vtx_handles[connect[40+4*i+j]];
+    result = gMB->create_element(MBQUAD, conn, 4, elems[5+i]);
+    if (MB_SUCCESS != result) return MB_FAILURE;
+  }
+  
+    // now the back pair
+  for (int i = 0; i < 2; i++) {
+    for (int j = 0; j < 4; j++)
+      conn[j] = vtx_handles[connect[40+4*i+j]];
+    result = gMB->create_element(MBQUAD, conn, 4, elems[7+i]);
+    if (MB_SUCCESS != result) return MB_FAILURE;
+  }
+
+    // make the duplicated edges explicitly too
+  for (int i = 0; i < 2; i++) {
+    for (int j = 0; j < 2; j++)
+      conn[j] = vtx_handles[connect[48+j]];
+    result = gMB->create_element(MBEDGE, conn, 2, elems[9+i]);
+    if (MB_SUCCESS != result) return MB_FAILURE;
+  }
+
+    // now the quad between the lower pair of hexes
+  for (int j = 0; j < 4; j++)
+    conn[j] = vtx_handles[connect[50+j]];
+  result = gMB->create_element(MBQUAD, conn, 4, elems[11]);
+  if (MB_SUCCESS != result) return MB_FAILURE;
+
+    // now set adjacencies explicitly
+    // front/rear duplicated edge to front/rear pair of quads
+  result = gMB->add_adjacencies(elems[9], &elems[5], 2, false);
+  if (MB_SUCCESS != result) return MB_FAILURE;
+  result = gMB->add_adjacencies(elems[10], &elems[7], 2, false);
+  if (MB_SUCCESS != result) return MB_FAILURE;
+
+    // rear duplicated edge to quad between lower pair of normal hexes
+  result = gMB->add_adjacencies(elems[10], &elems[11], 1, false);
+  if (MB_SUCCESS != result) return MB_FAILURE;
+
+    // front/rear duplicated edge to front/rear degen hex
+  result = gMB->add_adjacencies(elems[9], &elems[3], 1, false);
+  if (MB_SUCCESS != result) return MB_FAILURE;
+  result = gMB->add_adjacencies(elems[10], &elems[4], 1, false);
+  if (MB_SUCCESS != result) return MB_FAILURE;
+
+    // rear duplicated edge to normal hexes behind it
+  result = gMB->add_adjacencies(elems[10], &elems[1], 2, false);
+  if (MB_SUCCESS != result) return MB_FAILURE;
+
+    // front pair of quads to front degen hex
+  result = gMB->add_adjacencies(elems[5], &elems[3], 1, false);
+  if (MB_SUCCESS != result) return MB_FAILURE;
+  result = gMB->add_adjacencies(elems[6], &elems[3], 1, false);
+  if (MB_SUCCESS != result) return MB_FAILURE;
+
+    // rear pair of quads to rear degen hex
+  result = gMB->add_adjacencies(elems[7], &elems[4], 1, false);
+  if (MB_SUCCESS != result) return MB_FAILURE;
+  result = gMB->add_adjacencies(elems[8], &elems[4], 1, false);
+  if (MB_SUCCESS != result) return MB_FAILURE;
+
+    // rear pair of quads to normal hexes behind them
+  result = gMB->add_adjacencies(elems[7], &elems[1], 1, false);
+  if (MB_SUCCESS != result) return MB_FAILURE;
+  result = gMB->add_adjacencies(elems[8], &elems[2], 1, false);
+  if (MB_SUCCESS != result) return MB_FAILURE;
+
+  return MB_SUCCESS;
+}
+
+MBErrorCode make_triple_chord_push() 
+{
+    // make chord push configuration
+    // make all vertices
+  double vtx_coord[] = 
+    {
+        // first layer
+      0.0, 0.0, 0.5,
+      0.0, 1.0, 0.0,
+      -1.0, 0.5, 0.0, 
+      -1.0, -0.5, 0.0,
+      0.0, -1.0, 0.0,
+      1.0, -0.5, 0.0,
+      1.0, 0.5, 0.0,
+        // second layer
+      0.0, 0.0, -1.5,
+      0.0, 1.0, -1.0,
+      -1.0, 0.5, -1.0, 
+      -1.0, -0.5, -1.0,
+      0.0, -1.0, -1.0,
+      1.0, -0.5, -1.0,
+      1.0, 0.5, -1.0,
+        // 2 extra vertices in middle
+      0.0, 0.0, -0.25,
+      0.0, 0.0, 0.0
+    };
+
+  int connect[] = {
+      // 3 "normal" hexes first
+      // top hex
+    14, 2, 1, 6, 7, 9, 8, 13,
+      // bottom left
+    14, 4, 3, 2, 7, 11, 10, 9,
+      // bottom right
+    6, 5, 4, 14, 13, 12, 11, 7,
+      // front triple chord push hex
+    0, 4, 3, 2, 6, 5, 15, 1,
+      // back triple chord push hex
+    2, 1, 15, 3, 14, 6, 5, 4
+  };
+
+  MBErrorCode result;
+  MBEntityHandle vtx_handles[16];
+  
+  for (int i = 0; i < 16; i++) {
+    result = gMB->create_vertex(&vtx_coord[3*i], vtx_handles[i]);
+    if (MB_SUCCESS != result) return MB_FAILURE;
+  }
+  
+  MBEntityHandle conn[8], elems[12];
+
+    // make the five hexes
+  for (int i = 0; i < 5; i++) {
+    for (int j = 0; j < 8; j++)
+      conn[j] = vtx_handles[connect[8*i+j]];
+    result = gMB->create_element(MBHEX, conn, 8, elems[i]);
+    if (MB_SUCCESS != result) return MB_FAILURE;
+  }
+
+  return MB_SUCCESS;
+}
+
+MBErrorCode make_triple_hex_push() 
+{
+  return MB_FAILURE;
+}
+


Property changes on: MOAB/trunk/tools/makeops.cpp
___________________________________________________________________
Name: svn:keywords
   + Author Date Id Revision
Name: svn:mergeinfo
   + 
Name: svn:eol-style
   + native

Copied: MOAB/trunk/tools/mbconvert.man (from rev 2644, MOAB/trunk/tools/converter/mbconvert.man)
===================================================================
--- MOAB/trunk/tools/mbconvert.man	                        (rev 0)
+++ MOAB/trunk/tools/mbconvert.man	2009-02-24 16:35:31 UTC (rev 2653)
@@ -0,0 +1,81 @@
+.TH MBCONVERT 1 "September 2006" local
+.SH NAME
+mbconvert \- convert between file formats supported by MOAB
+.SH SYNOPSIS
+.B mbconvert [-h|-l]
+
+.B mbconvert
+.B [-a 
+.I sat_file
+.B |-A] [-t] [-g] [-v 
+.I vol_id_list
+.B ] [-s 
+.I surf_id_list
+.B ] [-c 
+.I curve_id_list
+.B ] [-V 
+.I vert_id_list
+.B ] [-m 
+.I block_id_list
+.B ] [-d 
+.I nodeset_id_list
+.B ] [-n 
+.I sideset_id_list
+.B ] [-1] [-2] [-3] 
+.I input_file output_file
+.SH DESCRIPTION
+.B mbconvert
+uses the MOAB library to translate between mesh file formats or
+to extract subsets of mesh files.  The type of the output file
+is determined from the file extension.  The 
+.B -l
+option can be used to list the file formats supported.
+
+The
+.I id_list
+passed to many of the subset options can contain either individual IDs 
+or ranges of IDs, separated by  a comma (',').  Ranges of IDs are 
+specified with a pair of values separated by a dash ('-').  An ID list
+may not contain spaces.  
+
+Any combination of subset options, including repetition of a singe option 
+with different ID lists may be specified.  The output will contain the
+union of all of the subset options.  If no subset options are specified
+the entire input mesh is written to the output file.
+
+.SH OPTIONS
+.IP -h
+Print help to stdout and exit.
+.IP -l
+List supported file formats to stdout.
+.IP "-a sat_file"
+File to store extracted geometry from .cub file.
+.IP -A
+Do not store extracted geometry from .cub file.
+.IP -t
+Print timing data for read and write operations to stdout.
+.IP -g
+Print verbose debugging and status information to stdout.
+.IP "-v idlist"
+List of IDs of geometric volumes for which the corresponding mesh is to be written.
+.IP "-s idlist"
+List of IDs of geometric surfaces for which the corresponding mesh is to be written.
+.IP "-c idlist"
+List of IDs of geometric curves for which the corresponding mesh is to be written.
+.IP "-V idlist"
+List of IDs of geometric vertices for which the corresponding mesh is to be written.
+.IP "-m idlist"
+List of IDs for material sets (blocks) to write.
+.IP "-d idlist"
+List of IDs for Dirchlet sets (nodesets) to write.
+.IP "-n idlist"
+List of IDs for Neumann sets (sidesets) to write.
+.IP "-1"
+Write all one-dimensional mesh entities (edges.)
+.IP "-2"
+Write all two-dimensional mesh entities (triangles,quads,polygons)
+.IP "-3"
+Write all three-dimensional mesh entities (tets,hexes,etc.)
+.SH FILES
+.SH ENVIRONMENT
+.SH DIAGNOSTICS


Property changes on: MOAB/trunk/tools/mbconvert.man
___________________________________________________________________
Name: svn:keywords
   + Author Date Id Revision
Name: svn:mergeinfo
   + 
Name: svn:eol-style
   + native

Copied: MOAB/trunk/tools/measure.cpp (from rev 2644, MOAB/trunk/tools/size/measure.cpp)
===================================================================
--- MOAB/trunk/tools/measure.cpp	                        (rev 0)
+++ MOAB/trunk/tools/measure.cpp	2009-02-24 16:35:31 UTC (rev 2653)
@@ -0,0 +1,200 @@
+/*
+ * Copyright (c) 2005 Lawrence Livermore National Laboratory under
+ * contract number B545069 with the University of Wisconsin - Madison.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <math.h>
+
+#include "measure.hpp"
+
+class CartVect {
+  private:
+    double coords[3];
+    
+  public:
+  
+    inline CartVect() {}
+    
+    inline CartVect( double x, double y, double z ) { set(x,y,z); }
+    
+    inline CartVect( const CartVect& other ) { set( other.coords); }
+    
+    inline void set( double x, double y, double z )
+      { coords[0] = x; coords[1] = y; coords[2] = z; }
+    
+    inline void set( const double* c )
+      { coords[0] = c[0]; coords[1] = c[1]; coords[2] = c[2]; }
+    
+    inline double x() const { return coords[0]; }
+    inline double y() const { return coords[1]; }
+    inline double z() const { return coords[2]; }
+  
+    inline CartVect& operator+=( const CartVect& other )
+    {
+      coords[0] += other.coords[0];
+      coords[1] += other.coords[1];
+      coords[2] += other.coords[2];
+      return *this;
+    }
+    
+    inline CartVect& operator-=( const CartVect& other )
+    {
+      coords[0] -= other.coords[0];
+      coords[1] -= other.coords[1];
+      coords[2] -= other.coords[2];
+      return *this;
+    }
+    
+    inline CartVect& operator*=( const CartVect& other );
+
+    inline double lensqr() const;
+    
+    inline double len() const;
+    
+    inline CartVect operator~( ) const;
+
+      
+    inline CartVect& operator*=( double a )
+    {
+      coords[0] *= a;
+      coords[1] *= a;
+      coords[2] *= a;
+      return *this;
+    }
+    
+    inline CartVect& operator/=( double a )
+    {
+      coords[0] /= a;
+      coords[1] /= a;
+      coords[2] /= a;
+      return *this;
+    }
+   
+    
+};
+
+inline CartVect operator+( const CartVect& v1, const CartVect& v2 )
+{
+  CartVect rval(v1);
+  rval += v2;
+  return rval;
+}
+
+inline CartVect operator-( const CartVect& v1, const CartVect& v2 )
+{
+  CartVect rval(v1);
+  rval -= v2;
+  return rval;
+}
+
+inline double operator%( const CartVect& v1, const CartVect& v2 )
+{
+  return v1.x() * v2.x() + v1.y() * v2.y() + v1.z() * v2.z();
+}
+
+inline CartVect operator*( const CartVect& v1, const CartVect& v2 )
+{
+  return CartVect( v1.y() * v2.z() - v1.z() * v2.y(),
+                   v1.z() * v2.x() - v1.x() * v2.z(),
+                   v1.x() * v2.y() - v1.y() * v2.x() );
+}
+
+inline CartVect CartVect::operator~() const
+{
+  double invlen = 1.0 / len();
+  return CartVect( invlen * x(), invlen * y(), invlen * z() );
+}
+     
+inline CartVect& CartVect::operator*=( const CartVect& other )
+      { return *this = *this * other; }
+
+inline double CartVect::lensqr() const
+      { return *this % *this; }
+    
+inline double CartVect::len() const
+      { return sqrt(lensqr()); }
+ 
+inline static double tet_volume( const CartVect& v0,
+                                 const CartVect& v1,
+                                 const CartVect& v2, 
+                                 const CartVect& v3 )
+{
+  return 1./6. * ( ((v1 - v0) * (v2 - v0)) % (v3 - v0) );
+}
+
+double edge_length( const double* start_vtx_coords,
+                    const double*   end_vtx_coords )
+{
+  const CartVect* start = reinterpret_cast<const CartVect*>(start_vtx_coords);
+  const CartVect*   end = reinterpret_cast<const CartVect*>(  end_vtx_coords);
+  return (*start - *end).len();
+}
+
+double measure( MBEntityType type,
+                int num_vertices,
+                const double* vertex_coordinates )
+{
+  const CartVect* coords = reinterpret_cast<const CartVect*>(vertex_coordinates);
+  switch( type )
+  {
+    case MBEDGE:
+      return (coords[0] - coords[1]).len();
+    case MBTRI:
+      return 0.5 * ((coords[1] - coords[0]) * (coords[2] - coords[0])).len();
+    case MBQUAD:
+      num_vertices = 4;
+    case MBPOLYGON:
+    {
+      CartVect mid(0,0,0);
+      for (int i = 0; i < num_vertices; ++i)
+        mid += coords[i];
+      mid /= num_vertices;
+      
+      double sum = 0.0;
+      for (int i = 0; i < num_vertices; ++i)
+      {
+        int j = (i+1)%num_vertices;
+        sum += ((mid - coords[i]) * (mid - coords[j])).len();
+      }
+      return 0.5 * sum;
+    }
+    case MBTET:
+      return tet_volume( coords[0], coords[1], coords[2], coords[3] ) ;
+    case MBPYRAMID:
+      return tet_volume( coords[0], coords[1], coords[2], coords[4] ) +
+             tet_volume( coords[0], coords[2], coords[3], coords[4] ) ;
+    case MBPRISM:
+      return tet_volume( coords[0], coords[1], coords[2], coords[5] ) +
+             tet_volume( coords[3], coords[4], coords[5], coords[0] ) +
+             tet_volume( coords[0], coords[1], coords[4], coords[5] ) ;
+    case MBHEX:
+      return tet_volume( coords[0], coords[1], coords[3], coords[4] ) +
+             tet_volume( coords[7], coords[3], coords[6], coords[4] ) +
+             tet_volume( coords[4], coords[5], coords[1], coords[6] ) +
+             tet_volume( coords[1], coords[6], coords[3], coords[4] ) +
+             tet_volume( coords[2], coords[6], coords[3], coords[1] ) ;
+    default:
+      return 0.0;
+  }
+}
+      


Property changes on: MOAB/trunk/tools/measure.cpp
___________________________________________________________________
Name: svn:keywords
   + Author Date Id Revision
Name: svn:mergeinfo
   + 
Name: svn:eol-style
   + native

Copied: MOAB/trunk/tools/measure.hpp (from rev 2644, MOAB/trunk/tools/size/measure.hpp)
===================================================================
--- MOAB/trunk/tools/measure.hpp	                        (rev 0)
+++ MOAB/trunk/tools/measure.hpp	2009-02-24 16:35:31 UTC (rev 2653)
@@ -0,0 +1,14 @@
+#ifndef MEASURE_HPP
+
+#include "MBCN.hpp"
+
+double edge_length( const double* start_vtx_coords,
+                    const double* end_vtx_coords );
+
+double measure( MBEntityType type,
+                int num_vertices,
+                const double* vertex_coordinatee );
+
+#endif
+
+                


Property changes on: MOAB/trunk/tools/measure.hpp
___________________________________________________________________
Name: svn:keywords
   + Author Date Id Revision
Name: svn:mergeinfo
   + 
Name: svn:eol-style
   + native

Copied: MOAB/trunk/tools/parse.cpp (from rev 2644, MOAB/trunk/tools/tagprop/parse.cpp)
===================================================================
--- MOAB/trunk/tools/parse.cpp	                        (rev 0)
+++ MOAB/trunk/tools/parse.cpp	2009-02-24 16:35:31 UTC (rev 2653)
@@ -0,0 +1,434 @@
+#include "parse.hpp"
+
+#include <iostream>
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+void tag_syntax( std::ostream& s )
+{
+  s << "Tags are specified as <name>=[value], where the tag value " << std::endl
+    << "is optional." << std::endl 
+    << std::endl
+    << "Values of integral types (INTEGER, BIT, and HANDLE) are " << std::endl
+    << "specified using standard C integer notation (a 0x prefix " << std::endl
+    << "for hexidecimal, 0 prefix for octal, and no prefix for " << std::endl
+    << "decimal.)  The value of an opaque tag is interpreted as " << std::endl
+    << "either a integral value or a character string. If the tag " << std::endl
+    << "value begins with the prefix 0x it will be interpreted as a " << std::endl
+    << "hexidecimal (base-16) number.  If the value does not begin " << std::endl
+    << "with the 0x prefix, it is interpreted as a character string." << std::endl
+    << "Characater strings will be padded with null characters as" << std::endl
+    << "necessary to fill the tag." << std::endl
+    << "Floating-point (real) values must be specified in base-10." << std::endl
+    << "C exponential notation (e.g. 1e-10) is accepted." << std::endl
+    << std::endl
+    << "If the tag is an array of integral or floating-point values " << std::endl
+    << "then the tag value must be specified as a comma-separated " << std::endl
+    << "list, with NO spaces." << std::endl
+    << std::endl
+    << "Tags are created with the syntax name=type:size[=default_value]." << std::endl
+    << "where type is one of {int,double,opaque,handle,bit} and size is " << std::endl
+    << "the number of values of the specified type, or the number of " << std::endl
+    << "bytes if the type is 'opaque',  A default value for the tag may " << std::endl
+    << "be specified." 
+    << std::endl;
+}
+
+  // Check endian-ness of platform.  Used when parsing numerical
+  // value for opaque tags.
+inline static bool is_platform_little_endian();
+
+  // Parse tag value from a string (vals).  The passed size
+  // is the size returned by MOAB (num values * sizeof(type)).
+void* parse_values( const char* vals, MBDataType type, int size );
+
+  // Parse opque tag data as either a hexidecimal number or
+  // an ASCII string.
+unsigned char* parse_opaque_value( const char* vals, int size );
+
+  // Parse one or more non-opaque tag values in a comma-separated list.
+  // The passed size is the size returned by MOAB (num values * sizeof(type)).
+template<typename T> T* parse_values_typed( const char* vals, int size );
+
+  // Template function to parse a single non-opaque tag value.
+  // Parses the value in the string pointed to by "iter" and updates
+  // iter to point passed the parsed value.  Returns zero on success.
+template<typename T> int parse_value( const char*& iter, T& value );
+
+  // Convert an ASCII hexidecimal digit to its numerical value.
+int hexdigit( char c );
+
+
+
+inline static bool is_platform_little_endian()
+{
+  static const unsigned int one = 1;
+  static const bool little = !*((char*)&one);
+  return little;
+}
+
+
+
+template<typename T> int parse_value( const char*& iter, T& value )
+{
+  char* endptr;
+  long parsed_val = strtol( iter, &endptr, 0 );
+  if (endptr == iter)
+    return 1;
+  iter = endptr; 
+  
+  value = (T)parsed_val;
+  if ((long)value != parsed_val)
+  {
+    std::cerr << "Value too large: " << iter << std::endl;
+    return 2;
+  }
+  
+  return 0;  
+}
+
+
+
+template<> int parse_value<double>( const char*& iter, double& value )
+{
+  char* endptr;
+  value = strtod( iter, &endptr );
+  if (endptr == iter)
+    return 1;
+  iter = endptr;
+  return 0;
+}
+
+
+
+int hexdigit( char c )
+{
+  if (c >= '0' && c <= '9')
+    return c - '0';
+  else if (c >= 'a' && c <= 'f')
+    return 10 + c - 'a';
+  else if (c >= 'A' && c <= 'F')
+    return 10 + c - 'A';
+  else
+    return -1;
+}
+
+
+
+unsigned char* parse_opaque_value( const char* vals, int size )
+{
+  unsigned char* data = (unsigned char*)malloc( size );
+  if (vals[0] && vals[0] == '0' && vals[1] && toupper(vals[1]) == 'X')
+  {
+    unsigned char *iter, *end;
+    int step;
+    if (is_platform_little_endian())
+    {
+      iter = data;
+      end = data + size;
+      step = 1;
+    }
+    else
+    {
+      iter = data + size - 1;
+      end = data - 1;
+      step = -1;
+    }
+    
+    const char* vals_end = vals + 1;
+    const char* vals_iter = vals + strlen(vals) - 1;
+    for ( ; iter != end; iter += step )
+    {
+      int less = 0;
+      int most = 0;
+      if (vals_iter != vals_end)
+      {
+        less = hexdigit( *vals_iter); 
+        --vals_iter;
+      }
+      if (vals_iter != vals_end)
+      {
+        most = hexdigit( *vals_iter);
+        --vals_iter;
+      }
+      if (less < 0 || most < 0)
+      {
+        std::cerr << "Error parsing hex value: " << vals << std::endl;
+        free (data);
+        return 0;
+      }
+      
+      *iter = 16 * most + less;
+    }
+  }
+  else
+  {
+    memset( data, 0, size );
+    strcpy( (char*)data, vals + 2 );
+  }
+  
+  return data;
+}
+
+
+
+template<typename T> T* parse_values_typed( const char* vals, int size )
+{
+  size_t tsize = sizeof(T);
+  if (size % tsize != 0) {
+    std::cerr << "Invalid tag size for type." << std::endl;
+    abort();
+  }
+  
+  int count = size / tsize;
+  if (!count)
+    return 0;
+    
+  T* data = (T*)malloc( size );
+  T* end = data + count;
+  if (parse_value<T>( vals, *data ))
+  {
+    free(data);
+    return 0;
+  }
+  for ( T* ptr = data + 1; ptr != end; ++ptr )
+  {
+    if (*vals != ',')
+    {
+      std::cerr << "Expected ',' separating tag values: " << vals << std::endl;
+      free( data );
+      return 0;
+    }
+    ++vals;
+    if (parse_value<T>( vals, *ptr ))
+    {
+      free(data);
+      return 0;
+    }
+  }
+  
+  return data;
+}
+
+
+
+void* parse_values( const char* vals, MBDataType type, int size )
+{
+  switch( type ) {
+    case MB_TYPE_OPAQUE:  return parse_opaque_value               ( vals, size );
+    case MB_TYPE_INTEGER: return parse_values_typed<          int>( vals, size );
+    case MB_TYPE_DOUBLE:  return parse_values_typed<       double>( vals, size );
+    case MB_TYPE_BIT:     return parse_values_typed<      bittype>( vals, size );
+    case MB_TYPE_HANDLE:  return parse_values_typed<MBEntityHandle>(vals, size );
+    default:
+      std::cerr << "Unknown tag data type: " << (int)type << std::endl;
+      return 0;
+  }
+}
+
+
+
+int parse_tag_spec( char* name, TagSpec& result, MBInterface* iface )
+{
+    //  Separate optional tag value from tag name
+  char* val = strrchr( name, '=' );
+  if (val)
+  {
+      // zero-length tag name>
+    if (val == name)
+    {
+      std::cerr << "Cannot create tag w/out name: " << name << std::endl;
+      return 1;
+    }
+    *val = '\0';
+    if (!*++val) // if name ends with an '=', set val to NULL.
+      val = 0;
+  } 
+  
+    // Get tag
+  MBErrorCode rval = iface->tag_get_handle( name, result.handle );
+  if (MB_TAG_NOT_FOUND == rval)
+  {
+    std::cerr << "Tag not found: " << name << std::endl;
+    return 2;
+  }
+  else if (MB_SUCCESS != rval)
+  {
+    std::cerr << "Error retrieving tag handle: " << name << std::endl;
+    return 3;
+  }
+  
+    // Parse tag value
+  result.value = 0;
+  if (val)
+  {
+    MBDataType type;
+    rval = iface->tag_get_data_type( result.handle, type );
+    if (MB_SUCCESS != rval)
+    {
+      std::cerr << "Error retrieving type for tag: " << name << std::endl;
+      return 3;
+    }
+    
+    int size;
+    rval = iface->tag_get_size( result.handle, size );
+    if (MB_SUCCESS != rval)
+    {
+      std::cerr << "Error retrieving size for tag: " << name << std::endl;
+      return 3;
+    }
+    
+    result.value = parse_values( val, type, size );
+    if (!result.value)
+      return 1;
+  }
+  
+  return 0;
+}
+
+  
+  
+
+int parse_tag_create( char* name, TagSpec& result, MBInterface* iface )
+{
+    // split at '=' signs
+  
+  char* eq1 = strrchr( name, '=' );
+  if (!eq1)
+  {
+    std::cerr << "Invalid tag specification: " << name << std::endl;
+    return 1;
+  }
+  *eq1 = '\0';
+  ++eq1;
+  char *type_str = eq1, *val = 0;
+
+  char* eq2 = strrchr( name, '=' );
+  if (eq2)
+  {
+    *eq2 = '\0';
+    ++eq2;
+    val = eq1;
+    type_str = eq2;
+  }
+  
+  if (*val == '\0')
+    val = 0;
+  
+    // parse type data
+  char* size_str = strchr( type_str, ':' );
+  if (!size_str)
+  {
+    std::cerr << "Invalid tag type specification: " << type_str << std::endl;
+    return 1;
+  }
+  *size_str = '\0';
+  ++size_str;
+  MBDataType type;
+  int tsize;
+  if (!strcmp(type_str,"int"))
+  {
+    type = MB_TYPE_INTEGER;
+    tsize = sizeof(int);
+  }
+  else if (!strcmp(type_str,"double"))
+  {
+    type = MB_TYPE_DOUBLE;
+    tsize = sizeof(double);
+  }
+  else if (!strcmp(type_str,"bit"))
+  {
+    type = MB_TYPE_BIT;
+    tsize = sizeof(bittype);
+  }
+  else if (!strcmp(type_str,"handle"))
+  {
+    type = MB_TYPE_HANDLE;
+    tsize = sizeof(MBEntityHandle);
+  }
+  else if (!strcmp(type_str,"opaque"))
+  {
+    type = MB_TYPE_OPAQUE;
+    tsize = 1;
+  }
+  else
+  {
+    std::cerr << "Invalid tag type specification: " << type_str << std::endl;
+    return 1;
+  }
+  char* end_ptr;
+  int count = (int)strtol(size_str, &end_ptr, 0);
+  if (!*size_str || *end_ptr || count < 1)
+  {
+    std::cerr << "Invalid tag size specification: " << size_str << std::endl;
+    return 1;
+  }
+  
+    // parse default value
+  result.value = 0;
+  if (val)
+  {
+    result.value = parse_values( val, type, count * tsize );
+    if (!result.value)
+      return 1;
+  }
+  
+    // check if tag exists
+  if (MB_SUCCESS == iface->tag_get_handle( name, result.handle ))
+  {
+      // make sure it matches
+    MBDataType etype;
+    int esize;
+    if (MB_SUCCESS != iface->tag_get_data_type( result.handle, etype ) ||
+        MB_SUCCESS != iface->tag_get_size( result.handle, esize ))
+    {
+      std::cerr << "Error accessing properties of tag: " << name << std::endl;
+      return 3;
+    }
+    
+    if (etype != type || esize != (count*tsize))
+    {
+      std::cerr << "Tag already exists with different type: " << name << std::endl;
+      return 1;
+    }
+    
+    std::vector<unsigned char> value(esize);
+    if (result.value)
+    {
+      MBErrorCode rval = iface->tag_get_default_value( result.handle, &value[0] );
+      if (rval != MB_ENTITY_NOT_FOUND && rval != MB_SUCCESS)
+      {
+        std::cerr << "Error checking default value of tag: " << name << std::endl;
+        return 3;
+      }
+      else if (rval == MB_ENTITY_NOT_FOUND || memcmp(&value[0], result.value, esize) )
+      {
+        std::cerr << "Tag already exists and default value doesn't match: " << name << std::endl;
+        return 1;
+      }
+    }
+  }
+  else
+  {
+    MBErrorCode rval = iface->tag_create( name, 
+                                   tsize*count, 
+                                   type == MB_TYPE_BIT ? MB_TAG_BIT : MB_TAG_SPARSE,
+                                   type,
+                                   result.handle,
+                                   result.value );
+    if (MB_SUCCESS != rval)
+    {
+      std::cerr << "Failed to create tag: " << name << std::endl;
+      return 3;
+    }
+  }
+  
+  return 0;
+}
+
+     
+  
+    
+  


Property changes on: MOAB/trunk/tools/parse.cpp
___________________________________________________________________
Name: svn:keywords
   + Author Date Id Revision
Name: svn:mergeinfo
   + 
Name: svn:eol-style
   + native

Copied: MOAB/trunk/tools/parse.hpp (from rev 2644, MOAB/trunk/tools/tagprop/parse.hpp)
===================================================================
--- MOAB/trunk/tools/parse.hpp	                        (rev 0)
+++ MOAB/trunk/tools/parse.hpp	2009-02-24 16:35:31 UTC (rev 2653)
@@ -0,0 +1,29 @@
+#ifndef PARSE_HPP
+#define PARSE_HPP
+
+#include <iosfwd>
+#include "MBInterface.hpp"
+
+// A structure containing the parsed CL tag specification.
+struct TagSpec
+{
+  MBTag handle;  // Tag handle
+  void* value;   // Tag value (malloc'd) or NULL if no value specified
+};
+
+// Parse a tag specified in the form: tagname=value,
+// where the "=value" portion is optional.  Returns 0 on
+// success.
+int parse_tag_spec( char* string, TagSpec& result, MBInterface* iface );
+
+// Parse a string specifying a new tag to create, and create it.
+int parse_tag_create( char* string, TagSpec& result, MBInterface* iface );
+
+// Print description of syntax accepted in the string passed to
+// parse_tag_spec.
+void tag_syntax( std::ostream& stream );
+
+// Data type used to store bit tags
+typedef unsigned char bittype;
+
+#endif


Property changes on: MOAB/trunk/tools/parse.hpp
___________________________________________________________________
Name: svn:keywords
   + Author Date Id Revision
Name: svn:mergeinfo
   + 
Name: svn:eol-style
   + native

Copied: MOAB/trunk/tools/propagate_tags.cpp (from rev 2644, MOAB/trunk/tools/tagprop/propagate_tags.cpp)
===================================================================
--- MOAB/trunk/tools/propagate_tags.cpp	                        (rev 0)
+++ MOAB/trunk/tools/propagate_tags.cpp	2009-02-24 16:35:31 UTC (rev 2653)
@@ -0,0 +1,385 @@
+/*
+ * Copyright (c) 2005 Lawrence Livermore National Laboratory under
+ * contract number B545069 with the University of Wisconsin - Madison.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <iostream>
+#include <vector>
+#include <cstdlib>
+
+#include "parse.hpp"
+
+#include "MBCore.hpp"
+#include "MBRange.hpp"
+#include "MBInterface.hpp"
+#define IS_BUILDING_MB
+#include "MBInternals.hpp"
+#undef IS_BUILDING_MB
+
+#define CALL(A,B) \
+  do { MBErrorCode _r = iface->A B ; \
+       if (MB_SUCCESS != _r) { \
+         std::cerr << #A << #B << " failed at " << __FILE__ << ":" << __LINE__ << std::endl; \
+         exit( 5 ); }\
+       } \
+  while (false)
+
+
+MBInterface* iface = 0;
+const char* exe_name = 0;
+
+void usage( bool error = true )
+{
+  std::ostream& s = error ? std::cerr : std::cout;
+  
+  s << "Usage: " << exe_name << " <options> <input_file> <output_file>" << std::endl
+    << "       " << exe_name << " -h" << std::endl
+    << "Options: " << std::endl
+    << "  -t <ident_tag>[=<value>]  " << std::endl
+    << "  -d <data_tag>[=<default>] " << std::endl
+    << "  -c <data_tag=type:size>[=defult] " << std::endl
+    << "  -w <write_tag>            " << std::endl
+    << "  -n|-e                     " << std::endl
+    << std::endl;
+  if (error) {
+    s << "Try '-h' for verbose help." << std::endl;
+    exit(1);
+  }
+  
+  s << "This utility will write tag data to a subset of the mesh entities " << std::endl
+    << "contained in a file.  The behavior is controlled by three main " << std::endl
+    << "properties:" << std::endl
+    << " 1) The ident_tag is used to identify sets of entities for which " << std::endl
+    << "    data will be stored on each contained element or node. The -n " << std::endl
+    << "    or -e flags can be used to restrict operation to only nodes or " << std::endl
+    << "    elements, respectively." << std::endl
+    << " 2) The data_tag is used to identify which value to write on to " << std::endl
+    << "    each entity.  This is a tag on the set containing the entities." << std::endl
+    << " 3) The write_tag is the name of the tag that the data is stored in " << std::endl
+    << "    on each mesh entity." << std::endl
+    << std::endl
+    << " -t : Specify an ident_tag.  If a value is specified, only those " << std::endl
+    << "      sets with the specified value are processed.  At least one " << std::endl
+    << "      ident_tag must be specified.  Multiple ident_tags may be " << std::endl
+    << "      specified, in which case any set that matches any of the " << std::endl
+    << "      specified ident_tags will be processed (logical OR)." << std::endl
+    << std::endl
+    << " -d : Specify the data_tag.  If multiple ident_tags are specified " << std::endl
+    << "      then the data_tag must be specified.  If only one ident_tag " << std::endl
+    << "      is specified then the data_tag specification is optional." << std::endl
+    << "      If no data_tag is specified, the value of the ident_tag " << std::endl
+    << "      will be used.  If a value is specified for the data_tag, " << std::endl
+    << "      then the specified value will be used for any set that " << std::endl
+    << "      doesn't have a value for the data_tag." << std::endl
+    << std::endl
+    << " -c : Similar to -d, except that the tag is created if it doesn't" << std::endl
+    << "      already exist.  If the tag is created, then all entities" << std::endl
+    << "      receive the specified default value for the tag.  In this " << std::endl
+    << "      case it is an error if no default value is specified." << std::endl
+    << std::endl
+    << " -w : Specify the tag to create and store values in on mesh " << std::endl
+    << "      entities.  If no write_tag is specified, the data_tag " << std::endl
+    << "      will be used." << std::endl
+    << std::endl
+    << " -n : Write tag data only on nodes (vertices)." << std::endl
+    << " -e : Write tag data only on elements." << std::endl
+    << std::endl
+    << "The syntax for specifying tag values is as follows: " 
+    << std::endl << std::endl;
+  tag_syntax(s);
+  s << std::endl;
+  exit(0);
+}
+
+void about( bool error = true )
+{
+  std::ostream& s = error ? std::cerr : std::cout;
+  s << "A utility to propogate tag values from the entity sets "
+       "containing mesh entities to the entities contained in "
+       "those sets." << std::endl << std::endl;
+  usage(error);
+}
+  
+void parse_error( const char* msg, const char* val = 0 )
+{
+  std::cerr << msg;
+  if (val)
+    std::cerr << ": " << val;
+  std::cerr << std::endl;
+  std::cerr << "Try '" << exe_name << " -h' for help" << std::endl;
+  exit(1);
+}
+
+int main( int argc, char* argv[] )
+{
+  MBCore mb_core;
+  exe_name = argv[0];
+  iface = &mb_core;
+
+  if (argc == 1)
+    about();
+    
+    // find file names 
+    // load input file before processing other options so
+    // tags are defined
+  const char* input_name = 0;
+  const char* output_name = 0;
+  for (int i = 1; i < argc; ++i)
+  {
+    if (argv[i][0] == '-')
+    {
+      switch (argv[i][1]) { 
+        case 't': case 'c': case 'd': case 'w': 
+          ++i; 
+          break;
+        case 'h': 
+          usage(false);
+          break;
+        default:
+          parse_error( "Invalid option", argv[i] );
+          break;
+      }
+    }
+    else if (!input_name)
+      input_name = argv[i];
+    else if (!output_name)
+      output_name = argv[i];
+    else 
+      parse_error( "Unexpected argument", argv[i] );
+  }
+  
+  if (!input_name)
+    parse_error( "No input file specified." );
+  if (!output_name)
+    parse_error( "No output file specified." );
+  
+    // Read the input file
+  if (MB_SUCCESS != iface->load_mesh( input_name ))
+  {
+    std::cerr << "Failed to read file: " << input_name << std::endl;
+    std::string message;
+    if (MB_SUCCESS == iface->get_last_error(message))
+      std::cerr << message << std::endl;
+    return 2;
+  }
+
+    
+    
+  bool nodes_spec = false;
+  bool elems_spec = false;
+  bool have_data_tag = false;
+  const char* write_tag_name = 0;
+  MBTag write_tag = 0;
+  TagSpec data_tag;
+  typedef std::vector<TagSpec> TagVect;
+  TagVect ident_tags;
+  int data_size = 0;
+  
+  for (int i = 1; i < argc; ++i)
+  {
+    if (argv[i] == input_name || argv[i] == output_name)
+      continue;
+    else if (!strcmp(argv[i],"-n"))
+      nodes_spec = true;
+    else if (!strcmp(argv[i], "-e"))
+      elems_spec = true;
+    else if (!argv[i][0])
+      usage();
+    else
+    {
+      char flag = argv[i][1];
+      if ((flag != 't' && flag != 'd' && flag != 'w' && flag != 'c') || argv[i][2])
+        parse_error( "Invalid argument", argv[i] );
+      
+      ++i;
+      if (i == argc)
+        parse_error( "Expected tag spec following option", argv[i-1] );
+    
+      if (flag == 'w')
+      {
+        if (write_tag_name)
+          parse_error( "Invalid argument", argv[i] );
+        write_tag_name = argv[i];
+      }
+      else if (flag == 'c')
+      {
+        TagSpec spec;
+        if (parse_tag_create( argv[i], spec, iface ))
+          parse_error( "Failed to parse tag spec", argv[i] );
+        
+        if (have_data_tag)
+          parse_error( "Invalid argument", argv[i] );
+        
+        data_tag = spec;
+        have_data_tag = true;
+      }         
+      else
+      {
+        TagSpec spec;
+        if (parse_tag_spec( argv[i], spec, iface))
+          parse_error("Failed to parse tag spec", argv[i] );
+        
+        if (flag == 'd')
+        {
+          if (have_data_tag)
+            parse_error( "Invalid argument", argv[i] );
+         
+          data_tag = spec;
+          have_data_tag = true;
+        }
+        else
+        {
+          ident_tags.push_back( spec );
+        }
+      }
+    }
+  } // for(args)
+  
+    // if neither, default to both
+  if (!nodes_spec && !elems_spec)
+    nodes_spec = elems_spec = true;
+  
+    // must have at least one identifying tag
+  if (ident_tags.empty())
+    parse_error ("At least one identifying tag must be specified.");
+  
+    // If data tag wasn't specified, use identifying tag for data
+  if (!have_data_tag)
+  {
+    if (ident_tags.size() > 1)
+      parse_error ("No data tag specified.");
+    data_tag.value = 0;
+    data_tag.handle = ident_tags[0].handle;
+  }
+  CALL( tag_get_size, (data_tag.handle, data_size) );
+  
+    // If write dat wasn't specified, use data tag 
+  if (!write_tag_name)
+  {
+    write_tag = data_tag.handle;
+  }
+    // If write tag was specified, if it exists its type
+    // msut match that of the data tag.  If it doesn't exist,
+    // create it.
+  else
+  {
+    MBDataType data_type;
+    CALL( tag_get_data_type, (data_tag.handle, data_type) );
+    
+    MBErrorCode rval = iface->tag_get_handle( write_tag_name, write_tag );
+    if (MB_FAILURE == rval)
+    {
+      std::cerr << "Unknown error retrieving handle for tag: " << write_tag_name << std::endl;
+      exit( 5 );
+    }
+    else if (MB_TAG_NOT_FOUND == rval)
+    {
+      CALL( tag_create, (write_tag_name, data_size, MB_TAG_SPARSE, data_type, write_tag, 0) );
+    }
+    else
+    {
+      MBDataType write_type;
+      int write_size;
+      CALL( tag_get_data_type, (write_tag, write_type) );
+      CALL( tag_get_size, (write_tag, write_size) );
+      
+      if (data_size != write_size ||
+          (write_type != MB_TYPE_OPAQUE &&
+           data_type != MB_TYPE_OPAQUE &&
+           write_type != data_type)
+          )
+      {
+        std::cerr << "Data and write tags have incompatible types." << std::endl;
+        exit( 3 );
+      }
+    }
+  }
+  
+  
+  /**************** Done processing input -- do actual work ****************/
+ 
+    // Get list of sets with identifying tags
+  MBRange sets, temp;
+  for (TagVect::iterator i = ident_tags.begin(); i != ident_tags.end(); ++i)
+  {
+    const void* value[] = { i->value };
+    CALL( get_entities_by_type_and_tag,
+          (0, MBENTITYSET, &i->handle, i->value ? value : 0, 1, temp) );
+    sets.merge( temp );
+  }
+  
+    // For each set, set tag on contained entities
+  std::vector<unsigned char> tag_data(data_size);
+  for (MBRange::iterator i = sets.begin(); i != sets.end(); ++i)
+  {
+      // Get tag value
+    MBErrorCode rval = iface->tag_get_data( data_tag.handle, &*i, 1, &tag_data[0] );
+    if (MB_TAG_NOT_FOUND == rval)
+    {
+      if (!data_tag.value)
+      {
+        std::cerr << "Data tag not set for entityset " 
+                  << iface->id_from_handle(*i) << std::endl;
+        continue;
+      }
+      memcpy( &tag_data[0], data_tag.value, data_size );
+    }
+    else if (MB_SUCCESS != rval)
+    {
+      CALL( tag_get_data, (data_tag.handle, &*i, 1, &tag_data[0]) );
+    }
+    
+      // Get entities
+    MBRange entities;
+    CALL( get_entities_by_handle, (*i, entities, true) );
+    int junk;
+    MBRange::iterator eb = entities.lower_bound( entities.begin(), 
+                                                 entities.end(),
+                                                 CREATE_HANDLE(MBEDGE,0,junk) );
+    MBRange::iterator j   = nodes_spec ? entities.begin() : eb;
+    MBRange::iterator end = elems_spec ? entities.end()   : eb;
+    for ( ; j != end; ++j)
+      CALL( tag_set_data, (write_tag, &*j, 1, &tag_data[0]) );
+  }
+  
+    // Write the output file
+  if (MB_SUCCESS != iface->write_mesh( output_name ))
+  {
+    std::cerr << "Failed to write file: " << output_name << std::endl;
+    std::string message;
+    if (MB_SUCCESS == iface->get_last_error(message))
+      std::cerr << message << std::endl;
+    return 2;
+  }
+  
+  return 0;
+}
+
+  
+  
+    
+    
+      
+  
+  
+  


Property changes on: MOAB/trunk/tools/propagate_tags.cpp
___________________________________________________________________
Name: svn:keywords
   + Author Date Id Revision
Name: svn:mergeinfo
   + 
Name: svn:eol-style
   + native

Copied: MOAB/trunk/tools/size.cpp (from rev 2644, MOAB/trunk/tools/size/size.cpp)
===================================================================
--- MOAB/trunk/tools/size.cpp	                        (rev 0)
+++ MOAB/trunk/tools/size.cpp	2009-02-24 16:35:31 UTC (rev 2653)
@@ -0,0 +1,487 @@
+/*
+ * Copyright (c) 2005 Lawrence Livermore National Laboratory under
+ * contract number B545069 with the University of Wisconsin - Madison.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <iostream>
+#include <stdlib.h>
+#include <vector>
+#include <string>
+#include <stdio.h>
+#if !defined(_MSC_VER) && !defined(__MINGW32__)
+#  include <unistd.h>
+#  include <termios.h>
+#  include <sys/ioctl.h>
+#endif
+#include <math.h>
+#include <assert.h>
+#include <float.h>
+
+#include "MBCore.hpp"
+#include "MBRange.hpp"
+#include "MBTagConventions.hpp"
+#include "MBInterface.hpp"
+
+#include "measure.hpp"
+
+void usage( const char* exe )
+{
+  std::cerr << "Usage: " << exe << " [-g] [-m] [-l] [-ll] <mesh file list>" << std::endl
+            << "-g  : print counts by geometric owner" << std::endl
+            << "-m  : print counts per block/boundary" << std::endl
+            << "-l  : print counts of mesh" << std::endl
+            << "-ll : verbose listing of every entity" << std::endl
+            ;
+  exit(1);
+}
+
+
+MBCore moab;
+
+
+struct stat_set 
+{
+  double sum;
+  double sqr;
+  double min; 
+  double max;
+  long count;
+  
+  inline stat_set() : sum(0), sqr(0), min(HUGE_VAL), max(0), count (0) {}
+  
+  inline void add( double val )
+  {
+    if (val < min)
+      min = val;
+    if (val > max)
+      max = val;
+    sum += val;
+    sqr += val*val;
+    ++count;
+  }
+  
+  inline void add( const stat_set& stats )
+  {
+    if (stats.min < min)
+      min = stats.min;
+    if (stats.max > max)
+      max = stats.max;
+    sum += stats.sum;
+    sqr += stats.sqr;
+    count += stats.count;
+  }
+  
+  inline void clear()
+  {
+    sum = sqr = max = count = 0;
+    min = HUGE_VAL;
+  }
+};
+
+struct set_stats {
+  stat_set stats[MBMAXTYPE];
+  stat_set edge_uses;
+  
+  void add( const set_stats& other )
+  {
+    for (int i = 0; i < MBMAXTYPE; ++i)
+      stats[i].add( other.stats[i] );
+    edge_uses.add( other.edge_uses );
+  }
+  
+  void clear()
+  {
+    for (int i = 0; i < MBMAXTYPE; ++i)
+      stats[i].clear();
+    edge_uses.clear();
+  }
+    
+};
+
+
+MBErrorCode gather_set_stats( MBEntityHandle set, set_stats& stats )
+{
+  MBErrorCode rval = MB_SUCCESS;
+  
+  int edge_vtx_idx[2];
+  std::vector<MBEntityHandle> conn;
+  std::vector<double> coords;
+  for (MBEntityType type = MBEDGE; type < MBENTITYSET; ++type)
+  {
+    int num_edges = MBCN::NumSubEntities( type, 1 );
+    
+    MBRange range;
+    rval = moab.get_entities_by_type( set, type, range, true );
+    if (MB_SUCCESS != rval) return rval;
+    for (MBRange::iterator i = range.begin(); i != range.end(); ++i)
+    {
+      rval = moab.get_connectivity( &*i, 1, conn, true );
+      if (MB_SUCCESS != rval) return rval;
+      coords.resize( 3*conn.size() );
+      rval = moab.get_coords( &conn[0], conn.size(), &coords[0] );
+      if (MB_SUCCESS != rval) return rval;
+      stats.stats[type].add( measure( type, conn.size(), &coords[0] ) );
+      
+      if (type != MBEDGE)
+      {
+        if (type == MBPOLYGON)
+          num_edges = conn.size();
+
+        for (int e = 0; e < num_edges; ++e)
+        {
+          MBCN::SubEntityVertexIndices( type, 1, e, edge_vtx_idx );
+          stats.edge_uses.add( edge_length( &coords[3*edge_vtx_idx[0]],
+                                            &coords[3*edge_vtx_idx[1]] ) );
+        }
+      }
+    }
+  }
+  return MB_SUCCESS;
+}
+
+const char* dashes( unsigned count )
+{
+  static std::vector<char> dashes;
+  dashes.clear();
+  dashes.resize( count + 1, '-' );
+  dashes[count] = '\0';
+  return &dashes[0];
+}
+
+void print_stats( set_stats& stats )
+{
+  const char* edge_use_name = "1D Side";
+  
+  bool have_some = stats.edge_uses.count > 0;
+  for (int i = 0; i < MBMAXTYPE; ++i)
+    if (stats.stats[i].count > 0)
+      have_some = true;
+  
+  if (!have_some)
+  {
+    std::cout << "NO MESH" << std::endl;
+    return;
+  }
+  
+    // get field widths
+  unsigned type_width = strlen( edge_use_name );
+  unsigned count_width = 5;
+  unsigned total_width = 5;
+  unsigned total_prec = 2;
+  unsigned precision = 5;
+  int total_log = -10000;
+  for (MBEntityType i = MBEDGE; i < MBMAXTYPE; ++i)
+  {
+    stat_set& s = (i == MBMAXTYPE) ? stats.edge_uses : stats.stats[i];
+
+    if (s.count == 0)
+      continue;
+    
+    unsigned len = strlen(MBCN::EntityTypeName(i));
+    if (len > type_width)
+      type_width = len;
+    
+    unsigned cw = (unsigned)(ceil(log10(s.count))) + 1;
+    if (cw > count_width)
+      count_width = cw;
+    
+    int tl = (unsigned)(ceil(log10(fabs(s.sum)))) + 1;
+    if (tl > total_log)
+      total_log = tl;
+  }
+  
+  if (total_log > (int)total_width)
+  {
+    total_width = 8;
+    total_prec = 2;
+  }
+  else if (total_log <= -(int)total_width)
+  {
+    total_width = -total_log + 5;
+    total_prec = 2;
+  }
+  else if (total_log < 1)
+  {
+    total_width = -total_log + 4;
+    total_prec = -total_log + 1;
+  }
+  else
+  {
+    total_width += 2;
+  }
+    
+  
+  // get terminal width
+  unsigned term_width = 80;
+#if !defined(_MSC_VER) && !defined(__MINGW32__)
+  struct winsize size;
+  if ( ioctl( fileno(stdout), TIOCGWINSZ, (char*)&size ) == 0 )
+    term_width = size.ws_col;
+  if (!term_width) term_width = 80;
+#endif
+  assert(term_width > 7 + type_width + count_width + total_width);
+  
+  term_width -= 7; // spaces
+  term_width -= type_width;
+  term_width -= count_width;
+  term_width -= total_width;
+  unsigned val_width = term_width / 5;
+  if (val_width < 8)
+    val_width = 8;
+  
+  printf( "%*s %*s %*s %*s %*s %*s %*s %*s\n",
+          type_width, "type",
+          count_width, "count",
+          total_width, "total",
+          val_width, "minimum",
+          val_width, "average",
+          val_width, "rms",
+          val_width, "maximum",
+          val_width, "std.dev." );
+  
+  printf( "%*s ", type_width, dashes(type_width) );
+  printf( "%*s ", count_width, dashes(count_width) );
+  printf( "%*s ", total_width, dashes(total_width) );
+  printf( "%*s ", val_width, dashes(val_width) );
+  printf( "%*s ", val_width, dashes(val_width) );
+  printf( "%*s ", val_width, dashes(val_width) );
+  printf( "%*s ", val_width, dashes(val_width) );
+  printf( "%*s\n", val_width, dashes(val_width) );
+  
+  for (MBEntityType i = MBEDGE; i <= MBMAXTYPE; ++i)
+  {
+    stat_set& s = (i == MBMAXTYPE) ? stats.edge_uses : stats.stats[i];
+    
+    if (s.count == 0)
+      continue;
+
+    double tmp_dbl = s.sqr / s.count - s.sum*s.sum / (double)s.count / (double)s.count;
+    if (tmp_dbl < 0.0) {
+      if (tmp_dbl < -100.0*DBL_EPSILON)
+        std::cout << "WARNING: stat values dubious, s^2 - sig_s = " << tmp_dbl << std::endl;
+      tmp_dbl = 0.0;
+    }
+    
+    printf( "%*s %*ld %*.*g %*.*g %*.*g %*.*g %*.*g %*.*g\n",
+            type_width, i == MBMAXTYPE ? edge_use_name : MBCN::EntityTypeName(i),
+            count_width, s.count,
+            total_width, total_prec, s.sum,
+            val_width, precision, s.min,
+            val_width, precision, s.sum / s.count,
+            val_width, precision, sqrt( s.sqr / s.count ),
+            val_width, precision, s.max,
+            val_width, precision,  
+            sqrt(tmp_dbl)
+          );
+  }
+  
+  puts("");
+}
+
+const char* geom_type_names[] = { "Vertex", "Curve", "Surface", "Volume" } ;
+const char* mesh_type_names[] = { "Nodeset", "Sideset", "Block" };
+const char* mesh_type_tags[] = { DIRICHLET_SET_TAG_NAME, NEUMANN_SET_TAG_NAME, MATERIAL_SET_TAG_NAME };
+
+int main( int argc, char* argv[] )
+{
+  bool geom_owners = false;
+  bool mesh_owners = false;
+  bool just_list = false;
+  bool just_list_basic = false;
+  std::vector<std::string> file_list;
+  set_stats total_stats, file_stats;
+  
+  for (int i = 1; i < argc; ++i)
+  {
+    if (!strcmp(argv[i],"-g"))
+      geom_owners = true;
+    else if (!strcmp(argv[i],"-ll"))
+      just_list = true;
+    else if (!strcmp(argv[i],"-l"))
+      just_list_basic = true;
+    else if (!strcmp(argv[i],"-m"))
+      mesh_owners = true;
+    else if (*argv[i] && *argv[i] != '-')
+      file_list.push_back( argv[i] );
+    else
+    {
+      std::cerr << "Invalid option: \"" << argv[i] << '"' << std::endl;
+      usage(argv[0]);
+    }
+  }
+  
+  if (file_list.empty())
+    usage(argv[0]);
+  
+  for (std::vector<std::string>::iterator f = file_list.begin(); 
+       f != file_list.end(); ++f)
+  {
+    printf("File %s:\n", f->c_str() );
+    if (MB_SUCCESS != moab.load_mesh( f->c_str(), 0, 0 ))
+    {
+      fprintf(stderr, "Error reading file: %s\n", f->c_str() );
+      return 1;
+    }
+
+    if (MB_SUCCESS != gather_set_stats( 0, file_stats ))
+    {
+      fprintf(stderr, "Error processing mesh from file: %s\n", f->c_str());
+      return 1;
+    }
+    
+    total_stats.add( file_stats );
+    print_stats( file_stats );
+    file_stats.clear();
+    
+    if (geom_owners)
+    {
+      MBRange entities;
+      MBTag dim_tag = 0, id_tag = 0;
+      MBErrorCode rval = moab.tag_get_handle( GEOM_DIMENSION_TAG_NAME, dim_tag );
+      if (MB_TAG_NOT_FOUND == rval) 
+      {
+        fprintf( stderr, "No geometry tag defined.\n" );
+      }
+      else if (MB_SUCCESS != rval)
+      {
+        fprintf( stderr, "Error retreiving geometry tag.\n");
+        return 2;
+      }
+      
+      rval = moab.tag_get_handle( GLOBAL_ID_TAG_NAME, id_tag );
+      if (MB_TAG_NOT_FOUND == rval) 
+      {
+        fprintf( stderr, "No ID tag defined.\n" );
+      }
+      else if (MB_SUCCESS != rval)
+      {
+        fprintf( stderr, "Error retreiving ID tag.\n");
+        return 2;
+      }
+      
+      if (dim_tag && id_tag)
+      {
+        if (MB_SUCCESS != moab.get_entities_by_type_and_tag( 0, 
+                                                        MBENTITYSET, 
+                                                        &dim_tag,
+                                                        0,
+                                                        1,
+                                                        entities ))
+        {
+          fprintf( stderr, "Error retreiving geometry entitities.\n" );
+        }
+      }
+      
+      if (entities.empty())
+      {
+        fprintf( stderr, "No geometry entities defined in file.\n" );
+      }
+      
+      for (MBRange::iterator i = entities.begin(); i != entities.end(); ++i)
+      {
+        int id = 0, dim = 0;
+        if (MB_SUCCESS != moab.tag_get_data( dim_tag, &*i, 1, &dim ) ||
+            MB_SUCCESS != moab.tag_get_data(  id_tag, &*i, 1,  &id ))
+        {
+          fprintf( stderr, "Error retreiving tag data for geometry entity.\n");
+          continue;
+        }
+        
+          // skip vertices
+        if (0 == dim)
+          continue;
+        
+        printf( "%s %d:\n", geom_type_names[dim], id );
+        if (MB_SUCCESS != gather_set_stats( *i, file_stats ))
+          fprintf(stderr, "Error processing mesh from file: %s\n", f->c_str());
+        else
+          print_stats( file_stats );
+        file_stats.clear();
+      }
+    }
+
+
+    if (mesh_owners)
+    {
+      for (int t = 0; t < 3; ++t)
+      {
+        MBRange entities;
+        MBTag tag = 0;
+        MBErrorCode rval = moab.tag_get_handle( mesh_type_tags[t], tag );
+        if (MB_TAG_NOT_FOUND == rval) 
+        {
+          continue;
+        }
+        else if (MB_SUCCESS != rval)
+        {
+          fprintf( stderr, "Error retreiving %s tag.\n", mesh_type_tags[t]);
+          return 2;
+        }
+      
+        if (MB_SUCCESS != moab.get_entities_by_type_and_tag( 0, 
+                                                        MBENTITYSET, 
+                                                        &tag,
+                                                        0,
+                                                        1,
+                                                        entities ))
+        {
+          fprintf( stderr, "Error retreiving %s entitities.\n", mesh_type_names[t] );
+          continue;
+        }
+      
+        for (MBRange::iterator i = entities.begin(); i != entities.end(); ++i)
+        {
+          int id = 0;
+          if (MB_SUCCESS != moab.tag_get_data( tag, &*i, 1, &id ))
+          {
+            fprintf( stderr, "Error retreiving tag data for %s entity.\n", mesh_type_names[t]);
+            continue;
+          }
+
+          printf( "%s %d:\n", mesh_type_names[t], id );
+          if (MB_SUCCESS != gather_set_stats( *i, file_stats ))
+            fprintf(stderr, "Error processing mesh from file: %s\n", f->c_str());
+          else
+            print_stats( file_stats );
+          file_stats.clear();
+        }
+      }
+    }
+
+    if (just_list) moab.list_entities(0, 1);
+   
+    if (just_list_basic) moab.list_entities(0, 0);
+    
+    moab.delete_mesh();
+  }
+  
+  if (file_list.size() > 1)
+  {
+    printf("Total for all files:\n");
+    print_stats( total_stats );
+  }
+  
+  return 0;
+}
+
+  


Property changes on: MOAB/trunk/tools/size.cpp
___________________________________________________________________
Name: svn:keywords
   + Author Date Id Revision
Name: svn:mergeinfo
   + 
Name: svn:eol-style
   + native

Copied: MOAB/trunk/tools/skin.cpp (from rev 2644, MOAB/trunk/tools/skin/skin.cpp)
===================================================================
--- MOAB/trunk/tools/skin.cpp	                        (rev 0)
+++ MOAB/trunk/tools/skin.cpp	2009-02-24 16:35:31 UTC (rev 2653)
@@ -0,0 +1,398 @@
+#include <iostream>
+#include <time.h>
+#include <vector>
+#include <cstdlib>
+#if !defined(_MSC_VER) && !defined(__MINGW32__)
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#endif
+#include <fcntl.h>
+#include "MBInterface.hpp"
+#include "MBTagConventions.hpp"
+#include "MBCore.hpp"
+#include "MBRange.hpp"
+#include "MBSkinner.hpp"
+
+void get_time_mem(double &tot_time, double &tot_mem);
+
+// Different platforms follow different conventions for usage
+#if !defined(_MSC_VER) && !defined(__MINGW32__)
+#include <sys/resource.h>
+#endif
+#ifdef SOLARIS
+extern "C" int getrusage(int, struct rusage *);
+#ifndef RUSAGE_SELF
+#include </usr/ucbinclude/sys/rusage.h>
+#endif
+#endif
+
+const char FIXED_TAG[] = "fixed"; 
+
+#define CHKERROR( A ) do { if (MB_SUCCESS != (A)) { \
+ std::cerr << "Internal error at line " << __LINE__ << std::endl; \
+ return 3; } } while(false)
+
+int main( int argc, char* argv[] )
+{
+  if (argc < 3)
+  {
+    std::cerr << "Usage: " << argv[0] 
+              << " [-b <block_num> [-b ...] ] [-p] [-s <sideset_num>] [-t] [-w]"
+              << " <input_file> [<output_file>]" << std::endl;
+    std::cerr << "Options: " << std::endl;
+    std::cerr << "-a : Compute skin using vert-elem adjacencies (more memory, less time)." << std::endl;
+    std::cerr << "-b <block_num> : Compute skin only for material set/block <block_num>." << std::endl;
+    std::cerr << "-p : Print cpu & memory performance." << std::endl;
+    std::cerr << "-s <sideset_num> : Put skin in neumann set/sideset <sideset_num>." << std::endl;
+    std::cerr << "-t : Set 'FIXED' tag on skin vertices." << std::endl;
+    std::cerr << "-w : Write out whole mesh (otherwise just writes skin)." << std::endl;
+    
+    return 1;
+  }
+
+  int i = 1;
+  std::vector<int> matsets;
+  int neuset_num = -1;
+  bool write_tag = false, write_whole_mesh = false;
+  bool print_perf = false;
+  bool use_vert_elem_adjs = false;
+  
+  while (i < argc) {
+    if (!strcmp(argv[i], "-a")) {
+      i++;
+      use_vert_elem_adjs = true;
+    }
+    else if (!strcmp(argv[i], "-b")) {
+      i++;
+      matsets.push_back(atoi(argv[i]));
+      i++;
+    }
+    else if (!strcmp(argv[i], "-p")) {
+      i++;
+      print_perf = true;
+    }
+    else if (!strcmp(argv[i], "-s")) {
+      i++;
+      neuset_num = atoi(argv[i]);
+      i++;
+    }
+    else if (!strcmp(argv[i], "-t")) {
+      i++;
+      write_tag = true;
+    }
+    
+    else if (!strcmp(argv[i], "-w")) {
+      i++;
+      write_whole_mesh = true;
+    }
+    else {
+      break;
+    }
+  }
+  
+  const char* input_file = argv[i++];
+  const char* output_file = NULL;
+  if (i < argc) 
+    output_file = argv[i++];
+  
+  MBErrorCode result;
+  MBCore mbimpl;
+  MBInterface* iface = &mbimpl;
+  
+  if (print_perf) {
+    double tmp_time1, tmp_mem1;
+    get_time_mem(tmp_time1, tmp_mem1);
+    std::cout << "Before reading: cpu time = " << tmp_time1 << ", memory = " 
+              << tmp_mem1/1.0e6 << "MB." << std::endl;
+  }
+
+    // read input file
+  result = iface->load_mesh( input_file );
+  if (MB_SUCCESS != result)
+  { 
+    std::cerr << "Failed to load \"" << input_file << "\"." << std::endl; 
+    return 2;
+  }
+  std::cerr << "Read \"" << input_file << "\"" << std::endl;
+  if (print_perf) {
+    double tmp_time2, tmp_mem2;
+    get_time_mem(tmp_time2, tmp_mem2);
+    std::cout << "After reading: cpu time = " << tmp_time2 << ", memory = " 
+              << tmp_mem2/1.0e6 << "MB." << std::endl;
+  }
+  
+    // get entities of largest dimension
+  int dim = 4;
+  MBRange entities;
+  while (entities.empty() && dim > 1)
+  {
+    dim--;
+    result = iface->get_entities_by_dimension( 0, dim, entities );
+    CHKERROR(result);
+  }
+
+  MBRange skin_ents;
+  MBTag matset_tag = 0, neuset_tag = 0;
+  result = iface->tag_get_handle(MATERIAL_SET_TAG_NAME, matset_tag);
+  result = iface->tag_get_handle(NEUMANN_SET_TAG_NAME, neuset_tag);
+
+  if (matsets.empty()) skin_ents = entities;
+  else {
+      // get all entities in the specified blocks
+    if (0 == matset_tag) {
+      std::cerr << "Couldn't find any material sets in this mesh." << std::endl;
+      return 1;
+    }
+    
+    for (std::vector<int>::iterator vit = matsets.begin(); vit != matsets.end(); vit++) {
+      int this_matset = *vit;
+      const void *this_matset_ptr = &this_matset;
+      MBRange this_range, ent_range;
+      result = iface->get_entities_by_type_and_tag(0, MBENTITYSET, &matset_tag,
+                                                    &this_matset_ptr, 1, this_range);
+      if (MB_SUCCESS != result) {
+        std::cerr << "Trouble getting material set #" << *vit << std::endl;
+        return 1;
+      }
+      else if (this_range.empty()) {
+        std::cerr << "Warning: couldn't find material set " << *vit << std::endl;
+        continue;
+      }
+      
+      result = iface->get_entities_by_dimension(*this_range.begin(), dim, ent_range, true);
+      if (MB_SUCCESS != result) continue;
+      skin_ents.merge(ent_range);
+    }
+  }
+  
+  if (skin_ents.empty()) {
+    std::cerr << "No entities for which to compute skin; exiting." << std::endl;
+    return 1;
+  }
+
+  if (use_vert_elem_adjs) {
+      // make a call which we know will generate vert-elem adjs
+    MBRange dum_range;
+    result = iface->get_adjacencies(&(*skin_ents.begin()), 1, 1, false,
+                                    dum_range);
+  }
+  
+  double tmp_time = 0.0, tmp_mem = 0.0;
+  if (print_perf) {
+    get_time_mem(tmp_time, tmp_mem);
+    std::cout << "Before skinning: cpu time = " << tmp_time << ", memory = " 
+              << tmp_mem/1.0e6 << "MB." << std::endl;
+  }
+
+    // skin the mesh
+  MBRange forward_lower, reverse_lower;
+  MBSkinner tool( iface );
+  result = tool.find_skin( skin_ents, forward_lower, reverse_lower );
+  MBRange boundary;
+  boundary.merge( forward_lower );
+  boundary.merge( reverse_lower );
+  if (MB_SUCCESS != result || boundary.empty())
+  {
+    std::cerr << "Mesh skinning failed." << std::endl;
+    return 3;
+  }
+
+  if (write_tag) {
+      // get tag handle
+    MBTag tag;
+    result = iface->tag_get_handle( FIXED_TAG, tag );
+    if (result == MB_SUCCESS)
+    {
+      int size;
+      MBDataType type;
+      iface->tag_get_size(tag, size);
+      iface->tag_get_data_type(tag, type);
+    
+      if (size != sizeof(int) || type != MB_TYPE_INTEGER)
+      {
+        std::cerr << '"' << FIXED_TAG << "\" tag defined with incorrect size or type" << std::endl;
+        return 3;
+      }
+    }
+    else if (result == MB_TAG_NOT_FOUND)
+    {
+      int zero = 0;
+      result = iface->tag_create( FIXED_TAG, sizeof(int), MB_TAG_DENSE, MB_TYPE_INTEGER, tag, &zero );
+      CHKERROR(result);
+    }
+    else
+    {
+      CHKERROR(result);
+    }
+  
+      // Set tags
+    std::vector<int> ones;
+    MBRange bverts;
+    result = iface->get_adjacencies(boundary, 0, false, bverts, MBInterface::UNION);
+    if (MB_SUCCESS != result) {
+      std::cerr << "Trouble getting vertices on boundary." << std::endl;
+      return 1;
+    }
+    ones.resize( bverts.size(), 1 );
+    result = iface->tag_set_data( tag, bverts, &ones[0] );
+    CHKERROR(result);
+  }
+  
+  if (-1 != neuset_num) {
+      // create a neumann set with these entities
+    if (0 == neuset_tag) {
+      result = iface->tag_create("NEUMANN_SET_TAG_NAME", sizeof(int), MB_TAG_SPARSE,
+                                  MB_TYPE_INTEGER, neuset_tag, NULL);
+      if (MB_SUCCESS != result || 0 == neuset_tag) return 1;
+    }
+    
+
+      // always create a forward neumann set, assuming we have something in the set
+    MBEntityHandle forward_neuset = 0;
+    result = iface->create_meshset(MESHSET_SET, forward_neuset);
+    if (MB_SUCCESS != result || 0 == forward_neuset) return 1;
+    result = iface->tag_set_data(neuset_tag, &forward_neuset, 1, &neuset_num);
+    if (MB_SUCCESS != result) return 1;
+
+    if (!forward_lower.empty()) {
+      result = iface->add_entities(forward_neuset, forward_lower);
+      if (MB_SUCCESS != result) return 1;
+    }
+    if (!reverse_lower.empty()) {
+      MBEntityHandle reverse_neuset = 1;
+      result = iface->create_meshset(MESHSET_SET, reverse_neuset);
+      if (MB_SUCCESS != result || 0 == forward_neuset) return 1;
+
+      result = iface->add_entities(reverse_neuset, reverse_lower);
+      if (MB_SUCCESS != result) return 1;
+      MBTag sense_tag;
+      result = iface->tag_get_handle("SENSE", sense_tag);
+      if (result == MB_TAG_NOT_FOUND) {
+        int dum_sense = 0;
+        result = iface->tag_create("SENSE", sizeof(int), MB_TAG_SPARSE, sense_tag, &dum_sense);
+      }
+      if (result != MB_SUCCESS) return 1;
+      int sense_val = -1;
+      result = iface->tag_set_data(neuset_tag, &reverse_neuset, 1, &sense_val);
+      if (MB_SUCCESS != result) return 0;
+      result = iface->add_entities(forward_neuset, &reverse_neuset, 1);
+      if (MB_SUCCESS != result) return 0;
+    }
+  }
+
+  if (NULL != output_file && write_whole_mesh) {
+    
+      // write output file
+    result = iface->write_mesh( output_file);
+    if (MB_SUCCESS != result)
+    { 
+      std::cerr << "Failed to write \"" << output_file << "\"." << std::endl; 
+      return 2;
+    }
+    std::cerr << "Wrote \"" << output_file << "\"" << std::endl;
+  }
+  else if (NULL != output_file) {
+      // write only skin; write them as one set
+    MBEntityHandle skin_set;
+    result = iface->create_meshset(MESHSET_SET, skin_set);
+    if (MB_SUCCESS != result) return 1;
+    result = iface->add_entities(skin_set, forward_lower);
+    if (MB_SUCCESS != result) return 1;
+    result = iface->add_entities(skin_set, reverse_lower);
+    if (MB_SUCCESS != result) return 1;
+
+    MBRange this_range, ent_range;
+    result = iface->get_entities_by_type_and_tag(0, MBENTITYSET, &matset_tag,
+                                                  NULL, 0, this_range);
+    if (!this_range.empty()) iface->delete_entities(this_range);
+
+    int dum = 10000;
+    result = iface->tag_set_data(matset_tag, &skin_set, 1, &dum);
+    
+
+    result = iface->write_mesh( output_file, &skin_set, 1);
+    if (MB_SUCCESS != result)
+    { 
+      std::cerr << "Failed to write \"" << output_file << "\"." << std::endl; 
+      return 2;
+    }
+    std::cerr << "Wrote \"" << output_file << "\"" << std::endl;
+  }
+
+  if (print_perf) {
+    double tot_time, tot_mem;
+    get_time_mem(tot_time, tot_mem);
+    std::cout << "Total cpu time = " << tot_time << " seconds." << std::endl;
+    std::cout << "Total skin cpu time = " << tot_time-tmp_time << " seconds." << std::endl;
+    std::cout << "Total memory = " << tot_mem/1.0e6 << " MB." << std::endl;
+    std::cout << "Total skin memory = " << (tot_mem-tmp_mem)/1.0e6 << " MB." << std::endl;
+    std::cout << "Entities: " << std::endl;
+    iface->list_entities(0, 0);
+  }
+  
+  return 0;
+}
+
+#if defined(_MSC_VER) || defined(__MINGW32__)
+void get_time_mem(double &tot_time, double &tot_mem) 
+{
+  tot_time = (double)clock() / CLOCKS_PER_SEC;
+  tot_mem = 0;
+}
+#else
+void get_time_mem(double &tot_time, double &tot_mem) 
+{
+  struct rusage r_usage;
+  getrusage(RUSAGE_SELF, &r_usage);
+  double utime = (double)r_usage.ru_utime.tv_sec +
+    ((double)r_usage.ru_utime.tv_usec/1.e6);
+  double stime = (double)r_usage.ru_stime.tv_sec +
+    ((double)r_usage.ru_stime.tv_usec/1.e6);
+  tot_time = utime + stime;
+  tot_mem = 0;
+  if (0 != r_usage.ru_maxrss) {
+    tot_mem = r_usage.ru_idrss; 
+  }
+  else {
+      // this machine doesn't return rss - try going to /proc
+      // print the file name to open
+    char file_str[4096], dum_str[4096];
+    int file_ptr = -1, file_len;
+    file_ptr = open("/proc/self/stat", O_RDONLY);
+    file_len = read(file_ptr, file_str, sizeof(file_str)-1);
+    if (file_len == 0) return;
+    
+    close(file_ptr);
+    file_str[file_len] = '\0';
+      // read the preceeding fields and the ones we really want...
+    int dum_int;
+    unsigned int dum_uint, vm_size, rss;
+    int num_fields = sscanf(file_str, 
+                            "%d " // pid
+                            "%s " // comm
+                            "%c " // state
+                            "%d %d %d %d %d " // ppid, pgrp, session, tty, tpgid
+                            "%u %u %u %u %u " // flags, minflt, cminflt, majflt, cmajflt
+                            "%d %d %d %d %d %d " // utime, stime, cutime, cstime, counter, priority
+                            "%u %u " // timeout, itrealvalue
+                            "%d " // starttime
+                            "%u %u", // vsize, rss
+                            &dum_int, 
+                            dum_str, 
+                            dum_str, 
+                            &dum_int, &dum_int, &dum_int, &dum_int, &dum_int, 
+                            &dum_uint, &dum_uint, &dum_uint, &dum_uint, &dum_uint,
+                            &dum_int, &dum_int, &dum_int, &dum_int, &dum_int, &dum_int, 
+                            &dum_uint, &dum_uint, 
+                            &dum_int,
+                            &vm_size, &rss);
+    if (num_fields == 24)
+      tot_mem = ((double)vm_size);
+  }
+}
+#endif
+  
+  
+  
+


Property changes on: MOAB/trunk/tools/skin.cpp
___________________________________________________________________
Name: svn:keywords
   + Author Date Id Revision
Name: svn:mergeinfo
   + 
Name: svn:eol-style
   + native

Copied: MOAB/trunk/tools/surfplot.cpp (from rev 2644, MOAB/trunk/tools/surfplot/surfplot.cpp)
===================================================================
--- MOAB/trunk/tools/surfplot.cpp	                        (rev 0)
+++ MOAB/trunk/tools/surfplot.cpp	2009-02-24 16:35:31 UTC (rev 2653)
@@ -0,0 +1,505 @@
+#include "MBCore.hpp"
+#include "MBRange.hpp"
+#include "MBTagConventions.hpp"
+#include <iostream>
+#include <fstream>
+#include <limits>
+#include <cstdlib>
+#include <math.h>
+
+/* Exit values */
+#define USAGE_ERROR 1
+#define READ_ERROR 2
+#define WRITE_ERROR 3
+#define SURFACE_NOT_FOUND 4
+#define OTHER_ERROR 5
+
+void usage_error( const char* name )
+{
+  std::cerr << "Usauge: " << name << 
+    " [-g|-p] <Surface_ID> <input_file>" << std::endl
+    << "\t-g           -  Write GNU Plot data file (default)." << std::endl
+    << "\t-p           -  Write encapsulated postscript file"  << std::endl
+    << "\t-s           -  Write an SVG file"                   << std::endl
+    << "\t<Surface_ID> -  ID of surface containing mesh to export." << std::endl
+    << "\t<input_file> -  Mesh file to read." << std::endl
+    << std::endl
+    << "  This utility plots the mesh of a single geometric surface "
+    << "projected to a plane.  The output file is written to stdout."
+    << std::endl;
+  
+  exit(USAGE_ERROR);
+}
+
+struct CartVect3D {
+
+    double x, y, z;
+    
+    CartVect3D() {}
+    
+    CartVect3D( double x_, double y_, double z_ )
+      : x(x_), y(y_), z(z_) {}
+
+    CartVect3D& operator+=( const CartVect3D& o )
+      { x += o.x; y += o.y; z += o.z; return *this; }
+  
+    CartVect3D& operator-=( const CartVect3D& o )
+      { x -= o.x; y -= o.y; z -= o.z; return *this; }
+      
+    CartVect3D& operator*=( const CartVect3D& );
+      
+    CartVect3D& operator+=( double v )
+      { x += v; y += v; z += v; return *this; }
+      
+    CartVect3D& operator-=( double v )
+      { x -= v; y -= v; z -= v; return *this; }
+      
+    CartVect3D& operator*=( double v )
+      { x *= v; y *= v; z *= v; return *this; }
+      
+    CartVect3D& operator/=( double v )
+      { x /= v; y /= v; z /= v; return *this; }
+    
+    double len() const
+      { return sqrt( x*x + y*y + z*z ); }
+};
+
+CartVect3D operator-( const CartVect3D a )
+  { return CartVect3D(-a.z, -a.y, -a.z);  }
+
+CartVect3D operator+( const CartVect3D a, const CartVect3D b )
+  { return CartVect3D(a.x+b.x, a.y+b.y, a.z+b.z); }
+
+CartVect3D operator-( const CartVect3D a, const CartVect3D b )
+  { return CartVect3D(a.x-b.x, a.y-b.y, a.z-b.z); }
+
+double operator%( const CartVect3D a, const CartVect3D b )
+  { return a.x*b.x + a.y*b.y + a.z*b.z; }
+
+CartVect3D operator*( const CartVect3D a, const CartVect3D b )
+{
+  CartVect3D result;
+  result.x = a.y * b.z - a.z * b.y;
+  result.y = a.z * b.x - a.x * b.z;
+  result.z = a.x * b.y - a.y * b.x;
+  return result;
+}
+
+CartVect3D& CartVect3D::operator*=( const CartVect3D& o )
+  { *this = *this * o; return *this; }
+
+static void find_rotation( CartVect3D plane_normal,
+                           double matrix[3][3] )
+{
+    // normalize
+  plane_normal /= plane_normal.len();
+  if (fabs(plane_normal.x) < 0.1)
+    plane_normal.x = 0.0;
+  if (fabs(plane_normal.y) < 0.1)
+    plane_normal.y = 0.0;
+  if (fabs(plane_normal.z) < 0.1)
+    plane_normal.z = 0.0;
+  
+    // calculate vector to rotate about
+  const CartVect3D Z(0,0,1);
+  CartVect3D vector = plane_normal * Z;
+  const double len = vector.len();
+  
+    // If vector is zero, no rotation
+  if (len < 1e-2) {
+    matrix[0][0] = matrix[1][1] = matrix[2][2] = 1.0;
+    matrix[0][1] = matrix[1][0] = 0.0;
+    matrix[0][2] = matrix[2][0] = 0.0;
+    matrix[1][2] = matrix[2][1] = 0.0;
+    return;
+  }
+  vector /= len;
+
+  const double cosine = plane_normal % Z;
+  const double sine = sqrt( 1 - cosine*cosine );
+  
+  std::cerr << "Rotation: " << acos(cosine) << " [" << vector.x << ' ' << vector.y << ' ' << vector.z << ']' << std::endl;
+  
+  const double x = vector.x;
+  const double y = vector.y;
+  const double z = vector.z;
+  const double c = cosine;
+  const double s = sine;
+  const double o = 1.0 - cosine;
+  
+  matrix[0][0] =    c + x*x*o;
+  matrix[0][1] = -z*s + x*y*o;
+  matrix[0][2] =  y*s + x*z*o;
+  
+  matrix[1][0] =  z*s + x*z*o;
+  matrix[1][1] =    c + y*y*o;
+  matrix[1][2] = -x*s + y*z*o;
+  
+  matrix[2][0] = -y*s + x*z*o;
+  matrix[2][1] =  x*s + y*z*o;
+  matrix[2][2] =    c + z*z*o;
+}
+  
+static void transform_point( CartVect3D& point, double matrix[3][3] )
+{
+  const double x = point.x;
+  const double y = point.y;
+  const double z = point.z;
+  
+  point.x = x*matrix[0][0] + y*matrix[0][1] + z*matrix[0][2];
+  point.y = x*matrix[1][0] + y*matrix[1][1] + z*matrix[1][2];
+  point.z = x*matrix[2][0] + y*matrix[2][1] + z*matrix[2][2];
+}
+  
+
+static void write_gnuplot( std::ostream& stream, 
+                           const std::vector<CartVect3D>& list );
+
+static void write_svg( std::ostream& stream,
+                       const std::vector<CartVect3D>& list );
+
+static void write_eps( std::ostream& stream,
+                       const std::vector<CartVect3D>& list,
+                       int surface_id );
+
+enum FileType {
+  POSTSCRIPT,
+  GNUPLOT,
+  SVG
+};
+
+int main(int argc, char* argv[])
+{
+  MBInterface* moab = new MBCore();
+  MBErrorCode result;
+  std::vector<CartVect3D>::iterator iter;
+  FileType type = GNUPLOT;
+
+  int idx = 1;
+  if (argc == 4)
+  {
+    if (!strcmp(argv[idx],"-p"))
+      type = POSTSCRIPT;
+    else if (!strcmp(argv[idx],"-g"))
+      type = GNUPLOT;
+    else if (!strcmp(argv[idx],"-s"))
+      type = SVG;
+    else
+      usage_error(argv[0]);
+    ++idx;
+  }
+  
+    
+
+    // scan CL args
+  int surface_id;
+  if (argc - idx != 2)
+    usage_error(argv[0]);
+  char* endptr;
+  surface_id = strtol( argv[idx], &endptr, 0 );
+  if (!endptr || *endptr || surface_id < 1)
+    usage_error(argv[0]);
+  ++idx;
+  
+    // Load mesh
+  result = moab->load_mesh( argv[idx] );
+  if (MB_SUCCESS != result) {
+    if (MB_FILE_DOES_NOT_EXIST == result)
+      std::cerr << argv[idx] << " : open failed.\n";
+    else
+      std::cerr << argv[idx] << " : error reading file.\n";
+    return READ_ERROR;
+  }
+  
+    // Get tag handles
+  MBTag tags[2];
+  result = moab->tag_get_handle( GEOM_DIMENSION_TAG_NAME, tags[0] );
+  if (MB_SUCCESS != result) {
+    std::cerr << "No geometry tag.\n";
+    return OTHER_ERROR;
+  }
+  result = moab->tag_get_handle( GLOBAL_ID_TAG_NAME, tags[1] );
+  if (MB_SUCCESS != result) {
+    std::cerr << "No ID tag.\n";
+    return OTHER_ERROR;
+  }
+ 
+    // Find entityset for surface.
+  int dimension = 2; // surface
+  const void* tag_values[] = { &dimension, &surface_id };
+  MBRange surfaces;
+  moab->get_entities_by_type_and_tag( 0, MBENTITYSET,
+                                      tags, tag_values,
+                                      2, surfaces );
+  if (surfaces.size() != 1) {
+    std::cerr << "Found " << surfaces.size() 
+              << " surfaces with ID " << surface_id
+              << std::endl;
+    return SURFACE_NOT_FOUND;
+  }
+  MBEntityHandle surface = *surfaces.begin();
+  
+    // Get surface mesh
+  MBRange elements;
+  result = moab->get_entities_by_dimension( surface, dimension, elements );
+  if (MB_SUCCESS != result) {
+    std::cerr << "Internal error\n";
+    return OTHER_ERROR;
+  }
+  
+    // Calculate average corner normal in surface mesh
+  CartVect3D normal(0,0,0);
+  std::vector<MBEntityHandle> vertices;
+  std::vector<CartVect3D> coords;
+  for (MBRange::iterator i = elements.begin(); i != elements.end(); ++i)
+  {
+    vertices.clear();
+    result = moab->get_connectivity( &*i, 1, vertices, true );
+    if (MB_SUCCESS != result) {
+      std::cerr << "Internal error\n";
+      return OTHER_ERROR;
+    }
+    coords.clear();
+    coords.resize( vertices.size() );
+    result = moab->get_coords( &vertices[0], vertices.size(),
+                               reinterpret_cast<double*>(&coords[0]) );
+    if (MB_SUCCESS != result) {
+      std::cerr << "Internal error\n";
+      return OTHER_ERROR;
+    }
+    
+    for (size_t j = 0; j < coords.size(); ++j) {
+      CartVect3D v1 = coords[(j+1)%coords.size()] - coords[j];
+      CartVect3D v2 = coords[(j+1)%coords.size()] - coords[(j+2)%coords.size()];
+      normal += (v1 * v2);
+    }
+  }
+  normal /= normal.len();
+
+  
+    // Get edges from elements
+  MBRange edge_range;
+  result = moab->get_adjacencies( elements, 1, true, edge_range, MBInterface::UNION );
+  if (MB_SUCCESS != result) {
+    std::cerr << "Internal error\n";
+    return OTHER_ERROR;
+  }
+  
+    // Get vertex coordinates for each edge
+  std::vector<MBEntityHandle> edges( edge_range.size() );
+  std::copy( edge_range.begin(), edge_range.end(), edges.begin() );
+  vertices.clear();
+  result = moab->get_connectivity( &edges[0], edges.size(), vertices, true );
+  if (MB_SUCCESS != result) {
+    std::cerr << "Internal error\n";
+    return OTHER_ERROR;
+  }
+  coords.clear();
+  coords.resize( vertices.size() );
+  result = moab->get_coords( &vertices[0], vertices.size(), 
+                             reinterpret_cast<double*>(&coords[0]) );
+  if (MB_SUCCESS != result) {
+    std::cerr << "Internal error\n";
+    return OTHER_ERROR;
+  }
+  
+    // Rotate points such that the projection into the view plane
+    // can be accomplished by disgarding the 'z' coordinate of each
+    // point.
+  
+  std::cerr << "Plane normal: [" << normal.x << ' ' << normal.y << ' ' << normal.z << ']' << std::endl;
+  double transform[3][3];
+  find_rotation( normal, transform );
+  
+  for (iter = coords.begin(); iter != coords.end(); ++iter)
+    transform_point( *iter, transform );
+  
+    // Write the file.
+  
+  switch (type) {
+    case POSTSCRIPT:
+      write_eps( std::cout, coords, surface_id );
+      break;
+    case SVG:
+      write_svg( std::cout, coords );
+      break;
+    default:
+      write_gnuplot( std::cout, coords );
+      break;
+  }
+  return 0;
+}
+    
+void  write_gnuplot( std::ostream& stream, 
+                     const std::vector<CartVect3D>& coords )
+{ 
+  std::vector<CartVect3D>::const_iterator iter;
+
+  stream << std::endl;
+  for (iter = coords.begin(); iter != coords.end(); ++iter) {
+    stream << iter->x << ' ' << iter->y << std::endl;
+    ++iter;
+    stream << iter->x << ' ' << iter->y << std::endl;
+    stream << std::endl;
+  }
+  std::cerr << "Display with gnuplot command \"plot with lines\"\n"; 
+}
+
+static void box_max( CartVect3D& cur_max, const CartVect3D& pt )
+{
+  if (pt.x > cur_max.x)
+    cur_max.x = pt.x;
+  if (pt.y > cur_max.y)
+    cur_max.y = pt.y;
+  //if (pt.z > cur_max.z)
+  //  cur_max.z = pt.z;
+}
+
+static void box_min( CartVect3D& cur_min, const CartVect3D& pt )
+{
+  if (pt.x < cur_min.x)
+    cur_min.x = pt.x;
+  if (pt.y < cur_min.y)
+    cur_min.y = pt.y;
+  //if (pt.z > cur_min.z)
+  //  cur_min.z = pt.z;
+}
+
+
+void write_eps( std::ostream& s, const std::vector<CartVect3D>& coords, int id )
+{
+    // Coordinate range to use within EPS file
+  const int X_MAX = 540;  // 540 pts / 72 pts/inch = 7.5 inches
+  const int Y_MAX = 720;  // 720 pts / 72 pts/inch = 10 inches 
+  
+  std::vector<CartVect3D>::const_iterator iter;
+ 
+    // Get bounding box
+  const double D_MAX = std::numeric_limits<double>::max();
+  CartVect3D min(  D_MAX,  D_MAX, 0 );
+  CartVect3D max( -D_MAX, -D_MAX, 0 );
+  for (iter = coords.begin(); iter != coords.end(); ++iter)
+  {
+    box_max( max, *iter );
+    box_min( min, *iter );
+  }
+  
+    // Calcuate translation to page coordiantes
+  CartVect3D offset = CartVect3D(0,0,0) - min;
+  CartVect3D scale  = max - min;
+  scale.x = X_MAX / scale.x;
+  scale.y = Y_MAX / scale.y;
+  if (scale.x > scale.y)  // keep proportions
+    scale.x = scale.y;
+  else
+    scale.y = scale.x;
+  
+  //std::cerr << "Min: " << min.x << ' ' << min.y << 
+  //           "  Max: " << max.x << ' ' << max.y << std::endl
+  //          << "Offset: " << offset.x << ' ' << offset.y <<
+  //           "  Scale: " << scale.x << ' ' << scale.y << std::endl;
+  
+    // Write header stuff
+  s << "%!PS-Adobe-2.0 EPSF-2.0"                      << std::endl;
+  s << "%%Creator: MOAB surfplot"                     << std::endl;
+  s << "%%Title: Surface " << id                      << std::endl;
+  s << "%%DocumentData: Clean7Bit"                    << std::endl;
+  s << "%%Origin: 0 0"                                << std::endl;
+  int max_x = (int)((max.x + offset.x) * scale.x);
+  int max_y = (int)((max.y + offset.y) * scale.y);
+  s << "%%BoundingBox: 0 0 " << max_x << ' ' << max_y << std::endl;
+  s << "%%Pages: 1"                                   << std::endl;
+  
+  s << "%%BeginProlog"                                << std::endl;
+  s << "save"                                         << std::endl;
+  s << "countdictstack"                               << std::endl;
+  s << "mark"                                         << std::endl;
+  s << "newpath"                                      << std::endl;
+  s << "/showpage {} def"                             << std::endl;
+  s << "/setpagedevice {pop} def"                     << std::endl;
+  s << "%%EndProlog"                                  << std::endl;
+  
+  s << "%%Page: 1 1"                                  << std::endl;
+  s << "1 setlinewidth"                               << std::endl;
+  s << "0.0 setgray"                                  << std::endl;
+  
+  for (iter = coords.begin(); iter != coords.end(); ++iter)
+  {
+    double x1 = (iter->x + offset.x) * scale.x;
+    double y1 = (iter->y + offset.y) * scale.y;
+    if (++iter == coords.end())
+      break;
+    double x2 = (iter->x + offset.x) * scale.x;
+    double y2 = (iter->y + offset.y) * scale.y;
+    
+    s << "newpath"                                    << std::endl;
+    s << x1 << ' ' << y1 << " moveto"                 << std::endl;
+    s << x2 << ' ' << y2 << " lineto"                 << std::endl;
+    s << "stroke"                                     << std::endl;
+  }
+  
+  s << "%%Trailer"                                    << std::endl;
+  s << "cleartomark"                                  << std::endl;
+  s << "countdictstack"                               << std::endl;
+  s << "exch sub { end } repeat"                      << std::endl;
+  s << "restore"                                      << std::endl;  
+  s << "%%EOF"                                        << std::endl;
+
+}
+
+
+void write_svg( std::ostream& file,
+                const std::vector<CartVect3D>& coords )
+{
+  
+  std::vector<CartVect3D>::const_iterator iter;
+ 
+    // Get bounding box
+  const double D_MAX = std::numeric_limits<double>::max();
+  CartVect3D min(  D_MAX,  D_MAX, 0 );
+  CartVect3D max( -D_MAX, -D_MAX, 0 );
+  for (iter = coords.begin(); iter != coords.end(); ++iter)
+  {
+    box_max( max, *iter );
+    box_min( min, *iter );
+  }
+  CartVect3D size = max - min;
+  
+    // scale to 640 pixels on a side
+  double scale = 640.0 / (size.x > size.y ? size.x : size.y);
+  size *= scale;
+  
+  
+
+  file << "<?xml version=\"1.0\" standalone=\"no\"?>"                << std::endl;
+  file << "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" " 
+       << "\"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">"    << std::endl;
+  file <<                                                               std::endl;
+  file << "<svg width=\"" << (int)size.x
+       << "\" height=\"" << (int)size.y
+       << "\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\">" << std::endl;
+  
+  int left = (int)(min.x * scale);
+  int top = (int)(min.y * scale);
+  iter = coords.begin(); 
+  while (iter != coords.end()) {
+    file << "<line "
+         << "x1=\"" << (int)(scale * iter->x) - left << "\" "
+         << "y1=\"" << (int)(scale * iter->y) - top << "\" ";
+    ++iter;
+    file << "x2=\"" << (int)(scale * iter->x) - left << "\" "
+         << "y2=\"" << (int)(scale * iter->y) - top << "\" "
+         << " style=\"stroke:rgb(99,99,99);stroke-width:2\""
+         << "/>" << std::endl;
+    ++iter;
+  }
+  
+    // Write footer
+  file << "</svg>" << std::endl;
+}
+    
+
+    
+  
+
+    


Property changes on: MOAB/trunk/tools/surfplot.cpp
___________________________________________________________________
Name: svn:keywords
   + Author Date Id Revision
Name: svn:mergeinfo
   + 
Name: svn:eol-style
   + native



More information about the moab-dev mailing list