![]() |
Mesh Oriented datABase
(version 5.4.1)
Array-based unstructured mesh datastructure
|
00001 /*
00002 * normals.cpp
00003 *
00004 * Created on: Oct 30, 2015
00005 * will take an occ model and compute normals at all vertices, using exact geometry info
00006 */
00007
00008 #include "iGeom.h"
00009 #include "iMesh.h"
00010 #include "iRel.h"
00011
00012 #include
00013 #include
00014 #include
00015
00016 #include "MBiMesh.hpp"
00017 #include "moab/Core.hpp"
00018
00019 #define STRINGIFY_( X ) #X
00020 #define STRINGIFY( X ) STRINGIFY_( X )
00021 #ifdef MESHDIR
00022 #ifdef HAVE_OCC
00023 #define DEFAULT_GEOM STRINGIFY( MESHDIR / irel / cyl2.stp )
00024 #define DEFAULT_MESH STRINGIFY( MESHDIR / irel / cyl2.h5m )
00025 #else
00026 #define DEFAULT_GEOM STRINGIFY( MESHDIR / irel / brick.facet )
00027 #define DEFAULT_MESH STRINGIFY( MESHDIR / irel / brick.h5m )
00028 #endif
00029 #endif
00030
00031 #define CHECK_SIZE_C( type, array, allocated_size, size ) \
00032 if( NULL == *( array ) || *( allocated_size ) == 0 ) \
00033 { \
00034 *( array ) = (type*)malloc( sizeof( type ) * ( size ) ); \
00035 *( allocated_size ) = size; \
00036 } \
00037 else if( *( allocated_size ) < ( size ) ) \
00038 { \
00039 printf( " Array passed in is non-zero but too short.\n" ); \
00040 }
00041
00042 typedef void* iRel_EntityHandle;
00043
00044 int print_geom_info( iGeom_Instance geom, iBase_EntityHandle gent )
00045 {
00046 /* print information about this entity */
00047 int ent_type;
00048 int result;
00049 const char* type_names[] = { "Vertex", "Edge", "Face", "Region" };
00050
00051 iGeom_getEntType( geom, gent, &ent_type, &result );
00052
00053 if( iBase_SUCCESS != result )
00054 {
00055 printf( "Trouble getting entity adjacencies or types." );
00056 return 0;
00057 }
00058
00059 printf( "%s 0x%lx\n", type_names[ent_type], (unsigned long)gent );
00060
00061 return 1;
00062 }
00063
00064 int print_mesh_info( iMesh_Instance mesh, iBase_EntityHandle ment )
00065 {
00066 /* print information about this entity */
00067
00068 /* get adjacencies first; assume not more than 50 */
00069 iBase_EntityHandle adj_ents[500], *adj_ents_ptr = adj_ents;
00070 int ent_types[500], *ent_types_ptr = ent_types;
00071 int adj_ents_alloc = 500, adj_ents_size, ent_types_size, ent_types_allocated = 500;
00072 int result;
00073
00074 iBase_TagHandle* ment_tags = NULL;
00075 int ment_tags_size, ment_tags_alloc;
00076
00077 char** tag_names;
00078 int i;
00079
00080 const char* type_names[] = { "Vertex", "Edge", "Face", "Region" };
00081
00082 iMesh_getEntAdj( mesh, ment, iBase_ALL_TYPES, &adj_ents_ptr, &adj_ents_alloc, &adj_ents_size, &result );
00083
00084 if( iBase_SUCCESS != result ) return 0;
00085
00086 /* put this ent on the end, then get types */
00087 adj_ents[adj_ents_size] = ment;
00088 iMesh_getEntArrType( mesh, adj_ents, adj_ents_size + 1, &ent_types_ptr, &ent_types_allocated, &ent_types_size,
00089 &result );
00090 if( iBase_SUCCESS != result )
00091 {
00092 printf( "Trouble getting entity adjacencies or types." );
00093 return 0;
00094 }
00095
00096 /* get tags on ment */
00097 iMesh_getAllTags( mesh, ment, &ment_tags, &ment_tags_alloc, &ment_tags_size, &result );
00098
00099 printf( "Trouble getting tags on an entity or their names." );
00100
00101 /* while we're at it, get all the tag names */
00102
00103 tag_names = (char**)malloc( ment_tags_size * sizeof( char* ) );
00104
00105 for( i = 0; i < ment_tags_size; i++ )
00106 {
00107 tag_names[i] = (char*)malloc( 120 * sizeof( char ) );
00108 iMesh_getTagName( mesh, ment_tags[i], tag_names[i], &result, 120 );
00109 }
00110
00111 /* now print the information */
00112 printf( "%s %ld:\n", type_names[ent_types[ent_types_size - 1]], (long)ment );
00113 printf( "Adjacencies:" );
00114 for( i = 0; i < adj_ents_size; i++ )
00115 {
00116 if( i > 0 ) printf( ", " );
00117 printf( "%s %ld", type_names[ent_types[i]], (long)adj_ents[i] );
00118 }
00119 printf( "\nTags: \n" );
00120 for( i = 0; i < ment_tags_size; i++ )
00121 {
00122 int tag_type;
00123
00124 printf( "%s ", tag_names[i] );
00125 iMesh_getTagType( mesh, ment_tags[i], &tag_type, &result );
00126 if( iBase_SUCCESS != result )
00127 printf( "(trouble getting type...)\n" );
00128 else
00129 {
00130 char* dum_handle = NULL;
00131 int dum_handle_alloc = 0, dum_handle_size = 0;
00132 int int_data;
00133 double dbl_data;
00134 iBase_EntityHandle eh_data;
00135
00136 switch( tag_type )
00137 {
00138 case iBase_INTEGER:
00139 iMesh_getIntData( mesh, ment, ment_tags[i], &int_data, &result );
00140 printf( "(Int value=%d)", int_data );
00141 break;
00142 case iBase_DOUBLE:
00143 iMesh_getDblData( mesh, ment, ment_tags[i], &dbl_data, &result );
00144 printf( "(Dbl value=%f)", dbl_data );
00145 break;
00146 case iBase_ENTITY_HANDLE:
00147 iMesh_getEHData( mesh, ment, ment_tags[i], &eh_data, &result );
00148 printf( "(EH value=%ld)", (long)eh_data );
00149 break;
00150 case iBase_BYTES:
00151 iMesh_getData( mesh, ment, ment_tags[i], (void**)&dum_handle, &dum_handle_alloc, &dum_handle_size,
00152 &result );
00153 if( NULL != dum_handle && dum_handle_size > 0 ) printf( "(Opaque value=%c)", dum_handle[0] );
00154 break;
00155 }
00156 }
00157
00158 printf( "\n" );
00159 }
00160 printf( "(end tags)\n\n" );
00161 free( ment_tags );
00162
00163 return 1;
00164 }
00165
00166 /*!
00167 @li Load a geom and a mesh file
00168 */
00169 int load_geom_mesh( const char* geom_filename, const char* mesh_filename, iGeom_Instance geom, iMesh_Instance mesh )
00170 {
00171 /* load a geom */
00172 int result;
00173 iGeom_load( geom, geom_filename, 0, &result, strlen( geom_filename ), 0 );
00174 if( iBase_SUCCESS != result )
00175 {
00176 printf( "ERROR : can not load a geometry\n" );
00177 return 0;
00178 }
00179
00180 /* load a mesh */
00181 iMesh_load( mesh, 0, mesh_filename, 0, &result, strlen( mesh_filename ), 0 );
00182 if( iBase_SUCCESS != result )
00183 {
00184 printf( "ERROR : can not load a mesh\n" );
00185 return 0;
00186 }
00187
00188 return 1;
00189 }
00190
00191 /*!
00192
00193 @li Create relation between geom and mesh
00194 */
00195 int create_relation( iRel_Instance assoc, iGeom_Instance geom, iMesh_Instance mesh, iRel_PairHandle* pair )
00196 {
00197 int result;
00198 iBase_Instance iface1, iface2;
00199 int type1, type2;
00200 int ent_or_set1, ent_or_set2;
00201 int status1, status2;
00202
00203 iRel_PairHandle tmp_pair;
00204 iRel_PairHandle* pair_ptr = &tmp_pair;
00205 int pairs_alloc = 1, pairs_size;
00206
00207 /* create an relation, entity to set */
00208 iRel_createPair( assoc, geom, iRel_ENTITY, iRel_IGEOM_IFACE, iRel_ACTIVE, mesh, iRel_SET, iRel_IMESH_IFACE,
00209 iRel_ACTIVE, pair, &result );
00210 if( iBase_SUCCESS != result )
00211 {
00212 printf( "Couldn't create a new relation.\n" );
00213 return 0;
00214 }
00215
00216 iRel_getPairInfo( assoc, *pair, &iface1, &ent_or_set1, &type1, &status1, &iface2, &ent_or_set2, &type2, &status2,
00217 &result );
00218 if( iBase_SUCCESS != result )
00219 {
00220 printf( "Couldn't retrieve relation info.\n" );
00221 return 0;
00222 }
00223 if( iface1 != geom || ent_or_set1 != iRel_ENTITY || type1 != iRel_IGEOM_IFACE || iface2 != mesh ||
00224 ent_or_set2 != iRel_SET || type2 != iRel_IMESH_IFACE )
00225 {
00226 printf( "Unexpected relation info returned.\n" );
00227 return 0;
00228 }
00229
00230 iRel_findPairs( assoc, geom, &pair_ptr, &pairs_alloc, &pairs_size, &result );
00231 if( iBase_SUCCESS != result )
00232 {
00233 printf( "Couldn't find relation pair when querying geom.\n" );
00234 return 0;
00235 }
00236 if( pairs_size != 1 || tmp_pair != *pair )
00237 {
00238 printf( "Unexpected relation pairs returned when querying geom.\n" );
00239 return 0;
00240 }
00241
00242 iRel_findPairs( assoc, mesh, &pair_ptr, &pairs_alloc, &pairs_size, &result );
00243 if( iBase_SUCCESS != result )
00244 {
00245 printf( "Couldn't find relation pair when querying mesh.\n" );
00246 return 0;
00247 }
00248 if( pairs_size != 1 || tmp_pair != *pair )
00249 {
00250 printf( "Unexpected relation pairs returned when querying mesh.\n" );
00251 return 0;
00252 }
00253
00254 return 1;
00255 }
00256
00257 /*!
00258 @li Check relation between geom and mesh
00259 */
00260 int relate_geom_mesh( iRel_Instance assoc, iGeom_Instance geom, iMesh_Instance mesh, iRel_PairHandle pair )
00261 {
00262 int result;
00263
00264 iBase_EntityHandle* gentities = NULL;
00265 int gentities_size = 0, gentities_alloc = 0;
00266
00267 iBase_EntitySetHandle* mentity_handles = NULL;
00268 int mentity_handles_size = 0, mentity_handles_alloc = 0;
00269
00270 const char* dim_tag_name = "GEOM_DIMENSION";
00271 iBase_TagHandle dim_tag_mesh;
00272
00273 iBase_EntitySetHandle* mentities_vec;
00274 int mentities_vec_size = 0;
00275 int i;
00276
00277 iBase_EntitySetHandle* out_mentities = NULL;
00278 int out_mentities_size = 0, out_mentities_alloc = 0;
00279
00280 iBase_EntitySetHandle* out_mentities2 = NULL;
00281 int out_mentities2_size = 0, out_mentities2_alloc = 0;
00282
00283 iBase_EntityHandle* out_gentities = NULL;
00284 int out_gentities_size = 0, out_gentities_alloc = 0;
00285
00286 /* relate geometry entities with coresponding mesh entity sets */
00287 iGeom_getEntities( geom, NULL, iBase_VERTEX, &gentities, &gentities_alloc, &gentities_size, &result );
00288 if( iBase_SUCCESS != result )
00289 {
00290 printf( "Failed to get gentities by type in relate_geom_mesh.\n" );
00291 return 0;
00292 }
00293
00294 iRel_inferEntArrRelations( assoc, pair, gentities, gentities_size, 0, &result );
00295 if( iBase_SUCCESS != result )
00296 {
00297 printf( "Failed to relate geom entities in relate_geom_mesh.\n" );
00298 return 0;
00299 }
00300
00301 /* relate coresponding mesh entity sets for geometry entities */
00302 /* get 1-dimensional mesh entitysets */
00303 iMesh_getEntSets( mesh, NULL, 1, &mentity_handles, &mentity_handles_alloc, &mentity_handles_size, &result );
00304 if( iBase_SUCCESS != result )
00305 {
00306 printf( "Problem to get all entity sets.\n" );
00307 return 0;
00308 }
00309
00310 /* get geom dimension tags for mesh entitysets */
00311 iMesh_createTag( mesh, dim_tag_name, 1, iBase_INTEGER, &dim_tag_mesh, &result, 15 );
00312 if( iBase_SUCCESS != result && result != iBase_TAG_ALREADY_EXISTS )
00313 {
00314 printf( "Couldn't create geom dim tag for mesh entities.\n" );
00315 return 0;
00316 }
00317
00318 /* get 1-dimensional mesh entitysets */
00319 mentities_vec = (iBase_EntitySetHandle*)malloc( mentity_handles_size * sizeof( iBase_EntitySetHandle ) );
00320 for( i = 0; i < mentity_handles_size; i++ )
00321 { /* test */
00322 int dim;
00323 iMesh_getEntSetIntData( mesh, mentity_handles[i], dim_tag_mesh, &dim, &result );
00324 if( iBase_SUCCESS != result ) continue;
00325
00326 if( dim == 1 ) mentities_vec[mentities_vec_size++] = mentity_handles[i];
00327 }
00328
00329 iRel_inferSetArrRelations( assoc, pair, mentities_vec, mentities_vec_size, 1, &result );
00330 if( iBase_SUCCESS != result )
00331 {
00332 printf( "Failed to relate mesh entities in relate_geom_mesh.\n" );
00333 return 0;
00334 }
00335
00336 /* relate all geometry and mesh entities */
00337 iRel_inferAllRelations( assoc, pair, &result );
00338 if( iBase_SUCCESS != result )
00339 {
00340 printf( "Failed to relate all geom and mesh entities in relate_geom_mesh.\n" );
00341 return 0;
00342 }
00343
00344 /* reset geom entities list and get all geom entities (prev
00345 only vertices) */
00346 free( gentities );
00347 gentities = NULL;
00348 gentities_alloc = 0;
00349 iGeom_getEntities( geom, NULL, iBase_ALL_TYPES, &gentities, &gentities_alloc, &gentities_size, &result );
00350 if( iBase_SUCCESS != result )
00351 {
00352 printf( "Failed to get gentities by type in relate_geom_mesh.\n" );
00353 return 0;
00354 }
00355
00356 /* get related mesh entity sets for geometry entities */
00357 iRel_getEntArrSetArrRelation( assoc, pair, gentities, gentities_size, 0, &out_mentities, &out_mentities_alloc,
00358 &out_mentities_size, &result );
00359 if( iBase_SUCCESS != result )
00360 {
00361 printf( "Failed to get geom entities in relate_geom_mesh.\n" );
00362 return 0;
00363 }
00364
00365 if( out_mentities_size != gentities_size )
00366 {
00367 printf( "Number of input geom entities and output mesh entity sets should be same\n" );
00368 return 0;
00369 }
00370
00371 /* now try deleting this relation */
00372 iRel_rmvEntArrRelation( assoc, pair, gentities, gentities_size, 0, &result );
00373 if( iBase_SUCCESS != result )
00374 {
00375 printf( "Failed to remove relation in relate_geom_mesh.\n" );
00376 return 0;
00377 }
00378
00379 iRel_getEntArrSetArrRelation( assoc, pair, gentities, gentities_size, 0, &out_mentities2, &out_mentities2_alloc,
00380 &out_mentities2_size, &result );
00381 if( iBase_SUCCESS == result )
00382 {
00383 printf( "Shouldn't have gotten mesh sets in relate_geom_mesh.\n" );
00384 return 0;
00385 }
00386
00387 /* restore the relation, since we need it later */
00388 iRel_setEntArrSetArrRelation( assoc, pair, gentities, gentities_size, out_mentities, out_mentities_size, &result );
00389 if( iBase_SUCCESS != result )
00390 {
00391 printf( "Failed to restore relation in relate_geom_mesh.\n" );
00392 return 0;
00393 }
00394
00395 /* get related geometry entities for mesh entity sets */
00396 iRel_getSetArrEntArrRelation( assoc, pair, out_mentities, out_mentities_size, 1, &out_gentities,
00397 &out_gentities_alloc, &out_gentities_size, &result );
00398 if( iBase_SUCCESS != result )
00399 {
00400 printf( "Failed to get mesh entities in relate_geom_mesh.\n" );
00401 return 0;
00402 }
00403
00404 if( out_mentities_size != out_gentities_size )
00405 {
00406 printf( "Number of input mesh entity sets and output geom entities should be same\n" );
00407 return 0;
00408 }
00409 free( mentity_handles );
00410 mentity_handles = NULL;
00411 free( gentities );
00412 gentities = NULL;
00413 free( mentity_handles );
00414 mentity_handles = NULL;
00415 free( out_mentities );
00416 out_mentities = NULL;
00417 free( mentities_vec );
00418 mentities_vec = NULL;
00419 free( out_gentities );
00420 out_gentities = NULL;
00421 return 1;
00422 }
00423
00424 /*!
00425 @li compute normals onto the given geometry
00426 */
00427 int compute_normals( iRel_Instance assoc, iGeom_Instance geom, iMesh_Instance mesh, iRel_PairHandle pair )
00428 {
00429 int result;
00430 int i;
00431
00432 iBase_EntityHandle* gentities = NULL;
00433 int gentities_size = 0, gentities_alloc = 0;
00434
00435 iBase_EntitySetHandle* out_mentities = NULL;
00436 int out_mentities_size, out_mentities_alloc = 0;
00437
00438 /* get all the face geo entities, and find relation to some mesh entity */
00439 iGeom_getEntities( geom, NULL, iBase_FACE, &gentities, &gentities_alloc, &gentities_size, &result );
00440 if( iBase_SUCCESS != result )
00441 {
00442 printf( "Problem getting all geom entities.\n" );
00443 return 0;
00444 }
00445 for( i = 0; i < gentities_size; i++ )
00446 {
00447 print_geom_info( geom, gentities[i] );
00448 }
00449
00450 iRel_getEntArrSetArrRelation( assoc, pair, gentities, gentities_size, 0, &out_mentities, &out_mentities_alloc,
00451 &out_mentities_size, &result );
00452 /* might not all be */
00453 if( iBase_SUCCESS != result )
00454 {
00455 printf( "Failed to get mesh entities related to geom entities in compute_normals.\n" );
00456 return 0;
00457 }
00458
00459 /* check that they're all non-null */
00460 if( out_mentities_size != gentities_size )
00461 {
00462 printf( "Number of mesh & related geom entities don't match.\n" );
00463 return 0;
00464 }
00465
00466 /* check to make sure they're mesh sets; how to do that? */
00467 for( i = 0; i < out_mentities_size; i++ )
00468 {
00469 int is_list;
00470 iMesh_isList( mesh, (iBase_EntitySetHandle)out_mentities[i], &is_list, &result );
00471 if( iBase_SUCCESS != result )
00472 {
00473 printf( "Entity set returned from classification wasn't valid.\n" );
00474 return 0;
00475 }
00476 }
00477
00478 moab::Interface* mb = reinterpret_cast< MBiMesh* >( mesh )->mbImpl;
00479 if( !mb ) return 0;
00480 moab::ErrorCode rval = MB_SUCCESS;
00481
00482 moab::Tag idtag;
00483 rval = mb->tag_get_handle( "GLOBAL_ID", idtag );
00484 if( MB_SUCCESS != rval ) return 0;
00485
00486 for( i = 0; i < gentities_size; i++ )
00487 {
00488
00489 EntityHandle meshSet = (EntityHandle)out_mentities[i];
00490 Range faces;
00491 rval = mb->get_entities_by_dimension( meshSet, 2, faces ); // MB_CHK_ERR(rval);
00492
00493 Range vertices;
00494 rval = mb->get_connectivity( faces, vertices );
00495
00496 std::vector< double > coords;
00497 coords.resize( vertices.size() * 3 );
00498 rval = mb->get_coords( vertices, &coords[0] );
00499
00500 int id;
00501 rval = mb->tag_get_data( idtag, &meshSet, 1, &id );
00502 printf( "surface %d has %d faces and %d vertices \n", id, (int)faces.size(), (int)vertices.size() );
00503
00504 std::vector< double > normals;
00505 normals.resize( 3 * vertices.size() );
00506
00507 std::vector< double > on_coordinates;
00508 on_coordinates.resize( 3 * vertices.size() );
00509
00510 for( int j = 0; j < (int)vertices.size(); j++ )
00511 {
00512 iGeom_getEntNrmlXYZ( geom, gentities[i], coords[3 * j], coords[3 * j + 1], coords[3 * j + 2],
00513 &normals[3 * j], &normals[3 * j + 1], &normals[3 * j + 2], &result );
00514 if( iBase_SUCCESS != result )
00515 {
00516 printf( "Problem getting normals.\n" );
00517 return 0;
00518 }
00519 EntityHandle vertex = vertices[j];
00520 rval = mb->tag_get_data( idtag, &vertex, 1, &id );
00521 printf( "v: %4d coor: %12.6f %12.6f %12.6f norm: %12.6f %12.6f %12.6f \n", id, coords[3 * j],
00522 coords[3 * j + 1], coords[3 * j + 2], normals[3 * j], normals[3 * j + 1], normals[3 * j + 2] );
00523 ;
00524 }
00525 }
00526
00527 free( gentities );
00528 gentities = NULL;
00529 free( out_mentities );
00530 out_mentities = NULL;
00531 /* ok, we're done */
00532 return 1;
00533 }
00534
00535 int main( int argc, char* argv[] )
00536 {
00537 /* Check command line arg */
00538 const char* geom_filename = DEFAULT_GEOM;
00539 const char* mesh_filename = DEFAULT_MESH;
00540
00541 int result;
00542
00543 iGeom_Instance geom;
00544 iMesh_Instance mesh;
00545 iRel_Instance assoc;
00546 iRel_PairHandle pair;
00547
00548 printf( "Usage: %s %s\n", geom_filename, mesh_filename );
00549
00550 if( argc == 2 && !strcmp( argv[1], "-h" ) )
00551 {
00552 printf( "Usage: %s \n", argv[0] );
00553 return 1;
00554 }
00555 else if( argc == 2 )
00556 {
00557 geom_filename = argv[1];
00558 mesh_filename = argv[1];
00559 }
00560 else if( argc == 3 )
00561 {
00562 geom_filename = argv[1];
00563 mesh_filename = argv[2];
00564 }
00565
00566 /* initialize the Geometry */
00567 iGeom_newGeom( 0, &geom, &result, 0 );
00568
00569 /* initialize the Mesh */
00570 iMesh_newMesh( 0, &mesh, &result, 0 );
00571
00572 /* initialize the Associate */
00573 iRel_create( 0, &assoc, &result, 0 );
00574
00575 printf( " load_geom_mesh: \n" );
00576 result = load_geom_mesh( geom_filename, mesh_filename, geom, mesh );
00577
00578 printf( " create_relation: \n" );
00579 result = create_relation( assoc, geom, mesh, &pair );
00580
00581 printf( " relate_geom_mesh: \n" );
00582 result = relate_geom_mesh( assoc, geom, mesh, pair );
00583
00584 /* compute normals */
00585 printf( " compute normals: \n" );
00586 result = compute_normals( assoc, geom, mesh, pair );
00587
00588 /* summary */
00589
00590 iRel_destroy( assoc, &result );
00591 iMesh_dtor( mesh, &result );
00592 iGeom_dtor( geom, &result );
00593
00594 return 0;
00595 }