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