cgma
test_edge_orient.cc
Go to the documentation of this file.
00001 #include "iGeom.h"
00002 #include "RefEntity.hpp"
00003 #include "RefFace.hpp"
00004 #include "RefEdge.hpp"
00005 #include "RefVertex.hpp"
00006 #include "Body.hpp"
00007 #include "CubitVector.hpp"
00008 #include "ModelQueryEngine.hpp"
00009 #include "GeometryQueryTool.hpp"
00010 #include <iostream>
00011 #define CHECK( STR ) if (err != iBase_SUCCESS) return print_error( STR, err, geom, __FILE__, __LINE__ )
00012 
00013 #if defined (HAVE_OCC)
00014 #  define ENGINE "OCC"
00015 #  define FORMAT "OCC"
00016 #  define FILE_NAME "brick_2.stp"
00017 #  define FILE_NAME1 "ilc_13body.stp"
00018 #  define FILE_NAME2 "ilc_1body.stp"
00019 #  define FILE_NAME3 "ilc_problem_surf8.stp"
00020 #else
00021 #  define ENGINE "FACET"
00022 #  define FORMAT "FACET"
00023 #  define FILE_NAME "brick.facet"
00024 #endif
00025 
00026 #define STRINGIFY(S) XSTRINGIFY(S)
00027 #define XSTRINGIFY(S) #S
00028 
00029 int getFirstVolume(iGeom_Instance geom, iBase_EntityHandle & volume);
00030 int checkEdgeOrientation(iGeom_Instance geom, iBase_EntityHandle & volume);
00031 
00032 static int print_error( const char* desc,
00033                          int err,
00034                          iGeom_Instance geom,
00035                          const char* file,
00036                          int line )
00037 {
00038   char buffer[1024];
00039   iGeom_getDescription( geom, buffer, sizeof(buffer) );
00040   buffer[sizeof(buffer)-1] = '\0';
00041   
00042   std::cerr << "ERROR: " << desc << std::endl
00043             << "  Error code: " << err << std::endl
00044             << "  Error desc: " << buffer << std::endl
00045             << "  At        : " << file << ':' << line << std::endl
00046             ;
00047   
00048   return 1; // must always return false or CHECK macro will break
00049 }
00050 
00051 int main(int argc, char *argv[])
00052 {
00053   // initialize the Mesh
00054   int i, err;
00055   iGeom_Instance geom;
00056   std::string engine_opt = ";engine=";
00057   engine_opt += ENGINE;
00058   iGeom_newGeom(engine_opt.c_str(), &geom, &err, engine_opt.length());
00059 
00060   // read in the geometry file, which is the geometry of a brick
00061   std::string input_file;
00062   input_file = STRINGIFY(SRCDIR)"/";
00063   input_file += FILE_NAME;
00064   if (argc>1)
00065     input_file = argv[1];
00066   iGeom_load(geom, input_file.c_str(), 0, &err, input_file.length(), 0);
00067   CHECK( "ERROR : can not load a geometry" );
00068 
00069   iBase_EntityHandle volume;
00070   err = getFirstVolume(geom, volume);
00071   if (err)
00072     return err;
00073 
00074   // get the bounding box of the brick and calculate its approximate center
00075   double minX, minY, minZ, maxX, maxY, maxZ;
00076   iGeom_getEntBoundBox(geom, volume, &minX, &minY, &minZ,
00077       &maxX, &maxY, &maxZ, &err);
00078   CHECK("Failed to get bounding box.");
00079   double cntrX = (minX + maxX) / 2.0;
00080   double cntrY = (minY + maxY) / 2.0;
00081   double cntrZ = (minZ + maxZ) / 2.0;
00082 
00083   // get brick faces
00084   iBase_EntityHandle* all_faces = NULL;
00085   int af_alloc = 0;
00086   int af_size = 0;
00087   iGeom_getEntAdj(geom, volume, iBase_FACE, &all_faces, &af_alloc,
00088                 &af_size, &err);
00089   CHECK("Failed to get faces.");
00090 
00091   // This is a check that is always applicable for a brick.
00092   // Check that the face sense relative to the brick is FORWARD if the normal
00093   // points outward and REVERSED if the normal points inward
00094   for (i = 0; i < af_size; i++) { // for all faces
00095     // get face sense compared by volume
00096     int face_sense;
00097     iGeom_getEntNrmlSense(geom, all_faces[i], volume, &face_sense, &err);
00098     CHECK("Failed to get face sense.");
00099     if (0==face_sense)
00100       continue; // this is introduced because for facets we do not easily define face orientation
00101     double clsstX, clsstY, clsstZ, nrmlX, nrmlY, nrmlZ;
00102     iGeom_getEntNrmlPlXYZ(geom, all_faces[i], cntrX, cntrY, cntrZ,
00103         &clsstX, &clsstY, &clsstZ, &nrmlX, &nrmlY, &nrmlZ, &err);
00104     CHECK("Failed to get closest point and normal direction.");
00105     double dotPrdct = nrmlX * (cntrX - clsstX) + nrmlY * (cntrY - clsstY)
00106         + nrmlZ * (cntrZ - clsstZ);
00107     int normalDir = 1;
00108     if (dotPrdct > 0) // normal is same dir as vector from closest to center
00109       normalDir = -1;
00110 
00111     // check that face sense is forward if the normal points outward from
00112     // the brick and reversed if the normal points inward
00113     if (face_sense != normalDir) {
00114       std::cerr << "Error: face sense does not match direction of normal."
00115           << std::endl;
00116       return 1;
00117     }
00118   }
00119 
00120   err = checkEdgeOrientation(geom, volume);
00121   if (err)
00122     return err;
00123 
00124 #if defined (HAVE_OCC)
00125   input_file = STRINGIFY(SRCDIR)"/";
00126   input_file  += FILE_NAME1;
00127   iGeom_deleteAll(geom, &err);
00128   iGeom_load(geom, input_file.c_str(), 0, &err, input_file.length(), 0);
00129   CHECK( "ERROR : can not load a geometry" );
00130   err = getFirstVolume(geom, volume);
00131   if (err)
00132     return err;
00133   err = checkEdgeOrientation(geom, volume);
00134   if (err)
00135     return err;
00136 
00137 
00138   input_file = STRINGIFY(SRCDIR)"/";
00139   input_file += FILE_NAME2;
00140   iGeom_deleteAll(geom, &err);
00141   iGeom_load(geom, input_file.c_str(), 0, &err, input_file.length(), 0);
00142   CHECK( "ERROR : can not load a geometry" );
00143   err = getFirstVolume(geom, volume);
00144   if (err)
00145     return err;
00146   err = checkEdgeOrientation(geom, volume);
00147   if (err)
00148     return err;
00149 
00150   input_file = STRINGIFY(SRCDIR)"/";
00151   input_file += FILE_NAME3;
00152   iGeom_deleteAll(geom, &err);
00153   iGeom_load(geom, input_file.c_str(), 0, &err, input_file.length(), 0);
00154   CHECK( "ERROR : can not load a geometry" );
00155   err = getFirstVolume(geom, volume);
00156   if (err)
00157     return err;
00158   err = checkEdgeOrientation(geom, volume);
00159   if (err)
00160     return err;
00161 #endif
00162 
00163   std::cout << "All tests are passed." << std::endl;
00164 
00165   return 0;
00166 }
00167 
00168 int getFirstVolume(iGeom_Instance geom, iBase_EntityHandle & volume)
00169 {
00170   int err;
00171 
00172   iBase_EntitySetHandle root_set;
00173   iGeom_getRootSet(geom, &root_set, &err);
00174   CHECK("Failed to get root set.");
00175   
00176   // get the (first) volume
00177   iBase_EntityHandle* vols = NULL;
00178   int v_alloc = 0;
00179   int v_size = 0;
00180   iGeom_getEntities(geom, root_set, iBase_REGION, &vols,
00181                     &v_alloc, &v_size, &err);
00182   CHECK("Failed to get volumes.");
00183 
00184   volume = vols[0];
00185 
00186   return 0;
00187 }
00188 
00189 int checkEdgeOrientation(iGeom_Instance geom, iBase_EntityHandle & volume)
00190 {
00191 
00192   int i, j, err;
00193 
00194   // get all edges
00195   iBase_EntityHandle* edges = NULL;
00196   int e_alloc = 0;
00197   int e_size = 0;
00198   iGeom_getEntAdj(geom, volume, iBase_EDGE, &edges, &e_alloc,
00199                   &e_size, &err);
00200   CHECK("Failed to get edges.");
00201 
00202   // Check that the edge senses to the two parent faces, each multiplied by
00203   // its parent face's sense to the volume, should be opposite
00204   for (i = 0; i < e_size; i++) { // for all edges
00205     // get parent faces 
00206     iBase_EntityHandle* faces = NULL;
00207     int f_alloc = 0;
00208     int f_size = 0;
00209     iGeom_getEntAdj(geom, edges[i], iBase_FACE, &faces, &f_alloc,
00210                     &f_size, &err);
00211     CHECK("Failed to get edges.");
00212 
00213     // check if # of parent faces of the edges on the volume is 2
00214     if (f_size != 2) {
00215       std::cerr << "Error: # of parent faces of solid edges should be 2."
00216           << std::endl;
00217       return 1;
00218     }
00219 
00220     // compute the edge to volume senses by multiplying the edge to face sense
00221     // by the parent face sense with respect to the volume.
00222     int face_sense;
00223     int sense[2];
00224     for (j = 0; j < 2; j++) {
00225       iGeom_getEgFcSense(geom, edges[i], faces[j], &sense[j], &err);
00226       CHECK("Failed to get edge to face sense.");
00227       iGeom_getEntNrmlSense(geom, faces[j], volume, &face_sense, &err);
00228       CHECK("Failed to get face to volume sense.");
00229       if(0!=face_sense)
00230         sense[j] *= face_sense;
00231     }
00232     
00233     // check if the edge to volume senses are opposite
00234     if (sense[0]*sense[1] != -1) {
00235       std::cerr << "Error: Edge senses to 2 parent faces should be opposite."
00236           << std::endl;
00237       return 1;
00238     }
00239   }
00240 
00241   std::cout << "Verified opposite edge to face senses for " << e_size
00242       << " edges." << std::endl;
00243 
00244   return 0;
00245 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines