[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