MOAB: Mesh Oriented datABase
(version 5.2.1)
|
00001 /** 00002 * MOAB, a Mesh-Oriented datABase, is a software component for creating, 00003 * storing and accessing finite element mesh data. 00004 * 00005 * Copyright 2004 Sandia Corporation. Under the terms of Contract 00006 * DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government 00007 * retains certain rights in this software. 00008 * 00009 * This library is free software; you can redistribute it and/or 00010 * modify it under the terms of the GNU Lesser General Public 00011 * License as published by the Free Software Foundation; either 00012 * version 2.1 of the License, or (at your option) any later version. 00013 * 00014 */ 00015 00016 /*! 00017 MBTest.cpp 00018 Test Harness for MB mesh database system 00019 */ 00020 00021 #ifdef WIN32 00022 #ifdef _DEBUG 00023 // turn off warnings that say they debugging identifier has been truncated 00024 // this warning comes up when using some STL containers 00025 #pragma warning( disable : 4786 ) 00026 #endif 00027 #endif 00028 00029 #include <iostream> 00030 #include <fstream> 00031 #include <algorithm> 00032 #include <cstdio> 00033 #include <time.h> 00034 #include <assert.h> 00035 #include <math.h> 00036 #include <stdio.h> 00037 #include "moab/Interface.hpp" 00038 #include "MBTagConventions.hpp" 00039 #include "moab/Range.hpp" 00040 #include "moab/Skinner.hpp" 00041 #include "moab/MeshTopoUtil.hpp" 00042 #include "moab/CN.hpp" 00043 #include "moab/OrientedBox.hpp" 00044 #include "moab/CartVect.hpp" 00045 #include "moab/WriteUtilIface.hpp" 00046 00047 #ifdef MOAB_HAVE_MPI 00048 #include "moab_mpi.h" 00049 #endif 00050 00051 #ifndef IS_BUILDING_MB 00052 #define IS_BUILDING_MB 00053 #endif 00054 #include "Internals.hpp" 00055 #include "moab/Core.hpp" 00056 #include "SequenceManager.hpp" 00057 #include "EntitySequence.hpp" 00058 #include "RangeSeqIntersectIter.hpp" 00059 #include "moab/Error.hpp" 00060 #include "moab/ScdInterface.hpp" 00061 00062 /* Use the following define to specify that our tests 00063 return an error code and not the default void */ 00064 #define TEST_USES_ERR_CODES 00065 #include "TestUtil.hpp" 00066 00067 using namespace std; 00068 using namespace moab; 00069 00070 #define CHKERR( A ) \ 00071 do \ 00072 { \ 00073 if( MB_SUCCESS != ( A ) ) \ 00074 { \ 00075 std::cerr << "Failure (error code " << ( A ) << ") at " __FILE__ ":" << __LINE__ << std::endl; \ 00076 return A; \ 00077 } \ 00078 } while( false ) 00079 00080 #ifdef MOAB_HAVE_NETCDF 00081 ErrorCode load_file_one( Interface* iface ) 00082 { 00083 std::string file_name = TestDir + "/mbtest1.g"; 00084 ErrorCode error = iface->load_mesh( file_name.c_str() ); 00085 if( MB_SUCCESS != error ) 00086 { 00087 std::cout << "Failed to load input file: " << file_name << std::endl; 00088 std::string error_reason; 00089 iface->get_last_error( error_reason ); 00090 cout << error_reason << std::endl; 00091 } 00092 return error; 00093 } 00094 #endif 00095 00096 /* Create a regular 2x2x2 hex mesh */ 00097 ErrorCode create_some_mesh( Interface* iface ); 00098 00099 ErrorCode check_valid_connectivity( Interface* iface ); 00100 00101 /*! 00102 @test 00103 Vertex Coordinates 00104 @li Get coordinates of vertex 1 correctly 00105 @li Get coordinates of vertex 8 correctly 00106 @li Get coordinates of vertex 6 correctly 00107 */ 00108 ErrorCode mb_vertex_coordinate_test() 00109 { 00110 Core moab; 00111 Interface* MB = &moab; 00112 ErrorCode error = create_some_mesh( MB );MB_CHK_ERR( error ); 00113 00114 Range vertices; 00115 error = MB->get_entities_by_type( 0, MBVERTEX, vertices );MB_CHK_ERR( error ); 00116 00117 std::vector< double > all_coords( 3 * vertices.size() ); 00118 double* coord_iter = &all_coords[0]; 00119 for( Range::iterator iter = vertices.begin(); iter != vertices.end(); ++iter ) 00120 { 00121 error = MB->get_coords( &( *iter ), 1, coord_iter );MB_CHK_ERR( error ); 00122 coord_iter += 3; 00123 } 00124 00125 // check blocked coordinates 00126 const size_t N = vertices.size() + 1; 00127 std::vector< double > x( N ), y( N ), z( N ); 00128 // set last value so we can check later that nothing wrote past the 00129 // intended end of an array 00130 x[vertices.size()] = y[vertices.size()] = z[vertices.size()] = -3.14159; 00131 error = MB->get_coords( vertices, &x[0], &y[0], &z[0] ); 00132 for( size_t i = 0; i < vertices.size(); ++i ) 00133 { 00134 CHECK_REAL_EQUAL( all_coords[3 * i], x[i], 1E-12 ); 00135 CHECK_REAL_EQUAL( all_coords[3 * i + 1], y[i], 1E-12 ); 00136 CHECK_REAL_EQUAL( all_coords[3 * i + 2], z[i], 1E-12 ); 00137 } 00138 // checkthat get_coords did not write past intended end of arrays 00139 CHECK_REAL_EQUAL( -3.14159, x[vertices.size()], 1E-12 ); 00140 CHECK_REAL_EQUAL( -3.14159, y[vertices.size()], 1E-12 ); 00141 CHECK_REAL_EQUAL( -3.14159, z[vertices.size()], 1E-12 ); 00142 00143 // add invalid handle to end of range and try query again 00144 vertices.insert( vertices.back() + 1 ); 00145 error = MB->get_coords( vertices, &x[0], &y[0], &z[0] ); 00146 CHECK_EQUAL( MB_ENTITY_NOT_FOUND, error ); 00147 00148 // Try getting coordinates for a hex (should fail) 00149 Range hexes; 00150 error = MB->get_entities_by_type( 0, MBHEX, hexes );MB_CHK_ERR( error ); 00151 EntityHandle handle = hexes.front(); 00152 error = MB->get_coords( &handle, 1, &x[0] );MB_CHK_ERR( error ); 00153 CHECK_REAL_EQUAL( 0.5, x[0], 1E-12 ); 00154 CHECK_REAL_EQUAL( 0.5, x[1], 1E-12 ); 00155 CHECK_REAL_EQUAL( 0.5, x[2], 1E-12 ); 00156 00157 return MB_SUCCESS; 00158 } 00159 00160 /*! 00161 @test 00162 MB Vertex Tag Test 00163 @li Add, Set and correctly get an int tag 00164 @li Add, Set and correctly get a boolean tag 00165 @li Add, Set and correctly get a double tag 00166 @li Add, Set and correctly get a struct tag 00167 */ 00168 ErrorCode mb_vertex_tag_test() 00169 { 00170 Core moab; 00171 Interface* MB = &moab; 00172 ErrorCode error = create_some_mesh( MB ); 00173 if( MB_SUCCESS != error ) return error; 00174 00175 // Add an int Vertex Tag to the database 00176 00177 Tag tag_id; 00178 00179 // Create a dense tag for all vertices 00180 error = MB->tag_get_handle( "int_tag", 1, MB_TYPE_INTEGER, tag_id, MB_TAG_SPARSE | MB_TAG_EXCL ); 00181 if( error != MB_SUCCESS ) return error; 00182 00183 // put a value in vertex 1 and retrieve 00184 std::vector< EntityHandle > verts; 00185 error = MB->get_entities_by_type( 0, MBVERTEX, verts ); 00186 if( MB_SUCCESS != error ) return error; 00187 EntityHandle handle = verts[0]; 00188 int input_value = 11; 00189 error = MB->tag_set_data( tag_id, &handle, 1, &input_value ); 00190 if( MB_SUCCESS != error ) return error; 00191 00192 int output_value; 00193 error = MB->tag_get_data( tag_id, &handle, 1, &output_value ); 00194 if( MB_SUCCESS != error ) 00195 return error; 00196 else if( output_value != input_value ) 00197 return MB_FAILURE; 00198 00199 // put a value in vertex 5 and retrieve 00200 00201 handle = verts[5]; 00202 input_value = 11; 00203 error = MB->tag_set_data( tag_id, &handle, 1, &input_value ); 00204 if( MB_SUCCESS != error ) return error; 00205 error = MB->tag_get_data( tag_id, &handle, 1, &output_value ); 00206 if( MB_SUCCESS != error ) 00207 return error; 00208 else if( output_value != input_value ) 00209 return MB_FAILURE; 00210 00211 // put a value in vertex 98088234 which doesn't exist 00212 handle = *std::max_element( verts.begin(), verts.end() ) + 1; 00213 input_value = 11; 00214 00215 error = MB->tag_set_data( tag_id, &handle, 1, &input_value ); 00216 if( error == MB_SUCCESS ) return error; 00217 00218 error = MB->tag_get_data( tag_id, &handle, 1, &output_value ); 00219 if( error == MB_SUCCESS ) return error; 00220 00221 if( output_value != input_value ) return MB_FAILURE; 00222 00223 // Add a bool Vertex Tag to the database 00224 00225 error = MB->tag_get_handle( "bool_tag", sizeof( bool ), MB_TYPE_OPAQUE, tag_id, MB_TAG_SPARSE | MB_TAG_EXCL ); 00226 if( error != MB_SUCCESS ) return error; 00227 00228 // put a value in vertex 5 and retrieve 00229 00230 handle = verts[5]; 00231 bool bool_input_value = true; 00232 bool bool_output_value = false; 00233 error = MB->tag_set_data( tag_id, &handle, 1, &bool_input_value ); 00234 if( error != MB_SUCCESS ) return error; 00235 error = MB->tag_get_data( tag_id, &handle, 1, &bool_output_value ); 00236 if( error != MB_SUCCESS ) 00237 return error; 00238 else if( bool_output_value != bool_input_value ) 00239 return MB_FAILURE; 00240 00241 // Add a double Vertex Tag to the database 00242 00243 error = MB->tag_get_handle( "double_tag", 1, MB_TYPE_DOUBLE, tag_id, MB_TAG_SPARSE | MB_TAG_EXCL ); 00244 if( error != MB_SUCCESS ) return error; 00245 00246 // put a value in vertex 8: and retrieve 00247 00248 handle = verts[8]; 00249 double double_input_value = 1.0; 00250 double double_output_value = 0.0; 00251 error = MB->tag_set_data( tag_id, &handle, 1, &double_input_value ); 00252 if( error != MB_SUCCESS ) return error; 00253 00254 error = MB->tag_get_data( tag_id, &handle, 1, &double_output_value ); 00255 if( error != MB_SUCCESS ) 00256 return error; 00257 else if( double_output_value != double_input_value ) 00258 return MB_FAILURE; 00259 00260 // Add a struct Vertex Tag to the database 00261 00262 struct TagStruct 00263 { 00264 int test_int; 00265 double test_double; 00266 }; 00267 error = 00268 MB->tag_get_handle( "struct_tag", sizeof( TagStruct ), MB_TYPE_OPAQUE, tag_id, MB_TAG_SPARSE | MB_TAG_EXCL ); 00269 if( error != MB_SUCCESS ) return error; 00270 00271 // put a value in vertex 7 and retrieve 00272 00273 handle = verts[7]; 00274 TagStruct input_tag_struct; 00275 input_tag_struct.test_int = 55; 00276 input_tag_struct.test_double = -1.2345; 00277 TagStruct output_tag_struct; 00278 error = MB->tag_set_data( tag_id, &handle, 1, &input_tag_struct ); 00279 if( error != MB_SUCCESS ) return error; 00280 error = MB->tag_get_data( tag_id, &handle, 1, &output_tag_struct ); 00281 if( error != MB_SUCCESS ) 00282 return error; 00283 else if( output_tag_struct.test_int != input_tag_struct.test_int || 00284 output_tag_struct.test_double != input_tag_struct.test_double ) 00285 return MB_FAILURE; 00286 00287 // Create sparse tags for 10 random entities including some outside the 00288 // range of allowable entities. 00289 00290 error = MB->tag_get_handle( "sparse_int_tag", 1, MB_TYPE_INTEGER, tag_id, MB_TAG_SPARSE | MB_TAG_EXCL ); 00291 00292 if( error != MB_SUCCESS ) return error; 00293 00294 // print_yes = true; 00295 int i; 00296 for( i = 0; i < 10; i++ ) 00297 { 00298 // use invalid handles for odd values 00299 00300 if( i % 2 ) 00301 handle = verts[i] + *std::max_element( verts.begin(), verts.end() ); 00302 else 00303 handle = verts[i]; 00304 00305 input_value = 11; 00306 error = MB->tag_set_data( tag_id, &handle, 1, &input_value ); 00307 00308 // should fail on odd values of i 00309 if( !( i % 2 ) ) 00310 { 00311 if( error != MB_SUCCESS ) // even case and if failed 00312 return error; 00313 } 00314 else 00315 { 00316 if( error == MB_SUCCESS ) // odd case and it says it worked! 00317 return MB_FAILURE; 00318 } 00319 00320 error = MB->tag_get_data( tag_id, &handle, 1, &output_value ); 00321 if( ( i % 2 ) && error != MB_FAILURE && error != MB_TAG_NOT_FOUND ) return error; 00322 00323 if( ( i % 2 ) && output_value != input_value ) return MB_FAILURE; 00324 } 00325 00326 // get the tag_name of the last tag created above 00327 std::string int_tag_name; 00328 error = MB->tag_get_name( tag_id, int_tag_name ); 00329 if( error != MB_SUCCESS ) return error; 00330 00331 if( int_tag_name != "sparse_int_tag" ) return MB_FAILURE; 00332 00333 // get the tag handle of the last tag created above 00334 Tag int_tag_handle; 00335 error = MB->tag_get_handle( int_tag_name.c_str(), 1, MB_TYPE_INTEGER, int_tag_handle ); 00336 if( MB_SUCCESS != error ) return error; 00337 00338 if( int_tag_handle != tag_id ) return MB_FAILURE; 00339 00340 // test tag_get_tags_on_entity and tag_delete_data 00341 std::vector< Tag > all_tags; 00342 handle = verts[0]; 00343 error = MB->tag_get_tags_on_entity( handle, all_tags ); 00344 if( MB_SUCCESS != error ) return error; 00345 00346 if( !all_tags.empty() ) 00347 { 00348 error = MB->tag_delete_data( all_tags[0], &handle, 1 ); 00349 if( MB_SUCCESS != error ) return error; 00350 00351 error = MB->tag_delete( all_tags[0] ); 00352 if( MB_SUCCESS != error ) return error; 00353 } 00354 // delete tags test 00355 00356 // delete 2 of the sparse tags that were created above. 00357 handle = verts[2]; 00358 error = MB->tag_delete_data( tag_id, &handle, 1 ); 00359 if( error != MB_SUCCESS ) return error; 00360 00361 handle = verts[6]; 00362 error = MB->tag_delete_data( tag_id, &handle, 1 ); 00363 if( error != MB_SUCCESS ) return error; 00364 00365 // delete all the rest of the sparse tags. 00366 00367 error = MB->tag_delete( tag_id ); 00368 if( error != MB_SUCCESS ) return error; 00369 00370 // delete the dense tag named bool_tag 00371 Tag bool_tag_handle; 00372 error = MB->tag_get_handle( "bool_tag", sizeof( bool ), MB_TYPE_OPAQUE, bool_tag_handle ); 00373 if( error != MB_SUCCESS ) return error; 00374 00375 error = MB->tag_delete( bool_tag_handle ); 00376 if( error != MB_SUCCESS ) return error; 00377 00378 return error; 00379 } 00380 00381 ErrorCode mb_temporary_test() 00382 { 00383 Core moab; 00384 Interface* gMB = &moab; 00385 00386 double array[3] = { 0.0, 0.0, 0.0 }; 00387 EntityHandle h_node1; 00388 ErrorCode result = gMB->create_vertex( array, h_node1 ); 00389 if( MB_SUCCESS != result ) return result; 00390 00391 EntityHandle ordered_meshset1; 00392 result = gMB->create_meshset( MESHSET_ORDERED | MESHSET_TRACK_OWNER, ordered_meshset1 ); 00393 if( MB_SUCCESS != result ) return result; 00394 00395 EntityHandle ordered_meshset2; 00396 result = gMB->create_meshset( MESHSET_ORDERED | MESHSET_TRACK_OWNER, ordered_meshset2 ); 00397 if( MB_SUCCESS != result ) return result; 00398 00399 result = gMB->add_entities( ordered_meshset1, &h_node1, 1 ); 00400 if( MB_SUCCESS != result ) return result; 00401 00402 result = gMB->remove_entities( ordered_meshset1, &h_node1, 1 ); 00403 if( MB_SUCCESS != result ) return result; 00404 00405 result = gMB->add_entities( ordered_meshset2, &h_node1, 1 ); 00406 if( MB_SUCCESS != result ) return result; 00407 00408 bool create_if_missing = false; 00409 std::vector< EntityHandle > meshsets; 00410 result = gMB->get_adjacencies( &h_node1, 1, 4, create_if_missing, meshsets ); 00411 if( MB_SUCCESS != result ) return result; 00412 00413 if( 1u != meshsets.size() ) return MB_FAILURE; 00414 00415 return MB_SUCCESS; 00416 } 00417 00418 ErrorCode mb_adjacent_vertex_test() 00419 { 00420 Core moab; 00421 Interface* mb = &moab; 00422 ErrorCode rval = create_some_mesh( mb ); 00423 if( MB_SUCCESS != rval ) return rval; 00424 00425 Range hexes, expt_vert, got_vert, some_hexes; 00426 Range::const_iterator i, j; 00427 int n; 00428 00429 // get all hexes 00430 rval = mb->get_entities_by_type( 0, MBHEX, hexes ); 00431 if( rval != MB_SUCCESS ) return rval; 00432 if( hexes.empty() ) // can't do test if no elements 00433 return MB_FAILURE; 00434 00435 // get every third hex and its vertices 00436 n = 0; 00437 for( i = hexes.begin(); i != hexes.end(); ++i ) 00438 { 00439 if( ++n % 3 ) continue; 00440 some_hexes.insert( *i ); 00441 const EntityHandle* conn; 00442 int len; 00443 rval = mb->get_connectivity( *i, conn, len ); 00444 if( MB_SUCCESS != rval ) return rval; 00445 for( int k = 0; k < len; ++k ) 00446 expt_vert.insert( conn[k] ); 00447 } 00448 00449 // use get_adjacencies to get vertices 00450 rval = mb->get_adjacencies( some_hexes, 0, false, got_vert, Interface::UNION ); 00451 if( MB_SUCCESS != rval ) 00452 { 00453 std::cout << "get_adjacencies failed with error code " << rval << std::endl; 00454 return rval; 00455 } 00456 00457 i = expt_vert.begin(); 00458 j = got_vert.begin(); 00459 while( i != expt_vert.end() && j != got_vert.end() ) 00460 { 00461 if( *i < *j ) 00462 { 00463 std::cout << "Result missing vertex: " << *i << std::endl; 00464 return MB_FAILURE; 00465 } 00466 else if( *j < *i ) 00467 { 00468 std::cout << "Result contains extra vertex: " << *j << std::endl; 00469 return MB_FAILURE; 00470 } 00471 ++i; 00472 ++j; 00473 } 00474 00475 if( i != expt_vert.end() ) 00476 { 00477 std::cout << "Result missing vertex: " << *i << std::endl; 00478 return MB_FAILURE; 00479 } 00480 else if( j != got_vert.end() ) 00481 { 00482 std::cout << "Result contains extra vertex: " << *j << std::endl; 00483 return MB_FAILURE; 00484 } 00485 00486 return MB_SUCCESS; 00487 } 00488 #ifdef MOAB_HAVE_NETCDF 00489 ErrorCode mb_adjacencies_test() 00490 { 00491 Core moab; 00492 Interface* mb = &moab; 00493 ErrorCode result = load_file_one( mb ); 00494 if( MB_SUCCESS != result ) return result; 00495 00496 // this test does the following: 00497 // 1. For each element, creates vertex-element adjacencies (only for 00498 // lowest-id vertex) 00499 // 2. Creates all lower-order ancillary entities 00500 // 3. Checks for proper number of same 00501 // 00502 // assume mesh has already been read 00503 00504 EntityType seq_type; 00505 Range handle_range; 00506 00507 // lets create a skin of the hexes 00508 // this may be far from being the most efficient, but 00509 // it certainly does exercise the adjacency routines 00510 00511 Range::iterator iter; 00512 Range::reverse_iterator riter; 00513 00514 // first get the hexes 00515 Range hexes; 00516 result = mb->get_entities_by_type( 0, MBHEX, hexes ); 00517 if( MB_SUCCESS != result ) return result; 00518 00519 unsigned int num_hexes = hexes.size(); 00520 00521 // make sure we got hexes 00522 for( riter = hexes.rbegin(); riter != hexes.rend(); ++riter ) 00523 { 00524 if( TYPE_FROM_HANDLE( *riter ) != MBHEX ) return MB_FAILURE; 00525 } 00526 00527 // get all the nodes that these hexes are connected to 00528 Range nodes; 00529 result = mb->get_adjacencies( hexes, 0, false, nodes, Interface::UNION ); 00530 if( MB_SUCCESS != result ) return result; 00531 00532 // make sure we got nodes 00533 for( iter = nodes.begin(); iter != nodes.end(); ++iter ) 00534 { 00535 if( TYPE_FROM_HANDLE( *iter ) != MBVERTEX ) return MB_FAILURE; 00536 } 00537 00538 // find the interior nodes; assume a structured mesh 00539 Range interior_nodes; 00540 std::vector< EntityHandle > attached_hexes; 00541 for( iter = nodes.begin(); iter != nodes.end(); ) 00542 { 00543 attached_hexes.clear(); 00544 result = mb->get_adjacencies( &( *iter ), 1, 3, false, attached_hexes ); 00545 if( MB_SUCCESS != result ) return result; 00546 attached_hexes.erase( std::remove_if( attached_hexes.begin(), attached_hexes.end(), 00547 type_not_equals( mb, MBHEX ) ), 00548 attached_hexes.end() ); 00549 00550 // if this node has less than 8 hexes attached to it, it is not 00551 // an interior node 00552 if( attached_hexes.size() == 8 ) 00553 { 00554 // add to the interior nodes list and remove from the nodes list 00555 interior_nodes.insert( *iter ); 00556 iter = nodes.erase( iter ); 00557 } 00558 else 00559 ++iter; 00560 } 00561 00562 // get interior quads from interior nodes 00563 Range interior_quads; 00564 result = mb->get_adjacencies( interior_nodes, 2, true, interior_quads, Interface::UNION ); 00565 if( MB_SUCCESS != result ) return result; 00566 00567 // get a list of quads generated adjacent to the exterior nodes 00568 Range temp_quads, exterior_quads; 00569 result = mb->get_adjacencies( nodes, 2, true, temp_quads, Interface::UNION ); 00570 if( MB_SUCCESS != result ) return result; 00571 00572 // now remove any interior quads from the previous quads list 00573 // and we should be left with exterior quads 00574 std::set_difference( temp_quads.begin(), temp_quads.end(), interior_quads.begin(), interior_quads.end(), 00575 range_inserter( exterior_quads ) ); 00576 00577 // check to make sure we have the right number of quads; for hexes, should be 00578 // .5(6*num_hexes - num_exterior_quads) 00579 unsigned int num_expected_int_quads = ( 6 * num_hexes - exterior_quads.size() ) / 2; 00580 if( num_expected_int_quads != interior_quads.size() ) return MB_FAILURE; 00581 00582 // delete the interior quads 00583 result = mb->delete_entities( interior_quads ); 00584 if( MB_SUCCESS != result ) return result; 00585 00586 Range remaining_quads; 00587 result = mb->get_entities_by_type( 0, MBQUAD, remaining_quads ); 00588 if( MB_SUCCESS != result ) return result; 00589 00590 if( remaining_quads.size() != exterior_quads.size() ) return MB_FAILURE; 00591 00592 // 3. Checks for proper number of same 00593 // re-retrieve and store the handle ranges for all element types 00594 00595 int num_ents; 00596 00597 for( seq_type = MBEDGE; seq_type != MBENTITYSET; seq_type++ ) 00598 { 00599 handle_range.clear(); 00600 00601 result = mb->get_entities_by_type( 0, seq_type, handle_range ); 00602 if( MB_SUCCESS != result ) return result; 00603 00604 result = mb->get_number_entities_by_type( 0, seq_type, num_ents ); 00605 if( MB_SUCCESS != result ) return result; 00606 00607 if( handle_range.size() != (unsigned int)num_ents ) return MB_FAILURE; 00608 } 00609 00610 return result; 00611 } 00612 00613 #endif 00614 00615 ErrorCode mb_adjacencies_create_delete_test() 00616 { 00617 Core moab; 00618 Interface* mb = &moab; 00619 ErrorCode rval; 00620 00621 double coords[] = { 0, 0, 0, 2, 0, 0, 1, 2, 0 }; 00622 Range verts; 00623 rval = mb->create_vertices( coords, 3, verts ); 00624 if( MB_SUCCESS != rval ) return rval; 00625 if( verts.size() != 3 ) return MB_FAILURE; 00626 EntityHandle vert_arr[3]; 00627 00628 EntityHandle tri; 00629 std::copy( verts.begin(), verts.end(), vert_arr ); 00630 rval = mb->create_element( MBTRI, vert_arr, 3, tri ); 00631 if( MB_SUCCESS != rval ) return rval; 00632 00633 vert_arr[2] = vert_arr[0]; 00634 EntityHandle forward_edge, reverse_edge; 00635 rval = mb->create_element( MBEDGE, vert_arr, 2, forward_edge ); 00636 if( MB_SUCCESS != rval ) return rval; 00637 00638 std::vector< EntityHandle > results; 00639 rval = mb->get_adjacencies( &forward_edge, 1, 2, false, results ); 00640 if( results.size() != 1 || results.front() != tri ) 00641 { 00642 std::cerr << "Adjacency query from forward edge to tri failed at " << __FILE__ << ":" << __LINE__ << std::endl; 00643 return MB_FAILURE; 00644 } 00645 results.clear(); 00646 rval = mb->get_adjacencies( &tri, 1, 1, false, results ); 00647 if( results.size() != 1 || results.front() != forward_edge ) 00648 { 00649 std::cerr << "Adjacency query from tri to forward edge failed at " << __FILE__ << ":" << __LINE__ << std::endl; 00650 return MB_FAILURE; 00651 } 00652 00653 rval = mb->delete_entities( &forward_edge, 1 ); 00654 if( MB_SUCCESS != rval ) return rval; 00655 00656 results.clear(); 00657 rval = mb->get_adjacencies( &tri, 1, 1, false, results ); 00658 if( !results.empty() ) 00659 { 00660 std::cerr << "Adjacency query from tri returned non-existent edge at " << __FILE__ << ":" << __LINE__ 00661 << std::endl; 00662 return MB_FAILURE; 00663 } 00664 00665 rval = mb->create_element( MBEDGE, vert_arr + 1, 2, reverse_edge ); 00666 if( MB_SUCCESS != rval ) return rval; 00667 00668 results.clear(); 00669 rval = mb->get_adjacencies( &reverse_edge, 1, 2, false, results ); 00670 if( results.size() != 1 || results.front() != tri ) 00671 { 00672 std::cerr << "Adjacency query from reverse edge to tri failed at " << __FILE__ << ":" << __LINE__ << std::endl; 00673 return MB_FAILURE; 00674 } 00675 results.clear(); 00676 rval = mb->get_adjacencies( &tri, 1, 1, false, results ); 00677 if( results.size() != 1 || results.front() != reverse_edge ) 00678 { 00679 std::cerr << "Adjacency query from tri to reverse edge failed at " << __FILE__ << ":" << __LINE__ << std::endl; 00680 return MB_FAILURE; 00681 } 00682 00683 return MB_SUCCESS; 00684 } 00685 00686 static ErrorCode create_two_hex_full_mesh( Interface* mb, EntityHandle vertices[12], EntityHandle hexes[2], 00687 EntityHandle hex1_faces[6], EntityHandle hex2_faces[6], 00688 EntityHandle hex1_edges[12], EntityHandle hex2_edges[12] ) 00689 { 00690 ErrorCode rval; 00691 // create a simple mesh containing 2 hexes 00692 const double coords[] = { 0, 0, 0, 1, 0, 0, 2, 0, 0, 0, 1, 0, 1, 1, 0, 2, 1, 0, 00693 0, 0, 1, 1, 0, 1, 2, 0, 1, 0, 1, 1, 1, 1, 1, 2, 1, 1 }; 00694 for( int i = 0; i < 12; ++i ) 00695 if( MB_SUCCESS != mb->create_vertex( coords + 3 * i, vertices[i] ) ) return MB_FAILURE; 00696 EntityHandle hex1_conn[] = { vertices[6], vertices[7], vertices[1], vertices[0], 00697 vertices[9], vertices[10], vertices[4], vertices[3] }; 00698 EntityHandle hex2_conn[] = { vertices[7], vertices[8], vertices[2], vertices[1], 00699 vertices[10], vertices[11], vertices[5], vertices[4] }; 00700 EntityHandle shared_quad_conn[] = { vertices[7], vertices[1], vertices[4], vertices[10] }; 00701 EntityHandle hex1_face_conn[][4] = { { vertices[6], vertices[7], vertices[10], vertices[9] }, 00702 { vertices[7], vertices[6], vertices[0], vertices[1] }, 00703 { vertices[1], vertices[0], vertices[3], vertices[4] }, 00704 { vertices[9], vertices[10], vertices[4], vertices[3] }, 00705 { vertices[3], vertices[0], vertices[6], vertices[9] } }; 00706 EntityHandle hex2_face_conn[][4] = { { vertices[7], vertices[8], vertices[11], vertices[10] }, 00707 { vertices[8], vertices[7], vertices[1], vertices[2] }, 00708 { vertices[2], vertices[1], vertices[4], vertices[5] }, 00709 { vertices[10], vertices[11], vertices[5], vertices[4] }, 00710 { vertices[5], vertices[2], vertices[8], vertices[11] } }; 00711 EntityHandle shared_edge_conn[][2] = { { vertices[1], vertices[7] }, 00712 { vertices[7], vertices[10] }, 00713 { vertices[10], vertices[4] }, 00714 { vertices[4], vertices[1] } }; 00715 EntityHandle hex1_edge_conn[][2] = { { vertices[6], vertices[7] }, { vertices[9], vertices[10] }, 00716 { vertices[3], vertices[4] }, { vertices[0], vertices[1] }, 00717 { vertices[6], vertices[9] }, { vertices[9], vertices[3] }, 00718 { vertices[3], vertices[0] }, { vertices[0], vertices[6] } }; 00719 EntityHandle hex2_edge_conn[][2] = { { vertices[7], vertices[8] }, { vertices[10], vertices[11] }, 00720 { vertices[4], vertices[5] }, { vertices[1], vertices[2] }, 00721 { vertices[8], vertices[11] }, { vertices[11], vertices[5] }, 00722 { vertices[5], vertices[2] }, { vertices[2], vertices[8] } }; 00723 rval = mb->create_element( MBHEX, hex1_conn, 8, hexes[0] ); 00724 if( MB_SUCCESS != rval ) return rval; 00725 rval = mb->create_element( MBHEX, hex2_conn, 8, hexes[1] ); 00726 if( MB_SUCCESS != rval ) return rval; 00727 rval = mb->create_element( MBQUAD, shared_quad_conn, 4, hex1_faces[0] ); 00728 if( MB_SUCCESS != rval ) return rval; 00729 hex2_faces[0] = hex1_faces[0]; 00730 for( int i = 0; i < 5; ++i ) 00731 { 00732 rval = mb->create_element( MBQUAD, hex1_face_conn[i], 4, hex1_faces[i + 1] ); 00733 if( MB_SUCCESS != rval ) return rval; 00734 rval = mb->create_element( MBQUAD, hex2_face_conn[i], 4, hex2_faces[i + 1] ); 00735 if( MB_SUCCESS != rval ) return rval; 00736 } 00737 for( int i = 0; i < 4; ++i ) 00738 { 00739 rval = mb->create_element( MBEDGE, shared_edge_conn[i], 2, hex1_edges[i] ); 00740 if( MB_SUCCESS != rval ) return rval; 00741 hex2_edges[i] = hex1_edges[i]; 00742 } 00743 for( int i = 0; i < 8; ++i ) 00744 { 00745 rval = mb->create_element( MBEDGE, hex1_edge_conn[i], 2, hex1_edges[i + 4] ); 00746 if( MB_SUCCESS != rval ) return rval; 00747 rval = mb->create_element( MBEDGE, hex2_edge_conn[i], 2, hex2_edges[i + 4] ); 00748 if( MB_SUCCESS != rval ) return rval; 00749 } 00750 return MB_SUCCESS; 00751 } 00752 00753 ErrorCode mb_upward_adjacencies_test() 00754 { 00755 ErrorCode rval; 00756 Core moab; 00757 Interface* mb = &moab; 00758 00759 // create a simple mesh containing 2 hexes 00760 EntityHandle vertices[12], hexes[2], hex1_faces[6], hex2_faces[6], hex1_edges[12], hex2_edges[12]; 00761 rval = create_two_hex_full_mesh( mb, vertices, hexes, hex1_faces, hex2_faces, hex1_edges, hex2_edges );MB_CHK_ERR( rval ); 00762 00763 // test adjacences from dim to 3 00764 for( int dim = 0; dim < 3; ++dim ) 00765 { 00766 std::vector< EntityHandle > hex1_ent, hex2_ent, shared; 00767 const EntityHandle *list1, *list2; 00768 int n; 00769 switch( dim ) 00770 { 00771 case 0: 00772 rval = mb->get_connectivity( hexes[0], list1, n );MB_CHK_ERR( rval ); 00773 rval = mb->get_connectivity( hexes[1], list2, n );MB_CHK_ERR( rval ); 00774 break; 00775 case 1: 00776 list1 = hex1_edges; 00777 list2 = hex2_edges; 00778 n = 12; 00779 break; 00780 case 2: 00781 list1 = hex1_faces; 00782 list2 = hex2_faces; 00783 n = 6; 00784 break; 00785 } 00786 // split entities into those uniquely in hex1, those uniquely in hex2 00787 // and those shared between the two 00788 for( int i = 0; i < n; ++i ) 00789 { 00790 if( std::find( list2, list2 + n, list1[i] ) - list2 == n ) 00791 hex1_ent.push_back( list1[i] ); 00792 else 00793 shared.push_back( list1[i] ); 00794 if( std::find( list1, list1 + n, list2[i] ) - list1 == n ) hex2_ent.push_back( list2[i] ); 00795 } 00796 // for each shared entity check that get_adjacencies returns both hexes 00797 for( size_t j = 0; j < shared.size(); ++j ) 00798 { 00799 std::vector< EntityHandle > adj; 00800 rval = mb->get_adjacencies( &shared[j], 1, 3, false, adj );MB_CHK_ERR( rval ); 00801 if( adj.size() != 2 ) 00802 { 00803 std::cout << "Expected 2 hexes adjacent to " << dim << "D entity " << j << ". Got " << adj.size() 00804 << " hexes." << std::endl; 00805 return MB_FAILURE; 00806 } 00807 if( !( adj[0] == hexes[0] && adj[1] == hexes[1] ) && !( adj[0] == hexes[1] && adj[1] == hexes[0] ) ) 00808 { 00809 std::cout << "Got incorrect hexes adjacent to " << dim << "D entity " << j << std::endl; 00810 return MB_FAILURE; 00811 } 00812 } 00813 00814 for( size_t j = 0; j < hex1_ent.size(); ++j ) 00815 { 00816 std::vector< EntityHandle > adj; 00817 rval = mb->get_adjacencies( &hex1_ent[j], 1, 3, false, adj );MB_CHK_ERR( rval ); 00818 CHECK( adj.size() == 1 && adj[0] == hexes[0] ); 00819 } 00820 00821 for( size_t j = 0; j < hex2_ent.size(); ++j ) 00822 { 00823 std::vector< EntityHandle > adj; 00824 rval = mb->get_adjacencies( &hex2_ent[j], 1, 3, false, adj );MB_CHK_ERR( rval ); 00825 CHECK( adj.size() == 1 && adj[0] == hexes[1] ); 00826 } 00827 } 00828 00829 // For each edge, get adjacent faces, and for each face 00830 // get adjacent hexes. Result should be the same as 00831 // direct query from edges to hexes 00832 std::vector< EntityHandle > all_edges( 24 ); 00833 std::copy( hex1_edges, hex1_edges + 12, all_edges.begin() ); 00834 std::copy( hex2_edges, hex2_edges + 12, all_edges.begin() + 12 ); 00835 std::sort( all_edges.begin(), all_edges.end() ); 00836 all_edges.erase( std::unique( all_edges.begin(), all_edges.end() ), all_edges.end() ); 00837 for( size_t j = 0; j < all_edges.size(); ++j ) 00838 { 00839 std::vector< EntityHandle > edge_hexes, edge_faces, face_hexes; 00840 rval = mb->get_adjacencies( &all_edges[j], 1, 3, false, edge_hexes );MB_CHK_ERR( rval ); 00841 rval = mb->get_adjacencies( &all_edges[j], 1, 2, false, edge_faces );MB_CHK_ERR( rval ); 00842 rval = mb->get_adjacencies( &edge_faces[0], edge_faces.size(), 3, false, face_hexes, Interface::UNION );MB_CHK_ERR( rval ); 00843 if( edge_hexes.size() != face_hexes.size() ) 00844 { 00845 std::cout << "Inconsistent adjacency data for edge " << j << ". edge->face->hex resulted in " 00846 << face_hexes.size() << "hexes while edge->hex resulted in " << edge_hexes.size() << std::endl; 00847 return MB_FAILURE; 00848 } 00849 switch( edge_hexes.size() ) 00850 { 00851 case 1: 00852 CHECK( edge_hexes[0] == face_hexes[0] ); 00853 break; 00854 case 2: 00855 CHECK( ( edge_hexes[0] == face_hexes[0] && edge_hexes[1] == face_hexes[1] ) || 00856 ( edge_hexes[0] == face_hexes[1] && edge_hexes[1] == face_hexes[0] ) ); 00857 break; 00858 default: 00859 std::cout << "Got " << edge_hexes.size() << " hexes adjacent to edge " << j << std::endl; 00860 return MB_FAILURE; 00861 } 00862 } 00863 return MB_SUCCESS; 00864 } 00865 00866 ErrorCode mb_adjacent_create_test() 00867 { 00868 Core moab; 00869 Interface& mb = moab; 00870 ErrorCode rval; 00871 00872 // create vertices 00873 const double coords[][3] = { { -0.5, -0.5, 0.5 }, { -0.5, -0.5, -0.5 }, { -0.5, 0.5, -0.5 }, { -0.5, 0.5, 0.5 }, 00874 { 0.5, -0.5, 0.5 }, { 0.5, -0.5, -0.5 }, { 0.5, 0.5, -0.5 }, { 0.5, 0.5, 0.5 } }; 00875 EntityHandle verts[8] = { 0 }; 00876 for( int i = 0; i < 8; ++i ) 00877 { 00878 rval = mb.create_vertex( coords[i], verts[i] );MB_CHK_ERR( rval ); 00879 } 00880 // create a single hex 00881 const EntityHandle hconn[8] = { verts[0], verts[1], verts[2], verts[3], verts[4], verts[5], verts[6], verts[7] }; 00882 EntityHandle hex; 00883 rval = mb.create_element( MBHEX, hconn, 8, hex );MB_CHK_ERR( rval ); 00884 // create hex faces 00885 std::vector< EntityHandle > quads; 00886 rval = mb.get_adjacencies( &hex, 1, 2, true, quads, Interface::UNION );MB_CHK_ERR( rval ); 00887 CHECK_EQUAL( (size_t)6, quads.size() ); 00888 // check that we got each of the 6 expected faces, with outwards 00889 // normals assuming CCW order and correct connectivity 00890 const EntityHandle faces[6][4] = { 00891 { verts[0], verts[1], verts[5], verts[4] }, { verts[1], verts[2], verts[6], verts[5] }, 00892 { verts[2], verts[3], verts[7], verts[6] }, { verts[3], verts[0], verts[4], verts[7] }, 00893 { verts[3], verts[2], verts[1], verts[0] }, { verts[4], verts[5], verts[6], verts[7] } 00894 }; 00895 for( int i = 0; i < 6; ++i ) 00896 { // for each expected face 00897 // get sorted list of verts first for easy comparison 00898 std::vector< EntityHandle > exp_sorted( 4 ); 00899 std::copy( faces[i], faces[i] + 4, exp_sorted.begin() ); 00900 std::sort( exp_sorted.begin(), exp_sorted.end() ); 00901 // search for matching face in output 00902 int j = 0; 00903 std::vector< EntityHandle > conn; 00904 for( ; j < 6; ++j ) 00905 { 00906 conn.clear(); 00907 rval = mb.get_connectivity( &quads[j], 1, conn );MB_CHK_ERR( rval ); 00908 CHECK_EQUAL( (size_t)4, conn.size() ); 00909 std::vector< EntityHandle > sorted( conn ); 00910 std::sort( sorted.begin(), sorted.end() ); 00911 if( sorted == exp_sorted ) break; 00912 } 00913 if( j == 6 ) 00914 { 00915 std::cerr << "No adjacent face matching hex face " << i << std::endl; 00916 CHECK( j < 6 ); 00917 } 00918 // check order 00919 int k = std::find( conn.begin(), conn.end(), faces[i][0] ) - conn.begin(); 00920 for( j = 1; j < 4; ++j ) 00921 if( faces[i][j] != conn[( j + k ) % 4] ) break; 00922 if( j != 4 ) 00923 { 00924 std::cerr << "Incorrect vertex order for hex face " << i << std::endl; 00925 std::cerr << "Expected: " << faces[i][0] << ", " << faces[i][1] << ", " << faces[i][2] << ", " 00926 << faces[i][3] << std::endl; 00927 std::cerr << "Actual: " << conn[0] << ", " << conn[1] << ", " << conn[2] << ", " << conn[3] << std::endl; 00928 CHECK( false ); 00929 } 00930 } 00931 return MB_SUCCESS; 00932 } 00933 00934 ErrorCode nothing_but_type( Range& range, EntityType type ) 00935 { 00936 00937 // make sure there's nothing but hexes in hex_ms 00938 Range::iterator iter, end_iter; 00939 iter = range.begin(); 00940 end_iter = range.end(); 00941 00942 for( ; iter != end_iter; ++iter ) 00943 { 00944 if( TYPE_FROM_HANDLE( *iter ) != type ) { return MB_FAILURE; } 00945 } 00946 return MB_SUCCESS; 00947 } 00948 00949 ErrorCode check_esets( Interface* MB, const int num_sets ) 00950 { 00951 int entity_sets_size; 00952 ErrorCode result = MB->get_number_entities_by_type( 0, MBENTITYSET, entity_sets_size ); 00953 if( MB_SUCCESS != result || entity_sets_size != num_sets ) return MB_FAILURE; 00954 00955 return MB_SUCCESS; 00956 } 00957 00958 ErrorCode mb_mesh_sets_test( int flags ) 00959 { 00960 Core moab; 00961 Interface* MB = &moab; 00962 ErrorCode result = create_some_mesh( MB ); 00963 if( MB_SUCCESS != result ) return result; 00964 00965 Range temp_range; 00966 std::vector< EntityHandle > temp_vector; 00967 EntityType ent_type; 00968 00969 EntityHandle ms_array[MBENTITYSET] = { 0 }; 00970 unsigned int number_array[MBENTITYSET] = { 0 }; 00971 unsigned int num_dim_array[4] = { 0, 0, 0, 0 }; 00972 int count, start_num_sets; 00973 00974 result = MB->get_number_entities_by_type( 0, MBENTITYSET, start_num_sets ); 00975 if( MB_SUCCESS != result ) return result; 00976 00977 // add entities to meshsets 00978 for( ent_type = MBEDGE; ent_type != MBENTITYSET; ent_type++ ) 00979 { 00980 result = MB->create_meshset( flags, ms_array[ent_type] ); 00981 if( result != MB_SUCCESS ) return result; 00982 00983 temp_range.clear(); 00984 result = MB->get_entities_by_type( 0, ent_type, temp_range ); 00985 if( result != MB_SUCCESS ) return result; 00986 result = MB->get_number_entities_by_type( 0, ent_type, count ); 00987 if( result != MB_SUCCESS ) return result; 00988 if( (unsigned)count != temp_range.size() ) return MB_FAILURE; 00989 result = MB->add_entities( ms_array[ent_type], temp_range ); 00990 if( result != MB_SUCCESS ) return result; 00991 00992 number_array[ent_type] = temp_range.size(); // KGM 00993 num_dim_array[CN::Dimension( ent_type )] += count; 00994 00995 // Check to make sure mesh set really has correct number of entities in it 00996 temp_range.clear(); 00997 temp_vector.clear(); 00998 result = MB->get_entities_by_handle( ms_array[ent_type], temp_range ); 00999 if( result != MB_SUCCESS ) return result; 01000 if( number_array[ent_type] != temp_range.size() ) 01001 { 01002 cout << "Number of entities in meshset test is not correct" << endl; 01003 return MB_FAILURE; 01004 } 01005 if( !temp_range.all_of_type( ent_type ) ) return MB_FAILURE; 01006 01007 result = MB->get_entities_by_handle( ms_array[ent_type], temp_vector ); 01008 if( result != MB_SUCCESS ) return result; 01009 if( number_array[ent_type] != temp_vector.size() ) 01010 { 01011 cout << "Number of entities in meshset test is not correct" << endl; 01012 return MB_FAILURE; 01013 } 01014 01015 temp_range.clear(); 01016 result = MB->get_entities_by_type( ms_array[ent_type], ent_type, temp_range ); 01017 if( result != MB_SUCCESS ) return result; 01018 if( number_array[ent_type] != temp_range.size() ) 01019 { 01020 cout << "Number of entities by type in meshset test is not correct" << endl; 01021 return MB_FAILURE; 01022 } 01023 if( !temp_range.all_of_type( ent_type ) ) return MB_FAILURE; 01024 01025 temp_range.clear(); 01026 result = MB->get_entities_by_type( ms_array[ent_type], MBVERTEX, temp_range ); 01027 if( result != MB_SUCCESS ) return result; 01028 if( 0 != temp_range.size() ) return MB_FAILURE; 01029 01030 temp_range.clear(); 01031 result = MB->get_entities_by_dimension( ms_array[ent_type], CN::Dimension( ent_type ), temp_range ); 01032 if( result != MB_SUCCESS ) return result; 01033 if( number_array[ent_type] != temp_range.size() ) 01034 { 01035 cout << "Number of entities by dimension in meshset test is not correct" << endl; 01036 return MB_FAILURE; 01037 } 01038 if( !temp_range.all_of_type( ent_type ) ) return MB_FAILURE; 01039 01040 temp_range.clear(); 01041 result = MB->get_entities_by_dimension( ms_array[ent_type], 0, temp_range ); 01042 if( result != MB_SUCCESS ) return result; 01043 if( 0 != temp_range.size() ) 01044 { 01045 cout << "Number of entities by dimension in meshset test is not correct" << endl; 01046 return MB_FAILURE; 01047 } 01048 01049 result = MB->get_number_entities_by_handle( ms_array[ent_type], count ); 01050 if( result != MB_SUCCESS ) return result; 01051 if( (unsigned)count != number_array[ent_type] ) return MB_FAILURE; 01052 01053 result = MB->get_number_entities_by_type( ms_array[ent_type], ent_type, count ); 01054 if( result != MB_SUCCESS ) return result; 01055 if( (unsigned)count != number_array[ent_type] ) return MB_FAILURE; 01056 01057 result = MB->get_number_entities_by_type( ms_array[ent_type], MBVERTEX, count ); 01058 if( result != MB_SUCCESS ) return result; 01059 if( count != 0 ) return MB_FAILURE; 01060 01061 result = MB->get_number_entities_by_dimension( ms_array[ent_type], CN::Dimension( ent_type ), count ); 01062 if( result != MB_SUCCESS ) return result; 01063 if( (unsigned)count != number_array[ent_type] ) return MB_FAILURE; 01064 01065 result = MB->get_number_entities_by_dimension( ms_array[ent_type], 0, count ); 01066 if( result != MB_SUCCESS ) return result; 01067 if( count != 0 ) return MB_FAILURE; 01068 } 01069 01070 result = check_esets( MB, start_num_sets + MBENTITYSET - MBEDGE ); 01071 if( MB_SUCCESS != result ) return result; 01072 01073 for( int dim = 1; dim < 4; ++dim ) 01074 { 01075 result = MB->get_number_entities_by_dimension( 0, dim, count ); 01076 if( MB_SUCCESS != result ) return MB_FAILURE; 01077 if( (unsigned)count != num_dim_array[dim] ) return MB_FAILURE; 01078 } 01079 01080 //----------TEST RECURSIVE OPERATIONS----------------// 01081 EntityHandle recursive1, recursive2; 01082 result = MB->create_meshset( MESHSET_SET, recursive1 ); 01083 if( result != MB_SUCCESS ) return result; 01084 result = MB->create_meshset( 0, recursive2 ); 01085 if( result != MB_SUCCESS ) return result; 01086 unsigned num_sets = MBENTITYSET - MBEDGE; 01087 result = MB->add_entities( recursive2, ms_array + MBEDGE, num_sets ); 01088 if( MB_SUCCESS != result ) return result; 01089 result = MB->add_entities( recursive1, &recursive2, 1 ); 01090 if( MB_SUCCESS != result ) return result; 01091 01092 temp_range.clear(); 01093 result = MB->get_entities_by_type( recursive1, MBENTITYSET, temp_range ); 01094 if( MB_SUCCESS != result ) return result; 01095 if( temp_range.size() != 1 || *( temp_range.begin() ) != recursive2 ) return MB_FAILURE; 01096 01097 temp_range.clear(); 01098 result = MB->get_entities_by_type( recursive2, MBENTITYSET, temp_range ); 01099 if( MB_SUCCESS != result ) return result; 01100 if( temp_range.size() != num_sets || !temp_range.all_of_type( MBENTITYSET ) ) return MB_FAILURE; 01101 01102 temp_range.clear(); 01103 result = MB->get_entities_by_handle( recursive1, temp_range ); 01104 if( MB_SUCCESS != result ) return result; 01105 if( temp_range.size() != 1 || *( temp_range.begin() ) != recursive2 ) return MB_FAILURE; 01106 01107 temp_range.clear(); 01108 result = MB->get_entities_by_handle( recursive2, temp_range ); 01109 if( MB_SUCCESS != result ) return result; 01110 if( temp_range.size() != num_sets || !temp_range.all_of_type( MBENTITYSET ) ) return MB_FAILURE; 01111 01112 unsigned total = 0; 01113 for( ent_type = MBEDGE; ent_type != MBENTITYSET; ent_type++ ) 01114 { 01115 total += number_array[ent_type]; 01116 temp_range.clear(); 01117 result = MB->get_entities_by_type( recursive1, ent_type, temp_range, true ); 01118 if( result != MB_SUCCESS ) return result; 01119 if( number_array[ent_type] != temp_range.size() ) 01120 { 01121 cout << "Recursive number of entities by type in meshset test is not correct" << endl; 01122 return MB_FAILURE; 01123 } 01124 if( !temp_range.all_of_type( ent_type ) ) return MB_FAILURE; 01125 result = MB->get_number_entities_by_type( recursive1, ent_type, count, true ); 01126 if( result != MB_SUCCESS ) return result; 01127 if( number_array[ent_type] != (unsigned)count ) 01128 { 01129 cout << "Recursive number of entities by type in meshset test is not correct" << endl; 01130 return MB_FAILURE; 01131 } 01132 if( !temp_range.all_of_type( ent_type ) ) return MB_FAILURE; 01133 } 01134 if( 0 == total ) 01135 { 01136 cout << "Invalid test input. No entities!" << endl; 01137 return MB_FAILURE; 01138 } 01139 01140 for( int dim = 1; dim < 4; ++dim ) 01141 { 01142 temp_range.clear(); 01143 result = MB->get_entities_by_dimension( recursive1, dim, temp_range, true ); 01144 if( MB_SUCCESS != result ) return MB_FAILURE; 01145 if( temp_range.size() != num_dim_array[dim] ) return MB_FAILURE; 01146 if( !temp_range.all_of_dimension( dim ) ) return MB_FAILURE; 01147 result = MB->get_number_entities_by_dimension( recursive1, dim, count, true ); 01148 if( MB_SUCCESS != result ) return MB_FAILURE; 01149 if( (unsigned)count != num_dim_array[dim] ) return MB_FAILURE; 01150 } 01151 01152 temp_range.clear(); 01153 result = MB->get_entities_by_handle( recursive1, temp_range, true ); 01154 if( result != MB_SUCCESS ) return result; 01155 if( total != temp_range.size() ) 01156 { 01157 cout << "Recursive number of entities in meshset test is not correct" << endl; 01158 return MB_FAILURE; 01159 } 01160 01161 // try circular relation 01162 result = MB->add_entities( recursive2, &recursive1, 1 ); 01163 if( MB_SUCCESS != result ) 01164 { 01165 std::cout << "Failed to create circular set containment" << std::endl; 01166 return result; 01167 } 01168 temp_range.clear(); 01169 result = MB->get_entities_by_handle( recursive1, temp_range, true ); 01170 if( result != MB_SUCCESS ) return result; 01171 if( total != temp_range.size() ) 01172 { 01173 cout << "Recursive number of entities in meshset test is not correct" << endl; 01174 return MB_FAILURE; 01175 } 01176 01177 result = check_esets( MB, start_num_sets + MBENTITYSET - MBEDGE + 2 ); 01178 if( MB_SUCCESS != result ) return result; 01179 01180 //----------TEST BOOLEAN OPERATIONS----------------// 01181 01182 EntityHandle temp_ms1, temp_ms2; 01183 result = MB->create_meshset( flags, temp_ms1 ); 01184 if( result != MB_SUCCESS ) return result; 01185 result = MB->create_meshset( flags, temp_ms2 ); 01186 if( result != MB_SUCCESS ) return result; 01187 01188 // Subtract 01189 // add all edges and hexes of ms_array[MBHEX] and ms_array[MBEDGE] to temp_ms1 01190 // get all Edge entities 01191 temp_range.clear(); 01192 result = MB->get_entities_by_handle( ms_array[MBEDGE], temp_range ); 01193 if( result != MB_SUCCESS ) return result; 01194 01195 // add Edges to ms1 01196 result = MB->add_entities( temp_ms1, temp_range ); 01197 if( result != MB_SUCCESS ) return result; 01198 01199 temp_range.clear(); 01200 result = MB->get_entities_by_handle( ms_array[MBHEX], temp_range ); 01201 if( result != MB_SUCCESS ) return result; 01202 01203 // add Hexes to ms1 01204 result = MB->add_entities( temp_ms1, temp_range ); 01205 if( result != MB_SUCCESS ) return result; 01206 01207 // subtract bars meshset out of hex meshset 01208 result = MB->subtract_meshset( temp_ms1, ms_array[MBEDGE] ); 01209 if( result != MB_SUCCESS ) return result; 01210 01211 // Perform the check 01212 temp_range.clear(); 01213 result = MB->get_entities_by_handle( temp_ms1, temp_range ); 01214 if( result != MB_SUCCESS ) return result; 01215 01216 if( number_array[MBHEX] != temp_range.size() ) 01217 { 01218 cout << "MBset subtraction is bad" << endl; 01219 return MB_FAILURE; 01220 } 01221 // make sure there's nothing but hexes in hex_ms 01222 if( nothing_but_type( temp_range, MBHEX ) != MB_SUCCESS ) return MB_FAILURE; 01223 01224 result = check_esets( MB, start_num_sets + MBENTITYSET - MBEDGE + 4 ); 01225 if( MB_SUCCESS != result ) return result; 01226 01227 //------------Intersect------------ 01228 // 01229 // clean out the temp_ms1 01230 MB->clear_meshset( &temp_ms1, 1 ); 01231 01232 temp_range.clear(); 01233 // get all quad entities 01234 temp_range.clear(); 01235 result = MB->get_entities_by_handle( ms_array[MBQUAD], temp_range ); 01236 if( result != MB_SUCCESS ) return result; 01237 01238 // add tets them to ms1 01239 result = MB->add_entities( temp_ms1, temp_range ); 01240 if( result != MB_SUCCESS ) return result; 01241 01242 // get all tet entities 01243 temp_range.clear(); 01244 result = MB->get_entities_by_handle( ms_array[MBTET], temp_range ); 01245 if( result != MB_SUCCESS ) return result; 01246 01247 // add tets them to ms1 01248 result = MB->add_entities( temp_ms1, temp_range ); 01249 if( result != MB_SUCCESS ) return result; 01250 01251 // intersect temp_ms1 (which contains all quads and tets) with tet meshset 01252 // temp_ms1 meshset is altered 01253 result = MB->intersect_meshset( temp_ms1, ms_array[MBTET] ); 01254 if( result != MB_SUCCESS ) return result; 01255 01256 // Perform the check, only tets should be in temp_ms1 01257 temp_range.clear(); 01258 result = MB->get_entities_by_handle( temp_ms1, temp_range ); 01259 if( result != MB_SUCCESS ) return result; 01260 if( number_array[MBTET] != temp_range.size() ) 01261 { 01262 cout << "MBset intersection is bad" << endl; 01263 return MB_FAILURE; 01264 } 01265 01266 // make sure there's nothing but tet in range 01267 if( nothing_but_type( temp_range, MBTET ) != MB_SUCCESS ) return MB_FAILURE; 01268 01269 result = check_esets( MB, start_num_sets + MBENTITYSET - MBEDGE + 4 ); 01270 if( MB_SUCCESS != result ) return result; 01271 01272 //-------------Unite-------------- 01273 // fill temp_ms1 with tets and tris 01274 // get all tris 01275 temp_range.clear(); 01276 result = MB->get_entities_by_handle( ms_array[MBTRI], temp_range ); 01277 if( result != MB_SUCCESS ) return result; 01278 01279 // add tets them to ms1 01280 result = MB->add_entities( temp_ms1, temp_range ); 01281 if( result != MB_SUCCESS ) return result; 01282 01283 temp_range.clear(); 01284 result = MB->get_entities_by_handle( ms_array[MBTET], temp_range ); 01285 if( result != MB_SUCCESS ) return result; 01286 01287 // add tets them to ms1 01288 result = MB->add_entities( temp_ms1, temp_range ); 01289 if( result != MB_SUCCESS ) return result; 01290 01291 // fill temp_ms2 with tris and hexes 01292 temp_range.clear(); 01293 result = MB->get_entities_by_handle( ms_array[MBTRI], temp_range ); 01294 if( result != MB_SUCCESS ) return result; 01295 01296 // add tets them to ms1 01297 result = MB->add_entities( temp_ms2, temp_range ); 01298 if( result != MB_SUCCESS ) return result; 01299 01300 temp_range.clear(); 01301 result = MB->get_entities_by_handle( ms_array[MBQUAD], temp_range ); 01302 if( result != MB_SUCCESS ) return result; 01303 01304 // add tets them to ms1 01305 result = MB->add_entities( temp_ms2, temp_range ); 01306 if( result != MB_SUCCESS ) return result; 01307 01308 // temp_ms1 is now filled with tets and tris 01309 // temp_ms2 is now filled with quads and tris 01310 int size1 = 0, size2 = 0; 01311 result = MB->get_number_entities_by_handle( ms_array[MBTRI], size1 ); 01312 if( result != MB_SUCCESS ) return result; 01313 01314 result = MB->intersect_meshset( temp_ms1, temp_ms2 ); 01315 if( result != MB_SUCCESS ) return result; 01316 result = MB->get_number_entities_by_handle( temp_ms1, size2 ); 01317 if( result != MB_SUCCESS ) return result; 01318 01319 if( size1 != size2 ) { return MB_FAILURE; } 01320 01321 temp_range.clear(); 01322 result = MB->get_entities_by_handle( temp_ms1, temp_range ); 01323 if( result != MB_SUCCESS ) return result; 01324 01325 // make sure there's nothing but tris in temp_range 01326 if( nothing_but_type( temp_range, MBTRI ) != MB_SUCCESS ) return MB_FAILURE; 01327 01328 result = check_esets( MB, start_num_sets + MBENTITYSET - MBEDGE + 4 ); 01329 if( MB_SUCCESS != result ) return result; 01330 01331 //-------------Misc tests-------------- 01332 EntityHandle temp_ms3; 01333 result = MB->create_meshset( flags, temp_ms3 ); 01334 if( result != MB_SUCCESS ) return result; 01335 01336 EntityHandle handle_array[] = { 1, 2, 3, 4, 5, 7, 8, 9, 10 }; 01337 const int num_handle = sizeof( handle_array ) / sizeof( handle_array[0] ); 01338 // add ents to set 01339 result = MB->add_entities( temp_ms3, handle_array, num_handle ); 01340 if( result != MB_SUCCESS ) return result; 01341 01342 // try adding again 01343 result = MB->add_entities( temp_ms3, handle_array, num_handle ); 01344 if( result != MB_SUCCESS ) return result; 01345 01346 int num_ents; 01347 result = MB->get_number_entities_by_handle( temp_ms3, num_ents ); 01348 if( result != MB_SUCCESS ) return result; 01349 01350 int num_expected = ( flags & MESHSET_SET ) ? num_handle : 2 * num_handle; 01351 if( num_ents != num_expected ) return MB_FAILURE; 01352 01353 return MB_SUCCESS; 01354 } 01355 01356 static bool compare_lists( std::vector< EntityHandle > vect, const EntityHandle* array, int count, bool ordered = true ) 01357 { 01358 if( vect.size() != (size_t)count ) return false; 01359 for( int i = 0; i < count; ++i ) 01360 { 01361 if( ordered ) 01362 { 01363 if( vect[i] != array[i] ) return false; 01364 } 01365 else if( std::find( vect.begin(), vect.end(), array[i] ) == vect.end() ) 01366 return false; 01367 } 01368 return true; 01369 } 01370 01371 // Test parent/child stuff in meshsets 01372 ErrorCode mb_mesh_set_parent_child_test() 01373 { 01374 Core moab; 01375 Interface* MB = &moab; 01376 01377 ErrorCode rval; 01378 std::vector< EntityHandle > list; 01379 Range range; 01380 Range::iterator iter; 01381 int count; 01382 01383 // create a few mesh sets 01384 const int num_sets = 10; 01385 EntityHandle sets[num_sets]; 01386 for( int i = 0; i < num_sets; ++i ) 01387 { 01388 rval = MB->create_meshset( i % 2 ? MESHSET_SET : 0, sets[i] ); 01389 if( MB_SUCCESS != rval ) return rval; 01390 } 01391 01392 // test adding child meshsets 01393 01394 // add first child 01395 rval = MB->add_child_meshset( sets[0], sets[1] ); 01396 if( MB_SUCCESS != rval ) return rval; 01397 list.clear(); 01398 rval = MB->get_child_meshsets( sets[0], list ); 01399 if( MB_SUCCESS != rval ) return rval; 01400 if( !compare_lists( list, sets + 1, 1 ) ) return MB_FAILURE; 01401 // try to add child again 01402 rval = MB->add_child_meshset( sets[0], sets[1] ); 01403 if( MB_SUCCESS != rval ) return rval; 01404 list.clear(); 01405 rval = MB->get_child_meshsets( sets[0], list ); 01406 if( MB_SUCCESS != rval ) return rval; 01407 if( !compare_lists( list, sets + 1, 1 ) ) return MB_FAILURE; 01408 01409 // add second child 01410 rval = MB->add_child_meshset( sets[0], sets[2] ); 01411 if( MB_SUCCESS != rval ) return rval; 01412 list.clear(); 01413 rval = MB->get_child_meshsets( sets[0], list ); 01414 if( MB_SUCCESS != rval ) return rval; 01415 if( !compare_lists( list, sets + 1, 2 ) ) return MB_FAILURE; 01416 // try adding child again 01417 rval = MB->add_child_meshset( sets[0], sets[1] ); 01418 if( MB_SUCCESS != rval ) return rval; 01419 list.clear(); 01420 rval = MB->get_child_meshsets( sets[0], list ); 01421 if( MB_SUCCESS != rval ) return rval; 01422 if( !compare_lists( list, sets + 1, 2 ) ) return MB_FAILURE; 01423 01424 // add third child 01425 rval = MB->add_child_meshset( sets[0], sets[3] ); 01426 if( MB_SUCCESS != rval ) return rval; 01427 list.clear(); 01428 rval = MB->get_child_meshsets( sets[0], list ); 01429 if( MB_SUCCESS != rval ) return rval; 01430 if( !compare_lists( list, sets + 1, 3 ) ) return MB_FAILURE; 01431 // try adding child again 01432 rval = MB->add_child_meshset( sets[0], sets[1] ); 01433 if( MB_SUCCESS != rval ) return rval; 01434 list.clear(); 01435 rval = MB->get_child_meshsets( sets[0], list ); 01436 if( MB_SUCCESS != rval ) return rval; 01437 if( !compare_lists( list, sets + 1, 3 ) ) return MB_FAILURE; 01438 01439 // add fourth child 01440 rval = MB->add_child_meshset( sets[0], sets[4] ); 01441 if( MB_SUCCESS != rval ) return rval; 01442 list.clear(); 01443 rval = MB->get_child_meshsets( sets[0], list ); 01444 if( MB_SUCCESS != rval ) return rval; 01445 if( !compare_lists( list, sets + 1, 4 ) ) return MB_FAILURE; 01446 01447 // make sure range query returns same result 01448 std::sort( list.begin(), list.end() ); 01449 rval = MB->get_child_meshsets( sets[0], range ); 01450 iter = range.begin(); 01451 for( unsigned i = 0; i < 4; ++i, ++iter ) 01452 if( *iter != list[i] ) return MB_FAILURE; 01453 01454 // remove first child 01455 rval = MB->remove_child_meshset( sets[0], sets[1] ); 01456 if( MB_SUCCESS != rval ) return rval; 01457 list.clear(); 01458 rval = MB->get_child_meshsets( sets[0], list ); 01459 if( MB_SUCCESS != rval ) return rval; 01460 if( !compare_lists( list, sets + 2, 3 ) ) return MB_FAILURE; 01461 // try removing child again 01462 rval = MB->remove_child_meshset( sets[0], sets[1] ); 01463 if( MB_SUCCESS != rval ) return rval; 01464 01465 // remove second child 01466 rval = MB->remove_child_meshset( sets[0], sets[2] ); 01467 if( MB_SUCCESS != rval ) return rval; 01468 list.clear(); 01469 rval = MB->get_child_meshsets( sets[0], list ); 01470 if( !compare_lists( list, sets + 3, 2 ) ) return MB_FAILURE; 01471 // try removing child again 01472 rval = MB->remove_child_meshset( sets[0], sets[2] ); 01473 if( MB_SUCCESS != rval ) return rval; 01474 01475 // remove third child 01476 rval = MB->remove_child_meshset( sets[0], sets[3] ); 01477 if( MB_SUCCESS != rval ) return rval; 01478 list.clear(); 01479 rval = MB->get_child_meshsets( sets[0], list ); 01480 if( list.size() != 1 || list[0] != sets[4] ) return MB_FAILURE; 01481 01482 // remove fourth child 01483 rval = MB->remove_child_meshset( sets[0], sets[4] ); 01484 if( MB_SUCCESS != rval ) return rval; 01485 list.clear(); 01486 rval = MB->get_child_meshsets( sets[0], list ); 01487 if( !list.empty() ) return MB_FAILURE; 01488 01489 // test adding parent meshsets 01490 01491 // add first parent 01492 rval = MB->add_parent_meshset( sets[0], sets[1] ); 01493 if( MB_SUCCESS != rval ) return rval; 01494 list.clear(); 01495 rval = MB->get_parent_meshsets( sets[0], list ); 01496 if( MB_SUCCESS != rval ) return rval; 01497 if( !compare_lists( list, sets + 1, 1 ) ) return MB_FAILURE; 01498 // try to add parent again 01499 rval = MB->add_parent_meshset( sets[0], sets[1] ); 01500 if( MB_SUCCESS != rval ) return rval; 01501 list.clear(); 01502 rval = MB->get_parent_meshsets( sets[0], list ); 01503 if( MB_SUCCESS != rval ) return rval; 01504 if( !compare_lists( list, sets + 1, 1 ) ) return MB_FAILURE; 01505 01506 // add second parent 01507 rval = MB->add_parent_meshset( sets[0], sets[2] ); 01508 if( MB_SUCCESS != rval ) return rval; 01509 list.clear(); 01510 rval = MB->get_parent_meshsets( sets[0], list ); 01511 if( MB_SUCCESS != rval ) return rval; 01512 if( !compare_lists( list, sets + 1, 2 ) ) return MB_FAILURE; 01513 // try adding parent again 01514 rval = MB->add_parent_meshset( sets[0], sets[1] ); 01515 if( MB_SUCCESS != rval ) return rval; 01516 list.clear(); 01517 rval = MB->get_parent_meshsets( sets[0], list ); 01518 if( MB_SUCCESS != rval ) return rval; 01519 if( !compare_lists( list, sets + 1, 2 ) ) return MB_FAILURE; 01520 01521 // add third parent 01522 rval = MB->add_parent_meshset( sets[0], sets[3] ); 01523 if( MB_SUCCESS != rval ) return rval; 01524 list.clear(); 01525 rval = MB->get_parent_meshsets( sets[0], list ); 01526 if( MB_SUCCESS != rval ) return rval; 01527 if( !compare_lists( list, sets + 1, 3 ) ) return MB_FAILURE; 01528 // try adding parent again 01529 rval = MB->add_parent_meshset( sets[0], sets[1] ); 01530 if( MB_SUCCESS != rval ) return rval; 01531 list.clear(); 01532 rval = MB->get_parent_meshsets( sets[0], list ); 01533 if( MB_SUCCESS != rval ) return rval; 01534 if( !compare_lists( list, sets + 1, 3 ) ) return MB_FAILURE; 01535 01536 // add fourth parent 01537 rval = MB->add_parent_meshset( sets[0], sets[4] ); 01538 if( MB_SUCCESS != rval ) return rval; 01539 list.clear(); 01540 rval = MB->get_parent_meshsets( sets[0], list ); 01541 if( MB_SUCCESS != rval ) return rval; 01542 if( !compare_lists( list, sets + 1, 4 ) ) return MB_FAILURE; 01543 01544 // make sure range query returns same result 01545 std::sort( list.begin(), list.end() ); 01546 rval = MB->get_parent_meshsets( sets[0], range ); 01547 iter = range.begin(); 01548 for( unsigned i = 0; i < 4; ++i, ++iter ) 01549 if( *iter != list[i] ) return MB_FAILURE; 01550 01551 // remove first parent 01552 rval = MB->remove_parent_meshset( sets[0], sets[1] ); 01553 if( MB_SUCCESS != rval ) return rval; 01554 list.clear(); 01555 rval = MB->get_parent_meshsets( sets[0], list ); 01556 if( MB_SUCCESS != rval ) return rval; 01557 if( !compare_lists( list, sets + 2, 3 ) ) return MB_FAILURE; 01558 // try removing parent again 01559 rval = MB->remove_parent_meshset( sets[0], sets[1] ); 01560 if( MB_SUCCESS != rval ) return rval; 01561 01562 // remove second parent 01563 rval = MB->remove_parent_meshset( sets[0], sets[2] ); 01564 if( MB_SUCCESS != rval ) return rval; 01565 list.clear(); 01566 rval = MB->get_parent_meshsets( sets[0], list ); 01567 if( !compare_lists( list, sets + 3, 2 ) ) return MB_FAILURE; 01568 // try removing parent again 01569 rval = MB->remove_parent_meshset( sets[0], sets[2] ); 01570 if( MB_SUCCESS != rval ) return rval; 01571 01572 // remove third parent 01573 rval = MB->remove_parent_meshset( sets[0], sets[3] ); 01574 if( MB_SUCCESS != rval ) return rval; 01575 list.clear(); 01576 rval = MB->get_parent_meshsets( sets[0], list ); 01577 if( list.size() != 1 || list[0] != sets[4] ) return MB_FAILURE; 01578 01579 // remove fourth parent 01580 rval = MB->remove_parent_meshset( sets[0], sets[4] ); 01581 if( MB_SUCCESS != rval ) return rval; 01582 list.clear(); 01583 rval = MB->get_parent_meshsets( sets[0], list ); 01584 if( !list.empty() ) return MB_FAILURE; 01585 01586 // setup tests of recursive child query 01587 // 0 01588 // / \ . 01589 // 1 2 01590 // / \ / \ . 01591 // 3 4 5 01592 // \ / \ / 01593 // 6 7 01594 rval = MB->add_child_meshset( sets[0], sets[1] ); 01595 if( MB_SUCCESS != rval ) return rval; 01596 rval = MB->add_child_meshset( sets[0], sets[2] ); 01597 if( MB_SUCCESS != rval ) return rval; 01598 rval = MB->add_child_meshset( sets[1], sets[3] ); 01599 if( MB_SUCCESS != rval ) return rval; 01600 rval = MB->add_child_meshset( sets[1], sets[4] ); 01601 if( MB_SUCCESS != rval ) return rval; 01602 rval = MB->add_child_meshset( sets[2], sets[4] ); 01603 if( MB_SUCCESS != rval ) return rval; 01604 rval = MB->add_child_meshset( sets[2], sets[5] ); 01605 if( MB_SUCCESS != rval ) return rval; 01606 rval = MB->add_child_meshset( sets[3], sets[6] ); 01607 if( MB_SUCCESS != rval ) return rval; 01608 rval = MB->add_child_meshset( sets[4], sets[6] ); 01609 if( MB_SUCCESS != rval ) return rval; 01610 rval = MB->add_child_meshset( sets[4], sets[7] ); 01611 if( MB_SUCCESS != rval ) return rval; 01612 rval = MB->add_child_meshset( sets[5], sets[7] ); 01613 if( MB_SUCCESS != rval ) return rval; 01614 01615 // test query at depth of 1 01616 list.clear(); 01617 rval = MB->get_child_meshsets( sets[0], list, 1 ); 01618 if( MB_SUCCESS != rval ) return rval; 01619 if( list.size() != 2 || list[0] != sets[1] || list[1] != sets[2] ) return MB_FAILURE; 01620 rval = MB->num_child_meshsets( sets[0], &count, 1 ); 01621 if( MB_SUCCESS != rval ) return rval; 01622 if( count != 2 ) return MB_FAILURE; 01623 01624 // test query at depth of 2 01625 list.clear(); 01626 rval = MB->get_child_meshsets( sets[0], list, 2 ); 01627 if( MB_SUCCESS != rval ) return rval; 01628 if( !compare_lists( list, sets + 1, 5, false ) ) return MB_FAILURE; 01629 rval = MB->num_child_meshsets( sets[0], &count, 2 ); 01630 if( MB_SUCCESS != rval ) return rval; 01631 if( count != 5 ) return MB_FAILURE; 01632 01633 // test query at depth of 3 01634 list.clear(); 01635 rval = MB->get_child_meshsets( sets[0], list, 3 ); 01636 if( MB_SUCCESS != rval ) return rval; 01637 if( !compare_lists( list, sets + 1, 7, false ) ) return MB_FAILURE; 01638 rval = MB->num_child_meshsets( sets[0], &count, 3 ); 01639 if( MB_SUCCESS != rval ) return rval; 01640 if( count != 7 ) return MB_FAILURE; 01641 01642 // test query at depth of 4 01643 list.clear(); 01644 rval = MB->get_child_meshsets( sets[0], list, 4 ); 01645 if( MB_SUCCESS != rval ) return rval; 01646 if( !compare_lists( list, sets + 1, 7, false ) ) return MB_FAILURE; 01647 rval = MB->num_child_meshsets( sets[0], &count, 4 ); 01648 if( MB_SUCCESS != rval ) return rval; 01649 if( count != 7 ) return MB_FAILURE; 01650 01651 // test query at all 01652 list.clear(); 01653 rval = MB->get_child_meshsets( sets[0], list, 0 ); 01654 if( MB_SUCCESS != rval ) return rval; 01655 if( !compare_lists( list, sets + 1, 7, false ) ) return MB_FAILURE; 01656 rval = MB->num_child_meshsets( sets[0], &count, 0 ); 01657 if( MB_SUCCESS != rval ) return rval; 01658 if( count != 7 ) return MB_FAILURE; 01659 01660 // clean up child links 01661 rval = MB->remove_child_meshset( sets[0], sets[1] ); 01662 if( MB_SUCCESS != rval ) return rval; 01663 rval = MB->remove_child_meshset( sets[0], sets[2] ); 01664 if( MB_SUCCESS != rval ) return rval; 01665 rval = MB->remove_child_meshset( sets[1], sets[3] ); 01666 if( MB_SUCCESS != rval ) return rval; 01667 rval = MB->remove_child_meshset( sets[1], sets[4] ); 01668 if( MB_SUCCESS != rval ) return rval; 01669 rval = MB->remove_child_meshset( sets[2], sets[4] ); 01670 if( MB_SUCCESS != rval ) return rval; 01671 rval = MB->remove_child_meshset( sets[2], sets[5] ); 01672 if( MB_SUCCESS != rval ) return rval; 01673 rval = MB->remove_child_meshset( sets[3], sets[6] ); 01674 if( MB_SUCCESS != rval ) return rval; 01675 rval = MB->remove_child_meshset( sets[4], sets[6] ); 01676 if( MB_SUCCESS != rval ) return rval; 01677 rval = MB->remove_child_meshset( sets[4], sets[7] ); 01678 if( MB_SUCCESS != rval ) return rval; 01679 rval = MB->remove_child_meshset( sets[5], sets[7] ); 01680 if( MB_SUCCESS != rval ) return rval; 01681 for( int i = 0; i < 5; ++i ) 01682 if( MB_SUCCESS != MB->num_child_meshsets( sets[i], &count ) || count ) return MB_FAILURE; 01683 01684 // setup tests of recursive parent query 01685 // 6 7 01686 // / \ / \ . 01687 // 3 4 5 01688 // \ / \ / 01689 // 1 2 01690 // \ / 01691 // 0 01692 rval = MB->add_parent_meshset( sets[0], sets[1] ); 01693 if( MB_SUCCESS != rval ) return rval; 01694 rval = MB->add_parent_meshset( sets[0], sets[2] ); 01695 if( MB_SUCCESS != rval ) return rval; 01696 rval = MB->add_parent_meshset( sets[1], sets[3] ); 01697 if( MB_SUCCESS != rval ) return rval; 01698 rval = MB->add_parent_meshset( sets[1], sets[4] ); 01699 if( MB_SUCCESS != rval ) return rval; 01700 rval = MB->add_parent_meshset( sets[2], sets[4] ); 01701 if( MB_SUCCESS != rval ) return rval; 01702 rval = MB->add_parent_meshset( sets[2], sets[5] ); 01703 if( MB_SUCCESS != rval ) return rval; 01704 rval = MB->add_parent_meshset( sets[3], sets[6] ); 01705 if( MB_SUCCESS != rval ) return rval; 01706 rval = MB->add_parent_meshset( sets[4], sets[6] ); 01707 if( MB_SUCCESS != rval ) return rval; 01708 rval = MB->add_parent_meshset( sets[4], sets[7] ); 01709 if( MB_SUCCESS != rval ) return rval; 01710 rval = MB->add_parent_meshset( sets[5], sets[7] ); 01711 if( MB_SUCCESS != rval ) return rval; 01712 01713 // test query at depth of 1 01714 list.clear(); 01715 rval = MB->get_parent_meshsets( sets[0], list, 1 ); 01716 if( MB_SUCCESS != rval ) return rval; 01717 if( list.size() != 2 || list[0] != sets[1] || list[1] != sets[2] ) return MB_FAILURE; 01718 rval = MB->num_parent_meshsets( sets[0], &count, 1 ); 01719 if( MB_SUCCESS != rval ) return rval; 01720 if( count != 2 ) return MB_FAILURE; 01721 01722 // test query at depth of 2 01723 list.clear(); 01724 rval = MB->get_parent_meshsets( sets[0], list, 2 ); 01725 if( MB_SUCCESS != rval ) return rval; 01726 if( !compare_lists( list, sets + 1, 5, false ) ) return MB_FAILURE; 01727 rval = MB->num_parent_meshsets( sets[0], &count, 2 ); 01728 if( MB_SUCCESS != rval ) return rval; 01729 if( count != 5 ) return MB_FAILURE; 01730 01731 // test query at depth of 3 01732 list.clear(); 01733 rval = MB->get_parent_meshsets( sets[0], list, 3 ); 01734 if( MB_SUCCESS != rval ) return rval; 01735 if( !compare_lists( list, sets + 1, 7, false ) ) return MB_FAILURE; 01736 rval = MB->num_parent_meshsets( sets[0], &count, 3 ); 01737 if( MB_SUCCESS != rval ) return rval; 01738 if( count != 7 ) return MB_FAILURE; 01739 01740 // test query at depth of 4 01741 list.clear(); 01742 rval = MB->get_parent_meshsets( sets[0], list, 4 ); 01743 if( MB_SUCCESS != rval ) return rval; 01744 if( !compare_lists( list, sets + 1, 7, false ) ) return MB_FAILURE; 01745 rval = MB->num_parent_meshsets( sets[0], &count, 4 ); 01746 if( MB_SUCCESS != rval ) return rval; 01747 if( count != 7 ) return MB_FAILURE; 01748 01749 // test query at all 01750 list.clear(); 01751 rval = MB->get_parent_meshsets( sets[0], list, 0 ); 01752 if( MB_SUCCESS != rval ) return rval; 01753 if( !compare_lists( list, sets + 1, 7, false ) ) return MB_FAILURE; 01754 rval = MB->num_parent_meshsets( sets[0], &count, 0 ); 01755 if( MB_SUCCESS != rval ) return rval; 01756 if( count != 7 ) return MB_FAILURE; 01757 01758 // clean up parent links 01759 rval = MB->remove_parent_meshset( sets[0], sets[1] ); 01760 if( MB_SUCCESS != rval ) return rval; 01761 rval = MB->remove_parent_meshset( sets[0], sets[2] ); 01762 if( MB_SUCCESS != rval ) return rval; 01763 rval = MB->remove_parent_meshset( sets[1], sets[3] ); 01764 if( MB_SUCCESS != rval ) return rval; 01765 rval = MB->remove_parent_meshset( sets[1], sets[4] ); 01766 if( MB_SUCCESS != rval ) return rval; 01767 rval = MB->remove_parent_meshset( sets[2], sets[4] ); 01768 if( MB_SUCCESS != rval ) return rval; 01769 rval = MB->remove_parent_meshset( sets[2], sets[5] ); 01770 if( MB_SUCCESS != rval ) return rval; 01771 rval = MB->remove_parent_meshset( sets[3], sets[6] ); 01772 if( MB_SUCCESS != rval ) return rval; 01773 rval = MB->remove_parent_meshset( sets[4], sets[6] ); 01774 if( MB_SUCCESS != rval ) return rval; 01775 rval = MB->remove_parent_meshset( sets[4], sets[7] ); 01776 if( MB_SUCCESS != rval ) return rval; 01777 rval = MB->remove_parent_meshset( sets[5], sets[7] ); 01778 if( MB_SUCCESS != rval ) return rval; 01779 for( int i = 0; i < 5; ++i ) 01780 if( MB_SUCCESS != MB->num_parent_meshsets( sets[i], &count ) || count ) return MB_FAILURE; 01781 01782 // test combined parent/child links 01783 01784 // test creation 01785 rval = MB->add_parent_child( sets[9], sets[8] ); 01786 if( MB_SUCCESS != rval ) return rval; 01787 list.clear(); 01788 rval = MB->get_child_meshsets( sets[9], list ); 01789 if( MB_SUCCESS != rval ) return rval; 01790 if( list.size() != 1 || list[0] != sets[8] ) return MB_FAILURE; 01791 list.clear(); 01792 rval = MB->get_parent_meshsets( sets[8], list ); 01793 if( MB_SUCCESS != rval ) return rval; 01794 if( list.size() != 1 || list[0] != sets[9] ) return MB_FAILURE; 01795 01796 // test deletion of parent/child 01797 rval = MB->add_parent_child( sets[7], sets[9] ); 01798 if( MB_SUCCESS != rval ) return rval; 01799 rval = MB->delete_entities( &sets[9], 1 ); 01800 if( MB_SUCCESS != rval ) return rval; 01801 list.clear(); 01802 rval = MB->get_parent_meshsets( sets[8], list ); 01803 if( !list.empty() ) return MB_FAILURE; 01804 list.clear(); 01805 rval = MB->get_child_meshsets( sets[7], list ); 01806 if( !list.empty() ) return MB_FAILURE; 01807 01808 // clean up remaining sets 01809 return MB->delete_entities( sets, 9 ); 01810 } 01811 01812 ErrorCode mb_mesh_sets_set_test() 01813 { 01814 return mb_mesh_sets_test( MESHSET_SET ); 01815 } 01816 01817 ErrorCode mb_mesh_sets_list_test() 01818 { 01819 return mb_mesh_sets_test( MESHSET_ORDERED ); 01820 } 01821 01822 // Verify that all query functions *append* to output Range 01823 ErrorCode mb_mesh_set_appends( int flags ) 01824 { 01825 Core moab; 01826 Interface* mb = &moab; 01827 ErrorCode rval = create_some_mesh( mb ); 01828 if( MB_SUCCESS != rval ) return rval; 01829 01830 // get all handles and subdivide into vertex and non-vertex ents 01831 Range all_ents, verts, elems, results; 01832 rval = mb->get_entities_by_handle( 0, all_ents ); 01833 if( MB_SUCCESS != rval ) return rval; 01834 Range::iterator ve = all_ents.upper_bound( MBVERTEX ); 01835 verts.merge( all_ents.begin(), ve ); 01836 elems.merge( ve, all_ents.end() ); 01837 01838 // If we're not testing queries from the root set, 01839 // create a set containing all the vertices 01840 EntityHandle set = 0; 01841 if( flags != -1 ) 01842 { 01843 rval = mb->create_meshset( flags, set ); 01844 if( MB_SUCCESS != rval ) return rval; 01845 rval = mb->add_entities( set, verts ); 01846 if( MB_SUCCESS != rval ) return rval; 01847 } 01848 01849 // Test get_entities_by_handle. This one doesn't make 01850 // much sense if we're testing the root set, but it doesn't 01851 // hurt to test it anyway. 01852 results = elems; 01853 rval = mb->get_entities_by_handle( set, results ); 01854 if( MB_SUCCESS != rval ) return rval; 01855 if( results != all_ents ) return MB_FAILURE; 01856 01857 // Test get_entities_by_dimension 01858 results = elems; 01859 rval = mb->get_entities_by_dimension( set, 0, results ); 01860 if( MB_SUCCESS != rval ) return rval; 01861 if( results != all_ents ) return MB_FAILURE; 01862 01863 // Test get_entities_by_type 01864 results = elems; 01865 rval = mb->get_entities_by_type( set, MBVERTEX, results ); 01866 if( MB_SUCCESS != rval ) return rval; 01867 if( results != all_ents ) return MB_FAILURE; 01868 01869 // choose a single entity for testing tag queries 01870 EntityHandle entity = verts.front(); 01871 Range expected( elems ); 01872 expected.insert( entity ); 01873 01874 Tag sparse, dense; 01875 const int zero = 0, one = 1; 01876 const void* vals[] = { &one }; 01877 01878 // Test get_entities_by_type_and_tag w/ sparse tag and no value 01879 rval = mb->tag_get_handle( "mb_mesh_set_appends_sparse", 1, MB_TYPE_INTEGER, sparse, MB_TAG_SPARSE | MB_TAG_EXCL ); 01880 if( MB_SUCCESS != rval ) return rval; 01881 rval = mb->tag_set_data( sparse, &entity, 1, &one ); 01882 if( MB_SUCCESS != rval ) return rval; 01883 results = elems; 01884 rval = 01885 mb->get_entities_by_type_and_tag( set, TYPE_FROM_HANDLE( entity ), &sparse, 0, 1, results, Interface::UNION ); 01886 if( MB_SUCCESS != rval ) return rval; 01887 if( results != expected ) return MB_FAILURE; 01888 // Test again, but specify tag value 01889 results = elems; 01890 rval = mb->get_entities_by_type_and_tag( set, TYPE_FROM_HANDLE( entity ), &sparse, vals, 1, results, 01891 Interface::UNION ); 01892 if( MB_SUCCESS != rval ) return rval; 01893 if( results != expected ) return MB_FAILURE; 01894 01895 // Test get_entities_by_type_and_tag w/ dense tag 01896 rval = 01897 mb->tag_get_handle( "mb_mesh_set_appends_dense", 1, MB_TYPE_INTEGER, dense, MB_TAG_DENSE | MB_TAG_EXCL, &zero ); 01898 if( MB_SUCCESS != rval ) return rval; 01899 rval = mb->tag_set_data( dense, &entity, 1, &one ); 01900 if( MB_SUCCESS != rval ) return rval; 01901 results = elems; 01902 rval = 01903 mb->get_entities_by_type_and_tag( set, TYPE_FROM_HANDLE( entity ), &dense, vals, 1, results, Interface::UNION ); 01904 if( MB_SUCCESS != rval ) return rval; 01905 if( results != expected ) return MB_FAILURE; 01906 01907 return MB_SUCCESS; 01908 } 01909 01910 ErrorCode mb_mesh_set_set_appends() 01911 { 01912 return mb_mesh_set_appends( MESHSET_SET ); 01913 } 01914 01915 ErrorCode mb_mesh_set_list_appends() 01916 { 01917 return mb_mesh_set_appends( MESHSET_ORDERED ); 01918 } 01919 01920 ErrorCode mb_mesh_set_root_appends() 01921 { 01922 return mb_mesh_set_appends( -1 ); 01923 } 01924 01925 ErrorCode mb_mesh_set_set_replace_test() 01926 { 01927 Core moab; 01928 Interface* mb = &moab; 01929 ErrorCode rval; 01930 Range r; 01931 // create 10 vertices to put in set 01932 std::vector< double > coords( 30 ); 01933 rval = mb->create_vertices( &coords[0], 10, r );MB_CHK_ERR( rval ); 01934 std::vector< EntityHandle > verts( r.size() ); 01935 std::copy( r.begin(), r.end(), verts.begin() ); 01936 r.clear(); 01937 // create a set 01938 EntityHandle set; 01939 rval = mb->create_meshset( MESHSET_SET, set );MB_CHK_ERR( rval ); 01940 // put every other vertex in set 01941 for( size_t i = 0; i < 10; i += 2 ) 01942 r.insert( verts[i] ); 01943 rval = mb->add_entities( set, r );MB_CHK_ERR( rval ); 01944 r.clear(); 01945 // swap 3 of the vertices 01946 EntityHandle old_ents[3] = { verts[2], verts[4], verts[6] }; 01947 EntityHandle new_ents[3] = { verts[1], verts[9], verts[5] }; 01948 rval = mb->replace_entities( set, old_ents, new_ents, 3 );MB_CHK_ERR( rval ); 01949 // check new set contents 01950 rval = mb->get_entities_by_handle( set, r );MB_CHK_ERR( rval ); 01951 Range r2; 01952 r2.insert( verts[0] ); 01953 r2.insert( verts[1] ); 01954 r2.insert( verts[9] ); 01955 r2.insert( verts[5] ); 01956 r2.insert( verts[8] ); 01957 if( r != r2 ) 01958 { 01959 std::cerr << "Range does not contain expected values." << std::endl 01960 << " Expected: " << r2 << std::endl 01961 << " Actual : " << r << std::endl; 01962 return MB_FAILURE; 01963 } 01964 01965 return MB_SUCCESS; 01966 } 01967 01968 ErrorCode mb_mesh_set_list_replace_test() 01969 { 01970 Core moab; 01971 Interface* mb = &moab; 01972 ErrorCode rval; 01973 // create 10 vertices to put in set 01974 Range r; 01975 std::vector< double > coords( 30 ); 01976 rval = mb->create_vertices( &coords[0], 10, r );MB_CHK_ERR( rval ); 01977 std::vector< EntityHandle > verts( r.size() ); 01978 std::copy( r.begin(), r.end(), verts.begin() ); 01979 r.clear(); 01980 // create a set 01981 EntityHandle set; 01982 rval = mb->create_meshset( MESHSET_ORDERED, set );MB_CHK_ERR( rval ); 01983 // put all vertices in set, but add the first one a second time 01984 std::vector< EntityHandle > list( verts ); 01985 list.push_back( verts.front() ); 01986 rval = mb->add_entities( set, &list[0], list.size() );MB_CHK_ERR( rval ); 01987 // swap 3 of the vertices 01988 EntityHandle old_ents[3] = { verts[2], verts[4], verts[6] }; 01989 EntityHandle new_ents[3] = { verts[1], verts[9], verts[5] }; 01990 rval = mb->replace_entities( set, old_ents, new_ents, 3 );MB_CHK_ERR( rval ); 01991 // check new set contents 01992 std::vector< EntityHandle > list2; 01993 rval = mb->get_entities_by_handle( set, list2 );MB_CHK_ERR( rval ); 01994 list[2] = verts[1]; 01995 list[4] = verts[9]; 01996 list[6] = verts[5]; 01997 if( list != list2 ) 01998 { 01999 std::cerr << "Range does not contain expected values." << std::endl; 02000 std::cerr << " Expected: "; 02001 std::copy( list.begin(), list.end(), std::ostream_iterator< EntityHandle >( std::cerr, " " ) ); 02002 std::cerr << std::endl << " Actual : "; 02003 std::copy( list2.begin(), list2.end(), std::ostream_iterator< EntityHandle >( std::cerr, " " ) ); 02004 std::cerr << std::endl; 02005 return MB_FAILURE; 02006 } 02007 // now try replacing a repeated value 02008 rval = mb->replace_entities( set, &verts[0], &verts[3], 1 );MB_CHK_ERR( rval ); 02009 list[0] = list[10] = verts[3]; 02010 list2.clear(); 02011 rval = mb->get_entities_by_handle( set, list2 );MB_CHK_ERR( rval ); 02012 if( list != list2 ) 02013 { 02014 std::cerr << "Range does not contain expected values." << std::endl; 02015 std::cerr << " Expected: "; 02016 std::copy( list.begin(), list.end(), std::ostream_iterator< EntityHandle >( std::cerr, " " ) ); 02017 std::cerr << std::endl << " Actual : "; 02018 std::copy( list2.begin(), list2.end(), std::ostream_iterator< EntityHandle >( std::cerr, " " ) ); 02019 std::cerr << std::endl; 02020 return MB_FAILURE; 02021 } 02022 02023 return MB_SUCCESS; 02024 } 02025 02026 /* Test the following changes to a meshset: 02027 set MB-> tracking 02028 tracking MB-> set 02029 unordered MB-> ordered 02030 ordered MB-> unordered 02031 */ 02032 ErrorCode mb_mesh_set_flag_test() 02033 { 02034 Core moab; 02035 Interface* mb = &moab; 02036 02037 ErrorCode rval; 02038 // create 10 vertices to put in set 02039 Range verts; 02040 std::vector< double > coords( 30 ); 02041 rval = mb->create_vertices( &coords[0], 10, verts );MB_CHK_ERR( rval ); 02042 02043 // CHECK SET->TRACKING 02044 // create a set and add the verts 02045 EntityHandle set; 02046 rval = mb->create_meshset( MESHSET_SET, set );MB_CHK_ERR( rval ); 02047 rval = mb->add_entities( set, verts );MB_CHK_ERR( rval ); 02048 // the verts should not be tracking adjacencies 02049 Range adj_sets; 02050 rval = mb->get_adjacencies( verts, 4, false, adj_sets );MB_CHK_ERR( rval ); 02051 if( !adj_sets.empty() ) 02052 { 02053 std::cerr << "range should be empty but contains:" << std::endl; 02054 rval = mb->list_entities( adj_sets ); 02055 return MB_FAILURE; 02056 } 02057 // check to make sure the flags on MESHSET_SET 02058 unsigned int flags; 02059 rval = mb->get_meshset_options( set, flags );MB_CHK_ERR( rval ); 02060 if( !( MESHSET_SET & flags ) || ( MESHSET_TRACK_OWNER & flags ) || ( MESHSET_ORDERED & flags ) ) 02061 { 02062 std::cerr << "set should be MESHSET_SET only, flags=" << flags << std::endl; 02063 return MB_FAILURE; 02064 } 02065 // change to a tracking set and check flags 02066 rval = mb->set_meshset_options( set, MESHSET_TRACK_OWNER );MB_CHK_ERR( rval ); 02067 rval = mb->get_meshset_options( set, flags );MB_CHK_ERR( rval ); 02068 if( ( MESHSET_SET & flags ) || !( MESHSET_TRACK_OWNER & flags ) || ( MESHSET_ORDERED & flags ) ) 02069 { 02070 std::cerr << "set should be MESHSET_TRACK_OWNER only, flags=" << flags << std::endl; 02071 return MB_FAILURE; 02072 } 02073 // check adjacencies 02074 rval = mb->get_adjacencies( verts, 4, false, adj_sets );MB_CHK_ERR( rval ); 02075 if( 1 != adj_sets.size() ) 02076 { 02077 std::cerr << "range should contain a set, adj_sets.size()=" << adj_sets.size() << std::endl; 02078 rval = mb->list_entities( adj_sets ); 02079 return MB_FAILURE; 02080 } 02081 02082 // CHECK TRACKING->SET 02083 // change to a standard set and check flags 02084 rval = mb->set_meshset_options( set, MESHSET_SET );MB_CHK_ERR( rval ); 02085 rval = mb->get_meshset_options( set, flags );MB_CHK_ERR( rval ); 02086 if( !( MESHSET_SET & flags ) || ( MESHSET_TRACK_OWNER & flags ) || ( MESHSET_ORDERED & flags ) ) 02087 { 02088 std::cerr << "set should be MESHSET_SET only, flags=" << flags << std::endl; 02089 return MB_FAILURE; 02090 } 02091 // the set should no longer be adjacent to the vertices 02092 adj_sets.clear(); 02093 rval = mb->get_adjacencies( verts, 4, false, adj_sets );MB_CHK_ERR( rval ); 02094 if( !adj_sets.empty() ) 02095 { 02096 std::cerr << "range should be empty but contains:" << std::endl; 02097 rval = mb->list_entities( adj_sets ); 02098 return MB_FAILURE; 02099 } 02100 // CHECK UNORDERED->ORDERED 02101 // add a duplicate vert 02102 rval = mb->add_entities( set, &verts.front(), 1 );MB_CHK_ERR( rval ); 02103 // unordered sets cannot hold duplicates so size shouldn't change 02104 std::vector< EntityHandle > entities; 02105 rval = mb->get_entities_by_handle( set, entities ); 02106 if( 10 != entities.size() ) 02107 { 02108 std::cerr << "set should not hold duplicate entities" << std::endl; 02109 return MB_FAILURE; 02110 } 02111 // change to an ordered set and check flags 02112 rval = mb->set_meshset_options( set, MESHSET_ORDERED );MB_CHK_ERR( rval ); 02113 rval = mb->get_meshset_options( set, flags );MB_CHK_ERR( rval ); 02114 if( ( MESHSET_SET & flags ) || ( MESHSET_TRACK_OWNER & flags ) || !( MESHSET_ORDERED & flags ) ) 02115 { 02116 std::cerr << "set should be MESHSET_ORDERED only, flags=" << flags << std::endl; 02117 return MB_FAILURE; 02118 } 02119 // swap the order with some entities to that the handles aren't ordered 02120 rval = mb->clear_meshset( &set, 1 );MB_CHK_ERR( rval ); 02121 entities.clear(); 02122 entities.resize( 2 ); 02123 entities[0] = verts[1]; 02124 entities[1] = verts[0]; 02125 rval = mb->add_entities( set, &entities[0], 2 );MB_CHK_ERR( rval ); 02126 // check to ensure the entities keep their order 02127 entities.clear(); 02128 rval = mb->get_entities_by_handle( set, entities ); 02129 if( verts[0] != entities[1] || verts[1] != entities[0] ) 02130 { 02131 std::cerr << "ordered set did not keep its order" << std::endl; 02132 return MB_FAILURE; 02133 } 02134 02135 // CHECK ORDERED->UNORDERED 02136 // change to an unordered set and check flags 02137 rval = mb->set_meshset_options( set, MESHSET_SET );MB_CHK_ERR( rval ); 02138 rval = mb->get_meshset_options( set, flags );MB_CHK_ERR( rval ); 02139 if( !( MESHSET_SET & flags ) || ( MESHSET_TRACK_OWNER & flags ) || MESHSET_ORDERED & flags ) 02140 { 02141 std::cerr << "set should be MESHSET_SET only, flags=" << flags << std::endl; 02142 return MB_FAILURE; 02143 } 02144 // the entities in the set should now be ordered by handle 02145 entities.clear(); 02146 rval = mb->get_entities_by_handle( set, entities ); 02147 if( verts[0] != entities[0] || verts[1] != entities[1] ) 02148 { 02149 std::cerr << "unordered set is still ordered" << std::endl; 02150 return MB_FAILURE; 02151 } 02152 return MB_SUCCESS; 02153 } 02154 02155 #ifdef MOAB_HAVE_NETCDF 02156 // number of entities of type MBVERTEX, MBEDGE, MBDTri, MBQUAD, MBTET, and MBHEX 02157 // in mbtest1.g (all other values are 0. 02158 static const EntityType types[] = { MBVERTEX, MBEDGE, MBTRI, MBQUAD, MBTET, MBHEX }; 02159 const int num_types = sizeof( types ) / sizeof( types[0] ); 02160 static const unsigned int num_entities[num_types + 1] = { 47, 12, 18, 8, 22, 8, 0 }; 02161 02162 ErrorCode mb_delete_mesh_test() 02163 { 02164 Core moab; 02165 Interface* gMB = &moab; 02166 ErrorCode error = load_file_one( gMB ); 02167 if( MB_SUCCESS != error ) return error; 02168 02169 // Lets also test the global MB pointer (gMB) here. 02170 error = gMB->delete_mesh(); 02171 if( error != MB_SUCCESS ) return error; 02172 02173 // load the mesh again 02174 error = load_file_one( gMB ); 02175 if( error != MB_SUCCESS ) return error; 02176 02177 // step through each element type 02178 for( EntityType type = MBVERTEX; type != MBENTITYSET; type++ ) 02179 { 02180 // There should be entities 02181 Range entities; 02182 error = gMB->get_entities_by_type( 0, type, entities ); 02183 if( error != MB_SUCCESS ) return error; 02184 02185 size_t idx = std::find( types, types + num_types, type ) - types; 02186 if( entities.size() != num_entities[idx] ) return MB_FAILURE; 02187 } 02188 02189 return MB_SUCCESS; 02190 } 02191 02192 ErrorCode mb_mesh_set_tracking_test() 02193 { 02194 Core moab; 02195 Interface* MB = &moab; 02196 02197 // read in a file so you have some data in the database 02198 02199 ErrorCode error = load_file_one( MB ); 02200 if( error != MB_SUCCESS ) return error; 02201 02202 EntityHandle ms1, ms2, ms3; 02203 02204 // create meshsets 02205 ErrorCode result = MB->create_meshset( MESHSET_TRACK_OWNER | MESHSET_ORDERED, ms1 ); 02206 if( result != MB_SUCCESS ) return result; 02207 result = MB->create_meshset( MESHSET_SET | MESHSET_TRACK_OWNER, ms2 ); 02208 if( result != MB_SUCCESS ) return result; 02209 result = MB->create_meshset( MESHSET_SET | MESHSET_TRACK_OWNER, ms3 ); 02210 if( result != MB_SUCCESS ) return result; 02211 02212 // get all hexes 02213 Range hexes; 02214 result = MB->get_entities_by_type( 0, MBHEX, hexes ); 02215 if( result != MB_SUCCESS ) return result; 02216 02217 // get all tris 02218 Range tris; 02219 result = MB->get_entities_by_type( 0, MBTRI, tris ); 02220 if( result != MB_SUCCESS ) return result; 02221 02222 // get all tets 02223 Range temp_range; 02224 result = MB->get_entities_by_type( 0, MBTET, temp_range ); 02225 if( result != MB_SUCCESS ) return result; 02226 02227 // copy all the tets from the range into a vector 'tets' 02228 std::vector< EntityHandle > tets( temp_range.size() ); 02229 std::copy( temp_range.begin(), temp_range.end(), tets.begin() ); 02230 02231 // Quick check on 'get_entities_by_dimension()' 02232 Range dim_3_range; 02233 result = MB->get_entities_by_dimension( 0, 3, dim_3_range ); 02234 if( result != MB_SUCCESS ) return result; 02235 02236 // hexes and tets should be only dimension 3 entities 02237 if( hexes.size() + tets.size() != dim_3_range.size() ) return MB_FAILURE; 02238 02239 // put all hexes in ms1, ms2, ms3 02240 result = MB->add_entities( ms1, hexes ); // add ents in a range 02241 if( result != MB_SUCCESS ) return result; 02242 // to ordered meshset 02243 02244 result = MB->add_entities( ms2, hexes ); // add ents in a range 02245 if( result != MB_SUCCESS ) return result; 02246 // to unordered meshset 02247 02248 result = MB->add_entities( ms3, hexes ); 02249 if( result != MB_SUCCESS ) return result; 02250 02251 // put all tets in ms1, ms2 02252 if( MB->add_entities( ms1, &tets[0], tets.size() ) != MB_SUCCESS ) // add ents in a vector 02253 return MB_FAILURE; // to ordered meshset 02254 02255 if( MB->add_entities( ms2, &tets[0], tets.size() ) != MB_SUCCESS ) // add ents in a vector 02256 return MB_FAILURE; // to unordered meshset 02257 02258 // put all tris in ms1 02259 result = MB->add_entities( ms1, tris ); 02260 if( result != MB_SUCCESS ) return result; 02261 02262 Range::iterator iter; 02263 iter = tris.begin(); 02264 02265 std::vector< EntityHandle > temp_vec; 02266 02267 // ask a tri which meshsets it is in 02268 result = MB->get_adjacencies( &( *iter ), 1, 4, false, temp_vec ); 02269 if( result != MB_SUCCESS ) return result; 02270 02271 // cout<<"tris temp_vec.size() = "<<temp_vec.size()<<endl; 02272 if( temp_vec.size() != 2 ) return MB_FAILURE; 02273 02274 // ask a tet which meshsets it is in 02275 temp_vec.clear(); 02276 std::vector< EntityHandle >::iterator vec_iter = tets.begin(); 02277 result = MB->get_adjacencies( &( *vec_iter ), 1, 4, false, temp_vec ); 02278 if( result != MB_SUCCESS ) return result; 02279 02280 // cout<<"tet temp_vec.size() = "<<temp_vec.size()<<endl; 02281 if( temp_vec.size() != 3 ) return MB_FAILURE; 02282 02283 // ask a hex which meshsets it is in 02284 temp_vec.clear(); 02285 iter = hexes.begin(); 02286 result = MB->get_adjacencies( &( *iter ), 1, 4, false, temp_vec ); 02287 if( result != MB_SUCCESS ) return result; 02288 02289 // should be in 4 temp_vec 02290 if( temp_vec.size() != 4 ) return MB_FAILURE; 02291 02292 // take this hex out of the ms1, ms2, ms3 02293 if( MB->remove_entities( ms1, &( *iter ), 1 ) != MB_SUCCESS ) // remove ents in a vector 02294 return MB_FAILURE; // from ordered meshset 02295 02296 if( MB->remove_entities( ms2, &( *iter ), 1 ) != MB_SUCCESS ) // remove ents in a vector 02297 return MB_FAILURE; // from unordered meshset 02298 02299 temp_range.clear(); 02300 temp_range.insert( *iter ); 02301 if( MB->remove_entities( ms3, temp_range ) != MB_SUCCESS ) // remove ents in a range 02302 return MB_FAILURE; // from unordered meshset 02303 02304 // ask the hex how many meshsets it is in 02305 temp_vec.clear(); 02306 result = MB->get_adjacencies( &( *iter ), 1, 4, false, temp_vec ); 02307 if( result != MB_SUCCESS ) return result; 02308 if( temp_vec.size() != 1 ) return MB_FAILURE; 02309 02310 // add the hex back into ms1 02311 result = MB->add_entities( ms1, temp_range ); 02312 if( result != MB_SUCCESS ) return result; 02313 02314 // ask the hex how many meshsets it is in 02315 temp_vec.clear(); 02316 result = MB->get_adjacencies( &( *iter ), 1, 4, false, temp_vec ); 02317 if( result != MB_SUCCESS ) return result; 02318 if( temp_vec.size() != 2 ) return MB_FAILURE; 02319 02320 temp_range.clear(); 02321 temp_range.insert( *iter ); 02322 if( MB->remove_entities( ms1, temp_range ) != MB_SUCCESS ) // remove ents in a range 02323 return MB_FAILURE; // from an ordered meshset 02324 02325 // ask the hex how many meshsets it is in 02326 temp_vec.clear(); 02327 result = MB->get_adjacencies( &( *iter ), 1, 4, false, temp_vec ); 02328 if( result != MB_SUCCESS ) return result; 02329 if( temp_vec.size() != 1 ) return MB_FAILURE; 02330 02331 // Deleting a meshset 02332 02333 iter = tris.begin(); 02334 temp_vec.clear(); 02335 // ask a tri which meshsets it is in 02336 result = MB->get_adjacencies( &( *iter ), 1, 4, false, temp_vec ); 02337 if( result != MB_SUCCESS ) return result; 02338 02339 if( temp_vec.size() != 2 ) return MB_FAILURE; 02340 02341 // Try deleting a meshset 02342 result = MB->delete_entities( &ms1, 1 ); 02343 if( result != MB_SUCCESS ) return result; 02344 02345 temp_vec.clear(); 02346 // Query tri again for meshsets it's in 02347 result = MB->get_adjacencies( &( *iter ), 1, 4, false, temp_vec ); 02348 if( result != MB_SUCCESS ) return result; 02349 02350 if( temp_vec.size() != 1 ) return MB_FAILURE; 02351 02352 // Delete an entitiy from ms2....make sure it's removed out of ms2 02353 int num_before = 0; 02354 MB->get_number_entities_by_handle( ms2, num_before ); 02355 vec_iter = tets.begin(); 02356 result = MB->delete_entities( &( *vec_iter ), 1 ); 02357 if( result != MB_SUCCESS ) return result; 02358 02359 int num_after = 0; 02360 MB->get_number_entities_by_handle( ms2, num_after ); 02361 if( num_before != num_after + 1 ) return MB_FAILURE; 02362 02363 return MB_SUCCESS; 02364 } 02365 #endif 02366 02367 // Compare internal representation of contents for a list (MESHSET_ORDERED) 02368 // set to expected contents. Assumes expected contents are correctly 02369 // ordered. 02370 static ErrorCode check_list_meshset_internal( const EntityHandle* expected, int num_expected, 02371 const EntityHandle* contents, int length ) 02372 { 02373 bool okay = true; 02374 for( int i = 0; i < std::min( num_expected, length ); ++i ) 02375 { 02376 if( expected[i] != contents[i] ) 02377 { 02378 std::cerr << "List set contents differ at index " << i << ": expected " << expected[i] << " but got " 02379 << contents[i] << std::endl; 02380 okay = false; 02381 } 02382 } 02383 if( num_expected > length ) 02384 { 02385 std::cerr << "List set is missing " << num_expected - length << "handles" << std::endl; 02386 okay = false; 02387 } 02388 else if( length > num_expected ) 02389 { 02390 std::cerr << "List set has " << num_expected - length << " extra handles" << std::endl; 02391 okay = false; 02392 } 02393 02394 if( okay ) return MB_SUCCESS; 02395 02396 std::cerr << "Expected contents: "; 02397 if( !num_expected ) 02398 std::cerr << "(empty)"; 02399 else 02400 std::cerr << expected[0]; 02401 for( int i = 1; i < num_expected; ++i ) 02402 std::cerr << ", " << expected[i]; 02403 std::cerr << std::endl; 02404 02405 std::cerr << "Actual contents: "; 02406 if( !length ) 02407 std::cerr << "(empty)"; 02408 else 02409 std::cerr << contents[0]; 02410 for( int i = 1; i < length; ++i ) 02411 std::cerr << ", " << contents[i]; 02412 std::cerr << std::endl; 02413 02414 return MB_FAILURE; 02415 } 02416 02417 // Compare internal representation of contents for a ranged (MESHSET_SET) 02418 // set to expected contents. Assumes expected contents are correctly 02419 // ordered. 02420 static ErrorCode check_ranged_meshset_internal( const EntityHandle* expected, int num_expected, 02421 const EntityHandle* contents, int length ) 02422 { 02423 if( length % 2 ) 02424 { 02425 std::cerr << "Range set is corrupt. Odd number of handles in content list" << std::endl; 02426 std::cerr << "Actual contents: " << contents[0]; 02427 for( int i = 1; i < length; ++i ) 02428 std::cerr << ", " << contents[i]; 02429 std::cerr << std::endl; 02430 return MB_FAILURE; 02431 } 02432 bool okay = true; 02433 // check that all range pairs are valid (first handle less than or 02434 // equal to second) 02435 for( int i = 0; i < length; i += 2 ) 02436 { 02437 if( contents[i] > contents[i + 1] ) 02438 { 02439 std::cerr << "Range set has invalid range pair at index " << i << ": [" << contents[i] << ',' 02440 << contents[i + 1] << ']' << std::endl; 02441 okay = false; 02442 } 02443 } 02444 // check that all range pairs are sorted and non-overlapping 02445 // (start of a range must be greater than end of previous range) 02446 for( int i = 2; i < length; i += 2 ) 02447 { 02448 if( contents[i] < contents[i - 1] ) 02449 { 02450 std::cerr << "Range set has incorrectly ordered ranges at index " << i << ": [...," << contents[i - 1] 02451 << "], [" << contents[i] << ",...]" << std::endl; 02452 okay = false; 02453 } 02454 if( contents[i] == contents[i - 1] + 1 ) 02455 { 02456 std::cerr << "Range set has pairs that should have been merged at index " << i << ": [...," 02457 << contents[i - 1] << "], [" << contents[i] << ",...]" << std::endl; 02458 okay = false; 02459 } 02460 } 02461 if( !okay ) 02462 { 02463 std::cerr << "Actual contents: "; 02464 if( !length ) 02465 std::cerr << "(empty)"; 02466 else 02467 std::cerr << '[' << contents[0] << ',' << contents[1] << ']'; 02468 for( int i = 2; i < length; i += 2 ) 02469 std::cerr << ", [" << contents[i] << ',' << contents[i + 1] << ']'; 02470 std::cerr << std::endl; 02471 return MB_FAILURE; 02472 } 02473 02474 int j = 0; 02475 for( int i = 0; i < length; i += 2 ) 02476 { 02477 for( ; j < num_expected && expected[j] < contents[i]; ++j ) 02478 { 02479 std::cerr << "Range set missing expected handle: " << expected[j] << std::endl; 02480 okay = false; 02481 } 02482 int k = j; 02483 while( k < num_expected && expected[k] <= contents[i + 1] ) 02484 ++k; 02485 if( ( EntityHandle )( k - j ) <= ( contents[i + 1] - contents[i] ) ) 02486 { 02487 std::cerr << "Handle range [" << contents[i] << ',' << contents[i + 1] 02488 << "] contains unexpected handles. Expected handles: "; 02489 if( k == j ) 02490 std::cerr << "(none)" << std::endl; 02491 else 02492 { 02493 std::cerr << expected[j]; 02494 for( ++j; j < k; ++j ) 02495 std::cerr << ", " << expected[j]; 02496 std::cerr << std::endl; 02497 } 02498 okay = false; 02499 } 02500 j = k; 02501 } 02502 02503 if( okay ) return MB_SUCCESS; 02504 02505 std::cerr << "Expected contents: "; 02506 if( !num_expected ) 02507 std::cerr << "(empty)"; 02508 else 02509 std::cerr << expected[0]; 02510 for( int i = 1; i < num_expected; ++i ) 02511 std::cerr << ", " << expected[i]; 02512 std::cerr << std::endl; 02513 02514 std::cerr << "Actual contents: "; 02515 if( !length ) 02516 std::cerr << "(empty)"; 02517 else 02518 std::cerr << '[' << contents[0] << ',' << contents[1] << ']'; 02519 for( int i = 2; i < length; i += 2 ) 02520 std::cerr << ", [" << contents[i] << ',' << contents[i + 1] << ']'; 02521 std::cerr << std::endl; 02522 02523 return MB_FAILURE; 02524 } 02525 02526 // Check the internal representation of a meshset 02527 // to verify that it is correct. 02528 static ErrorCode check_meshset_internal( Interface& mb, EntityHandle set, const EntityHandle* expected, 02529 int num_expected ) 02530 { 02531 ErrorCode rval; 02532 WriteUtilIface* tool = 0; 02533 rval = mb.query_interface( tool );MB_CHK_ERR( rval ); 02534 02535 const EntityHandle* contents; 02536 int length; 02537 unsigned char flags; 02538 rval = tool->get_entity_list_pointers( &set, 1, &contents, WriteUtilIface::CONTENTS, &length, &flags );MB_CHK_ERR( rval ); 02539 ErrorCode rval1 = mb.release_interface( tool );MB_CHK_ERR( rval1 ); 02540 02541 if( flags & MESHSET_ORDERED ) 02542 rval = check_list_meshset_internal( expected, num_expected, contents, length ); 02543 else 02544 rval = check_ranged_meshset_internal( expected, num_expected, contents, length );MB_CHK_ERR( rval ); 02545 return MB_SUCCESS; 02546 } 02547 02548 ErrorCode mb_mesh_set_set_add_remove_test() 02549 { 02550 Core core; 02551 Interface& mb = core; 02552 EntityHandle set; 02553 ErrorCode rval = mb.create_meshset( MESHSET_SET, set );MB_CHK_ERR( rval ); 02554 02555 EntityHandle list1[] = { 10, 16, 18, 20, 24, 27 }; 02556 size_t len1 = sizeof( list1 ) / sizeof( list1[0] ); 02557 EntityHandle list2[] = { 10, 16, 17, 18, 19, 20, 24, 27 }; 02558 size_t len2 = sizeof( list2 ) / sizeof( list2[0] ); 02559 rval = mb.add_entities( set, list1, len1 );MB_CHK_ERR( rval ); 02560 rval = check_meshset_internal( mb, set, list1, len1 );MB_CHK_ERR( rval ); 02561 rval = mb.add_entities( set, list2, len2 );MB_CHK_ERR( rval ); 02562 EntityHandle exp12[] = { 10, 16, 17, 18, 19, 20, 24, 27 }; 02563 size_t len12 = sizeof( exp12 ) / sizeof( exp12[0] ); 02564 rval = check_meshset_internal( mb, set, exp12, len12 );MB_CHK_ERR( rval ); 02565 02566 EntityHandle list3[] = { 15, 16, 18, 20, 21, 24, 28 }; 02567 size_t len3 = sizeof( list3 ) / sizeof( list3[0] ); 02568 rval = mb.remove_entities( set, list3, len3 );MB_CHK_ERR( rval ); 02569 EntityHandle exp123[] = { 10, 17, 19, 27 }; 02570 size_t len123 = sizeof( exp123 ) / sizeof( exp123[0] ); 02571 rval = check_meshset_internal( mb, set, exp123, len123 );MB_CHK_ERR( rval ); 02572 02573 EntityHandle list4[] = { 18, 10, 11, 12, 13, 14, 15, 16 }; 02574 size_t len4 = sizeof( list4 ) / sizeof( list4[0] ); 02575 rval = mb.add_entities( set, list4, len4 );MB_CHK_ERR( rval ); 02576 EntityHandle exp14[] = { 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 27 }; 02577 size_t len14 = sizeof( exp14 ) / sizeof( exp14[0] ); 02578 rval = check_meshset_internal( mb, set, exp14, len14 );MB_CHK_ERR( rval ); 02579 02580 EntityHandle list5[] = { 9, 10, 12, 13, 14, 15, 19, 20 }; 02581 rval = mb.remove_entities( set, list5, sizeof( list5 ) / sizeof( list5[0] ) );MB_CHK_ERR( rval ); 02582 EntityHandle exp5[] = { 11, 16, 17, 18, 27 }; 02583 rval = check_meshset_internal( mb, set, exp5, sizeof( exp5 ) / sizeof( exp5[0] ) );MB_CHK_ERR( rval ); 02584 02585 EntityHandle list6[] = { 9, 10, 15, 16, 18, 19, 28 }; 02586 rval = mb.add_entities( set, list6, sizeof( list6 ) / sizeof( list6[0] ) );MB_CHK_ERR( rval ); 02587 EntityHandle exp6[] = { 9, 10, 11, 15, 16, 17, 18, 19, 27, 28 }; 02588 rval = check_meshset_internal( mb, set, exp6, sizeof( exp6 ) / sizeof( exp6[0] ) );MB_CHK_ERR( rval ); 02589 02590 EntityHandle list7[] = { 13, 19, 27, 28 }; 02591 rval = mb.add_entities( set, list7, sizeof( list7 ) / sizeof( list7[0] ) );MB_CHK_ERR( rval ); 02592 EntityHandle exp7[] = { 9, 10, 11, 13, 15, 16, 17, 18, 19, 27, 28 }; 02593 rval = check_meshset_internal( mb, set, exp7, sizeof( exp7 ) / sizeof( exp7[0] ) );MB_CHK_ERR( rval ); 02594 02595 EntityHandle list8[] = { 12, 14, 33 }; 02596 rval = mb.add_entities( set, list8, sizeof( list8 ) / sizeof( list8[0] ) );MB_CHK_ERR( rval ); 02597 EntityHandle exp8[] = { 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 27, 28, 33 }; 02598 rval = check_meshset_internal( mb, set, exp8, sizeof( exp8 ) / sizeof( exp8[0] ) );MB_CHK_ERR( rval ); 02599 02600 EntityHandle list9[] = { 29, 30, 31, 32, 34 }; 02601 rval = mb.remove_entities( set, list9, sizeof( list9 ) / sizeof( list9[0] ) );MB_CHK_ERR( rval ); 02602 rval = check_meshset_internal( mb, set, exp8, sizeof( exp8 ) / sizeof( exp8[0] ) );MB_CHK_ERR( rval ); 02603 02604 EntityHandle list10[] = { 9, 11, 13, 17, 18, 19, 28, 33, 100 }; 02605 rval = mb.remove_entities( set, list10, sizeof( list10 ) / sizeof( list10[0] ) );MB_CHK_ERR( rval ); 02606 EntityHandle exp10[] = { 10, 12, 14, 15, 16, 27 }; 02607 rval = check_meshset_internal( mb, set, exp10, sizeof( exp10 ) / sizeof( exp10[0] ) );MB_CHK_ERR( rval ); 02608 02609 EntityHandle list11[] = { 11, 12, 13, 14, 27, 28 }; 02610 rval = mb.remove_entities( set, list11, sizeof( list11 ) / sizeof( list11[0] ) );MB_CHK_ERR( rval ); 02611 EntityHandle exp11[] = { 10, 15, 16 }; 02612 rval = check_meshset_internal( mb, set, exp11, sizeof( exp11 ) / sizeof( exp11[0] ) );MB_CHK_ERR( rval ); 02613 02614 EntityHandle list12[] = { 1, 10, 15, 16 }; 02615 rval = mb.remove_entities( set, list12, sizeof( list12 ) / sizeof( list12[0] ) );MB_CHK_ERR( rval ); 02616 rval = check_meshset_internal( mb, set, 0, 0 );MB_CHK_ERR( rval ); 02617 02618 return MB_SUCCESS; 02619 } 02620 02621 ErrorCode mb_higher_order_test() 02622 { 02623 Core moab; 02624 Interface* MB = &moab; 02625 02626 double nodes_array[7][3]; 02627 02628 nodes_array[0][0] = 0; 02629 nodes_array[0][1] = 0; 02630 nodes_array[0][2] = 0; 02631 nodes_array[1][0] = 2; 02632 nodes_array[1][1] = 0; 02633 nodes_array[1][2] = 0; 02634 nodes_array[2][0] = 1; 02635 nodes_array[2][1] = 2; 02636 nodes_array[2][2] = 1; 02637 nodes_array[3][0] = 1; 02638 nodes_array[3][1] = 0; 02639 nodes_array[3][2] = 0; 02640 nodes_array[4][0] = 1.5; 02641 nodes_array[4][1] = 0.5; 02642 nodes_array[4][2] = 0.5; 02643 nodes_array[5][0] = 0.5; 02644 nodes_array[5][1] = 0.5; 02645 nodes_array[5][2] = 0.5; 02646 nodes_array[6][0] = 1; 02647 nodes_array[6][1] = 1; 02648 nodes_array[6][2] = 0.5; 02649 02650 // create the nodes 02651 std::vector< EntityHandle > connectivity( 8 ); 02652 EntityHandle node_handle; 02653 int i; 02654 for( i = 0; i < 7; i++ ) 02655 { 02656 if( MB->create_vertex( nodes_array[i], node_handle ) != MB_SUCCESS ) return MB_FAILURE; 02657 connectivity[i] = node_handle; 02658 } 02659 02660 // create the higher order tri 02661 EntityHandle tri_handle; 02662 ErrorCode result = MB->create_element( MBTRI, &connectivity[0], 6, tri_handle ); 02663 if( result != MB_SUCCESS ) return result; 02664 02665 // create the higher order tri 02666 std::vector< EntityHandle > other_conn( 3 ); 02667 02668 double other_nodes[3][3]; 02669 other_nodes[0][0] = 1.999; 02670 other_nodes[0][1] = 1.999; 02671 other_nodes[0][2] = 1.999; 02672 other_nodes[1][0] = 2.999; 02673 other_nodes[1][1] = 2.999; 02674 other_nodes[1][2] = 2.999; 02675 other_nodes[2][0] = 3.999; 02676 other_nodes[2][1] = 3.999; 02677 other_nodes[2][2] = 3.999; 02678 02679 for( i = 0; i < 3; i++ ) 02680 { 02681 if( MB->create_vertex( other_nodes[i], node_handle ) != MB_SUCCESS ) return MB_FAILURE; 02682 other_conn[i] = node_handle; 02683 } 02684 02685 EntityHandle other_tri_handle; 02686 result = MB->create_element( MBTRI, &other_conn[0], 3, other_tri_handle ); 02687 if( result != MB_SUCCESS ) return result; 02688 02689 // get the connectivity now 02690 std::vector< EntityHandle > retrieved_conn; 02691 02692 result = MB->get_connectivity( &tri_handle, 1, retrieved_conn ); 02693 if( result != MB_SUCCESS ) return result; 02694 02695 unsigned int k; 02696 for( k = 0; k < retrieved_conn.size(); k++ ) 02697 if( connectivity[k] != retrieved_conn[k] ) return MB_FAILURE; 02698 02699 result = MB->get_connectivity( &other_tri_handle, 1, retrieved_conn ); 02700 if( result != MB_SUCCESS ) return result; 02701 02702 for( k = 0; k < other_conn.size(); k++ ) 02703 if( other_conn[k] != retrieved_conn[k] ) return MB_FAILURE; 02704 02705 // now let's just try getting the topological connectivity (the 3 corner vertices) 02706 std::vector< EntityHandle > topo_conn; 02707 result = MB->get_connectivity( &other_tri_handle, 1, topo_conn, true ); 02708 if( result != MB_SUCCESS ) return result; 02709 02710 if( topo_conn.size() != 3 ) return MB_FAILURE; 02711 02712 for( k = 0; k < 3; k++ ) 02713 if( topo_conn[k] != retrieved_conn[k] ) return MB_FAILURE; 02714 02715 // short check to make sure that Core::handle_from_id() works 02716 unsigned long handle_id = MB->id_from_handle( node_handle ); 02717 02718 EntityHandle test_handle; 02719 result = MB->handle_from_id( MBVERTEX, handle_id, test_handle ); 02720 if( result != MB_SUCCESS ) return result; 02721 02722 if( test_handle != node_handle ) return MB_FAILURE; 02723 02724 handle_id = MB->id_from_handle( tri_handle ); 02725 02726 result = MB->handle_from_id( MBTRI, handle_id, test_handle ); 02727 if( result != MB_SUCCESS ) return result; 02728 02729 if( test_handle != tri_handle ) return MB_FAILURE; 02730 02731 // make up some bogus id 02732 handle_id = 2140824; 02733 02734 result = MB->handle_from_id( MBTRI, handle_id, test_handle ); 02735 if( result != MB_ENTITY_NOT_FOUND ) return MB_FAILURE; 02736 02737 result = MB->handle_from_id( MBVERTEX, handle_id, test_handle ); 02738 if( result != MB_ENTITY_NOT_FOUND ) return MB_FAILURE; 02739 02740 return MB_SUCCESS; 02741 } 02742 02743 ErrorCode mb_bit_tags_test() 02744 { 02745 Core moab; 02746 Interface* MB = &moab; 02747 ErrorCode success = create_some_mesh( MB ); 02748 if( MB_SUCCESS != success ) return success; 02749 02750 Tag bit_tag; 02751 Range entities; 02752 MB->get_entities_by_type( 0, MBVERTEX, entities ); 02753 02754 if( MB->tag_get_handle( "bit on vertex", 3, MB_TYPE_BIT, bit_tag, MB_TAG_CREAT ) != MB_SUCCESS ) 02755 { 02756 cout << "couldn't create bit tag" << endl; 02757 return MB_FAILURE; 02758 } 02759 02760 Range::iterator iter; 02761 unsigned char bits; 02762 for( iter = entities.begin(); iter != entities.end(); ++iter ) 02763 { 02764 // tag each vertex with the low 3 bits of the entity handle 02765 bits = ( ( *iter ) & 0x7 ); 02766 success = MB->tag_set_data( bit_tag, &( *iter ), 1, &bits ); 02767 if( success != MB_SUCCESS ) return MB_FAILURE; 02768 } 02769 02770 bits = 0; 02771 for( iter = entities.begin(); iter != entities.end(); ++iter ) 02772 { 02773 // tag each vertex with the low 3 bits of the entity handle 02774 success = MB->tag_get_data( bit_tag, &( *iter ), 1, &bits ); 02775 if( success != MB_SUCCESS ) return MB_FAILURE; 02776 02777 if( bits != ( ( *iter ) & 0x7 ) ) return MB_FAILURE; 02778 } 02779 02780 // test range-based query for all vertices 02781 std::vector< unsigned char > data( entities.size() ); 02782 success = MB->tag_get_data( bit_tag, entities, &data[0] ); 02783 if( MB_SUCCESS != success ) return success; 02784 std::vector< unsigned char >::iterator i = data.begin(); 02785 for( iter = entities.begin(); iter != entities.end(); ++iter, ++i ) 02786 if( *i != ( ( *iter ) & 0x7 ) ) return MB_FAILURE; 02787 02788 // test vector-based query for all vertices 02789 std::vector< EntityHandle > verts( entities.begin(), entities.end() ); 02790 success = MB->tag_get_data( bit_tag, &verts[0], verts.size(), &data[0] ); 02791 if( MB_SUCCESS != success ) return success; 02792 i = data.begin(); 02793 for( iter = entities.begin(); iter != entities.end(); ++iter, ++i ) 02794 if( *i != ( ( *iter ) & 0x7 ) ) return MB_FAILURE; 02795 02796 // test default value 02797 const unsigned char default_bits = '\005'; // 0000 0101 02798 Tag tag2; 02799 success = MB->tag_get_handle( "bit with default", 4, MB_TYPE_BIT, tag2, MB_TAG_CREAT, &default_bits ); 02800 if( MB_SUCCESS != success ) 02801 { 02802 cout << "Failed to create bit tag with default value" << std::endl; 02803 return success; 02804 } 02805 02806 // set value to zero on a single vertex 02807 bits = 0; 02808 EntityHandle zh = verts[verts.size() / 2]; 02809 success = MB->tag_set_data( tag2, &zh, 1, &bits ); 02810 if( MB_SUCCESS != success ) return success; 02811 02812 // get tag values for all entities 02813 data.clear(); 02814 data.resize( verts.size(), 0x7A ); // initialize with 0111 1010 02815 success = MB->tag_get_data( tag2, entities, &data[0] ); 02816 if( MB_SUCCESS != success ) return success; 02817 02818 // check values 02819 i = data.begin(); 02820 for( iter = entities.begin(); iter != entities.end(); ++iter, ++i ) 02821 if( *iter == zh && *i ) // the one we set to zero 02822 return MB_FAILURE; 02823 else if( *iter != zh && *i != default_bits ) 02824 return MB_FAILURE; 02825 02826 return MB_SUCCESS; 02827 } 02828 02829 #ifdef MOAB_HAVE_NETCDF 02830 ErrorCode mb_tags_test() 02831 { 02832 Core moab; 02833 Interface* MB = &moab; 02834 ErrorCode result = load_file_one( MB ); 02835 if( MB_SUCCESS != result ) return result; 02836 02837 Tag stale_bits, stale_dense, stale_sparse; 02838 result = MB->tag_get_handle( "stale data", 5, MB_TYPE_BIT, stale_bits, MB_TAG_CREAT ); 02839 if( MB_SUCCESS != result ) return result; 02840 02841 int def_data = 9; 02842 result = MB->tag_get_handle( "dense stale_data", 1, MB_TYPE_INTEGER, stale_dense, MB_TAG_DENSE | MB_TAG_EXCL, 02843 &def_data ); 02844 if( MB_SUCCESS != result ) return result; 02845 result = MB->tag_get_handle( "sparse stale data", 1, MB_TYPE_INTEGER, stale_sparse, MB_TAG_SPARSE | MB_TAG_EXCL ); 02846 if( MB_SUCCESS != result ) return result; 02847 02848 double coords[3] = { 0, 0, 0 }; 02849 EntityHandle stale_handle1, stale_handle2; 02850 result = MB->create_vertex( coords, stale_handle1 ); 02851 if( MB_SUCCESS != result ) return result; 02852 02853 unsigned char bits = 0x5; 02854 result = MB->tag_set_data( stale_bits, &stale_handle1, 1, &bits ); 02855 if( MB_SUCCESS != result ) return result; 02856 bits = 0; 02857 result = MB->tag_get_data( stale_bits, &stale_handle1, 1, &bits ); 02858 if( MB_SUCCESS != result ) return result; 02859 if( bits != 0x5 ) return MB_FAILURE; 02860 02861 def_data = 1; 02862 result = MB->tag_set_data( stale_dense, &stale_handle1, 1, &def_data ); 02863 if( MB_SUCCESS != result ) return result; 02864 def_data = 0; 02865 result = MB->tag_get_data( stale_dense, &stale_handle1, 1, &def_data ); 02866 if( MB_SUCCESS != result ) return result; 02867 if( def_data != 1 ) return MB_FAILURE; 02868 02869 def_data = 100; 02870 result = MB->tag_set_data( stale_sparse, &stale_handle1, 1, &def_data ); 02871 if( MB_SUCCESS != result ) return result; 02872 def_data = 0; 02873 result = MB->tag_get_data( stale_sparse, &stale_handle1, 1, &def_data ); 02874 if( MB_SUCCESS != result ) return result; 02875 if( def_data != 100 ) return MB_FAILURE; 02876 02877 result = MB->delete_entities( &stale_handle1, 1 ); 02878 if( MB_SUCCESS != result ) return result; 02879 result = MB->create_vertex( coords, stale_handle2 ); 02880 if( MB_SUCCESS != result ) return result; 02881 02882 if( stale_handle1 != stale_handle2 ) 02883 cout << "Tag test could test stale data" << endl; 02884 else 02885 { 02886 bits = 0; 02887 result = MB->tag_get_data( stale_bits, &stale_handle2, 1, &bits ); 02888 if( MB_SUCCESS != result ) return result; 02889 if( bits != 0 ) return MB_FAILURE; 02890 02891 def_data = 3; 02892 result = MB->tag_get_data( stale_dense, &stale_handle2, 1, &def_data ); 02893 if( MB_SUCCESS != result ) return result; 02894 if( def_data != 9 ) return MB_FAILURE; 02895 02896 def_data = 3; 02897 ErrorCode stale_result = MB->tag_get_data( stale_sparse, &stale_handle2, 1, &def_data ); 02898 // we are supposed to fail here 02899 if( stale_result != MB_TAG_NOT_FOUND ) return MB_FAILURE; 02900 } 02901 02902 result = MB->tag_delete( stale_dense ); 02903 if( MB_SUCCESS != result ) return result; 02904 02905 result = MB->delete_entities( &stale_handle2, 1 ); 02906 if( MB_SUCCESS != result ) return result; 02907 02908 // get all blocks with material tag and with tag_value of 1 (should only be 1) 02909 Range entities; 02910 int value = 1; 02911 const void* dum_ptr = &value; 02912 Tag material_tag; 02913 result = MB->tag_get_handle( MATERIAL_SET_TAG_NAME, 1, MB_TYPE_INTEGER, material_tag ); 02914 if( MB_SUCCESS != result ) return result; 02915 if( MB->get_entities_by_type_and_tag( 0, MBENTITYSET, &material_tag, &dum_ptr, 1, entities ) != MB_SUCCESS ) 02916 return MB_FAILURE; 02917 02918 if( entities.size() != 1 ) return MB_FAILURE; 02919 02920 // add a dense tag to hexes 02921 Tag junk_tag; 02922 if( MB->tag_get_handle( "junk_tag", 1, MB_TYPE_INTEGER, junk_tag, MB_TAG_DENSE | MB_TAG_EXCL ) != MB_SUCCESS ) 02923 return MB_FAILURE; 02924 02925 // Set the dense tag on 5 hexes to 3489 02926 Range test_range; 02927 result = MB->get_entities_by_type( 0, MBHEX, test_range ); 02928 if( result != MB_SUCCESS ) return result; 02929 02930 Range::iterator iter, end_iter; 02931 iter = test_range.begin(); 02932 end_iter = test_range.end(); 02933 02934 int data = 3489; 02935 const void* ptr_data = &data; 02936 02937 // mark approxiamtely the first 20% of the hex entities; also put a bit tag on them 02938 unsigned int times = test_range.size() / 5; 02939 bits = 0x5; 02940 const void* ptr_bits = &bits; 02941 02942 for( unsigned int i = 0; i < times; i++ ) 02943 { 02944 if( MB->tag_set_data( junk_tag, &( *iter ), 1, &data ) != MB_SUCCESS ) return MB_FAILURE; 02945 if( MB->tag_set_data( stale_bits, &( *iter ), 1, &bits ) != MB_SUCCESS ) return MB_FAILURE; 02946 ++iter; 02947 } 02948 02949 entities.clear(); 02950 // fetch the hex entities of type--MBHEX, tag-"junk_tag", and tag value -- 3489 02951 if( MB->get_entities_by_type_and_tag( 0, MBHEX, &junk_tag, &ptr_data, 1, entities ) != MB_SUCCESS ) 02952 return MB_FAILURE; 02953 02954 if( entities.size() != times ) // should get as many hexes as you perviously marked 02955 return MB_FAILURE; 02956 02957 // fetch the hex entities of type--MBHEX, tag-"junk_tag", and tag value -- 3489 02958 entities.clear(); 02959 if( MB->get_entities_by_type_and_tag( 0, MBHEX, &stale_bits, &ptr_bits, 1, entities ) != MB_SUCCESS ) 02960 return MB_FAILURE; 02961 02962 if( entities.size() != times ) // should get as many hexes as you perviously marked 02963 return MB_FAILURE; 02964 02965 // test fetch by tag value again, this time limiting the results 02966 // to the contents of an entity set 02967 EntityHandle meshset; 02968 result = MB->create_meshset( MESHSET_SET, meshset ); 02969 if( MB_SUCCESS != result ) return result; 02970 result = MB->add_entities( meshset, test_range ); 02971 if( MB_SUCCESS != result ) return result; 02972 02973 // fetch the hex entities of type--MBHEX, tag-"junk_tag", and tag value -- 3489 02974 entities.clear(); 02975 result = MB->get_entities_by_type_and_tag( meshset, MBHEX, &junk_tag, &ptr_data, 1, entities ); 02976 if( MB_SUCCESS != result ) return result; 02977 02978 if( entities.size() != times ) // should get as many hexes as you perviously marked 02979 return MB_FAILURE; 02980 02981 // fetch the hex entities of type--MBHEX, tag-"stale_bits", and tag value -- 0x5 02982 entities.clear(); 02983 result = MB->get_entities_by_type_and_tag( meshset, MBHEX, &stale_bits, &ptr_bits, 1, entities ); 02984 if( MB_SUCCESS != result ) return result; 02985 02986 if( entities.size() != times ) // should get as many hexes as you perviously marked 02987 return MB_FAILURE; 02988 02989 // now try the query with an empty meshset, expecting to get back 02990 // an empty Range 02991 02992 result = MB->create_meshset( MESHSET_SET, meshset ); 02993 if( MB_SUCCESS != result ) return result; 02994 02995 entities.clear(); 02996 result = MB->get_entities_by_type_and_tag( meshset, MBHEX, &junk_tag, &ptr_data, 1, entities ); 02997 if( MB_SUCCESS != result ) return result; 02998 02999 if( !entities.empty() ) return MB_FAILURE; 03000 03001 result = MB->tag_delete( stale_bits ); 03002 if( MB_SUCCESS != result ) return result; 03003 03004 return MB_SUCCESS; 03005 } 03006 #endif 03007 ErrorCode mb_common_tag_test( TagType storage ) 03008 { 03009 Core moab; 03010 Interface* mb = &moab; 03011 ErrorCode result = create_some_mesh( mb ); 03012 if( MB_SUCCESS != result ) return result; 03013 03014 char tagname[64]; 03015 sprintf( tagname, "t%d", rand() ); 03016 03017 Tag tag; 03018 const EntityHandle def_val = ~(EntityHandle)0; 03019 ErrorCode rval = mb->tag_get_handle( tagname, 1, MB_TYPE_HANDLE, tag, storage | MB_TAG_EXCL, &def_val ); 03020 if( MB_SUCCESS != rval ) return rval; 03021 03022 Range entities; 03023 mb->get_entities_by_handle( 0, entities ); 03024 if( entities.empty() ) return MB_FAILURE; 03025 03026 // set tag on every other entity to be the entities handle 03027 Range::const_iterator i; 03028 bool odd = true; 03029 for( i = entities.begin(); i != entities.end(); ++i, odd = !odd ) 03030 { 03031 if( odd ) 03032 { 03033 const EntityHandle h = *i; 03034 rval = mb->tag_set_data( tag, &h, 1, &h ); 03035 if( MB_SUCCESS != rval ) return rval; 03036 } 03037 } 03038 03039 // check values on every entity -- expect default for every other entity 03040 odd = true; 03041 for( i = entities.begin(); i != entities.end(); ++i, odd = !odd ) 03042 { 03043 EntityHandle val = 0; 03044 rval = mb->tag_get_data( tag, &*i, 1, &val ); 03045 if( MB_SUCCESS != rval ) return rval; 03046 03047 if( odd ) 03048 { 03049 if( val != *i ) return MB_FAILURE; 03050 } 03051 else 03052 { 03053 if( val != def_val ) return MB_FAILURE; 03054 } 03055 } 03056 03057 // set tag values on all entities 03058 std::vector< EntityHandle > values( entities.size() ); 03059 std::copy( entities.begin(), entities.end(), values.begin() ); 03060 rval = mb->tag_set_data( tag, entities, &values[0] ); 03061 if( MB_SUCCESS != rval ) return rval; 03062 03063 // check values on every entity -- expect default for every other entity 03064 for( i = entities.begin(); i != entities.end(); ++i ) 03065 { 03066 EntityHandle val = 0; 03067 rval = mb->tag_get_data( tag, &*i, 1, &val ); 03068 if( MB_SUCCESS != rval ) return rval; 03069 if( val != *i ) return MB_FAILURE; 03070 } 03071 03072 // find each entity by tag value 03073 for( i = entities.begin(); i != entities.end(); ++i ) 03074 { 03075 const EntityHandle h = *i; 03076 const EntityType type = mb->type_from_handle( h ); 03077 const void* const tag_vals[] = { &h }; 03078 Range range; 03079 rval = mb->get_entities_by_type_and_tag( 0, type, &tag, tag_vals, 1, range ); 03080 if( MB_SUCCESS != rval ) return rval; 03081 if( range.size() != 1 ) return MB_FAILURE; 03082 if( range.front() != h ) return MB_FAILURE; 03083 } 03084 03085 return MB_SUCCESS; 03086 } 03087 03088 ErrorCode mb_dense_tag_test() 03089 { 03090 return mb_common_tag_test( MB_TAG_DENSE ); 03091 } 03092 03093 ErrorCode mb_sparse_tag_test() 03094 { 03095 return mb_common_tag_test( MB_TAG_SPARSE ); 03096 } 03097 03098 // class to offset hex center nodes 03099 class OffsetHexCenterNodes : public Interface::HONodeAddedRemoved 03100 { 03101 public: 03102 OffsetHexCenterNodes( Interface* mb, double x, double y, double z ) : gMB( mb ) 03103 { 03104 mCoords[0] = 0.0; 03105 mCoords[1] = 0.0; 03106 mCoords[2] = 0.0; 03107 mOffset[0] = x; 03108 mOffset[1] = y; 03109 mOffset[2] = z; 03110 } 03111 03112 ~OffsetHexCenterNodes() {} 03113 03114 void node_added( EntityHandle node, EntityHandle ) 03115 { 03116 gMB->get_coords( &node, 1, mCoords ); 03117 mCoords[0] += mOffset[0]; 03118 mCoords[1] += mOffset[1]; 03119 mCoords[2] += mOffset[2]; 03120 gMB->set_coords( &node, 1, mCoords ); 03121 } 03122 03123 // do nothing 03124 void node_removed( EntityHandle /*node*/ ) {} 03125 03126 private: 03127 Interface* gMB; 03128 double mCoords[3]; 03129 double mOffset[3]; 03130 }; 03131 #ifdef MOAB_HAVE_NETCDF 03132 ErrorCode mb_entity_conversion_test() 03133 { 03134 ErrorCode error; 03135 Core moab; 03136 Interface* MB = &moab; 03137 03138 // read in a file so you have some data in the database 03139 std::string file_name = TestDir + "/mbtest3.g"; 03140 error = MB->load_mesh( file_name.c_str(), NULL, 0 ); 03141 if( error != MB_SUCCESS ) return error; 03142 03143 Range entities; 03144 EntityHandle meshset; 03145 MB->create_meshset( MESHSET_SET, meshset ); 03146 03147 MB->get_entities_by_type( 0, MBHEX, entities ); 03148 MB->add_entities( meshset, entities ); 03149 03150 OffsetHexCenterNodes function_object( MB, 0.07, 0.15, 0 ); 03151 03152 MB->convert_entities( meshset, false, false, true, &function_object ); 03153 if( MB_SUCCESS != check_valid_connectivity( MB ) ) return MB_FAILURE; 03154 03155 file_name = "hex_mid_volume_nodes.g"; 03156 error = MB->write_mesh( file_name.c_str() ); 03157 if( error != MB_SUCCESS ) return error; 03158 03159 error = MB->delete_mesh(); 03160 if( error != MB_SUCCESS ) return error; 03161 03162 error = MB->load_mesh( file_name.c_str(), NULL, 0 ); 03163 if( error != MB_SUCCESS ) return error; 03164 03165 error = MB->delete_mesh(); 03166 if( error != MB_SUCCESS ) return error; 03167 03168 file_name = TestDir + "/mbtest3.g"; 03169 error = MB->load_mesh( file_name.c_str(), NULL, 0 ); 03170 if( error != MB_SUCCESS ) return error; 03171 03172 entities.clear(); 03173 MB->get_entities_by_type( 0, MBHEX, entities ); 03174 03175 MB->create_meshset( MESHSET_SET, meshset ); 03176 MB->add_entities( meshset, entities ); 03177 MB->convert_entities( meshset, true, true, true ); 03178 if( MB_SUCCESS != check_valid_connectivity( MB ) ) return MB_FAILURE; 03179 03180 file_name = "hex_mid_edge_face_vol_nodes.g"; 03181 error = MB->write_mesh( file_name.c_str() ); 03182 if( error != MB_SUCCESS ) return error; 03183 03184 error = MB->delete_mesh(); 03185 if( error != MB_SUCCESS ) return error; 03186 03187 error = MB->load_mesh( file_name.c_str(), NULL, 0 ); 03188 if( error != MB_SUCCESS ) return error; 03189 03190 error = MB->delete_mesh(); 03191 if( error != MB_SUCCESS ) return error; 03192 03193 file_name = TestDir + "/mbtest3.g"; 03194 error = MB->load_mesh( file_name.c_str(), NULL, 0 ); 03195 if( error != MB_SUCCESS ) return error; 03196 03197 entities.clear(); 03198 MB->get_entities_by_type( 0, MBVERTEX, entities ); 03199 unsigned int original_num_nodes = entities.size(); 03200 entities.clear(); 03201 MB->get_entities_by_type( 0, MBHEX, entities ); 03202 03203 MB->create_meshset( MESHSET_SET, meshset ); 03204 MB->add_entities( meshset, entities ); 03205 MB->convert_entities( meshset, true, false, false ); 03206 if( MB_SUCCESS != check_valid_connectivity( MB ) ) return MB_FAILURE; 03207 03208 file_name = "hex_mid_edge_nodes.g"; 03209 error = MB->write_mesh( file_name.c_str() ); 03210 if( error != MB_SUCCESS ) return error; 03211 03212 // convert them back to hex8's 03213 MB->convert_entities( meshset, false, false, false ); 03214 if( MB_SUCCESS != check_valid_connectivity( MB ) ) return MB_FAILURE; 03215 03216 entities.clear(); 03217 MB->get_entities_by_type( 0, MBVERTEX, entities ); 03218 // make sure the higher order nodes really were deleted 03219 if( entities.size() != original_num_nodes ) return MB_FAILURE; 03220 03221 error = MB->delete_mesh(); 03222 if( error != MB_SUCCESS ) return error; 03223 03224 error = MB->load_mesh( file_name.c_str(), NULL, 0 ); 03225 if( error != MB_SUCCESS ) return error; 03226 03227 error = MB->delete_mesh(); 03228 if( error != MB_SUCCESS ) return error; 03229 03230 file_name = TestDir + "/mbtest1.g"; 03231 error = MB->load_mesh( file_name.c_str(), NULL, 0 ); 03232 if( error != MB_SUCCESS ) return error; 03233 03234 entities.clear(); 03235 MB->get_entities_by_type( 0, MBTET, entities ); 03236 03237 MB->create_meshset( MESHSET_SET, meshset ); 03238 MB->add_entities( meshset, entities ); 03239 MB->convert_entities( meshset, true, false, false ); 03240 if( MB_SUCCESS != check_valid_connectivity( MB ) ) return MB_FAILURE; 03241 03242 file_name = "tet_mid_edge_nodes.g"; 03243 error = MB->write_mesh( file_name.c_str() ); 03244 if( error != MB_SUCCESS ) return error; 03245 03246 error = MB->delete_mesh(); 03247 if( error != MB_SUCCESS ) return error; 03248 03249 error = MB->load_mesh( file_name.c_str(), NULL, 0 ); 03250 if( error != MB_SUCCESS ) return error; 03251 03252 error = MB->delete_mesh(); 03253 if( error != MB_SUCCESS ) return error; 03254 03255 file_name = TestDir + "/mbtest1.g"; 03256 error = MB->load_mesh( file_name.c_str(), NULL, 0 ); 03257 if( error != MB_SUCCESS ) return error; 03258 03259 entities.clear(); 03260 MB->get_entities_by_type( 0, MBTET, entities ); 03261 03262 MB->create_meshset( MESHSET_SET, meshset ); 03263 MB->add_entities( meshset, entities ); 03264 MB->convert_entities( meshset, false, true, false ); 03265 if( MB_SUCCESS != check_valid_connectivity( MB ) ) return MB_FAILURE; 03266 03267 file_name = "tet_mid_face_nodes.g"; 03268 error = MB->write_mesh( file_name.c_str() ); 03269 if( error != MB_SUCCESS ) return error; 03270 03271 error = MB->delete_mesh(); 03272 if( error != MB_SUCCESS ) return error; 03273 03274 error = MB->load_mesh( file_name.c_str(), NULL, 0 ); 03275 if( error != MB_SUCCESS ) return error; 03276 03277 error = MB->delete_mesh(); 03278 if( error != MB_SUCCESS ) return error; 03279 03280 file_name = TestDir + "/mbtest1.g"; 03281 error = MB->load_mesh( file_name.c_str(), NULL, 0 ); 03282 if( error != MB_SUCCESS ) return error; 03283 03284 entities.clear(); 03285 MB->get_entities_by_type( 0, MBTET, entities ); 03286 03287 MB->create_meshset( MESHSET_SET, meshset ); 03288 MB->add_entities( meshset, entities ); 03289 MB->convert_entities( meshset, true, true, false ); 03290 if( MB_SUCCESS != check_valid_connectivity( MB ) ) return MB_FAILURE; 03291 03292 file_name = "tet_mid_edge_face_nodes.g"; 03293 error = MB->write_mesh( file_name.c_str() ); 03294 if( error != MB_SUCCESS ) return error; 03295 03296 error = MB->delete_mesh(); 03297 if( error != MB_SUCCESS ) return error; 03298 03299 error = MB->load_mesh( file_name.c_str(), NULL, 0 ); 03300 if( error != MB_SUCCESS ) return error; 03301 03302 error = MB->delete_mesh(); 03303 if( error != MB_SUCCESS ) return error; 03304 03305 file_name = TestDir + "/mbtest1.g"; 03306 error = MB->load_mesh( file_name.c_str(), NULL, 0 ); 03307 if( error != MB_SUCCESS ) return error; 03308 03309 // delete all MBTRI's 03310 entities.clear(); 03311 error = MB->get_entities_by_type( 0, MBTRI, entities ); 03312 if( MB_SUCCESS != error ) return error; 03313 error = MB->delete_entities( entities ); 03314 if( MB_SUCCESS != error ) return error; 03315 03316 entities.clear(); 03317 error = MB->get_entities_by_type( 0, MBTET, entities ); 03318 if( MB_SUCCESS != error ) return error; 03319 03320 // skin the model 03321 for( Range::iterator tet_iter = entities.begin(); tet_iter != entities.end(); ++tet_iter ) 03322 { 03323 std::vector< EntityHandle > adj; 03324 error = MB->get_adjacencies( &( *tet_iter ), 1, 2, true, adj ); 03325 if( MB_SUCCESS != error ) return error; 03326 for( std::vector< EntityHandle >::iterator tri_iter = adj.begin(); tri_iter != adj.end(); ++tri_iter ) 03327 { 03328 std::vector< EntityHandle > up_adj; 03329 MB->get_adjacencies( &( *tri_iter ), 1, 3, false, up_adj ); 03330 if( up_adj.size() > 1 ) 03331 { 03332 error = MB->delete_entities( &( *tri_iter ), 1 ); 03333 if( MB_SUCCESS != error ) return error; 03334 } 03335 } 03336 } 03337 03338 // create a meshset of the skin 03339 EntityHandle export_meshset; 03340 MB->create_meshset( MESHSET_SET, export_meshset ); 03341 Tag material_tag; 03342 MB->tag_get_handle( MATERIAL_SET_TAG_NAME, 1, MB_TYPE_INTEGER, material_tag ); 03343 int block_id = 100; 03344 MB->tag_set_data( material_tag, &export_meshset, 1, &block_id ); 03345 entities.clear(); 03346 MB->get_entities_by_type( 0, MBTRI, entities ); 03347 // remove the first few tri's for fun 03348 Range tmp_ents; 03349 tmp_ents.insert( *entities.begin() ); 03350 entities.erase( entities.begin() ); 03351 tmp_ents.insert( *entities.begin() ); 03352 entities.erase( entities.begin() ); 03353 tmp_ents.insert( *entities.begin() ); 03354 entities.erase( entities.begin() ); 03355 tmp_ents.insert( *entities.begin() ); 03356 entities.erase( entities.begin() ); 03357 03358 MB->add_entities( export_meshset, entities ); 03359 03360 // convert the skin 03361 MB->convert_entities( export_meshset, true, true, false ); 03362 if( MB_SUCCESS != check_valid_connectivity( MB ) ) return MB_FAILURE; 03363 03364 // make sure our first few tri's were untouched 03365 std::vector< EntityHandle > conn( 3 ); 03366 for( Range::iterator kter = tmp_ents.begin(); kter != tmp_ents.end(); ++kter ) 03367 { 03368 MB->get_connectivity( &( *kter ), 1, conn ); 03369 if( conn.size() != 3 ) return MB_FAILURE; 03370 } 03371 03372 // output the skin 03373 file_name = "tri_mid_edge_face_nodes.g"; 03374 error = MB->write_mesh( file_name.c_str(), &export_meshset, 1 ); 03375 if( error != MB_SUCCESS ) return error; 03376 03377 MB->delete_entities( &export_meshset, 1 ); 03378 03379 error = MB->delete_mesh(); 03380 if( error != MB_SUCCESS ) return error; 03381 03382 // read the skin back in 03383 error = MB->load_mesh( file_name.c_str(), NULL, 0 ); 03384 if( error != MB_SUCCESS ) return error; 03385 03386 entities.clear(); 03387 MB->get_entities_by_type( 0, MBVERTEX, entities ); 03388 // must have 101 nodes 03389 if( entities.size() != 101 ) return MB_FAILURE; 03390 03391 error = MB->delete_mesh(); 03392 if( error != MB_SUCCESS ) return error; 03393 03394 return MB_SUCCESS; 03395 } 03396 #endif 03397 //! Build two Quads with two edges shared between them. The 03398 //! edges share the same nodes. We should be able to get 03399 //! adjacencies on the edges and get one (correct) quad. We 03400 //! should be able to get the edge adjacencies of the quads 03401 //! and only get 4 (not 5) edges. 03402 //! 03403 03404 ErrorCode mb_forced_adjacencies_test() 03405 { 03406 //! first clean up any existing mesh. 03407 ErrorCode error; 03408 Core moab; 03409 Interface* MB = &moab; 03410 03411 //! create 6 nodes, 2 quads and 8 edges. Edge 4 is adjacent 03412 //! to quad 1 and edge 5 is adjacent to quad 2. 03413 //! 03414 //! 4 5 6 03415 //! o--e7---o--e8---o 03416 //! | | | 03417 //! e3 q1 e4 e5 q2 e6 03418 //! | | | 03419 //! o--e1---o--e2---o 03420 //! 1 2 3 03421 //! 03422 double node_coord1[3] = { 0., 0., 0. }; 03423 double node_coord2[3] = { 1., 0., 0. }; 03424 double node_coord3[3] = { 2., 0., 0. }; 03425 double node_coord4[3] = { 0., 1., 0. }; 03426 double node_coord5[3] = { 1., 1., 0. }; 03427 double node_coord6[3] = { 2., 1., 0. }; 03428 03429 EntityHandle node1, node2, node3, node4, node5, node6; 03430 error = MB->create_vertex( node_coord1, node1 ); 03431 if( error != MB_SUCCESS ) return error; 03432 03433 error = MB->create_vertex( node_coord2, node2 ); 03434 if( error != MB_SUCCESS ) return error; 03435 03436 error = MB->create_vertex( node_coord3, node3 ); 03437 if( error != MB_SUCCESS ) return error; 03438 03439 error = MB->create_vertex( node_coord4, node4 ); 03440 if( error != MB_SUCCESS ) return error; 03441 03442 error = MB->create_vertex( node_coord5, node5 ); 03443 if( error != MB_SUCCESS ) return error; 03444 03445 error = MB->create_vertex( node_coord6, node6 ); 03446 if( error != MB_SUCCESS ) return error; 03447 03448 std::vector< EntityHandle > conn( 4 ); 03449 //! create the first quad 03450 EntityHandle quad1; 03451 conn[0] = node1; 03452 conn[1] = node2; 03453 conn[2] = node5; 03454 conn[3] = node4; 03455 error = MB->create_element( MBQUAD, &conn[0], 4, quad1 ); 03456 if( error != MB_SUCCESS ) return error; 03457 03458 //! create the second quad 03459 EntityHandle quad2; 03460 conn[0] = node2; 03461 conn[1] = node3; 03462 conn[2] = node6; 03463 conn[3] = node5; 03464 error = MB->create_element( MBQUAD, &conn[0], 4, quad2 ); 03465 if( error != MB_SUCCESS ) return error; 03466 03467 //! create the edges 03468 EntityHandle edge1; 03469 conn.resize( 2 ); 03470 conn[0] = node1; 03471 conn[1] = node2; 03472 error = MB->create_element( MBEDGE, &conn[0], 2, edge1 ); 03473 if( error != MB_SUCCESS ) return error; 03474 03475 EntityHandle edge2; 03476 conn[0] = node2; 03477 conn[1] = node3; 03478 error = MB->create_element( MBEDGE, &conn[0], 2, edge2 ); 03479 if( error != MB_SUCCESS ) return error; 03480 03481 EntityHandle edge3; 03482 conn[0] = node1; 03483 conn[1] = node4; 03484 error = MB->create_element( MBEDGE, &conn[0], 2, edge3 ); 03485 if( error != MB_SUCCESS ) return error; 03486 03487 EntityHandle edge4; 03488 conn[0] = node2; 03489 conn[1] = node5; 03490 error = MB->create_element( MBEDGE, &conn[0], 2, edge4 ); 03491 if( error != MB_SUCCESS ) return error; 03492 03493 EntityHandle edge5; 03494 conn[0] = node2; 03495 conn[1] = node5; 03496 error = MB->create_element( MBEDGE, &conn[0], 2, edge5 ); 03497 if( error != MB_SUCCESS ) return error; 03498 03499 EntityHandle edge6; 03500 conn[0] = node3; 03501 conn[1] = node6; 03502 error = MB->create_element( MBEDGE, &conn[0], 2, edge6 ); 03503 if( error != MB_SUCCESS ) return error; 03504 03505 EntityHandle edge7; 03506 conn[0] = node4; 03507 conn[1] = node5; 03508 error = MB->create_element( MBEDGE, &conn[0], 2, edge7 ); 03509 if( error != MB_SUCCESS ) return error; 03510 03511 EntityHandle edge8; 03512 conn[0] = node5; 03513 conn[1] = node6; 03514 error = MB->create_element( MBEDGE, &conn[0], 2, edge8 ); 03515 if( error != MB_SUCCESS ) return error; 03516 03517 //! Edge 4 and 5 share the same nodes, but should be different entities 03518 if( edge4 == edge5 ) return MB_FAILURE; 03519 03520 //! Now that the geometry is created start adding the adjacency information 03521 std::vector< EntityHandle > edge_adjacencies1( 4 ); 03522 edge_adjacencies1[0] = edge1; 03523 edge_adjacencies1[1] = edge4; 03524 edge_adjacencies1[2] = edge7; 03525 edge_adjacencies1[3] = edge3; 03526 03527 //! does this (should this) say anything about order of the edges around the 03528 //! quad? Also, does this also build the edge->quad adjacency, or is that 03529 //! does with a separate call? 03530 error = MB->add_adjacencies( quad1, &edge_adjacencies1[0], edge_adjacencies1.size(), true ); 03531 if( error != MB_SUCCESS ) return error; 03532 03533 std::vector< EntityHandle > edge_adjacencies2( 4 ); 03534 edge_adjacencies2[0] = edge2; 03535 edge_adjacencies2[1] = edge6; 03536 edge_adjacencies2[2] = edge8; 03537 edge_adjacencies2[3] = edge5; 03538 error = MB->add_adjacencies( quad2, &edge_adjacencies2[0], edge_adjacencies2.size(), true ); 03539 if( error != MB_SUCCESS ) return error; 03540 03541 //! now get the adjacencies of each quad. 03542 std::vector< EntityHandle > quad1_adjacencies; 03543 error = MB->get_adjacencies( &( quad1 ), 1, 1, false, quad1_adjacencies ); 03544 if( error != MB_SUCCESS ) return error; 03545 03546 std::sort( quad1_adjacencies.begin(), quad1_adjacencies.end() ); 03547 std::sort( edge_adjacencies1.begin(), edge_adjacencies1.end() ); 03548 03549 if( quad1_adjacencies != edge_adjacencies1 ) return MB_FAILURE; 03550 03551 std::vector< EntityHandle > quad2_adjacencies; 03552 error = MB->get_adjacencies( &( quad2 ), 1, 1, false, quad2_adjacencies ); 03553 if( error != MB_SUCCESS ) return error; 03554 03555 std::sort( quad2_adjacencies.begin(), quad2_adjacencies.end() ); 03556 std::sort( edge_adjacencies2.begin(), edge_adjacencies2.end() ); 03557 03558 if( quad2_adjacencies != edge_adjacencies2 ) return MB_FAILURE; 03559 03560 //! try getting the adjacency of edge1 (should be quad1) 03561 std::vector< EntityHandle > edge1_adjacencies; 03562 error = MB->get_adjacencies( &( edge1 ), 1, 2, false, edge1_adjacencies ); 03563 if( error != MB_SUCCESS ) return error; 03564 03565 //! there should be only 1 entity adjacent to edge1 03566 if( edge1_adjacencies.size() != 1 ) return MB_FAILURE; 03567 03568 //! and that entity should be quad1 03569 if( edge1_adjacencies[0] != quad1 ) return MB_FAILURE; 03570 03571 //! try getting the adjacency of edge6 (should be one) 03572 std::vector< EntityHandle > edge6_adjacencies; 03573 error = MB->get_adjacencies( &( edge6 ), 1, 2, false, edge6_adjacencies ); 03574 if( error != MB_SUCCESS ) return error; 03575 03576 //! there should be only 1 entity adjacent to edge6 03577 if( edge6_adjacencies.size() != 1 ) return MB_FAILURE; 03578 03579 //! Now seal up the "gap" caused by edges 4 and 5. Remove edge5 03580 //! from the adjacencies of quad2 and add edge 4 to quad2. 03581 03582 std::vector< EntityHandle > edge5_adjacencies( 1, edge5 ); 03583 error = MB->remove_adjacencies( quad2, &edge5_adjacencies[0], edge5_adjacencies.size() ); 03584 if( error != MB_SUCCESS ) return error; 03585 03586 std::vector< EntityHandle > edge4_adjacencies( 1, edge4 ); 03587 error = MB->add_adjacencies( quad2, &edge4_adjacencies[0], edge4_adjacencies.size(), true ); 03588 if( error != MB_SUCCESS ) return error; 03589 03590 //! get the adjacencies of edge4 and it should return both quads. 03591 std::vector< EntityHandle > quad_adjacencies; 03592 error = MB->get_adjacencies( &( edge4 ), 1, 2, false, quad_adjacencies ); 03593 if( error != MB_SUCCESS ) return error; 03594 03595 //! there should be 2 entities adjacent to edge4 03596 if( quad_adjacencies.size() != 2 ) return MB_FAILURE; 03597 03598 //! and they should be quad1 and quad2. Note that we are not saying anything 03599 //! about order in the array. 03600 if( ( quad_adjacencies[0] != quad1 || quad_adjacencies[1] != quad2 ) && 03601 ( quad_adjacencies[0] != quad2 || quad_adjacencies[1] != quad1 ) ) 03602 return MB_FAILURE; 03603 03604 //! clean up on exit 03605 error = MB->delete_mesh(); 03606 if( error != MB_SUCCESS ) return error; 03607 03608 return MB_SUCCESS; 03609 } 03610 03611 /*bool lessnodesZ(const EntityHandle entity_handle1, const EntityHandle entity_handle2) 03612 { 03613 double coords1[3], coords2[3]; 03614 gMB->get_coords(entity_handle1, coords1); 03615 gMB->get_coords(entity_handle2, coords2); 03616 03617 return coords2[2] < coords1[2]; 03618 }*/ 03619 03620 /*void sort_verts(Range vertices) 03621 { 03622 std::vector<EntityHandle> vert_vec(vertices.size()); 03623 Range::const_iterator iter; 03624 for (iter = vertices.begin(); iter != vertices.end(); ++iter) 03625 vert_vec.push_back(*iter); 03626 vert_vec.sort(lessnodesZ); 03627 }*/ 03628 bool points_are_coincident( const double* first, const double* second ) 03629 { 03630 double diff[3]; 03631 diff[2] = first[2] - second[2]; 03632 // if (diff[2] > 0.001) return false; 03633 03634 diff[0] = first[0] - second[0]; 03635 diff[1] = first[1] - second[1]; 03636 03637 double length = diff[0] * diff[0] + diff[1] * diff[1] + diff[2] * diff[2]; 03638 if( fabs( length ) < .001 ) return true; 03639 03640 return false; 03641 } 03642 ErrorCode find_coincident_nodes( Interface* gMB, Range vertices, 03643 std::vector< std::pair< EntityHandle, EntityHandle > >& coin_nodes ) 03644 { 03645 double first_coords[3], second_coords[3]; 03646 Range::const_iterator iter, jter; 03647 std::pair< EntityHandle, EntityHandle > coincident_pair; 03648 ErrorCode result; 03649 03650 for( iter = vertices.begin(); iter != vertices.end(); ++iter ) 03651 { 03652 result = gMB->get_coords( &( *iter ), 1, first_coords ); 03653 if( result != MB_SUCCESS ) return result; 03654 03655 for( jter = iter; jter != vertices.end(); ++jter ) 03656 { 03657 if( *iter != *jter ) 03658 { 03659 result = gMB->get_coords( &( *jter ), 1, second_coords ); 03660 if( result != MB_SUCCESS ) return result; 03661 03662 if( points_are_coincident( first_coords, second_coords ) ) 03663 { 03664 coincident_pair.first = *iter; 03665 coincident_pair.second = *jter; 03666 coin_nodes.push_back( coincident_pair ); 03667 } 03668 } 03669 } 03670 } 03671 return MB_SUCCESS; 03672 } 03673 03674 ErrorCode find_coincident_elements( Interface* gMB, Range entities, int num_nodes, 03675 std::vector< std::pair< EntityHandle, EntityHandle > >& coin ) 03676 { 03677 double coords1[8][3], coords2[8][3]; 03678 Range::iterator iter, jter; 03679 std::vector< EntityHandle > conn( 8 ); 03680 std::pair< EntityHandle, EntityHandle > coincident_pair; 03681 int i = 0, /* j = 0,*/ ii = 0; 03682 03683 for( iter = entities.begin(); iter != entities.end(); ++iter ) 03684 { 03685 // Get the coordinates for the element corners. 03686 if( gMB->get_connectivity( &( *iter ), 1, conn ) != MB_SUCCESS ) return MB_FAILURE; 03687 for( ii = 0; ii < num_nodes; ii++ ) 03688 { 03689 if( gMB->get_coords( &( conn[ii] ), 1, coords1[ii] ) != MB_SUCCESS ) return MB_FAILURE; 03690 } 03691 03692 for( jter = iter; jter != entities.end(); ++jter ) 03693 { 03694 if( *iter != *jter ) 03695 { 03696 // Elements should be the same sense to merge. 03697 if( gMB->get_connectivity( &( *jter ), 1, conn ) != MB_SUCCESS ) return MB_FAILURE; 03698 03699 for( int tq = 0; tq < num_nodes; tq++ ) 03700 if( gMB->get_coords( &( conn[tq] ), 1, coords2[tq] ) != MB_SUCCESS ) return MB_FAILURE; 03701 // if(gMB->get_coords(&(conn[0]), 1, coords2[0]) != MB_SUCCESS) 03702 // return MB_FAILURE; 03703 03704 // Find if first node is coincident before testing the rest. 03705 bool first = false; 03706 for( i = 0; i < num_nodes; i++ ) 03707 { 03708 if( points_are_coincident( coords1[i], coords2[0] ) ) 03709 { 03710 /* cout <<"first("<<i<<",0) - "; 03711 cout <<" coords1["<<i<<"] = (" 03712 <<coords1[i][0]<<"," 03713 <<coords1[i][1]<<"," 03714 <<coords1[i][2]<<") "; 03715 cout <<" coords2["<<0<<"] = (" 03716 <<coords2[0][0]<<"," 03717 <<coords2[0][1]<<"," 03718 <<coords2[0][2]<<")\n";*/ 03719 first = true; 03720 break; 03721 } 03722 } 03723 // TEST -- Find if second node is coincident before testing the rest. 03724 bool second = false; 03725 for( int t2 = 0; t2 < num_nodes; t2++ ) 03726 { 03727 if( points_are_coincident( coords1[t2], coords2[1] ) ) 03728 { 03729 /* cout <<"second("<<t2<<",1) - "; 03730 cout <<" coords1["<<t2<<"] = (" 03731 <<coords1[t2][0]<<"," 03732 <<coords1[t2][1]<<"," 03733 <<coords1[t2][2]<<") "; 03734 cout <<" coords2["<<1<<"] = (" 03735 <<coords2[1][0]<<"," 03736 <<coords2[1][1]<<"," 03737 <<coords2[1][2]<<")\n";*/ 03738 second = true; 03739 break; 03740 } 03741 } 03742 // TEST -- Find if second node is coincident before testing the rest. 03743 bool third = false; 03744 for( int ti = 0; ti < num_nodes; ti++ ) 03745 { 03746 if( points_are_coincident( coords1[ti], coords2[2] ) ) 03747 { 03748 /* cout <<"third("<<ti<<",2) - "; 03749 cout <<" coords1["<<ti<<"] = (" 03750 <<coords1[ti][0]<<"," 03751 <<coords1[ti][1]<<"," 03752 <<coords1[ti][2]<<") "; 03753 cout <<" coords2["<<1<<"] = (" 03754 <<coords2[2][0]<<"," 03755 <<coords2[2][1]<<"," 03756 <<coords2[2][2]<<")\n";*/ 03757 third = true; 03758 break; 03759 } 03760 } 03761 if( ( first ) && ( second ) && ( third ) ) 03762 { 03763 cout << "i = " << i << "\n"; 03764 for( int tii = 0; tii < num_nodes; tii++ ) 03765 { 03766 cout << " coords1[" << tii << "] = (" << coords1[tii][0] << "," << coords1[tii][1] << "," 03767 << coords1[tii][2] << ") "; 03768 cout << " coords2[" << tii << "] = (" << coords2[tii][0] << "," << coords2[tii][1] << "," 03769 << coords2[tii][2] << ")\n"; 03770 } 03771 } 03772 03773 if( i < num_nodes ) 03774 { 03775 for( ii = 1; ii < num_nodes; ii++ ) 03776 { 03777 if( gMB->get_coords( &( conn[ii] ), 1, coords2[ii] ) != MB_SUCCESS ) return MB_FAILURE; 03778 } 03779 /* 03780 for(j=1; j<num_nodes; j++) 03781 { 03782 03783 if(!points_are_coincident(coords1[j], coords2[(j+i)%num_nodes])) 03784 break; 03785 } 03786 if(j == num_nodes)*/ 03787 if( ( first ) && ( second ) && ( third ) ) 03788 { 03789 coincident_pair.first = *iter; 03790 coincident_pair.second = *jter; 03791 coin.push_back( coincident_pair ); 03792 } 03793 } 03794 } 03795 } 03796 } 03797 03798 return MB_SUCCESS; 03799 } 03800 03801 #ifdef MOAB_HAVE_NETCDF 03802 ErrorCode mb_merge_test() 03803 { 03804 Core moab; 03805 Interface* MB = &moab; 03806 03807 time_t begin_time = clock(); 03808 unsigned int i; 03809 ErrorCode result; 03810 Skinner Skinner_Obj( MB ); 03811 03812 std::string test_files[] = { std::string( "cell1.gen" ), std::string( "cell2.gen" ) }; 03813 /* std::string("cell3.gen"), 03814 std::string("cell4.gen"), 03815 std::string("cell5.gen"), 03816 std::string("cell6.gen"), 03817 std::string("cell7.gen"), 03818 std::string("cell8.gen"), 03819 std::string("cell9.gen"), 03820 std::string("cell10.gen"), 03821 std::string("cell11.gen"), 03822 std::string("cell12.gen"), 03823 std::string("cell13.gen"), 03824 std::string("cell14.gen"), 03825 std::string("cell15.gen"), 03826 std::string("cell16.gen"), 03827 std::string("cell17.gen"), 03828 std::string("cell18.gen"), 03829 std::string("cell19.gen"), 03830 std::string("cell20.gen"), 03831 std::string("cell21.gen"), 03832 std::string("cell22.gen"), 03833 std::string("cell23.gen"), 03834 std::string("cell24.gen")};*/ 03835 03836 /*std::vector<Range> entities(sizeof(test_files)); 03837 std::vector<Range> forward_lower(sizeof(test_files)); 03838 std::vector<Range> reverse_lower(sizeof(test_files)); 03839 std::vector<Range> nodes(sizeof(test_files));*/ 03840 Range entities; 03841 Range forward_lower; 03842 Range reverse_lower; 03843 Range faces; 03844 Range nodes; 03845 03846 cout << "---Starting Merge Tests---" << endl << endl; 03847 for( i = 0; i < ( sizeof( test_files ) / sizeof( std::string ) ); i++ ) 03848 { 03849 03850 cout << "---Testing:\"" << test_files[i] << "\"---" << endl; 03851 result = MB->load_mesh( test_files[i].c_str(), NULL, 0 ); 03852 if( result == MB_SUCCESS ) cout << "Loaded " << test_files[i] << "\n"; 03853 // get Hexes from model 03854 } 03855 result = MB->get_entities_by_type( 0, MBHEX, entities ); 03856 if( MB_SUCCESS != result ) return result; 03857 Skinner_Obj.find_skin( 0, entities, false, forward_lower, &reverse_lower ); 03858 // cout <<"num hexes = "<<entities.size()<<"\n"; 03859 // cout <<"fl = "<<forward_lower.size()<<" rl = "<<reverse_lower.size()<<"\n"; 03860 03861 // Range::const_iterator iter; 03862 int dim = 0; 03863 // int num_ents = 1; 03864 result = MB->get_adjacencies( forward_lower, dim, true, nodes, Interface::UNION ); 03865 // cout <<"nodes.size() = "<<nodes.size() <<"\n"; 03866 03867 // result = MB->get_entities_by_type(0, MBQUAD, faces); 03868 // cout <<"num faces = "<<faces.size() <<"\n"; 03869 03870 std::vector< std::pair< EntityHandle, EntityHandle > > coin_nodes; 03871 // cout <<"Begining sort...\n"; 03872 // std::sort(nodes.begin(),nodes.end(),lessnodesZ); 03873 // cout <<"Ending sort...\n"; 03874 result = find_coincident_nodes( MB, nodes, coin_nodes ); 03875 cout << "coin_nodes.size() = " << coin_nodes.size() << "\n"; 03876 std::vector< std::pair< EntityHandle, EntityHandle > >::iterator n_iter; 03877 for( n_iter = coin_nodes.begin(); n_iter != coin_nodes.end(); ++n_iter ) 03878 { 03879 result = MB->merge_entities( ( *n_iter ).first, ( *n_iter ).second, false, true ); 03880 if( MB_SUCCESS != result ) return result; 03881 } 03882 /* std::vector<std::pair<EntityHandle, EntityHandle> > coin_faces; 03883 int nodes_per_elt = 4; 03884 result = find_coincident_elements(forward_lower, nodes_per_elt, coin_faces); 03885 if (result != MB_SUCCESS) cout <<"find_coincident_elements fail!\n"; 03886 cout <<"coin_faces.size() = "<<coin_faces.size() <<"\n"; 03887 std::vector< std::pair<EntityHandle, EntityHandle> >::iterator f_iter; 03888 for (f_iter=coin_faces.begin(); f_iter != coin_faces.end(); ++f_iter) 03889 MB->merge_entities((*f_iter).first, (*f_iter).second, true, true);*/ 03890 /* 03891 std::vector<std::pair<EntityHandle, EntityHandle> > coin_fl; 03892 nodes_per_elt = 4; 03893 result = find_coincident_elements(entities, nodes_per_elt, coin_fl); 03894 cout <<"coin_fl.size() = "<<coin_fl.size() <<"\n"; 03895 */ 03896 int num_ents; 03897 if( ( MB_SUCCESS == MB->get_number_entities_by_dimension( 0, 3, num_ents ) && 0 != num_ents ) || 03898 ( MB_SUCCESS == MB->get_number_entities_by_dimension( 0, 2, num_ents ) && 0 != num_ents ) ) 03899 result = MB->write_mesh( "merge_test.g" ); 03900 ; 03901 03902 double clocks_per_sec = (double)CLOCKS_PER_SEC; 03903 double real_time = difftime( time( NULL ), begin_time ); 03904 cout << "TIME: " << ( real_time / clocks_per_sec ) << " seconds.\n"; 03905 return result; 03906 } 03907 #endif 03908 03909 ErrorCode mb_merge_update_test() 03910 { 03911 Core moab; 03912 Interface* mb = &moab; 03913 ErrorCode rval; 03914 03915 // create two quads with a coincident edge pair 03916 double coords[] = { 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 2, 0, 0, 2, 1, 0 }; 03917 EntityHandle verts[8]; 03918 for( int i = 0; i < 8; ++i ) 03919 mb->create_vertex( coords + 3 * i, verts[i] ); 03920 EntityHandle quad1, quad2, edge1, edge2; 03921 mb->create_element( MBQUAD, verts, 4, quad1 ); 03922 mb->create_element( MBQUAD, verts + 4, 4, quad2 ); 03923 mb->create_element( MBEDGE, verts + 1, 2, edge1 ); 03924 mb->create_element( MBEDGE, verts + 4, 2, edge2 ); 03925 03926 // create two tracking sets containing the vertices 03927 // and edge of each quad 03928 EntityHandle set1, set2; 03929 mb->create_meshset( MESHSET_TRACK_OWNER | MESHSET_SET, set1 ); 03930 mb->create_meshset( MESHSET_TRACK_OWNER | MESHSET_ORDERED, set2 ); 03931 mb->add_entities( set1, verts, 4 ); 03932 mb->add_entities( set2, verts + 4, 4 ); 03933 mb->add_entities( set1, &edge1, 1 ); 03934 mb->add_entities( set2, &edge2, 1 ); 03935 03936 // now merge the coincident edges 03937 rval = mb->merge_entities( verts[1], verts[5], false, true ); 03938 if( MB_SUCCESS != rval ) 03939 { 03940 std::cerr << "Merge failed at " << __FILE__ << ":" << __LINE__ << std::endl; 03941 return rval; 03942 } 03943 rval = mb->merge_entities( verts[2], verts[4], false, true ); 03944 if( MB_SUCCESS != rval ) 03945 { 03946 std::cerr << "Merge failed at " << __FILE__ << ":" << __LINE__ << std::endl; 03947 return rval; 03948 } 03949 rval = mb->merge_entities( edge1, edge2, false, true ); 03950 if( MB_SUCCESS != rval ) 03951 { 03952 std::cerr << "Merge failed at " << __FILE__ << ":" << __LINE__ << std::endl; 03953 return rval; 03954 } 03955 03956 // check that there is only one edge and that it has the correct connectivity 03957 Range r; 03958 mb->get_entities_by_type( 0, MBEDGE, r ); 03959 if( r.size() != 1 || r.front() != edge1 ) 03960 { 03961 std::cerr << "Edge merge failed at " << __FILE__ << ":" << __LINE__ << std::endl; 03962 return MB_FAILURE; 03963 } 03964 std::vector< EntityHandle > exp( verts + 1, verts + 3 ), act; 03965 mb->get_connectivity( &edge1, 1, act ); 03966 if( exp != act ) 03967 { 03968 std::cerr << "Incorrect conn for edge at " << __FILE__ << ":" << __LINE__ << std::endl; 03969 return MB_FAILURE; 03970 } 03971 03972 // check that quad connectivity is as expected 03973 exp = std::vector< EntityHandle >( verts, verts + 4 ); 03974 act.clear(); 03975 mb->get_connectivity( &quad1, 1, act ); 03976 if( exp != act ) 03977 { 03978 std::cerr << "Incorrect conn for quad at " << __FILE__ << ":" << __LINE__ << std::endl; 03979 return MB_FAILURE; 03980 } 03981 exp.resize( 4 ); 03982 exp[0] = verts[2]; 03983 exp[1] = verts[1]; 03984 exp[2] = verts[6]; 03985 exp[3] = verts[7]; 03986 act.clear(); 03987 mb->get_connectivity( &quad2, 1, act ); 03988 if( exp != act ) 03989 { 03990 std::cerr << "Incorrect conn for quad at " << __FILE__ << ":" << __LINE__ << std::endl; 03991 return MB_FAILURE; 03992 } 03993 03994 // check that set contents are correctly updated 03995 exp = std::vector< EntityHandle >( verts, verts + 4 ); 03996 exp.push_back( edge1 ); 03997 act.clear(); 03998 mb->get_entities_by_handle( set1, act ); 03999 std::sort( exp.begin(), exp.end() ); 04000 std::sort( act.begin(), act.end() ); 04001 if( exp != act ) 04002 { 04003 std::cerr << "Incorrect set contents at " << __FILE__ << ":" << __LINE__ << std::endl; 04004 std::cerr << " Expected: "; 04005 std::copy( exp.begin(), exp.end(), std::ostream_iterator< EntityHandle >( std::cerr, " " ) ); 04006 std::cerr << std::endl << " Actual : "; 04007 std::copy( act.begin(), act.end(), std::ostream_iterator< EntityHandle >( std::cerr, " " ) ); 04008 std::cerr << std::endl; 04009 return MB_FAILURE; 04010 } 04011 04012 exp.resize( 5 ); 04013 exp[0] = verts[2]; 04014 exp[1] = verts[1]; 04015 exp[2] = verts[6]; 04016 exp[3] = verts[7]; 04017 exp[4] = edge1; 04018 act.clear(); 04019 mb->get_entities_by_handle( set2, act ); 04020 if( exp != act ) 04021 { 04022 std::cerr << "Incorrect set contents at " << __FILE__ << ":" << __LINE__ << std::endl; 04023 std::cerr << " Expected: "; 04024 std::copy( exp.begin(), exp.end(), std::ostream_iterator< EntityHandle >( std::cerr, " " ) ); 04025 std::cerr << std::endl << " Actual : "; 04026 std::copy( act.begin(), act.end(), std::ostream_iterator< EntityHandle >( std::cerr, " " ) ); 04027 std::cerr << std::endl; 04028 return MB_FAILURE; 04029 } 04030 04031 return MB_SUCCESS; 04032 } 04033 #ifdef MOAB_HAVE_NETCDF 04034 ErrorCode mb_stress_test() 04035 { 04036 ErrorCode error; 04037 Core moab; 04038 Interface* MB = &moab; 04039 04040 cout << " Beginning Stress Test . . ." << endl; 04041 cout << "\n Reading elements" << endl; 04042 clock_t start = clock(); 04043 clock_t total_start = clock(); 04044 04045 // read in a file so you have some data in the database 04046 std::string file_name = "mb_big_test.g"; 04047 error = MB->load_mesh( file_name.c_str(), NULL, 0 ); 04048 if( error != MB_SUCCESS ) return error; 04049 04050 clock_t stop = clock(); 04051 04052 int num_entities_local; 04053 error = MB->get_number_entities_by_type( 0, MBHEX, num_entities_local ); 04054 if( error != MB_SUCCESS ) return error; 04055 04056 if( num_entities_local != 256000 ) return error; 04057 04058 float time = static_cast< float >( stop - start ) / CLOCKS_PER_SEC; 04059 float speed = num_entities_local / time; 04060 cout << " Read " << num_entities_local << " entities" 04061 << " in " << time << " seconds" << endl; 04062 cout << " at " << speed << " elements per second." << endl; 04063 04064 cout << "\n Transforming and copying elements" << endl; 04065 start = clock(); 04066 04067 Range hexes; 04068 error = MB->get_entities_by_type( 0, MBHEX, hexes ); 04069 if( error != MB_SUCCESS ) return error; 04070 04071 std::vector< EntityHandle > conn; 04072 Range::iterator iter; 04073 for( iter = hexes.begin(); iter != hexes.end(); ++iter ) 04074 { 04075 error = MB->get_connectivity( &( *iter ), 1, conn ); 04076 if( error != MB_SUCCESS ) return error; 04077 04078 double coords[3]; 04079 int i = 0; 04080 std::vector< EntityHandle > vertex_handle( 8 ); 04081 EntityHandle element_handle; 04082 std::vector< EntityHandle >::iterator jter; 04083 04084 for( jter = conn.begin(); jter != conn.end(); ++jter ) 04085 { 04086 error = MB->get_coords( &( *jter ), 1, coords ); 04087 if( error != MB_SUCCESS ) return error; 04088 coords[2] += 20.0; 04089 error = MB->create_vertex( coords, vertex_handle[i++] ); 04090 if( error != MB_SUCCESS ) return error; 04091 } 04092 error = MB->create_element( MBHEX, &vertex_handle[0], 8, element_handle ); 04093 if( error != MB_SUCCESS ) return error; 04094 } 04095 04096 stop = clock(); 04097 time = static_cast< float >( stop - start ) / CLOCKS_PER_SEC; 04098 04099 cout << " Transformed and created " << num_entities_local << " entities" 04100 << " in " << time << " seconds" << endl; 04101 04102 // Create mesh set 04103 cout << "\n Creating meshset" << endl; 04104 start = clock(); 04105 error = MB->get_entities_by_type( 0, MBHEX, hexes ); 04106 if( error != MB_SUCCESS ) return error; 04107 04108 if( hexes.size() != 512000 ) return MB_FAILURE; 04109 04110 EntityHandle mesh_set; 04111 error = MB->create_meshset( MESHSET_SET, mesh_set ); 04112 if( error != MB_SUCCESS ) return error; 04113 04114 error = MB->add_entities( mesh_set, hexes ); 04115 if( error != MB_SUCCESS ) return error; 04116 04117 stop = clock(); 04118 time = static_cast< float >( stop - start ) / CLOCKS_PER_SEC; 04119 04120 cout << " Created meshset with " << hexes.size() << " entities" 04121 << " in " << time << " seconds" << endl; 04122 04123 cout << "\n Writing 512K element file . . ." << endl; 04124 start = clock(); 04125 04126 // set the block tag 04127 Tag tag_handle; 04128 ErrorCode result = MB->tag_get_handle( MATERIAL_SET_TAG_NAME, 1, MB_TYPE_INTEGER, tag_handle ); 04129 if( result != MB_SUCCESS ) return result; 04130 04131 int id = 1; 04132 result = MB->tag_set_data( tag_handle, &mesh_set, 1, &id ); 04133 if( result != MB_SUCCESS ) return result; 04134 04135 std::vector< EntityHandle > output_list; 04136 output_list.push_back( mesh_set ); 04137 04138 file_name = "mb_stress_out.g"; 04139 error = MB->write_mesh( file_name.c_str(), &output_list[0], output_list.size() ); 04140 if( error != MB_SUCCESS ) return error; 04141 04142 stop = clock(); 04143 time = static_cast< float >( stop - start ) / CLOCKS_PER_SEC; 04144 04145 cout << " Wrote file with " << hexes.size() << " entities" 04146 << " in " << time << " seconds" << endl; 04147 04148 clock_t total_stop = clock(); 04149 time = static_cast< float >( total_stop - total_start ) / CLOCKS_PER_SEC; 04150 04151 cout << " Total time: " << time << " seconds." << endl; 04152 04153 MB->delete_mesh(); 04154 04155 return MB_SUCCESS; 04156 } 04157 #endif 04158 04159 ErrorCode mb_canon_number_test() 04160 { 04161 Core moab; 04162 Interface* MB = &moab; 04163 04164 // various tests for canonical ordering 04165 04166 // CN::AdjacentSubEntities 04167 std::vector< int > vec1, vec2; 04168 ErrorCode result; 04169 04170 EntityType this_type; 04171 04172 for( this_type = MBEDGE; this_type != MBKNIFE; this_type++ ) 04173 { 04174 04175 for( int i = 0; i < CN::VerticesPerEntity( this_type ); i++ ) 04176 { 04177 // test for edges and faces 04178 for( int dim = 1; dim <= CN::Dimension( this_type ); dim++ ) 04179 { 04180 // get the sides adjacent to this vertex 04181 vec1.clear(); 04182 int temp_result = CN::AdjacentSubEntities( this_type, &i, 1, 0, dim, vec1 ); 04183 04184 if( 0 != temp_result || vec1.size() > (unsigned int)CN::NumSubEntities( this_type, dim ) ) 04185 { 04186 cout << "failed getting sides for type " << CN::EntityTypeName( this_type ) << " dimension" << dim 04187 << endl; 04188 return MB_FAILURE; 04189 } 04190 04191 // now get the vertices shared by these sides 04192 vec2.clear(); 04193 temp_result = CN::AdjacentSubEntities( this_type, &vec1[0], vec1.size(), dim, 0, vec2 ); 04194 04195 // vertex side recovered should be i 04196 if( 0 != temp_result || 04197 // if dimension is same as DIMENSION(this_type), will get back all the 04198 // vertices in the entity 04199 ( dim == CN::Dimension( this_type ) && 04200 vec2.size() != (unsigned int)CN::VerticesPerEntity( this_type ) ) || 04201 // otherwise, we should get back only one vertex, and it should be the one 04202 // we started with 04203 ( dim != CN::Dimension( this_type ) && ( vec2.size() != 1 || vec2[0] != i ) ) ) 04204 { 04205 cout << "traversal from verts to sides to verts failed for " << endl 04206 << "vertex " << i << " type " << CN::EntityTypeName( this_type ) << " dimension " << dim 04207 << endl; 04208 return MB_FAILURE; 04209 } 04210 } 04211 } 04212 } 04213 04214 // CN::side_number 04215 04216 // create vertices to use later 04217 double xyz[3] = { 0.0, 0.0, 0.0 }; 04218 EntityHandle vertex_handles[8]; 04219 for( int i = 0; i < 8; i++ ) 04220 { 04221 result = MB->create_vertex( xyz, vertex_handles[i] ); 04222 assert( result == MB_SUCCESS ); 04223 } 04224 int side, sense, offset; 04225 04226 EntityHandle this_entity; 04227 04228 for( this_type = MBEDGE; this_type != MBKNIFE; this_type++ ) 04229 { 04230 04231 // skip remainder of the loop for MBPOLYGONS and POLYHEDRA, which don't follow 04232 // the standard canonical ordering 04233 if( this_type == MBPOLYGON || this_type == MBPOLYHEDRON ) continue; 04234 04235 // make an entity of this type 04236 result = MB->create_element( this_type, vertex_handles, CN::VerticesPerEntity( this_type ), this_entity ); 04237 if( MB_SUCCESS != result || 0 == this_entity ) 04238 { 04239 cout << "failed to create entity of type " << CN::EntityTypeName( this_type ) << endl; 04240 return MB_FAILURE; 04241 } 04242 04243 // now get the connectivity vector * 04244 const EntityHandle* entity_vertices; 04245 int num_verts; 04246 result = MB->get_connectivity( this_entity, entity_vertices, num_verts ); 04247 if( MB_SUCCESS != result || num_verts != CN::VerticesPerEntity( this_type ) ) 04248 { 04249 cout << "failed to get connectivity for entity type " << CN::EntityTypeName( this_type ) << endl; 04250 return MB_FAILURE; 04251 } 04252 04253 // for each dimension 04254 for( int dim = 1; dim <= CN::Dimension( this_type ); dim++ ) 04255 { 04256 // for each side of this dimension 04257 const CN::ConnMap& cm = CN::mConnectivityMap[this_type][dim - 1]; 04258 int tmp_conn[moab::MAX_SUB_ENTITY_VERTICES]; 04259 04260 for( int side_no = 0; side_no < CN::NumSubEntities( this_type, dim ); side_no++ ) 04261 { 04262 04263 for( int j = 0; j < moab::MAX_SUB_ENTITY_VERTICES; j++ ) 04264 tmp_conn[j] = cm.conn[side_no][j]; 04265 int temp_result = CN::SideNumber( this_type, tmp_conn, 04266 CN::VerticesPerEntity( CN::SubEntityType( this_type, dim, side_no ) ), 04267 dim, side, sense, offset ); 04268 if( 0 != temp_result ) 04269 { 04270 cout << "call to CN::side_number failed with non-success result" 04271 << " for type " << CN::EntityTypeName( this_type ) << " dimension " << dim << " side no " 04272 << side_no << endl; 04273 return MB_FAILURE; 04274 } 04275 04276 // side number should be the same as side_no, sense should be forward, offset should 04277 // be zero 04278 if( side != side_no || sense != 1 || offset != 0 ) 04279 { 04280 cout << "call to CN::side_number failed for type " << CN::EntityTypeName( this_type ) 04281 << " dimension " << dim << " side no " << side_no << endl 04282 << "side, sense, offset = " << side << " " << sense << " " << offset << endl; 04283 return MB_FAILURE; 04284 } 04285 } 04286 } 04287 04288 // destroy the entity of this_type 04289 result = MB->delete_entities( &this_entity, 1 ); 04290 if( MB_SUCCESS != result ) return result; 04291 } 04292 04293 return MB_SUCCESS; 04294 } 04295 ErrorCode mb_side_number_test() 04296 { 04297 ErrorCode rval; 04298 Core moab; 04299 Interface* mb = &moab; 04300 04301 /* Create faces of a wedge: */ 04302 /* 04303 4 04304 /|\ 04305 / | \ 04306 / | \ 04307 / 2 \ 04308 3.../.\...5 04309 | / \ | 04310 | / \ | 04311 |/ \| 6 // off vertex 04312 0_________1 04313 */ 04314 04315 const double coords[][3] = { 04316 { 0, 0, 0 }, { 2, 0, 0 }, { 1, 0, 1 }, { 0, 2, 0 }, { 2, 2, 0 }, { 1, 2, 1 }, { 3, 1, 0 }, 04317 }; 04318 EntityHandle verts[7]; 04319 for( unsigned i = 0; i < 7; ++i ) 04320 mb->create_vertex( coords[i], verts[i] ); 04321 04322 EntityHandle faces[6]; 04323 EntityHandle tri[] = { verts[0], verts[1], verts[2] }; 04324 EntityHandle tri2[] = { verts[3], verts[4], verts[5] }; 04325 EntityHandle quad1[] = { verts[0], verts[1], verts[5], verts[3] }; 04326 EntityHandle quad2[] = { verts[1], verts[5], verts[4], verts[2] }; 04327 EntityHandle quad3[] = { verts[2], verts[4], verts[3], verts[0] }; 04328 rval = mb->create_element( MBTRI, tri, 3, faces[0] );MB_CHK_ERR( rval ); 04329 rval = mb->create_element( MBQUAD, quad1, 4, faces[1] );MB_CHK_ERR( rval ); 04330 rval = mb->create_element( MBQUAD, quad2, 4, faces[2] );MB_CHK_ERR( rval ); 04331 rval = mb->create_element( MBQUAD, quad3, 4, faces[3] );MB_CHK_ERR( rval ); 04332 rval = mb->create_element( MBTRI, tri2, 3, faces[4] );MB_CHK_ERR( rval ); 04333 04334 EntityHandle prism; 04335 rval = mb->create_element( MBPRISM, verts, 6, prism );MB_CHK_ERR( rval ); 04336 04337 /* 04338 * side_number(const EntityHandle parent, 04339 const EntityHandle child, 04340 int &side_number, 04341 int &sense, 04342 int &offset) 04343 */ 04344 int side_n, sen, ofs; 04345 rval = mb->side_number( prism, faces[0], side_n, sen, ofs );MB_CHK_ERR( rval ); 04346 CHECK_EQUAL( side_n, 3 ); 04347 CHECK_EQUAL( sen, -1 ); 04348 CHECK_EQUAL( ofs, 0 ); 04349 04350 // this diagonal should not be on the prism (not an edge of the prism) 04351 EntityHandle diagonal1; 04352 EntityHandle diag[] = { verts[2], verts[3] }; 04353 rval = mb->create_element( MBEDGE, diag, 2, diagonal1 );MB_CHK_ERR( rval ); 04354 rval = mb->side_number( prism, diagonal1, side_n, sen, ofs ); 04355 // expected fail 04356 if( rval != MB_FAILURE ) return MB_FAILURE; 04357 04358 // create another triangle, connected to the prism, but not on the side 04359 EntityHandle tri3[] = { verts[3], verts[4], verts[6] }; 04360 rval = mb->create_element( MBTRI, tri3, 3, faces[5] );MB_CHK_ERR( rval ); 04361 rval = mb->side_number( prism, faces[5], side_n, sen, ofs ); 04362 // expected fail 04363 if( rval != MB_FAILURE ) return MB_FAILURE; 04364 04365 return MB_SUCCESS; 04366 } 04367 04368 ErrorCode mb_poly_test() 04369 { 04370 Core moab; 04371 Interface* mb = &moab; 04372 04373 // test polygon and polyhedron representation 04374 // create a couple of polygons; vertices first 04375 const double vert_pos[48] = { 04376 -1, 0, 0, 1, 0, 0, 2, 0, 0, 2, 1, 0, 1, 1, 0, 0, 2, 0, -1, 1, 0, -2, 1, 0, 04377 -2, 0, 0, -2, -1, 0, -1, -1, 0, -1, -2, 0, 1, -2, 0, 1, -1, 0, 2, -1, 0, 1.5, .5, 1 04378 }; 04379 04380 EntityHandle verts[16]; 04381 ErrorCode result; 04382 int i; 04383 for( i = 0; i < 16; i++ ) 04384 { 04385 result = mb->create_vertex( &vert_pos[3 * i], verts[i] ); 04386 if( MB_SUCCESS != result ) 04387 { 04388 std::cout << "Failed to create vertex " << i << " in mb_poly_test." << std::endl; 04389 return result; 04390 } 04391 } 04392 04393 // then polygons 04394 const int connect_idx[] = { 1, 2, 5, 6, 7, 2, 3, 4, 5, 5, 4, 6, 7, 6, 8, 0, 1, 7, 8, 0, 1, 2, 3, 14, 04395 13, 12, 11, 10, 9, 0, 9, 10, 11, 12, 13, 14, 3, 4, 6, 8, 2, 3, 15, 5, 3, 4, 5, 15 }; 04396 04397 int num_connect_idx[] = { 5, 4, 3, 3, 4, 10, 11, 4, 4 }; 04398 04399 EntityHandle polygons[9], temp_connect[12]; 04400 int idx = 0, nump = 0; 04401 ErrorCode tmp_result; 04402 while( nump < 9 ) 04403 { 04404 for( i = 0; i < num_connect_idx[nump]; i++ ) 04405 temp_connect[i] = verts[connect_idx[idx + i]]; 04406 04407 tmp_result = mb->create_element( MBPOLYGON, temp_connect, num_connect_idx[nump], polygons[nump] ); 04408 if( MB_SUCCESS != tmp_result ) 04409 { 04410 std::cout << "mb_poly_test: create_element failed for polygon " << i << "." << std::endl; 04411 result = tmp_result; 04412 nump++; 04413 continue; 04414 } 04415 04416 idx += num_connect_idx[nump]; 04417 nump++; 04418 } 04419 04420 if( MB_SUCCESS != result ) return result; 04421 04422 // ok, made 'em; now get all the vertices and make sure they're the same 04423 const EntityHandle* connect; 04424 int num_connect; 04425 idx = 0; 04426 int j; 04427 for( i = 0; i < 9; i++ ) 04428 { 04429 tmp_result = mb->get_connectivity( polygons[i], connect, num_connect ); 04430 if( MB_SUCCESS != tmp_result || num_connect != num_connect_idx[i] ) 04431 { 04432 std::cout << "mb_poly_test: get_connectivity test failed for polygon " << i << "." << std::endl; 04433 result = ( tmp_result != MB_SUCCESS ? tmp_result : MB_FAILURE ); 04434 continue; 04435 } 04436 04437 for( j = 0; j < num_connect; j++ ) 04438 { 04439 if( connect[j] != verts[connect_idx[idx + j]] ) 04440 { 04441 std::cout << "mb_poly_test: get_connectivity test returned wrong vertices for polygon " << i << "." 04442 << std::endl; 04443 result = MB_FAILURE; 04444 continue; 04445 } 04446 } 04447 04448 idx += num_connect; 04449 } 04450 04451 if( MB_SUCCESS != result ) return result; 04452 04453 // check a different way, with ranges 04454 Range vert_range, poly_range; 04455 for( i = 0; i < 9; i++ ) 04456 poly_range.insert( polygons[i] ); 04457 result = mb->get_adjacencies( poly_range, 0, false, vert_range, Interface::UNION ); 04458 if( MB_SUCCESS != result ) 04459 { 04460 std::cout << "mb_poly_test: get_adjacencies failed for polygon " << i << "." << std::endl; 04461 return result; 04462 } 04463 04464 else if( vert_range.size() != 16 ) 04465 { 04466 std::cout << "mb_poly_test: get_adjacencies returned wrong # of vertices for polygon " << i << "." << std::endl; 04467 return MB_FAILURE; 04468 } 04469 04470 // make a couple polyhedra 04471 EntityHandle polyhedra[2]; 04472 result = mb->create_element( MBPOLYHEDRON, polygons, 7, polyhedra[0] ); 04473 if( MB_SUCCESS != result ) 04474 { 04475 std::cout << "mb_poly_test: create_element failed for polyhedron 1." << std::endl; 04476 return result; 04477 } 04478 04479 temp_connect[0] = polygons[1]; 04480 temp_connect[1] = polygons[7]; 04481 temp_connect[2] = polygons[8]; 04482 result = mb->create_element( MBPOLYHEDRON, temp_connect, 3, polyhedra[1] ); 04483 if( MB_SUCCESS != result ) 04484 { 04485 std::cout << "mb_poly_test: create_element failed for polyhedron 2." << std::endl; 04486 return result; 04487 } 04488 04489 // now look for vertices common to both 04490 std::vector< EntityHandle > temp_verts; 04491 result = mb->get_adjacencies( polyhedra, 2, 0, false, temp_verts ); 04492 if( MB_SUCCESS != result ) 04493 { 04494 std::cout << "mb_poly_test: get_adjacencies failed for polyhedra." << std::endl; 04495 return result; 04496 } 04497 04498 if( 4 != temp_verts.size() ) 04499 { 04500 std::cout << "mb_poly_test: get_adjacencies for polyhedra returned " << temp_verts.size() 04501 << " vertices, should be 4." << std::endl; 04502 return MB_FAILURE; 04503 } 04504 04505 // ok, we're probably fine 04506 return MB_SUCCESS; 04507 } 04508 04509 ErrorCode mb_topo_util_test() 04510 { 04511 Core moab; 04512 Interface* gMB = &moab; 04513 MeshTopoUtil mtu( gMB ); 04514 04515 // construct a four-hex mesh for testing purposes 04516 double grid_vert_pos[] = { 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 2.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 2.0, 1.0, 0.0, 04517 0.0, 2.0, 0.0, 1.0, 2.0, 0.0, 2.0, 2.0, 0.0, 04518 // 04519 0.0, 0.0, 1.0, 1.0, 0.0, 1.0, 2.0, 0.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 2.0, 1.0, 1.0, 04520 0.0, 2.0, 1.0, 1.0, 2.0, 1.0, 2.0, 2.0, 1.0 }; 04521 04522 EntityHandle grid_verts[18], grid_elems[4]; 04523 ErrorCode result; 04524 #define RR \ 04525 if( result != MB_SUCCESS ) return result 04526 int init_edges, init_faces; 04527 result = gMB->get_number_entities_by_dimension( 0, 1, init_edges );RR; 04528 result = gMB->get_number_entities_by_dimension( 0, 2, init_faces );RR; 04529 04530 // make vertices 04531 for( int i = 0; i < 18; i++ ) 04532 { 04533 result = gMB->create_vertex( &grid_vert_pos[3 * i], grid_verts[i] );RR; 04534 } 04535 04536 // make hexes 04537 int numv = 3, numv_sq = 9; 04538 #define VINDEX( i, j, k ) ( i + ( j * numv ) + ( k * numv_sq ) ) 04539 EntityHandle connect[8]; 04540 for( int j = 0; j < 2; j++ ) 04541 { 04542 for( int i = 0; i < 2; i++ ) 04543 { 04544 int vijk = VINDEX( i, j, 0 ); 04545 connect[0] = grid_verts[vijk]; 04546 connect[1] = grid_verts[vijk + 1]; 04547 connect[2] = grid_verts[vijk + 1 + numv]; 04548 connect[3] = grid_verts[vijk + numv]; 04549 connect[4] = grid_verts[vijk + numv * numv]; 04550 connect[5] = grid_verts[vijk + 1 + numv * numv]; 04551 connect[6] = grid_verts[vijk + 1 + numv + numv * numv]; 04552 connect[7] = grid_verts[vijk + numv + numv * numv]; 04553 result = gMB->create_element( MBHEX, connect, 8, grid_elems[2 * j + i] );RR; 04554 } 04555 } 04556 04557 Range vert_range; 04558 std::copy( grid_verts, grid_verts + 18, range_inserter( vert_range ) ); 04559 04560 // generate aentities 04561 result = mtu.construct_aentities( vert_range );RR; 04562 04563 int this_edges, this_faces; 04564 result = gMB->get_number_entities_by_dimension( 0, 1, this_edges );RR; 04565 result = gMB->get_number_entities_by_dimension( 0, 2, this_faces );RR; 04566 04567 if( this_edges != init_edges + 33 || this_faces != init_faces + 20 ) 04568 { 04569 std::cout << "Wrong number of edges or faces in mb_topo_util test." << std::endl; 04570 // return MB_FAILURE; 04571 } 04572 04573 // get average position 04574 double pos[3]; 04575 for( int j = 0; j < 2; j++ ) 04576 { 04577 for( int i = 0; i < 2; i++ ) 04578 { 04579 result = mtu.get_average_position( grid_elems[2 * j + i], pos );RR; 04580 if( pos[0] != .5 + i || pos[1] != .5 + j || pos[2] != .5 ) 04581 { 04582 std::cout << "Wrong position at i = " << i << ", j = " << j << std::endl; 04583 result = MB_FAILURE; 04584 } 04585 } 04586 } 04587 RR; 04588 04589 // get star faces 04590 Range all_hexes, middle_edge; 04591 std::copy( grid_elems, grid_elems + 4, range_inserter( all_hexes ) ); 04592 // get the shared edge 04593 result = gMB->get_adjacencies( all_hexes, 1, false, middle_edge ); 04594 if( MB_SUCCESS != result || 1 != middle_edge.size() ) 04595 { 04596 std::cout << "Bad result getting single shared edge." << std::endl; 04597 return MB_FAILURE; 04598 } 04599 04600 std::vector< EntityHandle > star_faces, star_hexes; 04601 bool bdy_edge; 04602 result = mtu.star_entities( *middle_edge.begin(), star_faces, bdy_edge, 0, &star_hexes ); 04603 if( MB_SUCCESS != result || bdy_edge || star_faces.size() != 4 || star_hexes.size() != 4 ) 04604 { 04605 std::cout << "Bad result from star_faces for non-bdy edge." << std::endl; 04606 return MB_FAILURE; 04607 } 04608 04609 // now try for a different edge, which has to be on the bdy 04610 Range other_edges; 04611 all_hexes.clear(); 04612 all_hexes.insert( grid_elems[0] ); 04613 result = gMB->get_adjacencies( all_hexes, 1, false, other_edges );RR; 04614 other_edges.erase( *middle_edge.begin() ); 04615 if( 11 != other_edges.size() ) 04616 { 04617 std::cout << "Wrong number of edges in hex." << std::endl; 04618 return MB_FAILURE; 04619 } 04620 star_faces.clear(); 04621 star_hexes.clear(); 04622 result = mtu.star_entities( *other_edges.begin(), star_faces, bdy_edge, 0, &star_hexes ); 04623 if( MB_SUCCESS != result || !bdy_edge || ( star_faces.size() != 2 && star_faces.size() != 3 ) || 04624 ( star_hexes.size() != 1 && star_hexes.size() != 2 ) ) 04625 { 04626 std::cout << "Bad result from star_faces for bdy edge." << std::endl; 04627 return MB_FAILURE; 04628 } 04629 04630 return MB_SUCCESS; 04631 } 04632 04633 ErrorCode mb_split_test() 04634 { 04635 Core moab; 04636 Interface* gMB = &moab; 04637 MeshTopoUtil mtu( gMB ); 04638 04639 // construct a four-hex mesh for testing purposes 04640 double grid_vert_pos[] = { 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 2.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 2.0, 1.0, 0.0, 04641 0.0, 2.0, 0.0, 1.0, 2.0, 0.0, 2.0, 2.0, 0.0, 04642 // 04643 0.0, 0.0, 1.0, 1.0, 0.0, 1.0, 2.0, 0.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 2.0, 1.0, 1.0, 04644 0.0, 2.0, 1.0, 1.0, 2.0, 1.0, 2.0, 2.0, 1.0, 04645 // 04646 0.0, 0.0, 2.0, 1.0, 0.0, 2.0, 2.0, 0.0, 2.0, 0.0, 1.0, 2.0, 1.0, 1.0, 2.0, 2.0, 1.0, 2.0, 04647 0.0, 2.0, 2.0, 1.0, 2.0, 2.0, 2.0, 2.0, 2.0 }; 04648 04649 EntityHandle grid_verts[27], grid_elems[8]; 04650 ErrorCode result; 04651 #define RR \ 04652 if( result != MB_SUCCESS ) return result 04653 int init_edges, init_faces, init_regions; 04654 result = gMB->get_number_entities_by_dimension( 0, 1, init_edges );RR; 04655 result = gMB->get_number_entities_by_dimension( 0, 2, init_faces );RR; 04656 result = gMB->get_number_entities_by_dimension( 0, 3, init_regions );RR; 04657 04658 // make vertices 04659 for( int i = 0; i < 27; i++ ) 04660 { 04661 result = gMB->create_vertex( &grid_vert_pos[3 * i], grid_verts[i] );RR; 04662 } 04663 04664 // make hexes 04665 int numv = 3, numv_sq = 9; 04666 #define VINDEX( i, j, k ) ( i + ( j * numv ) + ( k * numv_sq ) ) 04667 EntityHandle connect[8]; 04668 for( int k = 0; k < 2; k++ ) 04669 { 04670 for( int j = 0; j < 2; j++ ) 04671 { 04672 for( int i = 0; i < 2; i++ ) 04673 { 04674 int vijk = VINDEX( i, j, k ); 04675 connect[0] = grid_verts[vijk]; 04676 connect[1] = grid_verts[vijk + 1]; 04677 connect[2] = grid_verts[vijk + 1 + numv]; 04678 connect[3] = grid_verts[vijk + numv]; 04679 connect[4] = grid_verts[vijk + numv * numv]; 04680 connect[5] = grid_verts[vijk + 1 + numv * numv]; 04681 connect[6] = grid_verts[vijk + 1 + numv + numv * numv]; 04682 connect[7] = grid_verts[vijk + numv + numv * numv]; 04683 result = gMB->create_element( MBHEX, connect, 8, grid_elems[4 * k + 2 * j + i] );RR; 04684 } 04685 } 04686 } 04687 04688 Range vert_range; 04689 std::copy( grid_verts, grid_verts + 27, range_inserter( vert_range ) ); 04690 04691 // generate aentities 04692 result = mtu.construct_aentities( vert_range );RR; 04693 04694 int this_edges, this_faces; 04695 result = gMB->get_number_entities_by_dimension( 0, 1, this_edges );RR; 04696 result = gMB->get_number_entities_by_dimension( 0, 2, this_faces );RR; 04697 04698 if( this_edges != init_edges + 54 || this_faces != init_faces + 36 ) 04699 { 04700 std::cout << "Wrong number of edges or faces in mb_topo_util test." << std::endl; 04701 return MB_FAILURE; 04702 } 04703 04704 // split the faces between the 2 layers 04705 // first get the faces 04706 Range split_faces, tmp_ents, tmp_faces; 04707 for( int i = 0; i < 4; i++ ) 04708 { 04709 tmp_ents.clear(); 04710 tmp_ents.insert( grid_elems[i] ); 04711 tmp_ents.insert( grid_elems[i + 4] ); 04712 tmp_faces.clear(); 04713 result = gMB->get_adjacencies( tmp_ents, 2, false, tmp_faces ); 04714 if( MB_SUCCESS != result || tmp_faces.size() != 1 ) 04715 { 04716 std::cout << "mb_split_test failed to get shared quad." << std::endl; 04717 return MB_FAILURE; 04718 } 04719 split_faces.insert( *tmp_faces.begin() ); 04720 } 04721 04722 Range new_faces, new_regions; 04723 04724 // NOTE: passing in non-NULL pointer for new_regions requests that region between the 04725 // split entities be filled with an element; in this case, since we're splitting faces, 04726 // the new entities are polyhedra 04727 result = mtu.split_entities_manifold( split_faces, new_faces, &new_regions ); 04728 if( MB_SUCCESS != result || new_faces.size() != 4 || new_regions.size() != 4 ) 04729 { 04730 std::cout << "mb_split_test failed to split quads." << std::endl; 04731 return MB_FAILURE; 04732 } 04733 04734 int this_regions; 04735 result = gMB->get_number_entities_by_dimension( 0, 1, this_edges );RR; 04736 result = gMB->get_number_entities_by_dimension( 0, 2, this_faces );RR; 04737 result = gMB->get_number_entities_by_dimension( 0, 3, this_regions );RR; 04738 04739 if( this_edges != init_edges + 54 || this_faces != init_faces + 40 || this_regions != init_regions + 12 ) 04740 { 04741 std::cout << "Wrong number of edges or faces or regions after splitting in mb_topo_util test." << std::endl; 04742 return MB_FAILURE; 04743 } 04744 04745 return MB_SUCCESS; 04746 } 04747 04748 ErrorCode mb_range_seq_intersect_test() 04749 { 04750 ErrorCode rval; 04751 SequenceManager sequences; 04752 RangeSeqIntersectIter iter( &sequences ); 04753 Range range; 04754 04755 // create some entity sequences 04756 EntitySequence *ts1, *ts2, *ts3, *qs1; 04757 EntityHandle th1, th2, th3, qh1; 04758 const int nt1 = 100, nt2 = 10, nt3 = 1, nq1 = 20; 04759 rval = sequences.create_entity_sequence( MBTRI, nt1, 3, 5, th1, ts1, -1 ); 04760 if( MB_SUCCESS != rval ) return rval; 04761 rval = sequences.create_entity_sequence( MBTRI, nt2, 6, 0, th2, ts2, -1 ); 04762 if( MB_SUCCESS != rval ) return rval; 04763 rval = sequences.create_entity_sequence( MBTRI, nt3, 3, MB_END_ID, th3, ts3, -1 ); 04764 if( MB_SUCCESS != rval ) return rval; 04765 rval = sequences.create_entity_sequence( MBQUAD, nq1, 4, 0, qh1, qs1, -1 ); 04766 if( MB_SUCCESS != rval ) return rval; 04767 04768 // we're going to assume this below, so verify it now 04769 if( th1 > th2 || th2 > th3 || th3 > qh1 ) return MB_FAILURE; 04770 04771 // construct an Range containing all valid handles; 04772 range.clear(); 04773 range.insert( ts1->start_handle(), ts1->end_handle() ); 04774 range.insert( ts2->start_handle(), ts2->end_handle() ); 04775 range.insert( ts3->start_handle(), ts3->end_handle() ); 04776 range.insert( qs1->start_handle(), qs1->end_handle() ); 04777 04778 // iterate over all and check results 04779 04780 rval = iter.init( range.begin(), range.end() ); 04781 if( MB_SUCCESS != rval ) return rval; 04782 if( ts1 != iter.get_sequence() ) return MB_FAILURE; 04783 if( iter.get_start_handle() != ts1->start_handle() ) return MB_FAILURE; 04784 if( iter.get_end_handle() != ts1->end_handle() ) return MB_FAILURE; 04785 04786 rval = iter.step(); 04787 if( MB_SUCCESS != rval ) return rval; 04788 if( ts2 != iter.get_sequence() ) return MB_FAILURE; 04789 if( iter.get_start_handle() != ts2->start_handle() ) return MB_FAILURE; 04790 if( iter.get_end_handle() != ts2->end_handle() ) return MB_FAILURE; 04791 04792 rval = iter.step(); 04793 if( MB_SUCCESS != rval ) return rval; 04794 if( ts3 != iter.get_sequence() ) return MB_FAILURE; 04795 if( iter.get_start_handle() != ts3->start_handle() ) return MB_FAILURE; 04796 if( iter.get_end_handle() != ts3->end_handle() ) return MB_FAILURE; 04797 04798 rval = iter.step(); 04799 if( MB_SUCCESS != rval ) return rval; 04800 if( qs1 != iter.get_sequence() ) return MB_FAILURE; 04801 if( iter.get_start_handle() != qs1->start_handle() ) return MB_FAILURE; 04802 if( iter.get_end_handle() != qs1->end_handle() ) return MB_FAILURE; 04803 04804 if( !iter.is_at_end() ) return MB_FAILURE; 04805 rval = iter.step(); 04806 if( MB_FAILURE != rval ) return MB_FAILURE; 04807 04808 // iterate over just the quads 04809 04810 rval = iter.init( range.lower_bound( MBQUAD ), range.end() ); 04811 if( MB_SUCCESS != rval ) return rval; 04812 if( qs1 != iter.get_sequence() ) return MB_FAILURE; 04813 if( iter.get_start_handle() != qs1->start_handle() ) return MB_FAILURE; 04814 if( iter.get_end_handle() != qs1->end_handle() ) return MB_FAILURE; 04815 04816 if( !iter.is_at_end() ) return MB_FAILURE; 04817 rval = iter.step(); 04818 if( MB_FAILURE != rval ) return MB_FAILURE; 04819 04820 // iterate starting one past the beginning of the 04821 // triangles and stopping one before the end. The last 04822 // sequence contains only one tri, so should stop and end 04823 // of second-to-last sequence 04824 04825 rval = iter.init( ++( range.begin() ), --( range.lower_bound( MBQUAD ) ) ); 04826 if( MB_SUCCESS != rval ) return rval; 04827 if( ts1 != iter.get_sequence() ) return MB_FAILURE; 04828 if( iter.get_start_handle() != ts1->start_handle() + 1 ) return MB_FAILURE; 04829 if( iter.get_end_handle() != ts1->end_handle() ) return MB_FAILURE; 04830 04831 rval = iter.step(); 04832 if( MB_SUCCESS != rval ) return rval; 04833 if( ts2 != iter.get_sequence() ) return MB_FAILURE; 04834 if( iter.get_start_handle() != ts2->start_handle() ) return MB_FAILURE; 04835 if( iter.get_end_handle() != ts2->end_handle() ) return MB_FAILURE; 04836 04837 if( !iter.is_at_end() ) return MB_FAILURE; 04838 rval = iter.step(); 04839 if( MB_FAILURE != rval ) return MB_FAILURE; 04840 04841 // Iterate over the quad sequence, starting two past the 04842 // beginning and stopping one before the end 04843 04844 rval = iter.init( ++( range.lower_bound( MBQUAD ) ), --( range.end() ) ); 04845 if( MB_SUCCESS != rval ) return rval; 04846 if( qs1 != iter.get_sequence() ) return MB_FAILURE; 04847 if( iter.get_start_handle() != qs1->start_handle() + 1 ) return MB_FAILURE; 04848 if( iter.get_end_handle() != qs1->end_handle() - 1 ) return MB_FAILURE; 04849 04850 if( !iter.is_at_end() ) return MB_FAILURE; 04851 rval = iter.step(); 04852 if( MB_FAILURE != rval ) return MB_FAILURE; 04853 04854 // Iterate over two subsets of the quad sequence 04855 04856 Range quads = range.subset_by_type( MBQUAD ); 04857 EntityHandle removed = qs1->start_handle() + nq1 / 2; 04858 if( quads.erase( removed ) == quads.end() ) return MB_FAILURE; 04859 04860 rval = iter.init( quads.begin(), quads.end() ); 04861 if( MB_SUCCESS != rval ) return rval; 04862 if( qs1 != iter.get_sequence() ) return MB_FAILURE; 04863 if( iter.get_start_handle() != qs1->start_handle() ) return MB_FAILURE; 04864 if( iter.get_end_handle() != removed - 1 ) return MB_FAILURE; 04865 04866 rval = iter.step(); 04867 if( MB_SUCCESS != rval ) return rval; 04868 if( qs1 != iter.get_sequence() ) return MB_FAILURE; 04869 if( iter.get_start_handle() != removed + 1 ) return MB_FAILURE; 04870 if( iter.get_end_handle() != qs1->end_handle() ) return MB_FAILURE; 04871 04872 if( !iter.is_at_end() ) return MB_FAILURE; 04873 rval = iter.step(); 04874 if( MB_FAILURE != rval ) return MB_FAILURE; 04875 04876 // Iterate over everything, including a bunch of 04877 // invalid handles 04878 04879 Range big; 04880 int junk; 04881 EntityHandle last = CREATE_HANDLE( MBQUAD + 1, 0, junk ); 04882 big.insert( ts1->start_handle() - 1, last ); 04883 04884 // first some invalid handles in the beginning of the range 04885 rval = iter.init( big.begin(), big.end() ); 04886 if( MB_ENTITY_NOT_FOUND != rval ) return MB_FAILURE; 04887 if( NULL != iter.get_sequence() ) return MB_FAILURE; 04888 if( iter.get_start_handle() != *big.begin() ) return MB_FAILURE; 04889 if( iter.get_end_handle() != ts1->start_handle() - 1 ) return MB_FAILURE; 04890 04891 // next the first triangle sequence 04892 rval = iter.step(); 04893 if( MB_SUCCESS != rval ) return rval; 04894 if( ts1 != iter.get_sequence() ) return MB_FAILURE; 04895 if( iter.get_start_handle() != ts1->start_handle() ) return MB_FAILURE; 04896 if( iter.get_end_handle() != ts1->end_handle() ) return MB_FAILURE; 04897 04898 // next the the invalid handles between the first two tri sequences 04899 if( ts1->end_handle() + 1 != ts2->start_handle() ) 04900 { 04901 rval = iter.step(); 04902 if( MB_ENTITY_NOT_FOUND != rval ) return MB_FAILURE; 04903 if( NULL != iter.get_sequence() ) return MB_FAILURE; 04904 if( iter.get_start_handle() != ts1->end_handle() + 1 ) return MB_FAILURE; 04905 if( iter.get_end_handle() != ts2->start_handle() - 1 ) return MB_FAILURE; 04906 } 04907 04908 // next the second triangle sequence 04909 rval = iter.step(); 04910 if( MB_SUCCESS != rval ) return rval; 04911 if( ts2 != iter.get_sequence() ) return MB_FAILURE; 04912 if( iter.get_start_handle() != ts2->start_handle() ) return MB_FAILURE; 04913 if( iter.get_end_handle() != ts2->end_handle() ) return MB_FAILURE; 04914 04915 // next the the invalid handles between the 2nd and 3rd tri sequences 04916 if( ts2->end_handle() + 1 != ts3->start_handle() ) 04917 { 04918 rval = iter.step(); 04919 if( MB_ENTITY_NOT_FOUND != rval ) return MB_FAILURE; 04920 if( NULL != iter.get_sequence() ) return MB_FAILURE; 04921 if( iter.get_start_handle() != ts2->end_handle() + 1 ) return MB_FAILURE; 04922 if( iter.get_end_handle() != ts3->start_handle() - 1 ) return MB_FAILURE; 04923 } 04924 04925 // next the third triangle sequence 04926 rval = iter.step(); 04927 if( MB_SUCCESS != rval ) return rval; 04928 if( ts3 != iter.get_sequence() ) return MB_FAILURE; 04929 if( iter.get_start_handle() != ts3->start_handle() ) return MB_FAILURE; 04930 if( iter.get_end_handle() != ts3->end_handle() ) return MB_FAILURE; 04931 04932 // third tri sequence contains the MAX tri handle, so no more 04933 // invalid triangles. 04934 // next 1 invalid quad at the before MB_START_ID 04935 if( ts3->end_handle() + 1 != qs1->start_handle() ) 04936 { 04937 rval = iter.step(); 04938 if( MB_ENTITY_NOT_FOUND != rval ) return MB_FAILURE; 04939 if( NULL != iter.get_sequence() ) return MB_FAILURE; 04940 if( iter.get_start_handle() != ts3->end_handle() + 1 ) return MB_FAILURE; 04941 if( iter.get_end_handle() != qs1->start_handle() - 1 ) return MB_FAILURE; 04942 } 04943 04944 // next the quad sequence 04945 rval = iter.step(); 04946 if( MB_SUCCESS != rval ) return rval; 04947 if( qs1 != iter.get_sequence() ) return MB_FAILURE; 04948 if( iter.get_start_handle() != qs1->start_handle() ) return MB_FAILURE; 04949 if( iter.get_end_handle() != qs1->end_handle() ) return MB_FAILURE; 04950 04951 // next remaining invalid quad handles in the range 04952 rval = iter.step(); 04953 if( MB_ENTITY_NOT_FOUND != rval ) return MB_FAILURE; 04954 if( 0 != iter.get_sequence() ) return MB_FAILURE; 04955 if( iter.get_start_handle() != qs1->end_handle() + 1 ) return MB_FAILURE; 04956 if( iter.get_end_handle() != last - 1 ) return MB_FAILURE; 04957 04958 // next invalid entity after the last quad in the range 04959 rval = iter.step(); 04960 if( MB_ENTITY_NOT_FOUND != rval ) return MB_FAILURE; 04961 if( 0 != iter.get_sequence() ) return MB_FAILURE; 04962 if( iter.get_start_handle() != last ) return MB_FAILURE; 04963 if( iter.get_end_handle() != last ) return MB_FAILURE; 04964 04965 // now at the end 04966 if( !iter.is_at_end() ) return MB_FAILURE; 04967 rval = iter.step(); 04968 if( MB_FAILURE != rval ) return MB_FAILURE; 04969 04970 // Create some holes 04971 Error eh; 04972 EntityHandle ts1s = ts1->start_handle(); 04973 EntityHandle dead1 = ts1->start_handle() + 1; 04974 EntityHandle dead2 = ts1->start_handle() + 2; 04975 EntityHandle ts1e = ts1->end_handle(); 04976 EntityHandle dead3 = ts2->start_handle(); 04977 EntityHandle dead4 = ts2->end_handle(); 04978 EntityHandle qs1s = qs1->start_handle(); 04979 EntityHandle qs1e = qs1->end_handle(); 04980 EntityHandle dead5 = qs1->start_handle() + nq1 / 2; 04981 EntityHandle dead6 = dead5 + 1; 04982 rval = sequences.delete_entity( &eh, dead1 ); 04983 if( MB_SUCCESS != rval ) return rval; 04984 rval = sequences.delete_entity( &eh, dead2 ); 04985 if( MB_SUCCESS != rval ) return rval; 04986 rval = sequences.delete_entity( &eh, dead3 ); 04987 if( MB_SUCCESS != rval ) return rval; 04988 rval = sequences.delete_entity( &eh, dead4 ); 04989 if( MB_SUCCESS != rval ) return rval; 04990 rval = sequences.delete_entity( &eh, dead5 ); 04991 if( MB_SUCCESS != rval ) return rval; 04992 rval = sequences.delete_entity( &eh, dead6 ); 04993 if( MB_SUCCESS != rval ) return rval; 04994 04995 // Iterate over sequences w/out removing deleted entities 04996 // from range. 04997 04998 // first sequence should have one valid handle at beginning 04999 rval = iter.init( range.begin(), range.end() ); 05000 if( MB_SUCCESS != rval ) return rval; 05001 if( 0 == iter.get_sequence() || ts1s != iter.get_sequence()->start_handle() || 05002 dead1 - 1 != iter.get_sequence()->end_handle() ) 05003 return MB_FAILURE; 05004 if( iter.get_start_handle() != ts1->start_handle() ) return MB_FAILURE; 05005 if( iter.get_end_handle() != dead1 - 1 ) return MB_FAILURE; 05006 05007 // next two invalid handles in sequence in first sequence 05008 rval = iter.step(); 05009 if( MB_ENTITY_NOT_FOUND != rval ) return MB_FAILURE; 05010 if( 0 != iter.get_sequence() ) return MB_FAILURE; 05011 if( iter.get_start_handle() != dead1 ) return MB_FAILURE; 05012 if( iter.get_end_handle() != dead2 ) return MB_FAILURE; 05013 05014 // next the remainder of the fist sequence 05015 rval = iter.step(); 05016 if( MB_SUCCESS != rval ) return rval; 05017 if( 0 == iter.get_sequence() || dead2 + 1 != iter.get_sequence()->start_handle() || 05018 ts1e != iter.get_sequence()->end_handle() ) 05019 return MB_FAILURE; 05020 if( iter.get_start_handle() != dead2 + 1 ) return MB_FAILURE; 05021 if( iter.get_end_handle() != ts1e ) return MB_FAILURE; 05022 05023 // next an invalid handle at the start of the second sequence 05024 rval = iter.step(); 05025 if( MB_ENTITY_NOT_FOUND != rval ) return MB_FAILURE; 05026 if( 0 != iter.get_sequence() ) return MB_FAILURE; 05027 if( iter.get_start_handle() != dead3 ) return MB_FAILURE; 05028 if( iter.get_end_handle() != dead3 ) return MB_FAILURE; 05029 05030 // next the second sequence up to the invalid handle at the end 05031 rval = iter.step(); 05032 if( MB_SUCCESS != rval ) return rval; 05033 if( 0 == iter.get_sequence() || dead3 + 1 != iter.get_sequence()->start_handle() || 05034 dead4 - 1 != iter.get_sequence()->end_handle() ) 05035 return MB_FAILURE; 05036 if( ts2 != iter.get_sequence() ) return MB_FAILURE; 05037 if( iter.get_start_handle() != dead3 + 1 ) return MB_FAILURE; 05038 if( iter.get_end_handle() != dead4 - 1 ) return MB_FAILURE; 05039 05040 // next invaild handle at the end of the second sequence 05041 rval = iter.step(); 05042 if( MB_ENTITY_NOT_FOUND != rval ) return MB_FAILURE; 05043 if( 0 != iter.get_sequence() ) return MB_FAILURE; 05044 if( iter.get_start_handle() != dead4 ) return MB_FAILURE; 05045 if( iter.get_end_handle() != dead4 ) return MB_FAILURE; 05046 05047 // next the third sequence 05048 rval = iter.step(); 05049 if( MB_SUCCESS != rval ) return rval; 05050 if( ts3 != iter.get_sequence() ) return MB_FAILURE; 05051 if( iter.get_start_handle() != ts3->start_handle() ) return MB_FAILURE; 05052 if( iter.get_end_handle() != ts3->end_handle() ) return MB_FAILURE; 05053 05054 // next the quad sequence up to the invalid handle in the middle 05055 rval = iter.step(); 05056 if( MB_SUCCESS != rval ) return rval; 05057 if( 0 == iter.get_sequence() || qs1s != iter.get_sequence()->start_handle() || 05058 dead5 - 1 != iter.get_sequence()->end_handle() ) 05059 return MB_FAILURE; 05060 if( qs1 != iter.get_sequence() ) return MB_FAILURE; 05061 if( iter.get_start_handle() != qs1s ) return MB_FAILURE; 05062 if( iter.get_end_handle() != dead5 - 1 ) return MB_FAILURE; 05063 05064 // next the two invalid handles in the middle 05065 rval = iter.step(); 05066 if( MB_ENTITY_NOT_FOUND != rval ) return MB_FAILURE; 05067 if( 0 != iter.get_sequence() ) return MB_FAILURE; 05068 if( iter.get_start_handle() != dead5 ) return MB_FAILURE; 05069 if( iter.get_end_handle() != dead6 ) return MB_FAILURE; 05070 05071 // next the remainder of the quad sequence 05072 rval = iter.step(); 05073 if( MB_SUCCESS != rval ) return rval; 05074 if( 0 == iter.get_sequence() || dead6 + 1 != iter.get_sequence()->start_handle() || 05075 qs1e != iter.get_sequence()->end_handle() ) 05076 return MB_FAILURE; 05077 if( iter.get_start_handle() != dead6 + 1 ) return MB_FAILURE; 05078 if( iter.get_end_handle() != qs1e ) return MB_FAILURE; 05079 05080 // now at the end 05081 if( !iter.is_at_end() ) return MB_FAILURE; 05082 rval = iter.step(); 05083 if( MB_FAILURE != rval ) return MB_FAILURE; 05084 05085 // now remove the dead entities from the range and iterate again 05086 05087 if( range.erase( dead1 ) == quads.end() ) return MB_FAILURE; 05088 if( range.erase( dead2 ) == quads.end() ) return MB_FAILURE; 05089 if( range.erase( dead3 ) == quads.end() ) return MB_FAILURE; 05090 if( range.erase( dead4 ) == quads.end() ) return MB_FAILURE; 05091 if( range.erase( dead5 ) == quads.end() ) return MB_FAILURE; 05092 if( range.erase( dead6 ) == quads.end() ) return MB_FAILURE; 05093 05094 // first sequence should have one valid handle at beginning 05095 rval = iter.init( range.begin(), range.end() ); 05096 if( MB_SUCCESS != rval ) return rval; 05097 if( 0 == iter.get_sequence() || ts1s != iter.get_sequence()->start_handle() || 05098 dead1 - 1 != iter.get_sequence()->end_handle() ) 05099 return MB_FAILURE; 05100 if( iter.get_start_handle() != ts1s ) return MB_FAILURE; 05101 if( iter.get_end_handle() != dead1 - 1 ) return MB_FAILURE; 05102 05103 // next the remainder of the fist sequence after the hole 05104 rval = iter.step(); 05105 if( MB_SUCCESS != rval ) return rval; 05106 if( 0 == iter.get_sequence() || dead2 + 1 != iter.get_sequence()->start_handle() || 05107 ts1e != iter.get_sequence()->end_handle() ) 05108 return MB_FAILURE; 05109 if( iter.get_start_handle() != dead2 + 1 ) return MB_FAILURE; 05110 if( iter.get_end_handle() != ts1e ) return MB_FAILURE; 05111 05112 // next the second sequence between deleted start and end handles 05113 rval = iter.step(); 05114 if( MB_SUCCESS != rval ) return rval; 05115 if( 0 == iter.get_sequence() || dead3 + 1 != iter.get_sequence()->start_handle() || 05116 dead4 - 1 != iter.get_sequence()->end_handle() ) 05117 return MB_FAILURE; 05118 if( iter.get_start_handle() != dead3 + 1 ) return MB_FAILURE; 05119 if( iter.get_end_handle() != dead4 - 1 ) return MB_FAILURE; 05120 05121 // next the third sequence 05122 rval = iter.step(); 05123 if( MB_SUCCESS != rval ) return rval; 05124 if( ts3 != iter.get_sequence() ) return MB_FAILURE; 05125 if( iter.get_start_handle() != ts3->start_handle() ) return MB_FAILURE; 05126 if( iter.get_end_handle() != ts3->end_handle() ) return MB_FAILURE; 05127 05128 // next the quad sequence up to the hole in the middle 05129 rval = iter.step(); 05130 if( MB_SUCCESS != rval ) return rval; 05131 if( 0 == iter.get_sequence() || qs1s != iter.get_sequence()->start_handle() || 05132 dead5 - 1 != iter.get_sequence()->end_handle() ) 05133 return MB_FAILURE; 05134 if( iter.get_start_handle() != qs1s ) return MB_FAILURE; 05135 if( iter.get_end_handle() != dead5 - 1 ) return MB_FAILURE; 05136 05137 // next the remainder of the quad sequence after the hole 05138 rval = iter.step(); 05139 if( MB_SUCCESS != rval ) return rval; 05140 if( 0 == iter.get_sequence() || dead6 + 1 != iter.get_sequence()->start_handle() || 05141 qs1e != iter.get_sequence()->end_handle() ) 05142 return MB_FAILURE; 05143 if( iter.get_start_handle() != dead6 + 1 ) return MB_FAILURE; 05144 if( iter.get_end_handle() != qs1e ) return MB_FAILURE; 05145 05146 // now at the end 05147 if( !iter.is_at_end() ) return MB_FAILURE; 05148 rval = iter.step(); 05149 if( MB_FAILURE != rval ) return MB_FAILURE; 05150 05151 return MB_SUCCESS; 05152 } 05153 05154 #define ASSERT_EQUAL( A, B ) \ 05155 do \ 05156 { \ 05157 if( !_assert_equal( ( A ), ( B ), #A, #B, __LINE__ ) ) return MB_FAILURE; \ 05158 } while( false ) 05159 05160 #define ASSERT_NOT_EQUAL( A, B ) \ 05161 do \ 05162 { \ 05163 if( !_assert_not_equal( ( A ), ( B ), #A, #B, __LINE__ ) ) return MB_FAILURE; \ 05164 } while( false ) 05165 05166 template < typename T1, typename T2 > 05167 bool _assert_equal( T1 a, T2 b, const char* as, const char* bs, int line ) 05168 { 05169 if( a == b ) return true; 05170 05171 std::cout << "Assertion failed at line " << line << std::endl 05172 << "\t" << as << " == " << bs << std::endl 05173 << "\t" << as << " = " << a << std::endl 05174 << "\t" << bs << " = " << b << std::endl; 05175 return false; 05176 } 05177 05178 template < typename T1, typename T2 > 05179 bool _assert_not_equal( T1 a, T2 b, const char* as, const char* bs, int line ) 05180 { 05181 if( a != b ) return true; 05182 05183 std::cout << "Assertion failed at line " << line << std::endl 05184 << "\t" << as << " != " << bs << std::endl 05185 << "\t" << as << " = " << a << std::endl 05186 << "\t" << bs << " = " << b << std::endl; 05187 return false; 05188 } 05189 05190 std::ostream& operator<<( std::ostream& s, Range::const_iterator i ) 05191 { 05192 return s << *i; 05193 } 05194 05195 ErrorCode mb_poly_adjacency_test() 05196 { 05197 ErrorCode rval; 05198 Core moab; 05199 Interface* mbImpl = &moab; 05200 05201 // make a couple polygons and a polyhedron 05202 double coords[3] = { 0, 1, 2 }; 05203 EntityHandle verts[10], polygons[2], polyhedron; 05204 05205 for( int i = 0; i < 10; i++ ) 05206 { 05207 rval = mbImpl->create_vertex( coords, verts[i] ); 05208 if( MB_SUCCESS != rval ) return rval; 05209 } 05210 05211 for( int i = 0; i < 2; i++ ) 05212 { 05213 rval = mbImpl->create_element( MBPOLYGON, verts, 5, polygons[i] ); 05214 if( MB_SUCCESS != rval ) return rval; 05215 } 05216 rval = mbImpl->create_element( MBPOLYHEDRON, polygons, 2, polyhedron ); 05217 if( MB_SUCCESS != rval ) return rval; 05218 05219 // create the aentities 05220 Range dum_range; 05221 for( int dim = 0; dim < 3; dim++ ) 05222 { 05223 dum_range.clear(); 05224 rval = mbImpl->get_adjacencies( &polyhedron, 1, dim, true, dum_range ); 05225 if( MB_SUCCESS != rval ) return rval; 05226 } 05227 05228 // delete the polyhedron 05229 rval = mbImpl->delete_entities( &polyhedron, 1 ); 05230 if( MB_SUCCESS != rval ) return rval; 05231 05232 // check adjacencies 05233 return moab.check_adjacencies(); 05234 } 05235 05236 ErrorCode mb_poly_adjacency_test2() 05237 { 05238 ErrorCode rval; 05239 Core moab; 05240 Interface* mbImpl = &moab; 05241 05242 // make a polyhedra in shape of a cube with a corner cut 05243 05244 /* 05245 * 05246 * 7 ------------- 8 05247 * . | . | 05248 * . . | initial cube had 8 vertices; box [000 - 222] 05249 * 5 ------------- 6 | cut a triangle 123 on lower corner 05250 * | | | | 05251 * | | | faces of the polyhedra (pointing outward) 05252 * | | | | (123) (24653) (4 10 8 6) 05253 * 3 | | (9 10 4 2 1) (7 8 10 9) (5687) 05254 * \ | | | (1 3 5 7 9) 05255 * 9 - - -| - 10 05256 * \ . | . 05257 * 1, | . 05258 * (000) '2 ---- 4 05259 * 05260 */ 05261 double coords[] = { 05262 0, 1, 0, // vertex 1 05263 1, 0, 0, // vertex 2 05264 0, 0, 1, // vertex 3 05265 2, 0, 0, 0, 0, 2, 2, 0, 2, // vertex 6 05266 0, 2, 2, 2, 2, 2, // vertex 8 05267 0, 2, 0, // vertex 9 05268 2, 2, 0 // vertex 9 05269 05270 }; 05271 EntityHandle verts[10], polygons[7], polyhedron; 05272 05273 for( int i = 0; i < 10; i++ ) 05274 { 05275 rval = mbImpl->create_vertex( &coords[3 * i], verts[i] ); 05276 if( MB_SUCCESS != rval ) return rval; 05277 } 05278 05279 EntityHandle connect[] = { 05280 1, 2, 3, // poly 1 05281 2, 4, 6, 5, 3, // poly 2 05282 4, 10, 8, 6, // polygon 3... 05283 9, 10, 4, 2, 1, 7, 8, 10, 9, 5, 6, 8, 7, 1, 3, 5, 7, 9 // polygon 7 05284 }; // we know the handles directly 05285 05286 int num_verts[7] = { 3, 5, 4, 5, 4, 4, 5 }; 05287 int start_indx[7]; 05288 start_indx[0] = 0; 05289 for( int i = 0; i < 6; i++ ) 05290 start_indx[i + 1] = start_indx[i] + num_verts[i]; 05291 for( int j = 0; j < 7; j++ ) 05292 { 05293 rval = mbImpl->create_element( MBPOLYGON, &connect[start_indx[j]], num_verts[j], polygons[j] ); 05294 if( MB_SUCCESS != rval ) return rval; 05295 } 05296 rval = mbImpl->create_element( MBPOLYHEDRON, polygons, 7, polyhedron ); 05297 if( MB_SUCCESS != rval ) return rval; 05298 05299 // create the aentities 05300 Range dum_range; 05301 for( int dim = 0; dim < 3; dim++ ) 05302 { 05303 dum_range.clear(); 05304 rval = mbImpl->get_adjacencies( &polyhedron, 1, dim, true, dum_range, Interface::UNION ); 05305 if( MB_SUCCESS != rval ) return rval; 05306 // std::cout << "\n dimension:" << dim << " " << dum_range.size() << " entities"; 05307 } 05308 // std::cout << "\n"; 05309 /*rval=mbImpl->write_mesh("polyhedra.vtk"); 05310 if (MB_SUCCESS != rval) 05311 return rval;*/ 05312 // delete the polyhedron 05313 rval = mbImpl->delete_entities( &polyhedron, 1 ); 05314 if( MB_SUCCESS != rval ) return rval; 05315 05316 // check adjacencies 05317 return moab.check_adjacencies(); 05318 } 05319 05320 ErrorCode mb_memory_use_test() 05321 { 05322 Core mb; 05323 unsigned long long init_total, total_with_elem, total_with_tag, total_with_tag_data; 05324 mb.estimated_memory_use( 0, 0, 0, &init_total ); 05325 05326 double coords[12] = { 1, 2, 0, 3, 4, 0, 5, 6, 0, 7, 8, 0 }; 05327 EntityHandle verts[4]; 05328 for( int i = 0; i < 4; ++i ) 05329 if( MB_SUCCESS != mb.create_vertex( coords + 3 * i, verts[i] ) ) return MB_FAILURE; 05330 05331 EntityHandle elem; 05332 mb.create_element( MBQUAD, verts, 4, elem ); 05333 05334 mb.estimated_memory_use( 0, 0, 0, &total_with_elem ); 05335 if( total_with_elem <= init_total ) return MB_FAILURE; 05336 05337 unsigned long long min, am; 05338 Range r; 05339 r.insert( elem ); 05340 mb.estimated_memory_use( r, &min, &am ); 05341 if( min != 4 * sizeof( EntityHandle ) ) return MB_FAILURE; 05342 05343 r.clear(); 05344 r.insert( verts[0] ); 05345 r.insert( verts[1] ); 05346 mb.estimated_memory_use( r, &min, &am ); 05347 if( min != 6 * sizeof( double ) ) return MB_FAILURE; 05348 05349 Tag tag; 05350 if( MB_SUCCESS != mb.tag_get_handle( "TMP_TAG", 1, MB_TYPE_INTEGER, tag, MB_TAG_SPARSE | MB_TAG_EXCL ) ) 05351 return MB_FAILURE; 05352 mb.estimated_memory_use( r, &min, &am ); 05353 if( min != 6 * sizeof( double ) ) return MB_FAILURE; 05354 05355 mb.estimated_memory_use( 0, 0, 0, &total_with_tag ); 05356 if( total_with_tag <= total_with_elem ) return MB_FAILURE; 05357 05358 int tag_data[] = { 0xA, 0xB }; 05359 if( MB_SUCCESS != mb.tag_set_data( tag, r, &tag_data ) ) return MB_FAILURE; 05360 mb.estimated_memory_use( r, &min, &am ); 05361 if( min <= 6 * sizeof( double ) ) return MB_FAILURE; 05362 05363 mb.estimated_memory_use( 0, 0, 0, &total_with_tag_data ); 05364 if( total_with_tag_data <= total_with_tag ) return MB_FAILURE; 05365 05366 return MB_SUCCESS; 05367 } 05368 05369 ErrorCode mb_skin_curve_test_common( bool use_adj ); 05370 05371 ErrorCode mb_skin_curve_test() 05372 { 05373 return mb_skin_curve_test_common( false ); 05374 } 05375 05376 ErrorCode mb_skin_curve_adj_test() 05377 { 05378 return mb_skin_curve_test_common( true ); 05379 } 05380 05381 ErrorCode mb_skin_surface_test_common( bool use_adj ); 05382 05383 ErrorCode mb_skin_surface_test() 05384 { 05385 return mb_skin_surface_test_common( false ); 05386 } 05387 05388 ErrorCode mb_skin_surface_adj_test() 05389 { 05390 return mb_skin_surface_test_common( true ); 05391 } 05392 05393 ErrorCode mb_skin_volume_test_common( bool use_adj ); 05394 05395 ErrorCode mb_skin_volume_test() 05396 { 05397 return mb_skin_volume_test_common( false ); 05398 } 05399 05400 ErrorCode mb_skin_volume_adj_test() 05401 { 05402 return mb_skin_volume_test_common( true ); 05403 } 05404 05405 ErrorCode mb_skin_curve_test_common( bool use_adj ) 05406 { 05407 ErrorCode rval; 05408 Core moab; 05409 Interface* mb = &moab; 05410 05411 std::vector< EntityHandle > verts; 05412 for( unsigned i = 0; i < 10; ++i ) 05413 { 05414 double coords[] = { static_cast< double >( i ), 0, 0 }; 05415 EntityHandle h; 05416 mb->create_vertex( coords, h ); 05417 verts.push_back( h ); 05418 } 05419 Range edges; 05420 for( unsigned i = 1; i < verts.size(); ++i ) 05421 { 05422 EntityHandle conn[] = { verts[i - 1], verts[i] }; 05423 EntityHandle h; 05424 mb->create_element( MBEDGE, conn, 2, h ); 05425 edges.insert( h ); 05426 } 05427 05428 Range skin; 05429 Skinner tool( mb ); 05430 rval = tool.find_skin( 0, edges, 0, skin, use_adj ); 05431 if( MB_SUCCESS != rval ) 05432 { 05433 std::cerr << "Skinner failure at " __FILE__ ":" << __LINE__ << std::endl; 05434 return MB_FAILURE; 05435 } 05436 if( skin.size() != 2 ) 05437 { 05438 std::cerr << "Skinner bad result at " __FILE__ ":" << __LINE__ << std::endl; 05439 return MB_FAILURE; 05440 } 05441 05442 if( verts.front() > verts.back() ) std::swap( verts.front(), verts.back() ); 05443 if( skin.front() != verts.front() || skin.back() != verts.back() ) 05444 { 05445 std::cerr << "Skinner bad result at " __FILE__ ":" << __LINE__ << std::endl; 05446 return MB_FAILURE; 05447 } 05448 05449 // now test again with only one edge 05450 EntityHandle edge = edges.front(); 05451 Range range( edge, edge ); 05452 skin.clear(); 05453 rval = tool.find_skin( 0, range, 0, skin, use_adj ); 05454 if( MB_SUCCESS != rval ) 05455 { 05456 std::cerr << "Skinner failure at " __FILE__ ":" << __LINE__ << std::endl; 05457 return MB_FAILURE; 05458 } 05459 if( skin.size() != 2 ) 05460 { 05461 std::cerr << "Skinner bad result at " __FILE__ ":" << __LINE__ << std::endl; 05462 return MB_FAILURE; 05463 } 05464 05465 Range verts2; 05466 mb->get_connectivity( &edge, 1, verts2 ); 05467 if( skin.front() != verts2.front() || skin.back() != verts2.back() ) 05468 { 05469 std::cerr << "Skinner bad result at " __FILE__ ":" << __LINE__ << std::endl; 05470 return MB_FAILURE; 05471 } 05472 05473 return MB_SUCCESS; 05474 } 05475 05476 ErrorCode mb_skin_surface_test_common( bool use_adj ) 05477 { 05478 ErrorCode rval; 05479 Core moab; 05480 Interface* mb = &moab; 05481 05482 /* Create 4 of 5 faces of a wedge: */ 05483 /* 05484 4 05485 /|\ 05486 / | \ 05487 / | \ 05488 / 2 \ 05489 3.../.\...5 05490 | / \ | 05491 | / \ | 05492 |/ \| 05493 0_________1 05494 */ 05495 05496 const double coords[][3] = { { 0, 0, 0 }, { 2, 0, 0 }, { 1, 0, 1 }, { 0, 2, 0 }, { 2, 2, 0 }, { 1, 2, 1 } }; 05497 EntityHandle verts[6]; 05498 for( unsigned i = 0; i < 6; ++i ) 05499 mb->create_vertex( coords[i], verts[i] ); 05500 05501 EntityHandle faces[4]; 05502 EntityHandle tri[] = { verts[0], verts[1], verts[2] }; 05503 EntityHandle quad1[] = { verts[0], verts[1], verts[5], verts[3] }; 05504 EntityHandle quad2[] = { verts[1], verts[5], verts[4], verts[2] }; 05505 EntityHandle quad3[] = { verts[2], verts[4], verts[3], verts[0] }; 05506 mb->create_element( MBTRI, tri, 3, faces[0] ); 05507 mb->create_element( MBQUAD, quad1, 4, faces[1] ); 05508 mb->create_element( MBQUAD, quad2, 4, faces[2] ); 05509 mb->create_element( MBQUAD, quad3, 4, faces[3] ); 05510 Range source; 05511 std::copy( faces, faces + 4, range_inserter( source ) ); 05512 05513 // Now skin the mesh. The only missing face is the 05514 // back triangle (verts 3, 4, & 5) so the skin should 05515 // be the edges bordering that face. 05516 05517 Range skin; 05518 Skinner tool( mb ); 05519 rval = tool.find_skin( 0, source, 1, skin, use_adj ); 05520 if( MB_SUCCESS != rval ) 05521 { 05522 std::cerr << "Skinner failure at " __FILE__ ":" << __LINE__ << std::endl; 05523 return MB_FAILURE; 05524 } 05525 if( skin.size() != 3 || !skin.all_of_type( MBEDGE ) ) 05526 { 05527 std::cerr << "Skinner bad result at " __FILE__ ":" << __LINE__ << std::endl; 05528 return MB_FAILURE; 05529 } 05530 05531 // Check each edge 05532 std::vector< EntityHandle > conn[3]; 05533 rval = mb->get_connectivity( &skin.front(), 1, conn[0] ); 05534 if( MB_SUCCESS != rval ) return rval; 05535 rval = mb->get_connectivity( &*++skin.begin(), 1, conn[1] ); 05536 if( MB_SUCCESS != rval ) return rval; 05537 rval = mb->get_connectivity( &skin.back(), 1, conn[2] ); 05538 if( MB_SUCCESS != rval ) return rval; 05539 for( int i = 0; i < 3; ++i ) 05540 if( conn[i][0] > conn[i][1] ) std::swap( conn[i][0], conn[i][1] ); 05541 05542 for( int i = 0; i < 3; ++i ) 05543 { 05544 EntityHandle s = verts[i + 3], e = verts[( i + 1 ) % 3 + 3]; 05545 if( s > e ) std::swap( s, e ); 05546 int j = 0; 05547 for( j = 0; j < 3; ++j ) 05548 if( conn[j][0] == s && conn[j][1] == e ) break; 05549 05550 if( j == 3 ) 05551 { 05552 std::cerr << "Skin does not contain edge [" << s << "," << e << "] at " << __FILE__ ":" << __LINE__ 05553 << std::endl; 05554 return MB_FAILURE; 05555 } 05556 } 05557 05558 return MB_SUCCESS; 05559 } 05560 05561 ErrorCode mb_skin_volume_test_common( bool use_adj ) 05562 { 05563 ErrorCode rval; 05564 Core moab; 05565 Interface* mb = &moab; 05566 05567 /* A 2 adjacent hexes hexes */ 05568 /* 05569 9-----10----11 05570 / / /| 05571 / / / | 05572 6-----7-----8..5 05573 | . | . | / 05574 |. |. |/ 05575 0-----1-----2 05576 */ 05577 05578 const double coords[][3] = { { 0, 0, 0 }, { 1, 0, 0 }, { 2, 0, 0 }, { 0, 1, 0 }, { 1, 1, 0 }, { 2, 1, 0 }, 05579 { 0, 0, 1 }, { 1, 0, 1 }, { 2, 0, 1 }, { 0, 1, 1 }, { 1, 1, 1 }, { 2, 1, 1 } }; 05580 EntityHandle verts[12]; 05581 for( unsigned i = 0; i < 12; ++i ) 05582 mb->create_vertex( coords[i], verts[i] ); 05583 05584 EntityHandle hex1c[] = { verts[0], verts[1], verts[4], verts[3], verts[6], verts[7], verts[10], verts[9] }; 05585 EntityHandle hex2c[] = { verts[1], verts[2], verts[5], verts[4], verts[7], verts[8], verts[11], verts[10] }; 05586 EntityHandle hex1, hex2; 05587 mb->create_element( MBHEX, hex1c, 8, hex1 ); 05588 mb->create_element( MBHEX, hex2c, 8, hex2 ); 05589 Range source; 05590 source.insert( hex1 ); 05591 source.insert( hex2 ); 05592 05593 // get all quads and shared face 05594 Range tmp, all_faces; 05595 mb->get_adjacencies( source, 2, true, all_faces, Interface::UNION ); 05596 mb->get_adjacencies( source, 2, true, tmp, Interface::INTERSECT ); 05597 assert( tmp.size() == 1 ); 05598 Range non_shared = subtract( all_faces, tmp ); 05599 05600 // Now skin the mesh. 05601 05602 Range skin; 05603 Skinner tool( mb ); 05604 rval = tool.find_skin( 0, source, 2, skin, use_adj ); 05605 if( MB_SUCCESS != rval ) 05606 { 05607 std::cerr << "Skinner failure at " __FILE__ ":" << __LINE__ << std::endl; 05608 return MB_FAILURE; 05609 } 05610 if( skin != non_shared ) 05611 { 05612 std::cerr << "Skinner bad result at " __FILE__ ":" << __LINE__ << std::endl; 05613 return MB_FAILURE; 05614 } 05615 05616 return MB_SUCCESS; 05617 } 05618 05619 ErrorCode mb_skin_scd_test() 05620 { 05621 // make a 10x10x5 scd mesh 05622 Core moab; 05623 Interface* mb = &moab; 05624 ScdInterface* scdi; 05625 ErrorCode rval = mb->query_interface( scdi ); 05626 if( MB_SUCCESS != rval ) return rval; 05627 HomCoord low( 0, 0, 0 ), high( 10, 10, 5 ); 05628 ScdBox* this_box; 05629 rval = scdi->construct_box( low, high, NULL, 0, this_box ); 05630 if( MB_SUCCESS != rval ) return rval; 05631 05632 // now skin it with the structured and original method, and compare results 05633 Skinner tool( mb ); 05634 Range ents( this_box->start_element(), this_box->start_element() + this_box->num_elements() - 1 ), scd_skin_ents, 05635 skin_ents; 05636 rval = tool.find_skin( 0, ents, false, scd_skin_ents, NULL, true, true, true ); 05637 if( MB_SUCCESS != rval ) return rval; 05638 05639 rval = tool.find_skin( 0, ents, false, skin_ents, NULL, true, true, false ); 05640 if( MB_SUCCESS != rval ) return rval; 05641 05642 // should be same number of entities 05643 if( scd_skin_ents.size() != skin_ents.size() ) return MB_FAILURE; 05644 05645 skin_ents.clear(); 05646 scd_skin_ents.clear(); 05647 05648 // now test getting faces and vertices, also with existing faces now 05649 rval = tool.find_skin( 0, ents, true, scd_skin_ents, NULL, true, true, true ); 05650 if( MB_SUCCESS != rval ) return rval; 05651 05652 rval = tool.find_skin( 0, ents, true, skin_ents, NULL, true, true, false ); 05653 if( MB_SUCCESS != rval ) return rval; 05654 05655 // again, should have same numbers 05656 if( skin_ents.subset_by_type( MBVERTEX ).size() != scd_skin_ents.subset_by_type( MBVERTEX ).size() ) 05657 return MB_FAILURE; 05658 05659 return MB_SUCCESS; 05660 } 05661 05662 ErrorCode mb_skin_fileset_test() 05663 { 05664 Core moab; 05665 Interface* mb = &moab; 05666 ErrorCode error; 05667 const double coords[] = { 0, 0, 0, 1, 0, 0, 2, 0, 0, 2, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 2, 0, 1, 05668 2, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 2, 1, 0, 2, 2, 0, 2, 2, 1, 2, 1, 1, 2, 0, 1, 2 }; 05669 const size_t num_vtx = sizeof( coords ) / sizeof( double ) / 3; 05670 05671 const int conn[] = { 0, 1, 4, 5, 6, 7, 10, 11, 1, 2, 3, 4, 7, 8, 9, 10, 05672 6, 7, 10, 11, 12, 13, 16, 17, 7, 8, 9, 10, 13, 14, 15, 16 }; 05673 const size_t num_elems = sizeof( conn ) / sizeof( int ) / 8; 05674 05675 EntityHandle verts[num_vtx], cells[num_elems]; 05676 for( size_t i = 0; i < num_vtx; ++i ) 05677 { 05678 error = mb->create_vertex( coords + 3 * i, verts[i] );MB_CHK_ERR( error ); 05679 } 05680 05681 for( size_t i = 0; i < num_elems; ++i ) 05682 { 05683 EntityHandle c[8]; 05684 for( int j = 0; j < 8; j++ ) 05685 c[j] = verts[conn[8 * i + j]]; 05686 05687 error = mb->create_element( MBHEX, c, 8, cells[i] );MB_CHK_ERR( error ); 05688 } 05689 05690 EntityHandle fileset; 05691 error = mb->create_meshset( MESHSET_SET, fileset );MB_CHK_ERR( error ); 05692 error = mb->add_entities( fileset, &verts[0], num_vtx );MB_CHK_ERR( error ); 05693 error = mb->add_entities( fileset, &cells[0], num_elems );MB_CHK_ERR( error ); 05694 05695 Range fverts, fedges, ffaces, fcells; 05696 error = mb->get_entities_by_dimension( fileset, 0, fverts );MB_CHK_ERR( error ); 05697 error = mb->get_entities_by_dimension( fileset, 1, fedges );MB_CHK_ERR( error ); 05698 error = mb->get_entities_by_dimension( fileset, 2, ffaces );MB_CHK_ERR( error ); 05699 error = mb->get_entities_by_dimension( fileset, 3, fcells );MB_CHK_ERR( error ); 05700 05701 assert( fverts.size() == 18 && fedges.size() == 0 && ffaces.size() == 0 && fcells.size() == 4 ); 05702 05703 Skinner sk( mb ); 05704 Range skin_ents; 05705 error = sk.find_skin( fileset, fcells, 2, skin_ents, false, true );MB_CHK_ERR( error ); 05706 error = mb->get_entities_by_dimension( fileset, 2, ffaces );MB_CHK_ERR( error ); 05707 assert( ffaces.size() == 16 ); 05708 error = sk.find_skin( fileset, fcells, 1, skin_ents, false, true );MB_CHK_ERR( error ); 05709 error = mb->get_entities_by_dimension( fileset, 1, fedges );MB_CHK_ERR( error ); 05710 assert( fedges.size() == 32 ); 05711 05712 const double fcoords[] = { 0, 0, 3, 1, 0, 3, 2, 0, 3, 2, 1, 3, 1, 1, 3, 0, 1, 3 }; 05713 const size_t num_fvtx = sizeof( fcoords ) / sizeof( double ) / 3; 05714 05715 const int fconn[] = { 0, 1, 4, 5, 1, 2, 3, 4 }; 05716 const size_t num_faces = sizeof( fconn ) / sizeof( int ) / 4; 05717 EntityHandle nwverts[num_fvtx], faces[num_faces]; 05718 for( size_t i = 0; i < num_fvtx; ++i ) 05719 { 05720 error = mb->create_vertex( fcoords + 3 * i, nwverts[i] );MB_CHK_ERR( error ); 05721 } 05722 05723 for( size_t i = 0; i < num_faces; ++i ) 05724 { 05725 EntityHandle c[4]; 05726 for( int j = 0; j < 4; j++ ) 05727 c[j] = nwverts[fconn[4 * i + j]]; 05728 05729 error = mb->create_element( MBQUAD, c, 4, faces[i] );MB_CHK_ERR( error ); 05730 } 05731 EntityHandle fileset1; 05732 error = mb->create_meshset( MESHSET_SET, fileset1 );MB_CHK_ERR( error ); 05733 error = mb->add_entities( fileset1, &nwverts[0], num_fvtx );MB_CHK_ERR( error ); 05734 error = mb->add_entities( fileset1, &faces[0], num_faces );MB_CHK_ERR( error ); 05735 05736 Range verts1, edges1, faces1; 05737 error = mb->get_entities_by_dimension( fileset1, 0, verts1 );MB_CHK_ERR( error ); 05738 error = mb->get_entities_by_dimension( fileset1, 1, edges1 );MB_CHK_ERR( error ); 05739 error = mb->get_entities_by_dimension( fileset1, 2, faces1 );MB_CHK_ERR( error ); 05740 05741 assert( verts1.size() == 6 && edges1.size() == 0 && faces1.size() == 2 ); 05742 05743 // error = sk.find_skin(fileset1, faces1, 1, skin_ents, false, true);MB_CHK_ERR(error); 05744 error = sk.find_skin( fileset1, faces1, false, skin_ents, NULL, true, true, false );MB_CHK_ERR( error ); 05745 error = mb->get_entities_by_dimension( fileset1, 1, edges1 );MB_CHK_ERR( error ); 05746 assert( edges1.size() == 6 ); 05747 05748 return MB_SUCCESS; 05749 } 05750 05751 // It is a common problem for readers to incorrectly 05752 // handle invalid/unknown file types and non-existant 05753 // files. For either case, MOAB will try all readers 05754 // (assuming it doesn't recongnize the file extension), 05755 // so we can test all the readers w/out knowing which 05756 // readers we have. 05757 const char* argv0 = 0; 05758 ErrorCode mb_read_fail_test() 05759 { 05760 Core moab; 05761 Interface* mb = &moab; 05762 05763 const char BAD_FILE_NAME[] = "non-existant-file.txt"; 05764 ErrorCode rval; 05765 05766 FILE* fptr = fopen( BAD_FILE_NAME, "r" ); 05767 if( fptr ) 05768 { 05769 fclose( fptr ); 05770 std::cout << "Test cannot proceed while file exists: " << BAD_FILE_NAME << std::endl; 05771 return MB_FAILURE; 05772 } 05773 05774 // try reading a non-existant file 05775 05776 rval = mb->load_file( BAD_FILE_NAME ); 05777 if( MB_FILE_DOES_NOT_EXIST != rval ) return MB_FAILURE; 05778 05779 // try reading an invalid file 05780 if( !argv0 ) // not set by main, oops! 05781 return MB_FAILURE; 05782 rval = mb->load_file( argv0 ); 05783 if( MB_SUCCESS == rval ) return MB_FAILURE; 05784 05785 return MB_SUCCESS; 05786 } 05787 05788 #define TEST_ERROR_CODE( E ) \ 05789 if( mb->get_error_string( E ) != #E ) \ 05790 { \ 05791 std::cerr << "Invalid error string from get_error_string for " << #E << ": " << mb->get_error_string( E ) \ 05792 << std::endl; \ 05793 return MB_FAILURE; \ 05794 } 05795 05796 ErrorCode mb_enum_string_test() 05797 { 05798 Core moab; 05799 Interface* mb = &moab; 05800 05801 TEST_ERROR_CODE( MB_SUCCESS ); 05802 TEST_ERROR_CODE( MB_INDEX_OUT_OF_RANGE ); 05803 TEST_ERROR_CODE( MB_TYPE_OUT_OF_RANGE ); 05804 TEST_ERROR_CODE( MB_MEMORY_ALLOCATION_FAILED ); 05805 TEST_ERROR_CODE( MB_ENTITY_NOT_FOUND ); 05806 TEST_ERROR_CODE( MB_MULTIPLE_ENTITIES_FOUND ); 05807 TEST_ERROR_CODE( MB_TAG_NOT_FOUND ); 05808 TEST_ERROR_CODE( MB_FILE_DOES_NOT_EXIST ); 05809 TEST_ERROR_CODE( MB_FILE_WRITE_ERROR ); 05810 TEST_ERROR_CODE( MB_NOT_IMPLEMENTED ); 05811 TEST_ERROR_CODE( MB_ALREADY_ALLOCATED ); 05812 TEST_ERROR_CODE( MB_VARIABLE_DATA_LENGTH ); 05813 TEST_ERROR_CODE( MB_INVALID_SIZE ); 05814 TEST_ERROR_CODE( MB_UNSUPPORTED_OPERATION ); 05815 TEST_ERROR_CODE( MB_UNHANDLED_OPTION ); 05816 TEST_ERROR_CODE( MB_STRUCTURED_MESH ); 05817 TEST_ERROR_CODE( MB_FAILURE ); 05818 05819 return MB_SUCCESS; 05820 } 05821 05822 // Test basic skinning using vert-to-elem adjacencies 05823 ErrorCode mb_skin_verts_common( unsigned dim, bool skin_elems ); 05824 05825 ErrorCode mb_skin_surf_verts_test() 05826 { 05827 return mb_skin_verts_common( 2, false ); 05828 } 05829 05830 ErrorCode mb_skin_vol_verts_test() 05831 { 05832 return mb_skin_verts_common( 3, false ); 05833 } 05834 05835 ErrorCode mb_skin_surf_verts_elems_test() 05836 { 05837 return mb_skin_verts_common( 2, true ); 05838 } 05839 05840 ErrorCode mb_skin_vol_verts_elems_test() 05841 { 05842 return mb_skin_verts_common( 3, true ); 05843 } 05844 05845 ErrorCode mb_skin_verts_common( unsigned dim, bool skin_elems ) 05846 { 05847 const int INT = 10; // intervals+1 05848 const char* tmp_file = "structured.vtk"; 05849 std::ofstream str( tmp_file ); 05850 if( !str ) 05851 { 05852 std::cerr << tmp_file << ": filed to create temp file" << std::endl; 05853 return MB_FAILURE; 05854 } 05855 str << "#vtk DataFile Version 2.0" << std::endl 05856 << "mb_skin_verts_common temp file" << std::endl 05857 << "ASCII" << std::endl 05858 << "DATASET STRUCTURED_POINTS" << std::endl 05859 << "DIMENSIONS " << INT << " " << ( dim > 1 ? INT : 1 ) << " " << ( dim > 2 ? INT : 1 ) << std::endl 05860 << "ORIGIN 0 0 0" << std::endl 05861 << "SPACING 1 1 1" << std::endl; 05862 str.close(); 05863 05864 Core moab; 05865 Interface& mb = moab; 05866 ErrorCode rval; 05867 05868 rval = mb.load_file( tmp_file ); 05869 remove( tmp_file ); 05870 if( MB_SUCCESS != rval ) return rval; 05871 05872 Range ents; 05873 rval = mb.get_entities_by_dimension( 0, dim, ents ); 05874 if( MB_SUCCESS != rval ) return rval; 05875 if( ents.empty() ) return MB_FAILURE; 05876 05877 Skinner tool( &mb ); 05878 05879 // mesh is a structured quad/hex mesh, so we can 05880 // determine skin vertices from the number of 05881 // adjacent elements. 05882 unsigned interior_adj = 1; 05883 for( unsigned i = 0; i < dim; ++i ) 05884 interior_adj *= 2; 05885 Range expected, verts; 05886 rval = mb.get_entities_by_dimension( 0, 0, verts ); 05887 if( MB_SUCCESS != rval ) return rval; 05888 Range::iterator h = expected.begin(); 05889 std::vector< EntityHandle > adj; 05890 for( Range::iterator v = verts.begin(); v != verts.end(); ++v ) 05891 { 05892 adj.clear(); 05893 rval = mb.get_adjacencies( &*v, 1, dim, false, adj ); 05894 if( MB_SUCCESS != rval ) return rval; 05895 if( adj.size() < interior_adj ) h = expected.insert( h, *v ); 05896 } 05897 05898 // Get skin vertices using skinner 05899 Range actual; 05900 rval = tool.find_skin( 0, ents, !skin_elems, actual ); 05901 if( MB_SUCCESS != rval ) return rval; 05902 05903 Range extra, missing; 05904 if( !skin_elems ) 05905 { 05906 // Check that we got expected result 05907 extra = subtract( actual, expected ); 05908 missing = subtract( expected, actual ); 05909 if( !extra.empty() || !missing.empty() ) 05910 { 05911 std::cout << "Extra vertices returned: " << extra << std::endl 05912 << "Missing vertices: " << missing << std::endl; 05913 return MB_FAILURE; 05914 } 05915 return MB_SUCCESS; 05916 } 05917 05918 // test that no extra elements we're created 05919 extra.clear(); 05920 rval = mb.get_entities_by_dimension( 0, dim - 1, extra ); 05921 if( MB_SUCCESS != rval ) return rval; 05922 extra = subtract( extra, actual ); 05923 if( !extra.empty() ) 05924 { 05925 std::cout << "Extra/non-returned elements created: " << extra << std::endl; 05926 return MB_FAILURE; 05927 } 05928 05929 // check that each skin vertex has the correct number of adjacent quads 05930 missing.clear(); 05931 extra.clear(); 05932 for( Range::iterator i = expected.begin(); i != expected.end(); ++i ) 05933 { 05934 std::vector< EntityHandle > elem, side; 05935 rval = mb.get_adjacencies( &*i, 1, dim, false, elem ); 05936 if( MB_SUCCESS != rval ) return rval; 05937 rval = mb.get_adjacencies( &*i, 1, dim - 1, false, side ); 05938 if( MB_SUCCESS != rval ) return rval; 05939 if( elem.size() == 1 ) 05940 { 05941 if( side.size() < dim ) 05942 missing.insert( *i ); 05943 else if( side.size() > dim ) 05944 extra.insert( *i ); 05945 } 05946 else if( elem.size() == interior_adj ) 05947 { 05948 if( !side.empty() ) extra.insert( *i ); 05949 } 05950 else 05951 { 05952 if( side.size() < interior_adj / 2 ) 05953 missing.insert( *i ); 05954 else if( side.size() > interior_adj / 2 ) 05955 extra.insert( *i ); 05956 } 05957 } 05958 if( !missing.empty() || !extra.empty() ) 05959 { 05960 std::cout << "Skin elements missing at vertices: " << missing << std::endl 05961 << "Extra skin elements at vertices: " << extra << std::endl; 05962 return MB_FAILURE; 05963 } 05964 05965 // check that all returned elements are actually on the skin 05966 extra.clear(); 05967 for( Range::iterator i = actual.begin(); i != actual.end(); ++i ) 05968 { 05969 Range verts2; 05970 rval = mb.get_adjacencies( &*i, 1, 0, false, verts2 ); 05971 if( MB_SUCCESS != rval ) return rval; 05972 verts2 = subtract( verts2, expected ); 05973 if( !verts2.empty() ) extra.insert( *i ); 05974 } 05975 if( !extra.empty() ) 05976 { 05977 std::cout << "Skinner returned elements not on skin: " << extra << std::endl; 05978 return MB_FAILURE; 05979 } 05980 05981 return MB_SUCCESS; 05982 } 05983 05984 // Test that skinning of polyhedra works 05985 ErrorCode mb_skin_poly_test() 05986 { 05987 /* Create a mesh composed of 8 hexagonal prisms and 05988 two hexahedra by extruding the following cross section 05989 two steps in the Z direction. 05990 05991 0-----1 05992 / (0) \ 05993 (11)/ \(1) 05994 / \ 05995 11 2 05996 / \ Y / \ 05997 (10)/ \(12)^(13)/ \(2) 05998 / \ | / \ 05999 10 12-----13 3 06000 | | | | | 06001 (9)| | +--|-->X |(3) 06002 | | | | 06003 9 15-----14 4 06004 \ / \ / 06005 (8)\ /(15) (14)\ /(4) 06006 \ / \ / 06007 8 5 06008 \ / 06009 (7)\ /(5) 06010 \ (6) / 06011 7-----6 06012 */ 06013 06014 const double coords2D[][2] = { 06015 { -1, 5 }, // 0 06016 { 1, 5 }, { 3, 3 }, { 5, 1 }, { 5, -1 }, { 3, -3 }, // 5 06017 { 1, -5 }, { -1, -5 }, { -3, -3 }, { -5, -1 }, { -5, 1 }, // 10 06018 { -3, 3 }, { -1, 1 }, { 1, 1 }, { 1, -1 }, { -1, -1 } // 15 06019 }; 06020 const int polyconn[4][6] = { 06021 { 0, 1, 2, 13, 12, 11 }, { 2, 3, 4, 5, 14, 13 }, { 5, 6, 7, 8, 15, 14 }, { 8, 9, 10, 11, 12, 15 } 06022 }; 06023 const int polyside[4][6] = { 06024 { 0, 1, 13, 16, 12, 11 }, { 2, 3, 4, 14, 17, 13 }, { 5, 6, 7, 15, 18, 14 }, { 8, 9, 10, 12, 19, 15 } 06025 }; 06026 06027 ErrorCode rval; 06028 Core moab; 06029 Interface& mb = moab; 06030 Range regions, faces, interior_faces; 06031 06032 // create 48 vertices 06033 EntityHandle verts[3][16]; 06034 for( int i = 0; i < 3; ++i ) 06035 { 06036 for( int j = 0; j < 16; ++j ) 06037 { 06038 double coords[3] = { coords2D[j][0], coords2D[j][1], static_cast< double >( 2 * i ) }; 06039 rval = mb.create_vertex( coords, verts[i][j] ); 06040 if( MB_SUCCESS != rval ) return rval; 06041 } 06042 } 06043 06044 // create two hexahedra 06045 EntityHandle hexes[2]; 06046 for( int i = 0; i < 2; ++i ) 06047 { 06048 EntityHandle conn[8] = { verts[i][15], verts[i][14], verts[i][13], verts[i][12], 06049 verts[i + 1][15], verts[i + 1][14], verts[i + 1][13], verts[i + 1][12] }; 06050 rval = mb.create_element( MBHEX, conn, 8, hexes[i] ); 06051 if( MB_SUCCESS != rval ) return rval; 06052 regions.insert( hexes[i] ); 06053 } 06054 06055 // create hexagonal faces 06056 EntityHandle hexagons[3][4]; 06057 for( int i = 0; i < 3; ++i ) 06058 { 06059 for( int j = 0; j < 4; ++j ) 06060 { 06061 EntityHandle conn[6]; 06062 for( int k = 0; k < 6; ++k ) 06063 conn[k] = verts[i][polyconn[j][k]]; 06064 rval = mb.create_element( MBPOLYGON, conn, 6, hexagons[i][j] ); 06065 if( MB_SUCCESS != rval ) return rval; 06066 faces.insert( hexagons[i][j] ); 06067 if( i == 1 ) interior_faces.insert( hexagons[i][j] ); 06068 } 06069 } 06070 06071 // create quadrilateral faces 06072 EntityHandle quads[2][20]; 06073 for( int i = 0; i < 2; ++i ) 06074 { 06075 for( int j = 0; j < 20; ++j ) 06076 { 06077 int c1, c2; 06078 if( j < 12 ) 06079 { 06080 c1 = j; 06081 c2 = ( j + 1 ) % 12; 06082 } 06083 else if( j < 16 ) 06084 { 06085 c1 = j; 06086 c2 = 2 + 3 * ( ( j - 9 ) % 4 ); 06087 } 06088 else 06089 { 06090 c1 = j - 4; 06091 c2 = 12 + ( j - 15 ) % 4; 06092 } 06093 EntityHandle conn[4] = { verts[i][c1], verts[i][c2], verts[i + 1][c2], verts[i + 1][c1] }; 06094 rval = mb.create_element( MBQUAD, conn, 4, quads[i][j] ); 06095 if( MB_SUCCESS != rval ) return rval; 06096 faces.insert( quads[i][j] ); 06097 if( j > 11 ) interior_faces.insert( quads[i][j] ); 06098 } 06099 } 06100 06101 // create polyhedra 06102 EntityHandle poly[2][4]; 06103 for( int i = 0; i < 2; ++i ) 06104 { 06105 for( int j = 0; j < 4; ++j ) 06106 { 06107 EntityHandle conn[8]; 06108 for( int k = 0; k < 6; ++k ) 06109 conn[k] = quads[i][polyside[j][k]]; 06110 conn[6] = hexagons[i][j]; 06111 conn[7] = hexagons[i + 1][j]; 06112 rval = mb.create_element( MBPOLYHEDRON, conn, 8, poly[i][j] ); 06113 if( MB_SUCCESS != rval ) return rval; 06114 regions.insert( poly[i][j] ); 06115 } 06116 } 06117 06118 Range interior_verts; 06119 interior_verts.insert( verts[1][12] ); 06120 interior_verts.insert( verts[1][13] ); 06121 interior_verts.insert( verts[1][14] ); 06122 interior_verts.insert( verts[1][15] ); 06123 06124 Skinner tool( &mb ); 06125 Range skin; 06126 rval = tool.find_skin( 0, regions, true, skin, 0, true, false ); 06127 if( MB_SUCCESS != rval ) 06128 { 06129 std::cout << "Vertex skinning failed with: " << mb.get_error_string( rval ) << std::endl; 06130 return rval; 06131 } 06132 06133 Range all_verts, all_faces; 06134 rval = mb.get_entities_by_dimension( 0, 0, all_verts ); 06135 if( MB_SUCCESS != rval ) return rval; 06136 rval = mb.get_entities_by_dimension( 0, 2, all_faces ); 06137 if( MB_SUCCESS != rval ) return rval; 06138 06139 Range expected = subtract( all_verts, interior_verts ); 06140 if( expected != skin ) 06141 { 06142 std::cout << "Skinner returned incorrect vertices." << std::endl; 06143 return MB_FAILURE; 06144 } 06145 if( all_faces != faces ) 06146 { 06147 std::cout << "Skinner created/deleted faces for vertex-only skinning" << std::endl; 06148 return MB_FAILURE; 06149 } 06150 06151 skin.clear(); 06152 rval = tool.find_skin( 0, regions, false, skin, 0, true, false ); 06153 if( MB_SUCCESS != rval ) 06154 { 06155 std::cout << "Non-create face skinning failed with: " << mb.get_error_string( rval ) << std::endl; 06156 return rval; 06157 } 06158 expected = subtract( all_faces, interior_faces ); 06159 if( expected != skin ) 06160 { 06161 std::cout << "Skinner returned incorrect faces." << std::endl; 06162 return MB_FAILURE; 06163 } 06164 if( all_faces != faces ) 06165 { 06166 std::cout << "Skinner created/deleted faces for no-create skinning" << std::endl; 06167 return MB_FAILURE; 06168 } 06169 06170 skin.clear(); 06171 rval = tool.find_skin( 0, regions, false, skin, 0, true, true ); 06172 if( MB_SUCCESS != rval ) 06173 { 06174 std::cout << "Create face skinning failed with: " << mb.get_error_string( rval ) << std::endl; 06175 return rval; 06176 } 06177 Range all_faces2; 06178 rval = mb.get_entities_by_dimension( 0, 2, all_faces2 ); 06179 if( MB_SUCCESS != rval ) return rval; 06180 Range difference = subtract( all_faces2, all_faces ); 06181 if( difference.size() != 2 ) 06182 { // should have created two quads for hex top/bottom 06183 std::cout << "Skinner failed to create new quads or created to many." << std::endl; 06184 return MB_FAILURE; 06185 } 06186 expected.merge( difference ); 06187 if( expected != skin ) 06188 { 06189 std::cout << "Skinner returned incorrect faces." << std::endl; 06190 return MB_FAILURE; 06191 } 06192 // check that new faces are correct 06193 EntityHandle expected_conn[2][4] = { { verts[0][12], verts[0][13], verts[0][14], verts[0][15] }, 06194 { verts[2][12], verts[2][13], verts[2][14], verts[2][15] } }; 06195 EntityHandle nq[2] = { difference.front(), difference.back() }; 06196 for( int i = 0; i < 2; ++i ) 06197 { 06198 const EntityHandle* conn; 06199 int len; 06200 bool found = false; 06201 for( int j = 0; !found && j < 2; ++j ) 06202 { 06203 rval = mb.get_connectivity( nq[j], conn, len ); 06204 if( MB_SUCCESS != rval ) return rval; 06205 int idx1 = std::find( conn, conn + len, expected_conn[i][0] ) - conn; 06206 if( idx1 == len ) continue; 06207 found = true; 06208 for( int k = 1; k < 4; ++k ) 06209 if( conn[( idx1 + k ) % 4] != expected_conn[i][k] ) found = false; 06210 if( !found ) 06211 { 06212 found = true; 06213 for( int k = 1; k < 4; ++k ) 06214 if( conn[( idx1 + 4 - k ) % 4] != expected_conn[i][k] ) found = false; 06215 } 06216 } 06217 if( !found ) 06218 { 06219 std::cerr << "Skinner did not create & return expected quad " << i << std::endl; 06220 return MB_FAILURE; 06221 } 06222 } 06223 06224 return MB_SUCCESS; 06225 } 06226 06227 // Test that skinning of higher-order elements works 06228 ErrorCode mb_skin_higher_order_faces_common( bool use_adj ) 06229 { 06230 /* Create mesh: 06231 06232 0---1---2---3---4 06233 | | / 06234 | | / 06235 5 6 7 8 9 06236 | | / 06237 | | / 06238 10--11--12 06239 */ 06240 06241 ErrorCode rval; 06242 Core moab; 06243 Interface& mb = moab; 06244 06245 double coords[13][3] = { { 0, 4, 0 }, { 2, 4, 0 }, { 4, 4, 0 }, { 6, 4, 0 }, { 8, 4, 0 }, { 0, 2, 0 }, { 2, 2, 0 }, 06246 { 4, 2, 0 }, { 5, 2, 0 }, { 6, 2, 0 }, { 0, 0, 0 }, { 2, 0, 0 }, { 4, 0, 0 } }; 06247 EntityHandle verts[13]; 06248 for( int i = 0; i < 13; ++i ) 06249 { 06250 rval = mb.create_vertex( coords[i], verts[i] ); 06251 if( MB_SUCCESS != rval ) return rval; 06252 } 06253 06254 EntityHandle qconn[9] = { verts[0], verts[2], verts[12], verts[10], verts[1], 06255 verts[7], verts[11], verts[5], verts[6] }; 06256 EntityHandle tconn[7] = { verts[2], verts[4], verts[12], verts[3], verts[9], verts[7], verts[8] }; 06257 EntityHandle quad, tri; 06258 rval = mb.create_element( MBQUAD, qconn, 9, quad ); 06259 if( MB_SUCCESS != rval ) return rval; 06260 rval = mb.create_element( MBTRI, tconn, 7, tri ); 06261 if( MB_SUCCESS != rval ) return rval; 06262 06263 Range faces; 06264 faces.insert( quad ); 06265 faces.insert( tri ); 06266 06267 Range skin_verts; 06268 const int skin_vert_idx[] = { 0, 1, 2, 3, 4, 5, 9, 10, 11, 12 }; 06269 for( size_t i = 0; i < sizeof( skin_vert_idx ) / sizeof( skin_vert_idx[0] ); ++i ) 06270 skin_verts.insert( verts[skin_vert_idx[i]] ); 06271 06272 Skinner tool( &mb ); 06273 Range skin; 06274 06275 rval = tool.find_skin( 0, faces, true, skin, 0, use_adj, false ); 06276 if( MB_SUCCESS != rval ) 06277 { 06278 std::cout << "Vertex skinning failed with: " << mb.get_error_string( rval ) << std::endl; 06279 return rval; 06280 } 06281 if( skin != skin_verts ) 06282 { 06283 std::cout << "Skinner returned incorrect vertices." << std::endl; 06284 return MB_FAILURE; 06285 } 06286 06287 const int skin_edges[5][3] = { { 0, 1, 2 }, { 2, 3, 4 }, { 4, 9, 12 }, { 12, 11, 10 }, { 10, 5, 0 } }; 06288 skin.clear(); 06289 rval = tool.find_skin( 0, faces, false, skin, 0, use_adj, true ); 06290 if( MB_SUCCESS != rval ) 06291 { 06292 std::cout << "Edge skinning failed with: " << mb.get_error_string( rval ) << std::endl; 06293 return rval; 06294 } 06295 if( skin.size() != 5u ) 06296 { 06297 std::cout << "Skinner returned " << skin.size() << " vertices. Expected 5" << std::endl; 06298 return MB_FAILURE; 06299 } 06300 int num_quadratic = 0; 06301 const EntityHandle* conn; 06302 int len; 06303 for( Range::iterator i = skin.begin(); i != skin.end(); ++i ) 06304 { 06305 rval = mb.get_connectivity( *i, conn, len, false ); 06306 if( MB_SUCCESS != rval ) return rval; 06307 if( len == 3 ) 06308 num_quadratic++; 06309 else if( len != 2 ) 06310 { 06311 std::cerr << "Skinner created edge with " << len << " vertices" << std::endl; 06312 return MB_FAILURE; 06313 } 06314 } 06315 if( num_quadratic != 5 ) 06316 { 06317 std::cerr << num_quadratic << " of 5 created edges were quadratic" << std::endl; 06318 return MB_FAILURE; 06319 } 06320 06321 for( int i = 0; i < 5; ++i ) 06322 { 06323 bool found = false; 06324 for( Range::iterator j = skin.begin(); j != skin.end(); ++j ) 06325 { 06326 mb.get_connectivity( *j, conn, len, false ); 06327 if( conn[2] == verts[skin_edges[i][1]] ) 06328 { 06329 found = true; 06330 break; 06331 } 06332 } 06333 if( !found ) 06334 { 06335 std::cerr << "One or more skin edges is incorrect" << std::endl; 06336 return MB_FAILURE; 06337 } 06338 if( ( conn[0] != verts[skin_edges[i][0]] || conn[1] != verts[skin_edges[i][2]] ) && 06339 ( conn[0] != verts[skin_edges[i][2]] || conn[1] != verts[skin_edges[i][0]] ) ) 06340 { 06341 std::cerr << "Invalid skin edge connectivity" << std::endl; 06342 return MB_FAILURE; 06343 } 06344 } 06345 06346 return MB_SUCCESS; 06347 } 06348 ErrorCode mb_skin_higher_order_faces_test() 06349 { 06350 return mb_skin_higher_order_faces_common( false ); 06351 } 06352 ErrorCode mb_skin_adj_higher_order_faces_test() 06353 { 06354 return mb_skin_higher_order_faces_common( true ); 06355 } 06356 06357 // Test that skinning of higher-order elements works 06358 ErrorCode mb_skin_higher_order_regions_common( bool use_adj ) 06359 { 06360 // create mesh containing two 27-node hexes 06361 /* 06362 0,2---1,2---2,2---3,2---4,2 06363 | | | 06364 | | | 06365 0,1 1,1 2,1 3,1 4,1 06366 | | | 06367 | | | 06368 0,0---1,0---2,0---3,0---4,0 06369 */ 06370 06371 ErrorCode rval; 06372 Core moab; 06373 Interface& mb = moab; 06374 Range hexes; 06375 06376 EntityHandle verts[5][3][3]; 06377 for( int i = 0; i < 5; ++i ) 06378 for( int j = 0; j < 3; ++j ) 06379 for( int k = 0; k < 3; ++k ) 06380 { 06381 double coords[] = { static_cast< double >( i ), static_cast< double >( j ), 06382 static_cast< double >( k ) }; 06383 rval = mb.create_vertex( coords, verts[i][j][k] ); 06384 if( MB_SUCCESS != rval ) return rval; 06385 } 06386 06387 int hex_conn[][3] = { // corners 06388 { 0, 0, 0 }, 06389 { 2, 0, 0 }, 06390 { 2, 2, 0 }, 06391 { 0, 2, 0 }, 06392 { 0, 0, 2 }, 06393 { 2, 0, 2 }, 06394 { 2, 2, 2 }, 06395 { 0, 2, 2 }, 06396 // mid-edge 06397 { 1, 0, 0 }, 06398 { 2, 1, 0 }, 06399 { 1, 2, 0 }, 06400 { 0, 1, 0 }, 06401 { 0, 0, 1 }, 06402 { 2, 0, 1 }, 06403 { 2, 2, 1 }, 06404 { 0, 2, 1 }, 06405 { 1, 0, 2 }, 06406 { 2, 1, 2 }, 06407 { 1, 2, 2 }, 06408 { 0, 1, 2 }, 06409 // mid-face 06410 { 1, 0, 1 }, 06411 { 2, 1, 1 }, 06412 { 1, 2, 1 }, 06413 { 0, 1, 1 }, 06414 { 1, 1, 0 }, 06415 { 1, 1, 2 }, 06416 // mid-volume 06417 { 1, 1, 1 } 06418 }; 06419 06420 EntityHandle hexverts[2][27]; 06421 for( int i = 0; i < 2; ++i ) 06422 { 06423 EntityHandle h; 06424 for( int j = 0; j < 27; ++j ) 06425 hexverts[i][j] = verts[2 * i + hex_conn[j][0]][hex_conn[j][1]][hex_conn[j][2]]; 06426 rval = mb.create_element( MBHEX, hexverts[i], 27, h ); 06427 if( MB_SUCCESS != rval ) return rval; 06428 hexes.insert( h ); 06429 } 06430 06431 Range interior_verts; 06432 interior_verts.insert( verts[1][1][1] ); // mid-node of hex 1 06433 interior_verts.insert( verts[3][1][1] ); // mid-node of hex 2 06434 interior_verts.insert( verts[2][1][1] ); // mid-node of shared face 06435 06436 Skinner tool( &mb ); 06437 Range skin; 06438 06439 rval = tool.find_skin( 0, hexes, true, skin, 0, use_adj, false ); 06440 if( MB_SUCCESS != rval ) 06441 { 06442 std::cout << "Vertex skinning failed with: " << mb.get_error_string( rval ) << std::endl; 06443 return rval; 06444 } 06445 Range extra = intersect( skin, interior_verts ); 06446 if( !extra.empty() ) 06447 { 06448 std::cout << "Skinner returned " << extra.size() << " interior vertices" << std::endl; 06449 std::cout << extra << std::endl; 06450 return MB_FAILURE; 06451 } 06452 int num_vtx; 06453 mb.get_number_entities_by_dimension( 0, 0, num_vtx ); 06454 size_t num_skin = num_vtx - interior_verts.size(); 06455 if( skin.size() != num_skin ) 06456 { 06457 std::cout << "Skinner returned " << skin.size() << " of " << num_skin << " skin vertices" << std::endl; 06458 return MB_FAILURE; 06459 } 06460 06461 skin.clear(); 06462 rval = tool.find_skin( 0, hexes, false, skin, 0, use_adj, true ); 06463 if( MB_SUCCESS != rval ) 06464 { 06465 std::cout << "Element skinning failed with: " << mb.get_error_string( rval ) << std::endl; 06466 return rval; 06467 } 06468 06469 if( skin.size() > 10u ) 06470 { 06471 std::cout << "Skinner created too many faces" << std::endl; 06472 return MB_FAILURE; 06473 } 06474 06475 bool all_okay = true; 06476 bool faces[2][6] = { { 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0 } }; 06477 const EntityHandle* conn; 06478 int len; 06479 for( Range::iterator it = skin.begin(); it != skin.end(); ++it ) 06480 { 06481 rval = mb.get_connectivity( *it, conn, len ); 06482 if( MB_SUCCESS != rval ) return rval; 06483 if( len != 9 ) 06484 { 06485 std::cout << "Skinner created face with " << len << " nodes" << std::endl; 06486 all_okay = false; 06487 continue; 06488 } 06489 06490 int valid, side, sense, offset; 06491 for( int h = 0; h < 2; ++h ) 06492 { 06493 valid = CN::SideNumber( MBHEX, hexverts[h], conn, 4, 2, side, sense, offset ); 06494 if( valid != 0 ) continue; 06495 if( sense != 1 ) 06496 { 06497 std::cout << "Skinner created reversed face for hex " << h << " side " << side << std::endl; 06498 all_okay = false; 06499 continue; 06500 } 06501 06502 int idx[9], len2; 06503 EntityType sidetype; 06504 CN::SubEntityNodeIndices( MBHEX, 27, 2, side, sidetype, len2, idx ); 06505 assert( sidetype == MBQUAD ); 06506 assert( len2 == 9 ); 06507 if( conn[offset] != hexverts[h][idx[0]] || conn[( offset + 1 ) % 4] != hexverts[h][idx[1]] || 06508 conn[( offset + 2 ) % 4] != hexverts[h][idx[2]] || conn[( offset + 3 ) % 4] != hexverts[h][idx[3]] || 06509 conn[4 + offset] != hexverts[h][idx[4]] || conn[4 + ( offset + 1 ) % 4] != hexverts[h][idx[5]] || 06510 conn[4 + ( offset + 2 ) % 4] != hexverts[h][idx[6]] || 06511 conn[4 + ( offset + 3 ) % 4] != hexverts[h][idx[7]] || conn[8] != hexverts[h][idx[8]] ) 06512 { 06513 std::cout << "Side " << side << " of hex " << h << " has invalid connectivity" << std::endl; 06514 all_okay = false; 06515 } 06516 06517 faces[h][side] = true; 06518 } 06519 } 06520 06521 for( int h = 0; h < 2; ++h ) 06522 { 06523 for( int i = 0; i < 6; ++i ) 06524 { 06525 if( ( h == 0 && i == 1 ) || ( h == 1 && i == 3 ) ) 06526 { 06527 if( faces[h][i] ) 06528 { 06529 std::cout << "Skinner created interior face for side " << i << " of hex " << h << std::endl; 06530 all_okay = false; 06531 } 06532 } 06533 else if( !faces[h][i] ) 06534 { 06535 std::cout << "Skinner failed to create side " << i << " of hex " << h << std::endl; 06536 all_okay = false; 06537 } 06538 } 06539 } 06540 06541 return all_okay ? MB_SUCCESS : MB_FAILURE; 06542 } 06543 06544 // Test that skinning of higher-order elements works 06545 ErrorCode mb_skin_higher_order_pyramids() 06546 { 06547 // create mesh containing 13-node pyramid 06548 /* 06549 06550 */ 06551 06552 ErrorCode rval; 06553 Core moab; 06554 Interface& mb = moab; 06555 Range pyramids; 06556 06557 // easier to create a 27 node grid, and then pick a 13-node pyramid 06558 EntityHandle verts[3][3][3]; 06559 for( int i = 0; i < 3; ++i ) 06560 for( int j = 0; j < 3; ++j ) 06561 for( int k = 0; k < 3; ++k ) 06562 { 06563 double coords[] = { static_cast< double >( i ), static_cast< double >( j ), 06564 static_cast< double >( k ) }; 06565 rval = mb.create_vertex( coords, verts[i][j][k] ); 06566 if( MB_SUCCESS != rval ) return rval; 06567 } 06568 06569 EntityHandle piramid1[13] = { 19, 25, 27, 21, 1, 22, 26, 24, 20, 10, 13, 14, 11 }; 06570 06571 EntityHandle h; 06572 06573 rval = mb.create_element( MBPYRAMID, piramid1, 13, h ); 06574 if( MB_SUCCESS != rval ) return rval; 06575 pyramids.insert( h ); 06576 06577 Range faces; 06578 rval = mb.get_adjacencies( pyramids, 2, true, faces, Interface::UNION ); 06579 // triangles should have 6 nodes, quads 8 nodes 06580 06581 if( MB_SUCCESS != rval ) return rval; 06582 06583 Range tris = faces.subset_by_type( MBTRI ); 06584 Range quads = faces.subset_by_type( MBQUAD ); 06585 06586 for( Range::iterator tit = tris.begin(); tit != tris.end(); tit++ ) 06587 { 06588 EntityHandle triangle = *tit; 06589 const EntityHandle* conn; 06590 int num_verts; 06591 rval = mb.get_connectivity( triangle, conn, num_verts ); 06592 if( MB_SUCCESS != rval ) return rval; 06593 if( 6 != num_verts ) return MB_FAILURE; 06594 } 06595 for( Range::iterator qit = quads.begin(); qit != quads.end(); qit++ ) 06596 { 06597 EntityHandle quad = *qit; 06598 const EntityHandle* conn; 06599 int num_verts; 06600 rval = mb.get_connectivity( quad, conn, num_verts ); 06601 if( MB_SUCCESS != rval ) return rval; 06602 if( 8 != num_verts ) return MB_FAILURE; 06603 } 06604 06605 return MB_SUCCESS; 06606 } 06607 ErrorCode mb_skin_higher_order_regions_test() 06608 { 06609 return mb_skin_higher_order_regions_common( false ); 06610 } 06611 ErrorCode mb_skin_adj_higher_order_regions_test() 06612 { 06613 return mb_skin_higher_order_regions_common( true ); 06614 } 06615 06616 ErrorCode mb_skin_reversed_common( int dim, bool use_adj ) 06617 { 06618 EntityType type, subtype; 06619 switch( dim ) 06620 { 06621 case 2: 06622 type = MBTRI; 06623 subtype = MBEDGE; 06624 break; 06625 case 3: 06626 type = MBTET; 06627 subtype = MBTRI; 06628 break; 06629 default: 06630 assert( false ); 06631 return MB_FAILURE; 06632 } 06633 06634 /* 3 06635 /|\ 06636 / | \ 06637 / | \ 06638 / | \ 06639 0----1----2 06640 */ 06641 06642 ErrorCode rval; 06643 Core moab; 06644 Interface& mb = moab; 06645 Range hexes; 06646 06647 double coords[][3] = { { 0, 0, 0 }, { 1, 0, 0 }, { 2, 0, 0 }, { 1, 2, 0 }, { 1, 2, 2 } }; 06648 EntityHandle verts[5]; 06649 const int nvtx = 2 + dim; 06650 for( int i = 0; i < nvtx; ++i ) 06651 { 06652 rval = mb.create_vertex( coords[i], verts[i] ); 06653 if( MB_SUCCESS != rval ) return rval; 06654 } 06655 // NOTE: order connectivity such that side 1 is shared! 06656 EntityHandle conn[2][4] = { { verts[0], verts[1], verts[3], verts[4] }, 06657 { verts[2], verts[3], verts[1], verts[4] } }; 06658 const int conn_len = dim + 1; 06659 Range elems; 06660 for( int i = 0; i < 2; ++i ) 06661 { 06662 EntityHandle h; 06663 rval = mb.create_element( type, conn[i], conn_len, h ); 06664 if( MB_SUCCESS != rval ) return rval; 06665 elems.insert( h ); 06666 } 06667 06668 // create one reversed side 06669 EntityHandle side_conn[3]; 06670 int side_indices[3] = { 0, 0, 0 }; 06671 CN::SubEntityVertexIndices( type, dim - 1, 0, side_indices ); 06672 side_conn[0] = conn[0][side_indices[1]]; 06673 side_conn[1] = conn[0][side_indices[0]]; 06674 side_conn[2] = conn[0][side_indices[2]]; 06675 EntityHandle side; 06676 rval = mb.create_element( subtype, side_conn, dim, side ); 06677 if( MB_SUCCESS != rval ) return rval; 06678 06679 Range forward, reverse; 06680 Skinner tool( &mb ); 06681 rval = tool.find_skin( 0, elems, false, forward, &reverse, use_adj, true ); 06682 if( MB_SUCCESS != rval ) 06683 { 06684 std::cout << "Skinner failed." << std::endl; 06685 return rval; 06686 } 06687 06688 // expect all faces created by the skinner to be forward, 06689 // so the only reversed side should be the one created above. 06690 if( reverse.size() != 1 || reverse.front() != side ) 06691 { 06692 std::cout << "Expected 1 reversed side, got: " << reverse.size() << std::endl; 06693 return MB_FAILURE; 06694 } 06695 06696 return MB_SUCCESS; 06697 } 06698 ErrorCode mb_skin_faces_reversed_test() 06699 { 06700 return mb_skin_reversed_common( 2, false ); 06701 } 06702 ErrorCode mb_skin_adj_faces_reversed_test() 06703 { 06704 return mb_skin_reversed_common( 2, true ); 06705 } 06706 ErrorCode mb_skin_regions_reversed_test() 06707 { 06708 return mb_skin_reversed_common( 3, false ); 06709 } 06710 ErrorCode mb_skin_adj_regions_reversed_test() 06711 { 06712 return mb_skin_reversed_common( 3, true ); 06713 } 06714 06715 ErrorCode mb_skin_subset_common( int dimension, bool use_adj ) 06716 { 06717 EntityType type; 06718 switch( dimension ) 06719 { 06720 case 2: 06721 type = MBTRI; 06722 break; 06723 case 3: 06724 type = MBPRISM; 06725 break; 06726 default: 06727 assert( false ); 06728 return MB_FAILURE; 06729 } 06730 06731 /* 0 06732 /|\ 06733 / | \ 06734 5 | 1 06735 |\ | /| 06736 | \|/ | 06737 | 6 | 06738 | /|\ | 06739 |/ | \| 06740 4 | 2 06741 \ | / 06742 \|/ 06743 3 06744 */ 06745 06746 ErrorCode rval; 06747 Core moab; 06748 Interface& mb = moab; 06749 Range expected_verts; 06750 06751 const double coords2D[7][2] = { { 0, 2 }, { 1, 1 }, { 1, -1 }, { 0, -2 }, { -1, -1 }, { -1, 1 }, { 0, 0 } }; 06752 EntityHandle verts[2][7] = { { 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0 } }; 06753 for( int d = 1; d < dimension; ++d ) 06754 { 06755 for( int i = 0; i < 7; ++i ) 06756 { 06757 double coords[3] = { coords2D[i][0], coords2D[i][1], static_cast< double >( d - 1 ) }; 06758 rval = mb.create_vertex( coords, verts[d - 1][i] ); 06759 if( MB_SUCCESS != rval ) return rval; 06760 if( i != 4 && i != 5 ) expected_verts.insert( verts[d - 1][i] ); 06761 } 06762 } 06763 06764 EntityHandle elems[6]; 06765 for( int i = 0; i < 6; ++i ) 06766 { 06767 EntityHandle conn[6] = { verts[0][6], verts[0][( i + 1 ) % 6], verts[0][i], 06768 verts[1][6], verts[1][( i + 1 ) % 6], verts[1][i] }; 06769 rval = mb.create_element( type, conn, CN::VerticesPerEntity( type ), elems[i] ); 06770 if( MB_SUCCESS != rval ) return rval; 06771 } 06772 06773 Range input; 06774 input.insert( elems[0] ); 06775 input.insert( elems[1] ); 06776 input.insert( elems[2] ); 06777 06778 Range skin; 06779 Skinner tool( &mb ); 06780 rval = tool.find_skin( 0, input, true, skin, 0, use_adj, false ); 06781 if( MB_SUCCESS != rval ) 06782 { 06783 std::cout << "Skinner failed to find skin vertices" << std::endl; 06784 return MB_FAILURE; 06785 } 06786 if( skin != expected_verts ) 06787 { 06788 std::cout << "Skinner returned incorrect skin vertices" << std::endl; 06789 return MB_FAILURE; 06790 } 06791 int n = 0; 06792 mb.get_number_entities_by_dimension( 0, dimension - 1, n ); 06793 if( n > 0 ) 06794 { 06795 std::cout << "Skinner created lower-dimension entities for vertex-only skinning" << std::endl; 06796 return MB_FAILURE; 06797 } 06798 06799 std::vector< EntityHandle > sv( skin.begin(), skin.end() ); 06800 std::vector< int > counts( sv.size(), 0 ); 06801 skin.clear(); 06802 rval = tool.find_skin( 0, input, false, skin, 0, use_adj, true ); 06803 if( MB_SUCCESS != rval ) 06804 { 06805 std::cout << "Skinner failed to find skin elements" << std::endl; 06806 return MB_FAILURE; 06807 } 06808 for( Range::iterator i = skin.begin(); i != skin.end(); ++i ) 06809 { 06810 const EntityHandle* conn; 06811 int len; 06812 rval = mb.get_connectivity( *i, conn, len ); 06813 if( MB_SUCCESS != rval ) return rval; 06814 for( int j = 0; j < len; ++j ) 06815 { 06816 size_t idx = std::find( sv.begin(), sv.end(), conn[j] ) - sv.begin(); 06817 if( idx == sv.size() ) 06818 { 06819 std::cout << "Skinner returned non-skin element" << std::endl; 06820 return MB_FAILURE; 06821 } 06822 counts[idx]++; 06823 } 06824 } 06825 for( size_t i = 0; i < counts.size(); ++i ) 06826 { 06827 if( counts[i] < dimension ) 06828 { // 2 for dim==2, {3,4,5} for dim==3 06829 std::cout << "Skinner did not return all skin elements" << std::endl; 06830 return MB_FAILURE; 06831 } 06832 } 06833 mb.get_number_entities_by_dimension( 0, dimension - 1, n ); 06834 if( (size_t)n != skin.size() ) 06835 { 06836 std::cout << "Skinner created extra lower-dimension entities" << std::endl; 06837 return MB_FAILURE; 06838 } 06839 06840 return MB_SUCCESS; 06841 } 06842 06843 ErrorCode mb_skin_faces_subset_test() 06844 { 06845 return mb_skin_subset_common( 2, false ); 06846 } 06847 ErrorCode mb_skin_adj_faces_subset_test() 06848 { 06849 return mb_skin_subset_common( 2, true ); 06850 } 06851 ErrorCode mb_skin_regions_subset_test() 06852 { 06853 return mb_skin_subset_common( 3, false ); 06854 } 06855 ErrorCode mb_skin_adj_regions_subset_test() 06856 { 06857 return mb_skin_subset_common( 3, true ); 06858 } 06859 06860 ErrorCode mb_skin_full_common( int dimension, bool use_adj ) 06861 { 06862 EntityType type; 06863 switch( dimension ) 06864 { 06865 case 2: 06866 type = MBQUAD; 06867 break; 06868 case 3: 06869 type = MBHEX; 06870 break; 06871 default: 06872 assert( false ); 06873 return MB_FAILURE; 06874 } 06875 06876 /* 06877 3----4----5 06878 | | | 06879 | | | 06880 0----1----2 06881 */ 06882 06883 ErrorCode rval; 06884 Core moab; 06885 Interface& mb = moab; 06886 06887 // create vertices 06888 const double coords2D[6][2] = { { 0, 0 }, { 1, 0 }, { 2, 0 }, { 0, 1 }, { 1, 1 }, { 2, 1 } }; 06889 EntityHandle v[2][6] = { { 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0 } }; 06890 for( int d = 1; d < dimension; ++d ) 06891 { 06892 for( int i = 0; i < 6; ++i ) 06893 { 06894 double coords[3] = { coords2D[i][0], coords2D[i][1], static_cast< double >( d - 1 ) }; 06895 rval = mb.create_vertex( coords, v[d - 1][i] ); 06896 if( MB_SUCCESS != rval ) return rval; 06897 } 06898 } 06899 06900 // create elements 06901 Range input; 06902 EntityHandle elems[2], econn[2][8]; 06903 ; 06904 for( int i = 0; i < 2; ++i ) 06905 { 06906 EntityHandle conn[8] = { v[0][i], v[0][i + 1], v[0][i + 4], v[0][i + 3], 06907 v[1][i], v[1][i + 1], v[1][i + 4], v[1][i + 3] }; 06908 memcpy( econn[i], conn, sizeof( conn ) ); 06909 rval = mb.create_element( type, conn, CN::VerticesPerEntity( type ), elems[i] ); 06910 if( MB_SUCCESS != rval ) return rval; 06911 input.insert( elems[i] ); 06912 } 06913 06914 // create sides 06915 // NOTE: Shared side is element 0 side 1 and element 1 side 3 06916 Range expected; 06917 for( int i = 0; i < CN::NumSubEntities( type, dimension - 1 ); ++i ) 06918 { 06919 EntityType subtype; 06920 int len; 06921 const short* indices = CN::SubEntityVertexIndices( type, dimension - 1, i, subtype, len ); 06922 EntityHandle conn[4]; 06923 assert( (size_t)len <= sizeof( conn ) / sizeof( conn[0] ) ); 06924 for( int j = 0; j < 2; ++j ) 06925 { 06926 if( j == 1 && i == 3 ) // don't create shared face twice 06927 continue; 06928 for( int k = 0; k < len; ++k ) 06929 conn[k] = econn[j][indices[k]]; 06930 EntityHandle h; 06931 rval = mb.create_element( subtype, conn, len, h ); 06932 if( MB_SUCCESS != rval ) return rval; 06933 if( j != 0 || i != 1 ) // don't insert shared face 06934 expected.insert( h ); 06935 } 06936 } 06937 06938 Range skin; 06939 Skinner tool( &mb ); 06940 rval = tool.find_skin( 0, input, false, skin, 0, use_adj, true ); 06941 if( MB_SUCCESS != rval ) 06942 { 06943 std::cout << "Skinner failed to find skin elements" << std::endl; 06944 return MB_FAILURE; 06945 } 06946 if( skin != expected ) 06947 { 06948 std::cout << "Skinner returned incorrect skin elements" << std::endl; 06949 return MB_FAILURE; 06950 } 06951 06952 int n = 0; 06953 mb.get_number_entities_by_dimension( 0, dimension - 1, n ); 06954 if( (size_t)n != expected.size() + 1 ) 06955 { 06956 std::cout << "Skinner created extra lower-dimension entities" << std::endl; 06957 return MB_FAILURE; 06958 } 06959 06960 return MB_SUCCESS; 06961 } 06962 06963 ErrorCode mb_skin_faces_full_test() 06964 { 06965 return mb_skin_full_common( 2, false ); 06966 } 06967 ErrorCode mb_skin_adj_faces_full_test() 06968 { 06969 return mb_skin_full_common( 2, true ); 06970 } 06971 ErrorCode mb_skin_regions_full_test() 06972 { 06973 return mb_skin_full_common( 3, false ); 06974 } 06975 ErrorCode mb_skin_adj_regions_full_test() 06976 { 06977 return mb_skin_full_common( 3, true ); 06978 } 06979 06980 ErrorCode mb_skin_adjacent_surf_patches() 06981 { 06982 Core moab; 06983 Interface& mb = moab; 06984 ErrorCode rval; 06985 Skinner tool( &mb ); 06986 06987 /* Mesh with vertices and quads numbered. 06988 Groups are indicated by letters {A,B,C,D} 06989 06990 0----1----2----3----4----5 06991 | (0)| (1)| (2)| (3)| (4)| 06992 | A | A | B | B | B | 06993 6----7----8----9---10---11 06994 | (5)| (6)| (7)| (8)| (9)| 06995 | A | A | A | B | B | 06996 12---13---14---15---16---17 06997 |(10)|(11)|(12)|(13)|(14)| 06998 | A | C | D | D | D | 06999 18---19---20---21---22---23 07000 |(15)|(16)|(17)|(18)|(19)| 07001 | C | C | C | D | D | 07002 24---25---26---27---28---29 07003 */ 07004 07005 const int num_vtx = 30; 07006 EntityHandle vtx[num_vtx]; 07007 for( int i = 0; i < 6; ++i ) 07008 { 07009 for( int j = 0; j < 5; ++j ) 07010 { 07011 double coords[3] = { static_cast< double >( i ), static_cast< double >( j ), 0 }; 07012 rval = mb.create_vertex( coords, vtx[6 * j + i] ); 07013 if( MB_SUCCESS != rval ) return rval; 07014 } 07015 } 07016 07017 EntityHandle quads[20]; 07018 for( int i = 0; i < 5; ++i ) 07019 { 07020 for( int j = 0; j < 4; ++j ) 07021 { 07022 int v = 6 * j + i; 07023 EntityHandle conn[4] = { vtx[v + 6], vtx[v + 7], vtx[v + 1], vtx[v + 0] }; 07024 rval = mb.create_element( MBQUAD, conn, 4, quads[5 * j + i] ); 07025 if( MB_SUCCESS != rval ) return rval; 07026 } 07027 } 07028 07029 // Define four groups of quads (as labeled above) 07030 const int Aquads[] = { 0, 1, 5, 6, 7, 10 }; 07031 const int Aquads_size = sizeof( Aquads ) / sizeof( Aquads[0] ); 07032 const int Bquads[] = { 2, 3, 4, 8, 9 }; 07033 const int Bquads_size = sizeof( Bquads ) / sizeof( Bquads[0] ); 07034 const int Cquads[] = { 11, 15, 16, 17 }; 07035 const int Cquads_size = sizeof( Cquads ) / sizeof( Cquads[0] ); 07036 const int Dquads[] = { 12, 13, 14, 18, 19 }; 07037 const int Dquads_size = sizeof( Dquads ) / sizeof( Dquads[0] ); 07038 07039 // Define the results we expect for each group as a loop 07040 // of vertex indices 07041 const int Askin[] = { 0, 1, 2, 8, 9, 15, 14, 13, 19, 18, 12, 6 }; 07042 const int Ashared[] = { -1, -1, 1, 1, 1, 3, 2, 2, 2, -1, -1, -1 }; 07043 const int Askin_size = sizeof( Askin ) / sizeof( Askin[0] ); 07044 const int Bskin[] = { 2, 3, 4, 5, 11, 17, 16, 15, 9, 8 }; 07045 const int Bshared[] = { -1, -1, -1, -1, -1, 3, 3, 0, 0, 0 }; 07046 const int Bskin_size = sizeof( Bskin ) / sizeof( Bskin[0] ); 07047 const int Cskin[] = { 18, 19, 13, 14, 20, 21, 27, 26, 25, 24 }; 07048 const int Cshared[] = { 0, 0, 0, 3, 3, 3, -1, -1, -1, -1 }; 07049 const int Cskin_size = sizeof( Cskin ) / sizeof( Cskin[0] ); 07050 const int Dskin[] = { 14, 15, 16, 17, 23, 29, 28, 27, 21, 20 }; 07051 const int Dshared[] = { 0, 1, 1, -1, -1, -1, -1, 2, 2, 2 }; 07052 const int Dskin_size = sizeof( Dskin ) / sizeof( Dskin[0] ); 07053 07054 // Make the above stuff indexable for easier looping 07055 const int* const gquads[4] = { Aquads, Bquads, Cquads, Dquads }; 07056 const int gquads_size[4] = { Aquads_size, Bquads_size, Cquads_size, Dquads_size }; 07057 const int* const skin[4] = { Askin, Bskin, Cskin, Dskin }; 07058 const int* const shared[4] = { Ashared, Bshared, Cshared, Dshared }; 07059 const int skin_size[4] = { Askin_size, Bskin_size, Cskin_size, Dskin_size }; 07060 07061 // Create an Range for each group of quads 07062 Range ranges[4]; 07063 for( int grp = 0; grp < 4; ++grp ) 07064 for( int i = 0; i < gquads_size[grp]; ++i ) 07065 ranges[grp].insert( quads[gquads[grp][i]] ); 07066 07067 // run test 4 times, one for each of: 07068 // o no adjacencies, no edges 07069 // o no adjacencies, edges 07070 // o adjacencies, edges 07071 // o adjacencies, no edges 07072 // 07073 // Be careful here: once we specify use_adj, we can't 07074 // unspecify it (the adjacencies will exist so the skinner 07075 // will use them, regardless of the passed flag.) 07076 int error_count = 0; 07077 for( int run = 0; run < 4; ++run ) 07078 { 07079 const bool use_adj = run > 1; 07080 if( run == 3 ) 07081 { 07082 Range dead; 07083 mb.get_entities_by_type( 0, MBEDGE, dead ); 07084 mb.delete_entities( dead ); 07085 } 07086 07087 // test each group 07088 Range edges[4]; 07089 for( int grp = 0; grp < 4; ++grp ) 07090 { 07091 // get the skin edges 07092 rval = tool.find_skin( 0, ranges[grp], 1, edges[grp], use_adj ); 07093 if( MB_SUCCESS != rval ) 07094 { 07095 std::cout << "Skinner failed for run " << run << " group " << grp << std::endl; 07096 return rval; 07097 } 07098 07099 // check that we have the expected result 07100 std::vector< bool > seen( skin_size[grp], false ); 07101 for( Range::iterator e = edges[grp].begin(); e != edges[grp].end(); ++e ) 07102 { 07103 const EntityHandle* conn; 07104 int len; 07105 rval = mb.get_connectivity( *e, conn, len ); 07106 if( MB_SUCCESS != rval ) return rval; 07107 if( len != 2 ) return MB_FAILURE; 07108 const int idx1 = std::find( vtx, vtx + num_vtx, conn[0] ) - vtx; 07109 const int idx2 = std::find( vtx, vtx + num_vtx, conn[1] ) - vtx; 07110 int pos = std::find( skin[grp], skin[grp] + skin_size[grp], idx1 ) - skin[grp]; 07111 if( pos == skin_size[grp] ) 07112 { 07113 std::cout << "Non-skin vertex in skin for run " << run << " group " << grp << std::endl; 07114 std::cout << "idx1 = " << idx1 << ", idx2 = " << idx2 << std::endl; 07115 ++error_count; 07116 continue; 07117 } 07118 07119 if( skin[grp][( pos + skin_size[grp] - 1 ) % skin_size[grp]] == idx2 ) 07120 pos = ( pos + skin_size[grp] - 1 ) % skin_size[grp]; 07121 else if( skin[grp][( pos + 1 ) % skin_size[grp]] != idx2 ) 07122 { 07123 std::cout << "Non-skin edge in skin for run " << run << " group " << grp << std::endl; 07124 std::cout << "idx1 = " << idx1 << ", idx2 = " << idx2 << std::endl; 07125 ++error_count; 07126 continue; 07127 } 07128 07129 if( seen[pos] ) 07130 { 07131 std::cout << "Duplicate edge in skin for run " << run << " group " << grp << std::endl; 07132 std::cout << "idx1 = " << idx1 << ", idx2 = " << idx2 << std::endl; 07133 ++error_count; 07134 } 07135 seen[pos] = true; 07136 07137 int shared_with = shared[grp][pos]; 07138 if( shared_with < 0 ) // not shared with another group 07139 continue; 07140 if( shared_with > grp ) // didn't skin other group yet 07141 continue; 07142 if( edges[shared_with].find( *e ) == edges[shared_with].end() ) 07143 { 07144 std::cout << "Skin edge duplicated for run " << run << " group " << grp << std::endl; 07145 std::cout << "idx1 = " << idx1 << ", idx2 = " << idx2 << " not in skin for group " << shared_with 07146 << std::endl; 07147 ++error_count; 07148 } 07149 } 07150 07151 int missing = std::count( seen.begin(), seen.end(), false ); 07152 if( missing ) 07153 { 07154 std::cout << "Missking " << missing << " skin edges for run " << run << " group " << grp << std::endl; 07155 error_count += missing; 07156 } 07157 } 07158 } 07159 07160 return error_count ? MB_FAILURE : MB_SUCCESS; 07161 } 07162 07163 static ErrorCode get_by_all_types_and_tag( Interface* mb, EntityHandle meshset, const Tag* tag_handles, 07164 const void* const* values, int num_tags, Range& result, int condition, 07165 bool recursive ) 07166 { 07167 ErrorCode rval; 07168 Range tmp; 07169 const EntityType LAST = recursive ? MBENTITYSET : MBMAXTYPE; 07170 for( EntityType t = MBVERTEX; t < LAST; ++t ) 07171 { 07172 tmp.clear(); 07173 rval = mb->get_entities_by_type_and_tag( meshset, t, tag_handles, values, num_tags, tmp, condition, recursive ); 07174 if( MB_SUCCESS != rval ) return rval; 07175 result.insert( tmp.begin(), tmp.end() ); 07176 } 07177 return MB_SUCCESS; 07178 } 07179 07180 /** Check that functions which accept a type return the 07181 * result for all types when passed MBMAXTYPE 07182 */ 07183 ErrorCode mb_type_is_maxtype_test() 07184 { 07185 Core moab; 07186 Interface* mb = &moab; 07187 ErrorCode rval = create_some_mesh( mb ); 07188 if( MB_SUCCESS != rval ) return rval; 07189 07190 Range r1, r2; 07191 rval = mb->get_entities_by_type( 0, MBMAXTYPE, r1, false );MB_CHK_ERR( rval ); 07192 rval = mb->get_entities_by_handle( 0, r2, false );MB_CHK_ERR( rval ); 07193 CHECK( r1 == r2 ); 07194 07195 std::vector< EntityHandle > v1, v2; 07196 rval = mb->get_entities_by_type( 0, MBMAXTYPE, v1, false );MB_CHK_ERR( rval ); 07197 rval = mb->get_entities_by_handle( 0, v2, false );MB_CHK_ERR( rval ); 07198 CHECK( v1 == v2 ); 07199 07200 int c1, c2; 07201 rval = mb->get_number_entities_by_type( 0, MBMAXTYPE, c1, false );MB_CHK_ERR( rval ); 07202 rval = mb->get_number_entities_by_handle( 0, c2, false );MB_CHK_ERR( rval ); 07203 CHECK( c1 == c2 ); 07204 07205 Range h1, h2; 07206 Range::iterator it = r1.begin() + r1.size() / 2; 07207 h1.insert( r1.begin(), it ); 07208 if( it != r1.end() ) h2.insert( ++it, r1.end() ); 07209 07210 EntityHandle s1, s2; 07211 rval = mb->create_meshset( MESHSET_SET, s1 );MB_CHK_ERR( rval ); 07212 rval = mb->create_meshset( MESHSET_ORDERED, s2 );MB_CHK_ERR( rval ); 07213 rval = mb->add_entities( s1, r1 );MB_CHK_ERR( rval ); 07214 rval = mb->add_entities( s2, r2 );MB_CHK_ERR( rval ); 07215 rval = mb->add_entities( s2, &s1, 1 );MB_CHK_ERR( rval ); 07216 07217 r1.clear(); 07218 r2.clear(); 07219 rval = mb->get_entities_by_type( s1, MBMAXTYPE, r1, false );MB_CHK_ERR( rval ); 07220 rval = mb->get_entities_by_handle( s1, r2, false );MB_CHK_ERR( rval ); 07221 CHECK( r1 == r2 ); 07222 07223 r1.clear(); 07224 r2.clear(); 07225 rval = mb->get_entities_by_type( s2, MBMAXTYPE, r1, false );MB_CHK_ERR( rval ); 07226 rval = mb->get_entities_by_handle( s2, r2, false );MB_CHK_ERR( rval ); 07227 CHECK( r1 == r2 ); 07228 07229 r1.clear(); 07230 r2.clear(); 07231 rval = mb->get_entities_by_type( s2, MBMAXTYPE, r1, true );MB_CHK_ERR( rval ); 07232 rval = mb->get_entities_by_handle( s2, r2, true );MB_CHK_ERR( rval ); 07233 CHECK( r1 == r2 ); 07234 07235 v1.clear(); 07236 v2.clear(); 07237 rval = mb->get_entities_by_type( s1, MBMAXTYPE, v1, false );MB_CHK_ERR( rval ); 07238 rval = mb->get_entities_by_handle( s1, v2, false );MB_CHK_ERR( rval ); 07239 CHECK( v1 == v2 ); 07240 07241 v1.clear(); 07242 v2.clear(); 07243 rval = mb->get_entities_by_type( s2, MBMAXTYPE, v1, false );MB_CHK_ERR( rval ); 07244 rval = mb->get_entities_by_handle( s2, v2, false );MB_CHK_ERR( rval ); 07245 CHECK( v1 == v2 ); 07246 07247 v1.clear(); 07248 v2.clear(); 07249 rval = mb->get_entities_by_type( s2, MBMAXTYPE, v1, true );MB_CHK_ERR( rval ); 07250 rval = mb->get_entities_by_handle( s2, v2, true );MB_CHK_ERR( rval ); 07251 CHECK( v1 == v2 ); 07252 07253 rval = mb->get_number_entities_by_type( s1, MBMAXTYPE, c1, false );MB_CHK_ERR( rval ); 07254 rval = mb->get_number_entities_by_handle( s1, c2, false );MB_CHK_ERR( rval ); 07255 CHECK( c1 == c2 ); 07256 07257 rval = mb->get_number_entities_by_type( s2, MBMAXTYPE, c1, false );MB_CHK_ERR( rval ); 07258 rval = mb->get_number_entities_by_handle( s2, c2, false );MB_CHK_ERR( rval ); 07259 CHECK( c1 == c2 ); 07260 07261 rval = mb->get_number_entities_by_type( s2, MBMAXTYPE, c1, true );MB_CHK_ERR( rval ); 07262 rval = mb->get_number_entities_by_handle( s2, c2, true );MB_CHK_ERR( rval ); 07263 CHECK( c1 == c2 ); 07264 07265 r1.clear(); 07266 rval = mb->get_entities_by_handle( s1, r1 );MB_CHK_ERR( rval ); 07267 Tag t1; 07268 rval = mb->tag_get_handle( "maxtype1", 1, MB_TYPE_INTEGER, t1, MB_TAG_SPARSE | MB_TAG_EXCL );MB_CHK_ERR( rval ); 07269 std::vector< int > d1( r1.size() ); 07270 Range::iterator ri; 07271 std::vector< int >::iterator ii = d1.begin(); 07272 for( ri = r1.begin(); ri != r1.end(); ++ri, ++ii ) 07273 *ii = ( (int)ID_FROM_HANDLE( *ri ) ) % 20; 07274 rval = mb->tag_set_data( t1, r1, &d1[0] );MB_CHK_ERR( rval ); 07275 07276 r1.clear(); 07277 r2.clear(); 07278 rval = mb->get_entities_by_type_and_tag( 0, MBMAXTYPE, &t1, 0, 1, r1, Interface::INTERSECT, false );MB_CHK_ERR( rval ); 07279 rval = mb->get_number_entities_by_type_and_tag( 0, MBMAXTYPE, &t1, 0, 1, c1, Interface::INTERSECT, false );MB_CHK_ERR( rval ); 07280 rval = get_by_all_types_and_tag( mb, 0, &t1, 0, 1, r2, Interface::INTERSECT, false );MB_CHK_ERR( rval ); 07281 CHECK( r1 == r2 ); 07282 CHECK( (unsigned)c1 == r2.size() ); 07283 07284 r1.clear(); 07285 r2.clear(); 07286 rval = mb->get_entities_by_type_and_tag( s1, MBMAXTYPE, &t1, 0, 1, r1, Interface::INTERSECT, false );MB_CHK_ERR( rval ); 07287 rval = mb->get_number_entities_by_type_and_tag( s1, MBMAXTYPE, &t1, 0, 1, c1, Interface::INTERSECT, false );MB_CHK_ERR( rval ); 07288 rval = get_by_all_types_and_tag( mb, s1, &t1, 0, 1, r2, Interface::INTERSECT, false );MB_CHK_ERR( rval ); 07289 CHECK( r1 == r2 ); 07290 CHECK( (unsigned)c1 == r2.size() ); 07291 07292 r1.clear(); 07293 r2.clear(); 07294 rval = mb->get_entities_by_type_and_tag( s2, MBMAXTYPE, &t1, 0, 1, r1, Interface::INTERSECT, false );MB_CHK_ERR( rval ); 07295 rval = mb->get_number_entities_by_type_and_tag( s2, MBMAXTYPE, &t1, 0, 1, c1, Interface::INTERSECT, false );MB_CHK_ERR( rval ); 07296 rval = get_by_all_types_and_tag( mb, s2, &t1, 0, 1, r2, Interface::INTERSECT, false );MB_CHK_ERR( rval ); 07297 CHECK( r1 == r2 ); 07298 CHECK( (unsigned)c1 == r2.size() ); 07299 07300 r1.clear(); 07301 r2.clear(); 07302 rval = mb->get_entities_by_type_and_tag( s2, MBMAXTYPE, &t1, 0, 1, r1, Interface::INTERSECT, true );MB_CHK_ERR( rval ); 07303 rval = mb->get_number_entities_by_type_and_tag( s2, MBMAXTYPE, &t1, 0, 1, c1, Interface::INTERSECT, true );MB_CHK_ERR( rval ); 07304 rval = get_by_all_types_and_tag( mb, s2, &t1, 0, 1, r2, Interface::INTERSECT, true );MB_CHK_ERR( rval ); 07305 CHECK( r1 == r2 ); 07306 CHECK( (unsigned)c1 == r2.size() ); 07307 07308 int value = 3; 07309 const void* vallist[2] = { &value, 0 }; 07310 07311 r1.clear(); 07312 r2.clear(); 07313 rval = mb->get_entities_by_type_and_tag( 0, MBMAXTYPE, &t1, vallist, 1, r1, Interface::INTERSECT, false );MB_CHK_ERR( rval ); 07314 rval = mb->get_number_entities_by_type_and_tag( 0, MBMAXTYPE, &t1, vallist, 1, c1, Interface::INTERSECT, false );MB_CHK_ERR( rval ); 07315 rval = get_by_all_types_and_tag( mb, 0, &t1, vallist, 1, r2, Interface::INTERSECT, false );MB_CHK_ERR( rval ); 07316 CHECK( r1 == r2 ); 07317 CHECK( (unsigned)c1 == r2.size() ); 07318 07319 r1.clear(); 07320 r2.clear(); 07321 rval = mb->get_entities_by_type_and_tag( s1, MBMAXTYPE, &t1, vallist, 1, r1, Interface::INTERSECT, false );MB_CHK_ERR( rval ); 07322 rval = mb->get_number_entities_by_type_and_tag( s1, MBMAXTYPE, &t1, vallist, 1, c1, Interface::INTERSECT, false );MB_CHK_ERR( rval ); 07323 rval = get_by_all_types_and_tag( mb, s1, &t1, vallist, 1, r2, Interface::INTERSECT, false );MB_CHK_ERR( rval ); 07324 CHECK( r1 == r2 ); 07325 CHECK( (unsigned)c1 == r2.size() ); 07326 07327 r1.clear(); 07328 r2.clear(); 07329 rval = mb->get_entities_by_type_and_tag( s2, MBMAXTYPE, &t1, vallist, 1, r1, Interface::INTERSECT, false );MB_CHK_ERR( rval ); 07330 rval = mb->get_number_entities_by_type_and_tag( s2, MBMAXTYPE, &t1, vallist, 1, c1, Interface::INTERSECT, false );MB_CHK_ERR( rval ); 07331 rval = get_by_all_types_and_tag( mb, s2, &t1, vallist, 1, r2, Interface::INTERSECT, false );MB_CHK_ERR( rval ); 07332 CHECK( r1 == r2 ); 07333 CHECK( (unsigned)c1 == r2.size() ); 07334 07335 r1.clear(); 07336 r2.clear(); 07337 rval = mb->get_entities_by_type_and_tag( s2, MBMAXTYPE, &t1, vallist, 1, r1, Interface::INTERSECT, true );MB_CHK_ERR( rval ); 07338 rval = mb->get_number_entities_by_type_and_tag( s2, MBMAXTYPE, &t1, vallist, 1, c1, Interface::INTERSECT, true );MB_CHK_ERR( rval ); 07339 rval = get_by_all_types_and_tag( mb, s2, &t1, vallist, 1, r2, Interface::INTERSECT, true );MB_CHK_ERR( rval ); 07340 CHECK( r1 == r2 ); 07341 CHECK( (unsigned)c1 == r2.size() ); 07342 07343 r1.clear(); 07344 r2.clear(); 07345 rval = mb->get_entities_by_handle( s1, r1 );MB_CHK_ERR( rval ); 07346 r2.insert( r1.back() ); 07347 r1.clear(); 07348 rval = mb->get_entities_by_handle( s2, r1 );MB_CHK_ERR( rval ); 07349 r2.insert( r1.front() ); 07350 07351 Tag t2; 07352 rval = mb->tag_get_handle( "maxtype2", 1, MB_