Branch data Line data Source code
1 : : #include "iGeom.h"
2 : : #include "RefEntity.hpp"
3 : : #include "RefFace.hpp"
4 : : #include "RefEdge.hpp"
5 : : #include "RefVertex.hpp"
6 : : #include "Body.hpp"
7 : : #include "CubitVector.hpp"
8 : : #include "ModelQueryEngine.hpp"
9 : : #include "GeometryQueryTool.hpp"
10 : : #include <iostream>
11 : : #define CHECK( STR ) if (err != iBase_SUCCESS) return print_error( STR, err, geom, __FILE__, __LINE__ )
12 : :
13 : : #if defined (HAVE_OCC)
14 : : # define ENGINE "OCC"
15 : : # define FORMAT "OCC"
16 : : # define FILE_NAME "brick_2.stp"
17 : : # define FILE_NAME1 "ilc_13body.stp"
18 : : # define FILE_NAME2 "ilc_1body.stp"
19 : : # define FILE_NAME3 "ilc_problem_surf8.stp"
20 : : #else
21 : : # define ENGINE "FACET"
22 : : # define FORMAT "FACET"
23 : : # define FILE_NAME "brick.facet"
24 : : #endif
25 : :
26 : : #define STRINGIFY(S) XSTRINGIFY(S)
27 : : #define XSTRINGIFY(S) #S
28 : :
29 : : int getFirstVolume(iGeom_Instance geom, iBase_EntityHandle & volume);
30 : : int checkEdgeOrientation(iGeom_Instance geom, iBase_EntityHandle & volume);
31 : :
32 : 0 : static int print_error( const char* desc,
33 : : int err,
34 : : iGeom_Instance geom,
35 : : const char* file,
36 : : int line )
37 : : {
38 : : char buffer[1024];
39 [ # # ]: 0 : iGeom_getDescription( geom, buffer, sizeof(buffer) );
40 : 0 : buffer[sizeof(buffer)-1] = '\0';
41 : :
42 [ # # ][ # # ]: 0 : std::cerr << "ERROR: " << desc << std::endl
[ # # ]
43 [ # # ][ # # ]: 0 : << " Error code: " << err << std::endl
[ # # ]
44 [ # # ][ # # ]: 0 : << " Error desc: " << buffer << std::endl
[ # # ]
45 [ # # ][ # # ]: 0 : << " At : " << file << ':' << line << std::endl
[ # # ][ # # ]
46 [ # # ]: 0 : ;
47 : :
48 : 0 : return 1; // must always return false or CHECK macro will break
49 : : }
50 : :
51 : 1 : int main(int argc, char *argv[])
52 : : {
53 : : // initialize the Mesh
54 : : int i, err;
55 : : iGeom_Instance geom;
56 [ + - ]: 1 : std::string engine_opt = ";engine=";
57 [ + - ]: 1 : engine_opt += ENGINE;
58 [ + - ][ + - ]: 1 : iGeom_newGeom(engine_opt.c_str(), &geom, &err, engine_opt.length());
[ + - ]
59 : :
60 : : // read in the geometry file, which is the geometry of a brick
61 [ + - ][ + - ]: 2 : std::string input_file;
62 [ + - ]: 1 : input_file = STRINGIFY(SRCDIR)"/";
63 [ + - ]: 1 : input_file += FILE_NAME;
64 [ - + ]: 1 : if (argc>1)
65 [ # # ]: 0 : input_file = argv[1];
66 [ + - ][ + - ]: 1 : iGeom_load(geom, input_file.c_str(), 0, &err, input_file.length(), 0);
[ + - ]
67 [ - + ][ # # ]: 1 : CHECK( "ERROR : can not load a geometry" );
68 : :
69 : : iBase_EntityHandle volume;
70 [ + - ]: 1 : err = getFirstVolume(geom, volume);
71 [ - + ]: 1 : if (err)
72 : 0 : return err;
73 : :
74 : : // get the bounding box of the brick and calculate its approximate center
75 : : double minX, minY, minZ, maxX, maxY, maxZ;
76 : : iGeom_getEntBoundBox(geom, volume, &minX, &minY, &minZ,
77 [ + - ]: 1 : &maxX, &maxY, &maxZ, &err);
78 [ - + ][ # # ]: 1 : CHECK("Failed to get bounding box.");
79 : 1 : double cntrX = (minX + maxX) / 2.0;
80 : 1 : double cntrY = (minY + maxY) / 2.0;
81 : 1 : double cntrZ = (minZ + maxZ) / 2.0;
82 : :
83 : : // get brick faces
84 : 1 : iBase_EntityHandle* all_faces = NULL;
85 : 1 : int af_alloc = 0;
86 : 1 : int af_size = 0;
87 : : iGeom_getEntAdj(geom, volume, iBase_FACE, &all_faces, &af_alloc,
88 [ + - ]: 1 : &af_size, &err);
89 [ - + ][ # # ]: 1 : CHECK("Failed to get faces.");
90 : :
91 : : // This is a check that is always applicable for a brick.
92 : : // Check that the face sense relative to the brick is FORWARD if the normal
93 : : // points outward and REVERSED if the normal points inward
94 [ + + ]: 7 : for (i = 0; i < af_size; i++) { // for all faces
95 : : // get face sense compared by volume
96 : : int face_sense;
97 [ + - ]: 6 : iGeom_getEntNrmlSense(geom, all_faces[i], volume, &face_sense, &err);
98 [ - + ][ # # ]: 6 : CHECK("Failed to get face sense.");
99 [ - + ]: 6 : if (0==face_sense)
100 : 0 : continue; // this is introduced because for facets we do not easily define face orientation
101 : : double clsstX, clsstY, clsstZ, nrmlX, nrmlY, nrmlZ;
102 : 6 : iGeom_getEntNrmlPlXYZ(geom, all_faces[i], cntrX, cntrY, cntrZ,
103 [ + - ]: 6 : &clsstX, &clsstY, &clsstZ, &nrmlX, &nrmlY, &nrmlZ, &err);
104 [ - + ][ # # ]: 6 : CHECK("Failed to get closest point and normal direction.");
105 : 6 : double dotPrdct = nrmlX * (cntrX - clsstX) + nrmlY * (cntrY - clsstY)
106 : 6 : + nrmlZ * (cntrZ - clsstZ);
107 : 6 : int normalDir = 1;
108 [ + + ]: 6 : if (dotPrdct > 0) // normal is same dir as vector from closest to center
109 : 5 : normalDir = -1;
110 : :
111 : : // check that face sense is forward if the normal points outward from
112 : : // the brick and reversed if the normal points inward
113 [ - + ]: 6 : if (face_sense != normalDir) {
114 [ # # ]: 0 : std::cerr << "Error: face sense does not match direction of normal."
115 [ # # ]: 0 : << std::endl;
116 : 6 : return 1;
117 : : }
118 : : }
119 : :
120 [ + - ]: 1 : err = checkEdgeOrientation(geom, volume);
121 [ - + ]: 1 : if (err)
122 : 0 : return err;
123 : :
124 : : #if defined (HAVE_OCC)
125 [ + - ]: 1 : input_file = STRINGIFY(SRCDIR)"/";
126 [ + - ]: 1 : input_file += FILE_NAME1;
127 [ + - ]: 1 : iGeom_deleteAll(geom, &err);
128 [ + - ][ + - ]: 1 : iGeom_load(geom, input_file.c_str(), 0, &err, input_file.length(), 0);
[ + - ]
129 [ - + ][ # # ]: 1 : CHECK( "ERROR : can not load a geometry" );
130 [ + - ]: 1 : err = getFirstVolume(geom, volume);
131 [ - + ]: 1 : if (err)
132 : 0 : return err;
133 [ + - ]: 1 : err = checkEdgeOrientation(geom, volume);
134 [ - + ]: 1 : if (err)
135 : 0 : return err;
136 : :
137 : :
138 [ + - ]: 1 : input_file = STRINGIFY(SRCDIR)"/";
139 [ + - ]: 1 : input_file += FILE_NAME2;
140 [ + - ]: 1 : iGeom_deleteAll(geom, &err);
141 [ + - ][ + - ]: 1 : iGeom_load(geom, input_file.c_str(), 0, &err, input_file.length(), 0);
[ + - ]
142 [ - + ][ # # ]: 1 : CHECK( "ERROR : can not load a geometry" );
143 [ + - ]: 1 : err = getFirstVolume(geom, volume);
144 [ - + ]: 1 : if (err)
145 : 0 : return err;
146 [ + - ]: 1 : err = checkEdgeOrientation(geom, volume);
147 [ - + ]: 1 : if (err)
148 : 0 : return err;
149 : :
150 [ + - ]: 1 : input_file = STRINGIFY(SRCDIR)"/";
151 [ + - ]: 1 : input_file += FILE_NAME3;
152 [ + - ]: 1 : iGeom_deleteAll(geom, &err);
153 [ + - ][ + - ]: 1 : iGeom_load(geom, input_file.c_str(), 0, &err, input_file.length(), 0);
[ + - ]
154 [ - + ][ # # ]: 1 : CHECK( "ERROR : can not load a geometry" );
155 [ + - ]: 1 : err = getFirstVolume(geom, volume);
156 [ - + ]: 1 : if (err)
157 : 0 : return err;
158 [ + - ]: 1 : err = checkEdgeOrientation(geom, volume);
159 [ - + ]: 1 : if (err)
160 : 0 : return err;
161 : : #endif
162 : :
163 [ + - ][ + - ]: 1 : std::cout << "All tests are passed." << std::endl;
164 : :
165 [ + - ]: 2 : return 0;
166 : : }
167 : :
168 : 4 : int getFirstVolume(iGeom_Instance geom, iBase_EntityHandle & volume)
169 : : {
170 : : int err;
171 : :
172 : : iBase_EntitySetHandle root_set;
173 [ + - ]: 4 : iGeom_getRootSet(geom, &root_set, &err);
174 [ - + ][ # # ]: 4 : CHECK("Failed to get root set.");
175 : :
176 : : // get the (first) volume
177 : 4 : iBase_EntityHandle* vols = NULL;
178 : 4 : int v_alloc = 0;
179 : 4 : int v_size = 0;
180 : : iGeom_getEntities(geom, root_set, iBase_REGION, &vols,
181 [ + - ]: 4 : &v_alloc, &v_size, &err);
182 [ - + ][ # # ]: 4 : CHECK("Failed to get volumes.");
183 : :
184 : 4 : volume = vols[0];
185 : :
186 : 4 : return 0;
187 : : }
188 : :
189 : 4 : int checkEdgeOrientation(iGeom_Instance geom, iBase_EntityHandle & volume)
190 : : {
191 : :
192 : : int i, j, err;
193 : :
194 : : // get all edges
195 : 4 : iBase_EntityHandle* edges = NULL;
196 : 4 : int e_alloc = 0;
197 : 4 : int e_size = 0;
198 : : iGeom_getEntAdj(geom, volume, iBase_EDGE, &edges, &e_alloc,
199 [ + - ]: 4 : &e_size, &err);
200 [ - + ][ # # ]: 4 : CHECK("Failed to get edges.");
201 : :
202 : : // Check that the edge senses to the two parent faces, each multiplied by
203 : : // its parent face's sense to the volume, should be opposite
204 [ + + ]: 344 : for (i = 0; i < e_size; i++) { // for all edges
205 : : // get parent faces
206 : 340 : iBase_EntityHandle* faces = NULL;
207 : 340 : int f_alloc = 0;
208 : 340 : int f_size = 0;
209 : 340 : iGeom_getEntAdj(geom, edges[i], iBase_FACE, &faces, &f_alloc,
210 [ + - ]: 340 : &f_size, &err);
211 [ - + ][ # # ]: 340 : CHECK("Failed to get edges.");
212 : :
213 : : // check if # of parent faces of the edges on the volume is 2
214 [ - + ]: 340 : if (f_size != 2) {
215 [ # # ]: 0 : std::cerr << "Error: # of parent faces of solid edges should be 2."
216 [ # # ]: 0 : << std::endl;
217 : 0 : return 1;
218 : : }
219 : :
220 : : // compute the edge to volume senses by multiplying the edge to face sense
221 : : // by the parent face sense with respect to the volume.
222 : : int face_sense;
223 : : int sense[2];
224 [ + + ]: 1020 : for (j = 0; j < 2; j++) {
225 [ + - ]: 680 : iGeom_getEgFcSense(geom, edges[i], faces[j], &sense[j], &err);
226 [ - + ][ # # ]: 680 : CHECK("Failed to get edge to face sense.");
227 [ + - ]: 680 : iGeom_getEntNrmlSense(geom, faces[j], volume, &face_sense, &err);
228 [ - + ][ # # ]: 680 : CHECK("Failed to get face to volume sense.");
229 [ + - ]: 680 : if(0!=face_sense)
230 : 680 : sense[j] *= face_sense;
231 : : }
232 : :
233 : : // check if the edge to volume senses are opposite
234 [ - + ]: 340 : if (sense[0]*sense[1] != -1) {
235 [ # # ]: 0 : std::cerr << "Error: Edge senses to 2 parent faces should be opposite."
236 [ # # ]: 0 : << std::endl;
237 : 0 : return 1;
238 : : }
239 : : }
240 : :
241 [ + - ][ + - ]: 4 : std::cout << "Verified opposite edge to face senses for " << e_size
242 [ + - ][ + - ]: 4 : << " edges." << std::endl;
243 : :
244 : 4 : return 0;
245 [ + - ][ + - ]: 4 : }
|