moab
|
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 }