MOAB: Mesh Oriented datABase  (version 5.4.1)
normals.cpp
Go to the documentation of this file.
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 <cstdio>
00013 #include <cstdlib>
00014 #include <cstring>
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 <geom_filename> <mesh_filename>\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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines