moab
SphereDecomp.cpp
Go to the documentation of this file.
00001 #include "SphereDecomp.hpp"
00002 #include "moab/MeshTopoUtil.hpp"
00003 #include "moab/Range.hpp"
00004 #include "moab/CN.hpp"
00005 #include <math.h>
00006 #include <assert.h>
00007 #include <iostream>
00008 
00009 #define RR if (MB_SUCCESS != result) return result
00010 
00011 const char *SUBDIV_VERTICES_TAG_NAME = "subdiv_vertices";
00012 
00013 using namespace moab;
00014 
00015 SphereDecomp::SphereDecomp(Interface *impl) 
00016 {
00017   mbImpl = impl;
00018 }
00019 
00020 ErrorCode SphereDecomp::build_sphere_mesh(const char *sphere_radii_tag_name,
00021                                             EntityHandle *hex_set) 
00022 {
00023   ErrorCode result = mbImpl->tag_get_handle(sphere_radii_tag_name, 1, MB_TYPE_DOUBLE, sphereRadiiTag); RR;
00024 
00025     // need to make sure all interior edges and faces are created
00026   Range all_verts;
00027   result = mbImpl->get_entities_by_type(0, MBVERTEX, all_verts); RR;
00028   MeshTopoUtil mtu(mbImpl);
00029   result = mtu.construct_aentities(all_verts);
00030   
00031     // create tag to hold vertices
00032   result = mbImpl->tag_get_handle(SUBDIV_VERTICES_TAG_NAME, 9, MB_TYPE_HANDLE, 
00033                                   subdivVerticesTag, MB_TAG_DENSE|MB_TAG_EXCL); RR;
00034 
00035     // compute nodal positions for each dimension element
00036   result = compute_nodes(1); RR;
00037   result = compute_nodes(2); RR;
00038   result = compute_nodes(3); RR;
00039   
00040     // build hex elements
00041   std::vector<EntityHandle> sphere_hexes, interstic_hexes;
00042   result = build_hexes(sphere_hexes, interstic_hexes); 
00043 
00044   result = mbImpl->tag_delete(subdivVerticesTag); RR;
00045 
00046   if (NULL != hex_set) {
00047     if (0 == *hex_set) {
00048       EntityHandle this_set;
00049         // make a new set
00050       result = mbImpl->create_meshset(MESHSET_SET, this_set); RR;
00051       *hex_set = this_set;
00052     }
00053     
00054       // save all the hexes to this set
00055     result = mbImpl->add_entities(*hex_set, &sphere_hexes[0], 
00056                                   sphere_hexes.size()); RR;
00057     result = mbImpl->add_entities(*hex_set, &interstic_hexes[0], 
00058                                   interstic_hexes.size()); RR;
00059   }
00060       
00061   return result;
00062 }
00063 
00064 ErrorCode SphereDecomp::compute_nodes(const int dim) 
00065 {
00066     // get facets of that dimension
00067   Range these_ents;
00068   const EntityType the_types[4] = {MBVERTEX, MBEDGE, MBTRI, MBTET};
00069   
00070   ErrorCode result = mbImpl->get_entities_by_dimension(0, dim, these_ents); RR;
00071   assert(mbImpl->type_from_handle(*these_ents.begin()) == the_types[dim] &&
00072          mbImpl->type_from_handle(*these_ents.rbegin()) == the_types[dim]);
00073   
00074   EntityHandle subdiv_vertices[9];
00075   MeshTopoUtil mtu(mbImpl);
00076   double avg_pos[3], vert_pos[12], new_vert_pos[12], new_new_vert_pos[3];
00077   double radii[4], unitv[3];
00078   int num_verts = CN::VerticesPerEntity(the_types[dim]);
00079   
00080   for (Range::iterator rit = these_ents.begin(); rit != these_ents.end(); rit++) {
00081     
00082       // get vertices
00083     const EntityHandle *connect;
00084     int num_connect;
00085     result = mbImpl->get_connectivity(*rit, connect, num_connect); RR;
00086 
00087       // compute center
00088     result = mtu.get_average_position(connect, num_connect, avg_pos); RR;
00089 
00090       // create center vertex
00091     result = mbImpl->create_vertex(avg_pos, subdiv_vertices[num_verts]); RR;
00092     
00093       // get coords of other vertices
00094     result = mbImpl->get_coords(connect, num_connect, vert_pos); RR;
00095     
00096       // get radii associated with each vertex
00097     result = mbImpl->tag_get_data(sphereRadiiTag, connect, num_connect, radii); RR;
00098     
00099       // compute subdiv vertex position for each vertex
00100     for (int i = 0; i < num_verts; i++) {
00101       for (int j = 0; j < 3; j++) unitv[j] = avg_pos[j] - vert_pos[3*i+j];
00102       double vlength = sqrt(unitv[0]*unitv[0] + unitv[1]*unitv[1] + unitv[2]*unitv[2]);
00103       if (vlength < radii[i]) {
00104         std::cout << "Radius too large at vertex " << i << std::endl;
00105         result = MB_FAILURE;
00106         continue;
00107       }
00108       
00109       
00110       for (int j = 0; j < 3; j++) unitv[j] /= vlength;
00111           
00112       for (int j = 0; j < 3; j++)
00113         new_vert_pos[3*i+j] = vert_pos[3*i+j] + radii[i] * unitv[j];
00114 
00115       // create vertex at this position
00116       ErrorCode tmp_result = mbImpl->create_vertex(&new_vert_pos[3*i], subdiv_vertices[i]);
00117       if (MB_SUCCESS != tmp_result) result = tmp_result;
00118     }
00119     
00120     if (MB_SUCCESS != result) return result;
00121     
00122       // compute subdiv vertex positions for vertices inside spheres; just mid-pt between
00123       // previous subdiv vertex and corner vertex
00124     for (int i = 0; i < num_verts; i++) {
00125       for (int j = 0; j < 3; j++) 
00126         new_new_vert_pos[j] = .5 * (vert_pos[3*i+j] + new_vert_pos[3*i+j]);
00127 
00128       result = mbImpl->create_vertex(new_new_vert_pos, subdiv_vertices[num_verts+1+i]);
00129     }
00130 
00131       // set the tag
00132     result = mbImpl->tag_set_data(subdivVerticesTag, &(*rit), 1, subdiv_vertices); RR;
00133   }
00134   
00135   return result;
00136 }
00137 
00138 ErrorCode SphereDecomp::build_hexes(std::vector<EntityHandle> &sphere_hexes,
00139                         std::vector<EntityHandle> &interstic_hexes) 
00140 {
00141     // build hexes inside each tet element separately
00142   Range tets;
00143   ErrorCode result = mbImpl->get_entities_by_type(0, MBTET, tets); RR;
00144   
00145   for (Range::iterator vit = tets.begin(); vit != tets.end(); vit++) {
00146     result = subdivide_tet(*vit, sphere_hexes, interstic_hexes); RR;
00147   }
00148   
00149   return MB_SUCCESS;
00150 }
00151 
00152 ErrorCode SphereDecomp::subdivide_tet(EntityHandle tet, 
00153                           std::vector<EntityHandle> &sphere_hexes,
00154                           std::vector<EntityHandle> &interstic_hexes) 
00155 {
00156     // 99: (#subdiv_verts/entity=9) * (#edges=6 + #faces=4 + 1=tet)
00157   EntityHandle subdiv_verts[99];
00158 
00159     // get tet connectivity
00160   std::vector<EntityHandle> tet_conn;
00161   ErrorCode result = mbImpl->get_connectivity(&tet, 1, tet_conn); RR;
00162   
00163   for (int dim = 1; dim <= 3; dim++) {
00164       // get entities of this dimension
00165     std::vector<EntityHandle> ents;
00166     if (dim != 3) {
00167       result = mbImpl->get_adjacencies(&tet, 1, dim, false, ents); RR; 
00168     }
00169     else ents.push_back(tet);
00170     
00171       // for each, get subdiv verts & put into vector
00172     for (std::vector<EntityHandle>::iterator vit = ents.begin(); vit != ents.end(); vit++) {
00173       result = retrieve_subdiv_verts(tet, *vit, &tet_conn[0], dim, subdiv_verts); RR;
00174     }
00175   }
00176 
00177     // ok, subdiv_verts are in canonical order; now create the hexes, using pre-computed templates
00178 
00179     // Templates are specified in terms of the vertices making up each hex; vertices are specified 
00180     // by specifying the facet index and type they resolve, and the index of that vertex in that facet's
00181     // subdivision vertices list.
00182 
00183     // Each facet is subdivided into:
00184     // - a mid vertex
00185     // - one vertex for each corner vertex on the facet (located on a line between the mid vertex and
00186     //   the corresponding corner vertex, a distance equal to the sphere radius away from the corner
00187     //   vertex)
00188     // - one vertex midway between each corner vertex and the corresponding "sphere surface" vertex
00189     // For edges, tris and tets this gives 5, 7 and 9 subdivision vertices, respectively.  Subdivision vertices
00190     // appear in the list in the order: sphere surface vertices, mid vertex, sphere interior vertices.  In
00191     // each of those sub lists, vertices are listed in the canonical order of the corresponding corner vertices
00192     // for that facet.
00193 
00194     // Subdivision vertices for facetes are indexed by listing the facet type they resolve (EDGE, FACE, TET), the index of
00195     // that facet (integer = 0..5, 0..3, 0 for edges, tris, tet, resp), and subdivision index (AINDEX..EINDEX for
00196     // edges, AINDEX..GINDEX for tris, AINDEX..IINDEX for tets).
00197 
00198     // Subdivision vertices for all facets of a tet are stored in one subdivision vertex vector, in order of increasing
00199     // facet dimension and index (index varies fastest).  The ESV, FSV, and TSV macros are used to compute the
00200     // indices into that vector for various parameters.  The CV macro is used to index into the tet connectivity
00201     // vector.
00202 
00203     // Subdivision templates for splitting the tet into 28 hexes were derived by hand, and are listed below 
00204     // (using the indexing scheme described above).
00205 
00206 #define EDGE 0
00207 #define FACE 1
00208 #define TET 2
00209 #define AINDEX 0
00210 #define BINDEX 1
00211 #define CINDEX 2
00212 #define DINDEX 3
00213 #define EINDEX 4
00214 #define FINDEX 5
00215 #define GINDEX 6
00216 #define HINDEX 7
00217 #define IINDEX 8
00218 #define V0INDEX 0
00219 #define V1INDEX 1
00220 #define V2INDEX 2
00221 #define V3INDEX 3
00222 #define CV(a) tet_conn[a]
00223 #define ESV(a,b) subdiv_verts[a*9+b]
00224 #define FSV(a,b) subdiv_verts[54+a*9+b]
00225 #define TSV(a,b) subdiv_verts[90+a*9+b]
00226 
00227   EntityHandle this_connect[8], this_hex;
00228 
00229     // first, interstices hexes, three per vertex/spherical surface
00230 // V0:
00231   int i = 0;
00232   this_connect[i++]=ESV(0,AINDEX); this_connect[i++]=ESV(0,CINDEX); this_connect[i++]=FSV(3,DINDEX); this_connect[i++]=FSV(3,AINDEX); 
00233   this_connect[i++]=FSV(0,AINDEX); this_connect[i++]=FSV(0,DINDEX); this_connect[i++]=TSV(0,EINDEX); this_connect[i++]=TSV(0,AINDEX);
00234   result = mbImpl->create_element(MBHEX, this_connect, 8, this_hex); RR;
00235   interstic_hexes.push_back(this_hex);
00236 
00237   i = 0;
00238   this_connect[i++]=FSV(0,AINDEX); this_connect[i++]=FSV(0,DINDEX); this_connect[i++]=TSV(0,EINDEX); this_connect[i++]=TSV(0,AINDEX); 
00239   this_connect[i++]=ESV(3,AINDEX); this_connect[i++]=ESV(3,CINDEX); this_connect[i++]=FSV(2,DINDEX); this_connect[i++]=FSV(2,AINDEX);
00240   result = mbImpl->create_element(MBHEX, this_connect, 8, this_hex); RR;
00241   interstic_hexes.push_back(this_hex);
00242 
00243   i = 0;
00244   this_connect[i++]=FSV(3,AINDEX); this_connect[i++]=FSV(3,DINDEX); this_connect[i++]=ESV(2,CINDEX); this_connect[i++]=ESV(2,BINDEX); 
00245   this_connect[i++]=TSV(0,AINDEX); this_connect[i++]=TSV(0,EINDEX); this_connect[i++]=FSV(2,DINDEX); this_connect[i++]=FSV(2,AINDEX);
00246   result = mbImpl->create_element(MBHEX, this_connect, 8, this_hex); RR;
00247   interstic_hexes.push_back(this_hex);
00248 
00249 
00250 // V1:
00251   i = 0;
00252   this_connect[i++]=ESV(0,CINDEX); this_connect[i++]=ESV(0,BINDEX); this_connect[i++]=FSV(3,CINDEX); this_connect[i++]=FSV(3,DINDEX); 
00253   this_connect[i++]=FSV(0,DINDEX); this_connect[i++]=FSV(0,BINDEX); this_connect[i++]=TSV(0,BINDEX); this_connect[i++]=TSV(0,EINDEX);
00254   result = mbImpl->create_element(MBHEX, this_connect, 8, this_hex); RR;
00255   interstic_hexes.push_back(this_hex);
00256 
00257   i = 0;
00258   this_connect[i++]=FSV(0,DINDEX); this_connect[i++]=FSV(0,BINDEX); this_connect[i++]=TSV(0,BINDEX); this_connect[i++]=TSV(0,EINDEX); 
00259   this_connect[i++]=ESV(4,CINDEX); this_connect[i++]=ESV(4,AINDEX); this_connect[i++]=FSV(1,AINDEX); this_connect[i++]=FSV(1,DINDEX);
00260   result = mbImpl->create_element(MBHEX, this_connect, 8, this_hex); RR;
00261   interstic_hexes.push_back(this_hex);
00262 
00263   i = 0;
00264   this_connect[i++]=FSV(1,DINDEX); this_connect[i++]=FSV(1,AINDEX); this_connect[i++]=TSV(0,BINDEX); this_connect[i++]=TSV(0,EINDEX); 
00265   this_connect[i++]=ESV(1,CINDEX); this_connect[i++]=ESV(1,AINDEX); this_connect[i++]=FSV(3,CINDEX); this_connect[i++]=FSV(3,DINDEX);
00266   result = mbImpl->create_element(MBHEX, this_connect, 8, this_hex); RR;
00267   interstic_hexes.push_back(this_hex);
00268 
00269 
00270 // V2:
00271   i = 0;
00272   this_connect[i++]=FSV(3,DINDEX); this_connect[i++]=ESV(1,CINDEX); this_connect[i++]=ESV(1,BINDEX); this_connect[i++]=FSV(3,BINDEX); 
00273   this_connect[i++]=TSV(0,EINDEX); this_connect[i++]=FSV(1,DINDEX); this_connect[i++]=FSV(1,BINDEX); this_connect[i++]=TSV(0,CINDEX);
00274   result = mbImpl->create_element(MBHEX, this_connect, 8, this_hex); RR;
00275   interstic_hexes.push_back(this_hex);
00276 
00277   i = 0;
00278   this_connect[i++]=TSV(0,EINDEX); this_connect[i++]=FSV(1,DINDEX); this_connect[i++]=FSV(1,BINDEX); this_connect[i++]=TSV(0,CINDEX); 
00279   this_connect[i++]=FSV(2,DINDEX); this_connect[i++]=ESV(5,CINDEX); this_connect[i++]=ESV(5,AINDEX); this_connect[i++]=FSV(2,CINDEX);
00280   result = mbImpl->create_element(MBHEX, this_connect, 8, this_hex); RR;
00281   interstic_hexes.push_back(this_hex);
00282 
00283   i = 0;
00284   this_connect[i++]=TSV(0,CINDEX); this_connect[i++]=FSV(2,CINDEX); this_connect[i++]=ESV(2,AINDEX); this_connect[i++]=FSV(3,BINDEX); 
00285   this_connect[i++]=TSV(0,EINDEX); this_connect[i++]=FSV(2,DINDEX); this_connect[i++]=ESV(2,CINDEX); this_connect[i++]=FSV(3,DINDEX);
00286   result = mbImpl->create_element(MBHEX, this_connect, 8, this_hex); RR;
00287   interstic_hexes.push_back(this_hex);
00288 
00289 
00290 // V3:
00291   i = 0;
00292   this_connect[i++]=TSV(0,EINDEX); this_connect[i++]=FSV(1,DINDEX); this_connect[i++]=ESV(5,CINDEX); this_connect[i++]=FSV(2,DINDEX); 
00293   this_connect[i++]=TSV(0,DINDEX); this_connect[i++]=FSV(1,CINDEX); this_connect[i++]=ESV(5,BINDEX); this_connect[i++]=FSV(2,BINDEX);
00294   result = mbImpl->create_element(MBHEX, this_connect, 8, this_hex); RR;
00295   interstic_hexes.push_back(this_hex);
00296 
00297   i = 0;
00298   this_connect[i++]=FSV(0,DINDEX); this_connect[i++]=ESV(4,CINDEX); this_connect[i++]=FSV(1,DINDEX); this_connect[i++]=TSV(0,EINDEX); 
00299   this_connect[i++]=FSV(0,CINDEX); this_connect[i++]=ESV(4,BINDEX); this_connect[i++]=FSV(1,CINDEX); this_connect[i++]=TSV(0,DINDEX);
00300   result = mbImpl->create_element(MBHEX, this_connect, 8, this_hex); RR;
00301   interstic_hexes.push_back(this_hex);
00302 
00303   i = 0;
00304   this_connect[i++]=ESV(3,CINDEX); this_connect[i++]=FSV(0,DINDEX); this_connect[i++]=TSV(0,EINDEX); this_connect[i++]=FSV(2,DINDEX); 
00305   this_connect[i++]=ESV(3,BINDEX); this_connect[i++]=FSV(0,CINDEX); this_connect[i++]=TSV(0,DINDEX); this_connect[i++]=FSV(2,BINDEX);
00306   result = mbImpl->create_element(MBHEX, this_connect, 8, this_hex); RR;
00307   interstic_hexes.push_back(this_hex);
00308 
00309     // now, the sphere interiors, four hexes per vertex sphere
00310 
00311 // V0:
00312   i = 0;
00313   this_connect[i++]=CV(V0INDEX); this_connect[i++]=ESV(0,DINDEX); this_connect[i++]=FSV(3,EINDEX); this_connect[i++]=ESV(2,EINDEX); 
00314   this_connect[i++]=ESV(3,DINDEX); this_connect[i++]=FSV(0,EINDEX); this_connect[i++]=TSV(0,FINDEX); this_connect[i++]=FSV(2,EINDEX);
00315   result = mbImpl->create_element(MBHEX, this_connect, 8, this_hex); RR;
00316   sphere_hexes.push_back(this_hex);
00317 
00318   i = 0;
00319   this_connect[i++]=ESV(0,DINDEX); this_connect[i++]=ESV(0,AINDEX); this_connect[i++]=FSV(3,AINDEX); this_connect[i++]=FSV(3,EINDEX); 
00320   this_connect[i++]=FSV(0,EINDEX); this_connect[i++]=FSV(0,AINDEX); this_connect[i++]=TSV(0,AINDEX); this_connect[i++]=TSV(0,FINDEX);
00321   result = mbImpl->create_element(MBHEX, this_connect, 8, this_hex); RR;
00322   sphere_hexes.push_back(this_hex);
00323 
00324   i = 0;
00325   this_connect[i++]=FSV(3,EINDEX); this_connect[i++]=FSV(3,AINDEX); this_connect[i++]=ESV(2,BINDEX); this_connect[i++]=ESV(2,EINDEX); 
00326   this_connect[i++]=TSV(0,FINDEX); this_connect[i++]=TSV(0,AINDEX); this_connect[i++]=FSV(2,AINDEX); this_connect[i++]=FSV(2,EINDEX);
00327   result = mbImpl->create_element(MBHEX, this_connect, 8, this_hex); RR;
00328   sphere_hexes.push_back(this_hex);
00329 
00330   i = 0;
00331   this_connect[i++]=TSV(0,FINDEX); this_connect[i++]=TSV(0,AINDEX); this_connect[i++]=FSV(2,AINDEX); this_connect[i++]=FSV(2,EINDEX); 
00332   this_connect[i++]=FSV(0,EINDEX); this_connect[i++]=FSV(0,AINDEX); this_connect[i++]=ESV(3,AINDEX); this_connect[i++]=ESV(3,DINDEX);
00333   result = mbImpl->create_element(MBHEX, this_connect, 8, this_hex); RR;
00334   sphere_hexes.push_back(this_hex);
00335 
00336 
00337 // V1:
00338   i = 0;
00339   this_connect[i++]=CV(V1INDEX); this_connect[i++]=ESV(1,DINDEX); this_connect[i++]=FSV(3,GINDEX); this_connect[i++]=ESV(0,EINDEX); 
00340   this_connect[i++]=ESV(4,DINDEX); this_connect[i++]=FSV(1,EINDEX); this_connect[i++]=TSV(0,GINDEX); this_connect[i++]=FSV(0,FINDEX);
00341   result = mbImpl->create_element(MBHEX, this_connect, 8, this_hex); RR;
00342   sphere_hexes.push_back(this_hex);
00343 
00344   i = 0;
00345   this_connect[i++]=FSV(3,GINDEX); this_connect[i++]=ESV(1,DINDEX); this_connect[i++]=ESV(1,AINDEX); this_connect[i++]=FSV(3,CINDEX); 
00346   this_connect[i++]=TSV(0,GINDEX); this_connect[i++]=FSV(1,EINDEX); this_connect[i++]=FSV(1,AINDEX); this_connect[i++]=TSV(0,BINDEX);
00347   result = mbImpl->create_element(MBHEX, this_connect, 8, this_hex); RR;
00348   sphere_hexes.push_back(this_hex);
00349 
00350   i = 0;
00351   this_connect[i++]=TSV(0,GINDEX); this_connect[i++]=FSV(1,EINDEX); this_connect[i++]=FSV(1,AINDEX); this_connect[i++]=TSV(0,BINDEX); 
00352   this_connect[i++]=FSV(0,FINDEX); this_connect[i++]=ESV(4,DINDEX); this_connect[i++]=ESV(4,AINDEX); this_connect[i++]=FSV(0,BINDEX);
00353   result = mbImpl->create_element(MBHEX, this_connect, 8, this_hex); RR;
00354   sphere_hexes.push_back(this_hex);
00355 
00356   i = 0;
00357   this_connect[i++]=ESV(0,BINDEX); this_connect[i++]=ESV(0,EINDEX); this_connect[i++]=FSV(3,GINDEX); this_connect[i++]=FSV(3,CINDEX); 
00358   this_connect[i++]=FSV(0,BINDEX); this_connect[i++]=FSV(0,FINDEX); this_connect[i++]=TSV(0,GINDEX); this_connect[i++]=TSV(0,BINDEX);
00359   result = mbImpl->create_element(MBHEX, this_connect, 8, this_hex); RR;
00360   sphere_hexes.push_back(this_hex);
00361 
00362 
00363 // V2:
00364   i = 0;
00365   this_connect[i++]=ESV(1,BINDEX); this_connect[i++]=ESV(1,EINDEX); this_connect[i++]=FSV(3,FINDEX); this_connect[i++]=FSV(3,BINDEX); 
00366   this_connect[i++]=FSV(1,BINDEX); this_connect[i++]=FSV(1,FINDEX); this_connect[i++]=TSV(0,HINDEX); this_connect[i++]=TSV(0,CINDEX);
00367   result = mbImpl->create_element(MBHEX, this_connect, 8, this_hex); RR;
00368   sphere_hexes.push_back(this_hex);
00369 
00370   i = 0;
00371   this_connect[i++]=FSV(3,FINDEX); this_connect[i++]=ESV(1,EINDEX); this_connect[i++]=CV(V2INDEX); this_connect[i++]=ESV(2,DINDEX); 
00372   this_connect[i++]=TSV(0,HINDEX); this_connect[i++]=FSV(1,FINDEX); this_connect[i++]=ESV(5,DINDEX); this_connect[i++]=FSV(2,GINDEX);
00373   result = mbImpl->create_element(MBHEX, this_connect, 8, this_hex); RR;
00374   sphere_hexes.push_back(this_hex);
00375 
00376   i = 0;
00377   this_connect[i++]=TSV(0,HINDEX); this_connect[i++]=FSV(1,FINDEX); this_connect[i++]=ESV(5,DINDEX); this_connect[i++]=FSV(2,GINDEX); 
00378   this_connect[i++]=TSV(0,CINDEX); this_connect[i++]=FSV(1,BINDEX); this_connect[i++]=ESV(5,AINDEX); this_connect[i++]=FSV(2,CINDEX);
00379   result = mbImpl->create_element(MBHEX, this_connect, 8, this_hex); RR;
00380   sphere_hexes.push_back(this_hex);
00381 
00382   i = 0;
00383   this_connect[i++]=FSV(3,BINDEX); this_connect[i++]=FSV(3,FINDEX); this_connect[i++]=ESV(2,DINDEX); this_connect[i++]=ESV(2,AINDEX); 
00384   this_connect[i++]=TSV(0,CINDEX); this_connect[i++]=TSV(0,HINDEX); this_connect[i++]=FSV(2,GINDEX); this_connect[i++]=FSV(2,CINDEX);
00385   result = mbImpl->create_element(MBHEX, this_connect, 8, this_hex); RR;
00386   sphere_hexes.push_back(this_hex);
00387 
00388 
00389 // V3:
00390   i = 0;
00391   this_connect[i++]=FSV(0,CINDEX); this_connect[i++]=ESV(4,BINDEX); this_connect[i++]=FSV(1,CINDEX); this_connect[i++]=TSV(0,DINDEX); 
00392   this_connect[i++]=FSV(0,GINDEX); this_connect[i++]=ESV(4,EINDEX); this_connect[i++]=FSV(1,GINDEX); this_connect[i++]=TSV(0,IINDEX);
00393   result = mbImpl->create_element(MBHEX, this_connect, 8, this_hex); RR;
00394   sphere_hexes.push_back(this_hex);
00395 
00396   i = 0;
00397   this_connect[i++]=ESV(3,BINDEX); this_connect[i++]=FSV(0,CINDEX); this_connect[i++]=TSV(0,DINDEX); this_connect[i++]=FSV(2,BINDEX); 
00398   this_connect[i++]=ESV(3,EINDEX); this_connect[i++]=FSV(0,GINDEX); this_connect[i++]=TSV(0,IINDEX); this_connect[i++]=FSV(2,FINDEX);
00399   result = mbImpl->create_element(MBHEX, this_connect, 8, this_hex); RR;
00400   sphere_hexes.push_back(this_hex);
00401 
00402   i = 0;
00403   this_connect[i++]=TSV(0,DINDEX); this_connect[i++]=FSV(1,CINDEX); this_connect[i++]=ESV(5,BINDEX); this_connect[i++]=FSV(2,BINDEX); 
00404   this_connect[i++]=TSV(0,IINDEX); this_connect[i++]=FSV(1,GINDEX); this_connect[i++]=ESV(5,EINDEX); this_connect[i++]=FSV(2,FINDEX);
00405   result = mbImpl->create_element(MBHEX, this_connect, 8, this_hex); RR;
00406   sphere_hexes.push_back(this_hex);
00407 
00408   i = 0;
00409   this_connect[i++]=FSV(0,GINDEX); this_connect[i++]=ESV(4,EINDEX); this_connect[i++]=FSV(1,GINDEX); this_connect[i++]=TSV(0,IINDEX); 
00410   this_connect[i++]=ESV(3,EINDEX); this_connect[i++]=CV(V3INDEX); this_connect[i++]=ESV(5,EINDEX); this_connect[i++]=FSV(2,FINDEX);
00411   result = mbImpl->create_element(MBHEX, this_connect, 8, this_hex); RR;
00412   sphere_hexes.push_back(this_hex);
00413 
00414   return result;
00415 }
00416 
00417 ErrorCode SphereDecomp::retrieve_subdiv_verts(EntityHandle tet, EntityHandle this_ent,
00418                                   const EntityHandle *tet_conn,
00419                                   const int dim, EntityHandle *subdiv_verts) 
00420 {
00421     // get the subdiv verts for this entity
00422   ErrorCode result;
00423   
00424     // if it's a tet, just put them on the end & return
00425   if (tet == this_ent) {
00426     result = mbImpl->tag_get_data(subdivVerticesTag, &this_ent, 1, &subdiv_verts[90]);
00427     return MB_SUCCESS;
00428   }
00429   
00430     // if it's a sub-entity, need to find index, relative orientation, and offset
00431     // get connectivity of sub-entity
00432   std::vector<EntityHandle> this_conn;
00433   result = mbImpl->get_connectivity(&this_ent, 1, this_conn); RR;
00434   
00435     // get relative orientation
00436   std::vector<int> conn_tet_indices(this_conn.size());
00437   for (size_t i = 0; i < this_conn.size(); ++i)
00438     conn_tet_indices[i] = std::find(tet_conn, tet_conn+4, this_conn[i]) - tet_conn;
00439   int sense, side_no, offset;
00440   int success = CN::SideNumber(MBTET, &conn_tet_indices[0],
00441                                  this_conn.size(), dim, side_no, sense, offset);
00442   if (-1 == success) return MB_FAILURE;
00443   
00444     // start of this entity's subdiv_verts; edges go first, then preceding sides, then this one;
00445     // this assumes 6 edges/tet
00446   EntityHandle *subdiv_start = &subdiv_verts[((dim-1)*6 + side_no) * 9];
00447   
00448     // get subdiv_verts and put them into proper place
00449   result = mbImpl->tag_get_data(subdivVerticesTag, &this_ent, 1, subdiv_start);
00450 
00451     // could probably do this more elegantly, but isn't worth it
00452 #define SWITCH(a,b) {EntityHandle tmp_handle = a; a = b; b = tmp_handle;}
00453   switch (dim) {
00454     case 1:
00455       if (offset != 0 || sense == -1) {
00456         SWITCH(subdiv_start[0], subdiv_start[1]);
00457         SWITCH(subdiv_start[3], subdiv_start[4]);
00458       }
00459       break;
00460     case 2:
00461         // rotate first
00462       if (0 != offset) {
00463         std::rotate(subdiv_start, subdiv_start+offset, subdiv_start+3);
00464         std::rotate(subdiv_start+4, subdiv_start+4+offset, subdiv_start+7);
00465       }
00466         // now flip, if necessary
00467       if (-1 == sense) {
00468         SWITCH(subdiv_start[1], subdiv_start[2]);
00469         SWITCH(subdiv_start[5], subdiv_start[6]);
00470       }
00471       break;
00472     default:
00473       return MB_FAILURE;
00474   }
00475   
00476     // ok, we're done
00477   return MB_SUCCESS;
00478 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines