Branch data Line data Source code
1 : : //----------------------------------------------------------
2 : : //Class: GeomMeasureTool
3 : : //Description: Does Geometric measureing and statistical
4 : : // gathering on various topologies.
5 : : //Creator: David R. White
6 : : //Date: 7/9/2002
7 : : //----------------------------------------------------------
8 : :
9 : :
10 : : #include "GeomMeasureTool.hpp"
11 : : #include "RefEntity.hpp"
12 : : #include "RefVertex.hpp"
13 : : #include "RefEdge.hpp"
14 : : #include "RefFace.hpp"
15 : : #include "RefVolume.hpp"
16 : : #include "Body.hpp"
17 : : #include "RefGroup.hpp"
18 : : #include "RefEntityFactory.hpp"
19 : : #include "CoEdge.hpp"
20 : : #include "Loop.hpp"
21 : : #include "Shell.hpp"
22 : : #include "Chain.hpp"
23 : : #include "CastTo.hpp"
24 : : #include "GMem.hpp"
25 : : #include "Curve.hpp"
26 : : #include "Surface.hpp"
27 : : #include "GeometryQueryEngine.hpp"
28 : : #include "GeomSeg.hpp"
29 : : #include "GeomPoint.hpp"
30 : : #include "RTree.hpp"
31 : : #include "AbstractTree.hpp"
32 : : #include "IntersectionTool.hpp"
33 : : #include "CpuTimer.hpp"
34 : : #include "GeometryQueryTool.hpp"
35 : : #include "GeometryModifyTool.hpp"
36 : : #include "MergeTool.hpp"
37 : : #include "GeomDataObserver.hpp"
38 : : #include "Lump.hpp"
39 : : #include "ModelQueryEngine.hpp"
40 : : #include "ProgressTool.hpp"
41 : : #include "AppUtil.hpp"
42 : :
43 : : #include <set>
44 : : #include <map>
45 : : #include <stack>
46 : : #include <algorithm>
47 : :
48 : 0 : void GeomMeasureTool::get_edges_from_list(DLIList <RefEntity*> &entity_list,
49 : : DLIList <RefEdge*> &ref_edges )
50 : : {
51 : : //assume the mark is zero.
52 : : int ii,jj;
53 : : RefEntity *entity_ptr;
54 : : RefEdge *ref_edge;
55 : :
56 : : TopologyEntity *topo_ent;
57 [ # # ]: 0 : DLIList <RefEdge*> tmp_edges;
58 [ # # ][ # # ]: 0 : for ( ii = entity_list.size(); ii > 0; ii-- )
59 : : {
60 [ # # ]: 0 : tmp_edges.clean_out();
61 [ # # ]: 0 : entity_ptr = entity_list.get_and_step();
62 [ # # ]: 0 : topo_ent = CAST_TO(entity_ptr, TopologyEntity);
63 [ # # ]: 0 : if ( topo_ent == NULL )
64 : 0 : continue;
65 [ # # ]: 0 : topo_ent->ref_edges(tmp_edges);
66 [ # # ][ # # ]: 0 : for ( jj = tmp_edges.size(); jj > 0; jj-- )
67 : : {
68 [ # # ]: 0 : ref_edge = tmp_edges.pop();
69 [ # # ][ # # ]: 0 : if ( !ref_edge->marked() )
70 : : {
71 [ # # ]: 0 : ref_edge->marked(1);
72 [ # # ]: 0 : ref_edges.append(ref_edge);
73 : : }
74 : : }
75 : : }
76 [ # # ][ # # ]: 0 : for ( ii = ref_edges.size(); ii > 0; ii-- )
77 [ # # ][ # # ]: 0 : ref_edges.get_and_step()->marked(0);
[ # # ]
78 : 0 : }
79 : :
80 : 0 : void GeomMeasureTool::get_bodies_from_list(DLIList <RefVolume*> &entity_list,
81 : : DLIList <Body*> &ref_bodies )
82 : : {
83 : : //assume the mark is zero.
84 : : int ii, jj;
85 : : RefVolume *entity_ptr;
86 : : Body *ref_body;
87 : :
88 : : TopologyEntity *topo_ent;
89 [ # # ]: 0 : DLIList <Body*> tmp_bodies;
90 [ # # ][ # # ]: 0 : for ( ii = entity_list.size(); ii > 0; ii-- )
91 : : {
92 [ # # ]: 0 : tmp_bodies.clean_out();
93 [ # # ]: 0 : entity_ptr = entity_list.get_and_step();
94 : 0 : topo_ent = CAST_TO(entity_ptr, TopologyEntity);
95 [ # # ]: 0 : if ( topo_ent == NULL )
96 : 0 : continue;
97 [ # # ]: 0 : topo_ent->bodies(tmp_bodies);
98 [ # # ][ # # ]: 0 : for ( jj = tmp_bodies.size(); jj > 0; jj-- )
99 : : {
100 [ # # ]: 0 : ref_body = tmp_bodies.pop();
101 [ # # ][ # # ]: 0 : if ( !ref_body->marked() )
102 : : {
103 [ # # ]: 0 : ref_body->marked(1);
104 [ # # ]: 0 : ref_bodies.append(ref_body);
105 : : }
106 : : }
107 : : }
108 [ # # ][ # # ]: 0 : for ( ii = ref_bodies.size(); ii > 0; ii-- )
109 [ # # ][ # # ]: 0 : ref_bodies.get_and_step()->marked(0);
[ # # ]
110 : 0 : }
111 : :
112 : 0 : void GeomMeasureTool::get_faces_from_list(DLIList <RefEntity*> &entity_list,
113 : : DLIList <RefFace*> &ref_faces )
114 : : {
115 : : //assume the mark is zero.
116 : : int ii,jj;
117 : : RefEntity *entity_ptr;
118 : : RefFace *ref_face;
119 : :
120 : : TopologyEntity *topo_ent;
121 [ # # ]: 0 : DLIList <RefFace*> tmp_faces;
122 [ # # ][ # # ]: 0 : for ( ii = entity_list.size(); ii > 0; ii-- )
123 : : {
124 [ # # ]: 0 : tmp_faces.clean_out();
125 [ # # ]: 0 : entity_ptr = entity_list.get_and_step();
126 [ # # ]: 0 : topo_ent = CAST_TO(entity_ptr, TopologyEntity);
127 [ # # ]: 0 : topo_ent->ref_faces(tmp_faces);
128 [ # # ][ # # ]: 0 : for ( jj = tmp_faces.size(); jj > 0; jj-- )
129 : : {
130 [ # # ]: 0 : ref_face = tmp_faces.pop();
131 [ # # ][ # # ]: 0 : if ( !ref_face->marked() )
132 : : {
133 [ # # ]: 0 : ref_face->marked(1);
134 [ # # ]: 0 : ref_faces.append(ref_face);
135 : : }
136 : : }
137 : : }
138 [ # # ][ # # ]: 0 : for ( ii = ref_faces.size(); ii > 0; ii-- )
139 [ # # ][ # # ]: 0 : ref_faces.get_and_step()->marked(0);
[ # # ]
140 : 0 : }
141 : 0 : void GeomMeasureTool::get_volumes_from_list(DLIList <RefEntity*> &entity_list,
142 : : DLIList <RefVolume*> &ref_volumes )
143 : : {
144 : : //assume the mark is zero.
145 : : int ii,jj;
146 : : RefEntity *entity_ptr;
147 : : RefVolume *ref_volume;
148 : :
149 : : TopologyEntity *topo_ent;
150 [ # # ]: 0 : DLIList <RefVolume*> tmp_volumes;
151 [ # # ][ # # ]: 0 : for ( ii = entity_list.size(); ii > 0; ii-- )
152 : : {
153 [ # # ]: 0 : tmp_volumes.clean_out();
154 [ # # ]: 0 : entity_ptr = entity_list.get_and_step();
155 [ # # ]: 0 : topo_ent = CAST_TO(entity_ptr, TopologyEntity);
156 [ # # ]: 0 : topo_ent->ref_volumes(tmp_volumes);
157 [ # # ][ # # ]: 0 : for ( jj = tmp_volumes.size(); jj > 0; jj-- )
158 : : {
159 [ # # ]: 0 : ref_volume = tmp_volumes.pop();
160 [ # # ][ # # ]: 0 : if ( !ref_volume->marked() )
161 : : {
162 [ # # ]: 0 : ref_volume->marked(1);
163 [ # # ]: 0 : ref_volumes.append(ref_volume);
164 : : }
165 : : }
166 : : }
167 [ # # ][ # # ]: 0 : for ( ii = ref_volumes.size(); ii > 0; ii-- )
168 [ # # ][ # # ]: 0 : ref_volumes.get_and_step()->marked(0);
[ # # ]
169 : 0 : }
170 : 0 : void GeomMeasureTool::measure_curve_length(DLIList <RefEntity*> &entity_list,
171 : : double &smallest,
172 : : RefEdge *&smallest_edge,
173 : : double &largest,
174 : : RefEdge *&largest_edge,
175 : : double &average,
176 : : double &sum)
177 : : {
178 [ # # ]: 0 : DLIList<RefEdge*> ref_edges;
179 [ # # ]: 0 : get_edges_from_list(entity_list, ref_edges);
180 : : measure_curve_length(ref_edges, smallest, smallest_edge,
181 [ # # ][ # # ]: 0 : largest, largest_edge, average, sum);
182 : :
183 : 0 : }
184 : :
185 : 0 : void GeomMeasureTool::measure_curve_length(DLIList <RefEdge*> &ref_edges,
186 : : double &smallest,
187 : : RefEdge *&smallest_edge,
188 : : double &largest,
189 : : RefEdge *&largest_edge,
190 : : double &average,
191 : : double &sum)
192 : : {
193 : : int ii;
194 : 0 : double curr_length, total_length = 0.0;
195 : 0 : smallest = CUBIT_DBL_MAX;
196 : 0 : largest = 0.0;
197 : : RefEdge *curr_edge;
198 [ # # ]: 0 : for ( ii = ref_edges.size(); ii > 0; ii-- )
199 : : {
200 : 0 : curr_edge = ref_edges.get_and_step();
201 [ # # ]: 0 : if( curr_edge->geometry_type() == POINT_CURVE_TYPE )
202 : 0 : continue;
203 : 0 : curr_length = curr_edge->measure();
204 [ # # ]: 0 : if ( curr_length < smallest )
205 : : {
206 : 0 : smallest = curr_length;
207 : 0 : smallest_edge = curr_edge;
208 : : }
209 [ # # ]: 0 : if ( curr_length > largest )
210 : : {
211 : 0 : largest = curr_length;
212 : 0 : largest_edge = curr_edge;
213 : : }
214 : 0 : total_length += curr_length;
215 : : }
216 [ # # ]: 0 : if ( ref_edges.size() != 0 )
217 : 0 : average = total_length/ref_edges.size();
218 : 0 : sum = total_length;
219 : :
220 : 0 : }
221 : 0 : void GeomMeasureTool::measure_face_curves( RefFace *ref_face,
222 : : double &min_curve_length,
223 : : double &max_curve_ratio,
224 : : RefEdge *&min_ref_edge)
225 : : {
226 [ # # ]: 0 : DLIList<DLIList<CoEdge*> > co_edge_loops;
227 [ # # ]: 0 : ref_face->co_edge_loops(co_edge_loops);
228 : : CoEdge *curr_co_edge, *next_co_edge;
229 : 0 : min_curve_length = CUBIT_DBL_MAX;
230 : : double curve_length, next_curve_length, ratio;
231 : 0 : max_curve_ratio = -CUBIT_DBL_MAX;
232 : 0 : CubitBoolean ratio_set = CUBIT_FALSE;
233 : : int ii, jj;
234 [ # # ][ # # ]: 0 : for ( ii = co_edge_loops.size(); ii > 0; ii-- )
235 : : {
236 [ # # ]: 0 : DLIList <CoEdge*> &co_edge_list = co_edge_loops.get_and_step();
237 [ # # ][ # # ]: 0 : curve_length = co_edge_list.get()->get_ref_edge_ptr()->measure();
[ # # ]
238 [ # # ][ # # ]: 0 : for ( jj = co_edge_list.size(); jj > 0; jj-- )
239 : : {
240 [ # # ]: 0 : curr_co_edge = co_edge_list.get_and_step();
241 [ # # ]: 0 : next_co_edge = co_edge_list.get();
242 [ # # ][ # # ]: 0 : next_curve_length = next_co_edge->get_ref_edge_ptr()->measure();
243 : : //find the smallest curve
244 [ # # ]: 0 : if ( curve_length < min_curve_length )
245 : : {
246 : 0 : min_curve_length = curve_length;
247 [ # # ]: 0 : min_ref_edge = curr_co_edge->get_ref_edge_ptr();
248 : : }
249 [ # # ][ # # ]: 0 : if ( co_edge_list.size() > 1 )
250 : : {
251 : : //find the biggest change in curve lengths.
252 [ # # ]: 0 : if ( curve_length > next_curve_length )
253 : : {
254 [ # # ]: 0 : if ( next_curve_length < CUBIT_RESABS )
255 : 0 : ratio = CUBIT_DBL_MAX;
256 : : else
257 : 0 : ratio = curve_length / next_curve_length;
258 : : }
259 : : else
260 : : {
261 [ # # ]: 0 : if ( curve_length < CUBIT_RESABS )
262 : 0 : ratio = CUBIT_DBL_MAX;
263 : : else
264 : 0 : ratio = next_curve_length /curve_length;
265 : : }
266 : 0 : curve_length = next_curve_length;
267 [ # # ]: 0 : if ( ratio > max_curve_ratio )
268 : : {
269 : 0 : ratio_set = CUBIT_TRUE;
270 : 0 : max_curve_ratio = ratio;
271 : : }
272 : : }
273 : : }
274 : : }
275 [ # # ]: 0 : if ( !ratio_set )
276 [ # # ]: 0 : max_curve_ratio = -1.0;
277 : 0 : }
278 : :
279 : :
280 : :
281 : :
282 : 0 : CubitStatus GeomMeasureTool::measure_face_loops( RefFace *face,
283 : : double &min_distance_between_loops,
284 : : double &min_distance_in_one_loop,
285 : : double &min_angle,
286 : : double &max_angle,
287 : : double tolerance)
288 : : {
289 : : //This is the most tricky of these functions.
290 : : //To do this I'm going to facet the edges, then use an AbstractTree to
291 : : //find the minimum distance between the loops and between a single
292 : : //loop.
293 [ # # ]: 0 : PointLoopList boundary_point_loops;
294 : : CubitStatus stat;
295 [ # # ]: 0 : stat = get_boundary_points(face, boundary_point_loops, tolerance);
296 [ # # ]: 0 : if ( stat != CUBIT_SUCCESS )
297 : 0 : return CUBIT_FAILURE;
298 : :
299 [ # # ][ # # ]: 0 : SegLoopList boundary_seg_loops;
300 : : stat = convert_to_lines( boundary_point_loops,
301 : : boundary_seg_loops,
302 [ # # ]: 0 : face);
303 [ # # ]: 0 : if ( stat != CUBIT_SUCCESS )
304 : 0 : return stat;
305 : :
306 : : //Now add the points to the AbstractTree.
307 [ # # ][ # # ]: 0 : DLIList<AbstractTree<GeomSeg*>*> atree_list;
308 : : AbstractTree<GeomSeg*> *curr_tree;
309 : : SegList *seg_list;
310 : : GeomSeg *curr_seg, *next_seg;
311 : : int ii,jj, kk;
312 : : double angle;
313 : 0 : min_angle = CUBIT_DBL_MAX;
314 : 0 : max_angle = 0.0;
315 : 0 : double creation_time=0.0;
316 [ # # ]: 0 : CpuTimer creation_timer;
317 : 0 : const double angle_convert = 180.0/CUBIT_PI;
318 [ # # ]: 0 : boundary_seg_loops.reset();
319 : 0 : int num_segs = 0;
320 [ # # ][ # # ]: 0 : for (ii = 0; ii < boundary_seg_loops.size(); ii++ )
321 : : {
322 [ # # ]: 0 : seg_list = boundary_seg_loops.get_and_step();
323 [ # # ]: 0 : creation_timer.cpu_secs();
324 [ # # ][ # # ]: 0 : curr_tree = new RTree<GeomSeg*>(GEOMETRY_RESABS);
325 [ # # ]: 0 : creation_time += creation_timer.cpu_secs();
326 [ # # ][ # # ]: 0 : for ( jj = seg_list->size(); jj > 0; jj-- )
327 : : {
328 : : //build the r-tree.
329 : 0 : num_segs++;
330 [ # # ]: 0 : creation_timer.cpu_secs();
331 [ # # ]: 0 : curr_seg = seg_list->get_and_step();
332 [ # # ]: 0 : curr_tree->add(curr_seg);
333 [ # # ]: 0 : creation_time += creation_timer.cpu_secs();
334 : : //calculate the interior angles.
335 [ # # ]: 0 : next_seg = seg_list->get();
336 : :
337 [ # # ][ # # ]: 0 : RefEntity* temp_ent = curr_seg->get_end()->owner();
338 : : //only measure the angle at vertices. This
339 : : //should make things slightly faster.
340 [ # # ][ # # ]: 0 : if ( CAST_TO(temp_ent, RefVertex) )
[ # # ]
341 : : {
342 : : stat = interior_angle(curr_seg, next_seg,
343 [ # # ]: 0 : face, angle);
344 [ # # ]: 0 : if ( stat != CUBIT_SUCCESS )
345 : : {
346 : 0 : min_angle = 0.0;
347 : 0 : max_angle = 360.0;
348 : : }
349 [ # # ]: 0 : else if ( angle < min_angle )
350 : : {
351 : 0 : min_angle = angle;
352 : : }
353 [ # # ]: 0 : else if ( angle > max_angle )
354 : : {
355 : 0 : max_angle = angle;
356 : : }
357 : : }
358 : : }
359 [ # # ]: 0 : atree_list.append(curr_tree);
360 : : }
361 : 0 : min_angle *= angle_convert;
362 : 0 : max_angle *= angle_convert;
363 : :
364 [ # # ][ # # ]: 0 : if ( atree_list.size() <= 1 )
365 : 0 : min_distance_between_loops = -1.0;
366 : : else
367 : : {
368 : : //determine the minimum distance between the loops.
369 [ # # ]: 0 : CpuTimer atree_time;
370 [ # # ]: 0 : atree_time.cpu_secs();
371 : : PointList *curr_points;
372 : : GeomPoint *curr_point;
373 [ # # ]: 0 : DLIList <GeomSeg*> nearest_neighbors;
374 : :
375 [ # # ]: 0 : CubitVector curr_loc;
376 : : double closest_dist;
377 : 0 : min_distance_between_loops = CUBIT_DBL_MAX;
378 [ # # ]: 0 : atree_list.reset();
379 [ # # ][ # # ]: 0 : for ( ii = 0; ii < atree_list.size(); ii++ )
380 : : {
381 [ # # ]: 0 : curr_points = boundary_point_loops.get_and_step();
382 [ # # ][ # # ]: 0 : for ( jj = ii+1; jj < atree_list.size(); jj++ )
383 : : {
384 [ # # ]: 0 : curr_tree = atree_list.next(jj);
385 : : //now for every point in curr_points, find it's closest_point
386 : : //in the curr_tree.
387 [ # # ][ # # ]: 0 : for ( kk = 0; kk < curr_points->size(); kk++ )
388 : : {
389 [ # # ]: 0 : curr_point = curr_points->get_and_step();
390 [ # # ][ # # ]: 0 : curr_loc.set(curr_point->coordinates());
391 [ # # ]: 0 : nearest_neighbors.clean_out();
392 : : curr_tree->k_nearest_neighbor(curr_loc,
393 : : 1, closest_dist, nearest_neighbors,
394 [ # # ]: 0 : dist_sq_point_data);
395 [ # # ][ # # ]: 0 : if ( nearest_neighbors.size() == 0)
396 : : {
397 : : //hmm, not sure what is wrong here.
398 [ # # ][ # # ]: 0 : PRINT_ERROR("Can't find closest point between loops.\n");
[ # # ][ # # ]
399 : 0 : return CUBIT_FAILURE;
400 : : }
401 [ # # ]: 0 : if (closest_dist < min_distance_between_loops)
402 : 0 : min_distance_between_loops = closest_dist;
403 : : }
404 : : }
405 : : }
406 [ # # ]: 0 : double time = atree_time.cpu_secs();
407 [ # # ][ # # ]: 0 : PRINT_DEBUG_139("Time to create atree: %f\n", creation_time);
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
408 [ # # ][ # # ]: 0 : PRINT_DEBUG_139("Time for atree nn search: %f\n", time);
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
409 : : }
410 [ # # ]: 0 : if ( min_distance_between_loops != -1.0 )
411 : 0 : min_distance_between_loops = sqrt(min_distance_between_loops);
412 : : //Now find the min distance inside a loop. This is tricky
413 : : //in that we want to find distances that are across some area
414 : : //and not just between adjacent curves.
415 [ # # ]: 0 : atree_list.reset();
416 : : GeomSeg *tmp_seg;
417 : : double dist;
418 : 0 : min_distance_in_one_loop = CUBIT_DBL_MAX;
419 : 0 : int k=5;
420 [ # # ]: 0 : CubitVector curr_loc;
421 [ # # ][ # # ]: 0 : DLIList <GeomSeg*> nearest_neighbors;
422 : : RefEntity *ent_1, *ent_2;
423 : : TopologyEntity *top_1, *top_2;
424 : :
425 : :
426 [ # # ][ # # ]: 0 : for ( ii = atree_list.size(); ii > 0; ii-- )
427 : : {
428 [ # # ]: 0 : curr_tree = atree_list.get_and_step();
429 [ # # ]: 0 : seg_list = boundary_seg_loops.get_and_step();
430 [ # # ][ # # ]: 0 : for ( jj = seg_list->size(); jj > 0; jj-- )
431 : : {
432 [ # # ]: 0 : nearest_neighbors.clean_out();
433 [ # # ]: 0 : curr_seg = seg_list->get_and_step();
434 : : //get the k closest segments.
435 [ # # ][ # # ]: 0 : curr_loc.set(curr_seg->get_start()->coordinates());
[ # # ]
436 : : curr_tree->k_nearest_neighbor(curr_loc,
437 : : k, dist, nearest_neighbors,
438 [ # # ]: 0 : dist_sq_point_data);
439 : : //go through these nearest_neighbors and through out
440 : : //the segments that are attached to curr_seg.
441 [ # # ][ # # ]: 0 : for ( kk = 0; kk < nearest_neighbors.size(); kk++ )
442 : : {
443 [ # # ]: 0 : tmp_seg = nearest_neighbors.get();
444 [ # # ][ # # ]: 0 : if ( tmp_seg == curr_seg ||
445 [ # # ][ # # ]: 0 : tmp_seg == curr_seg->get_prev() ||
[ # # ]
446 [ # # ]: 0 : tmp_seg == curr_seg->get_next() )
447 [ # # ]: 0 : nearest_neighbors.remove();
448 : : }
449 [ # # ][ # # ]: 0 : if ( nearest_neighbors.size() == 0 )
450 : 0 : continue;
451 : : //The min distance is the distance between the curr_loc
452 : : //and the top nearest_neighbor.
453 [ # # ]: 0 : nearest_neighbors.reset();
454 [ # # ]: 0 : tmp_seg = nearest_neighbors.get();
455 [ # # ]: 0 : ent_1 = tmp_seg->owner();
456 [ # # ][ # # ]: 0 : ent_2 = curr_seg->get_start()->owner();
457 [ # # ]: 0 : top_1 = CAST_TO(ent_1, TopologyEntity);
458 [ # # ]: 0 : top_2 = CAST_TO(ent_2, TopologyEntity);
459 : :
460 [ # # ][ # # ]: 0 : if ( top_1->is_directly_related(top_2) )
461 : 0 : continue;
462 : :
463 : : //we'll need to recompute it...
464 [ # # ]: 0 : dist = dist_sq_point_data(curr_loc, tmp_seg);
465 [ # # ]: 0 : if ( dist < min_distance_in_one_loop )
466 : 0 : min_distance_in_one_loop = dist;
467 : : }
468 : : }
469 [ # # ]: 0 : if ( min_distance_in_one_loop == CUBIT_DBL_MAX )
470 : : {
471 [ # # ]: 0 : ent_1 = (RefEntity*)face;
472 [ # # ]: 0 : DLIList<RefEntity*> entities;
473 [ # # ]: 0 : entities.append(ent_1);
474 : : double smallest, largest, ave, sum;
475 : : RefEdge *small_e, *large_e;
476 : : measure_curve_length(entities, smallest, small_e,
477 [ # # ]: 0 : largest, large_e, ave, sum);
478 [ # # ]: 0 : min_distance_in_one_loop = smallest;
479 : : }
480 : : else
481 : 0 : min_distance_in_one_loop = sqrt(min_distance_in_one_loop);
482 : : //clean up the memory.
483 : : int ll,mm;
484 [ # # ]: 0 : atree_list.reset();
485 [ # # ]: 0 : boundary_seg_loops.reset();
486 [ # # ][ # # ]: 0 : for ( ll = boundary_seg_loops.size(); ll > 0; ll-- )
487 : : {
488 [ # # ][ # # ]: 0 : delete atree_list.pop();
[ # # ]
489 [ # # ]: 0 : seg_list = boundary_seg_loops.pop();
490 [ # # ][ # # ]: 0 : for ( mm = seg_list->size(); mm > 0; mm-- )
491 [ # # ][ # # ]: 0 : delete seg_list->pop();
[ # # ]
492 [ # # ][ # # ]: 0 : delete seg_list;
493 : : }
494 : :
495 : : PointList *point_list;
496 [ # # ][ # # ]: 0 : for ( ll = boundary_point_loops.size(); ll > 0; ll-- )
497 : : {
498 [ # # ]: 0 : point_list = boundary_point_loops.pop();
499 [ # # ][ # # ]: 0 : for ( mm = point_list->size(); mm > 0; mm-- )
500 : : {
501 [ # # ]: 0 : GeomPoint *tmp_point = point_list->pop();
502 : : //delete the CubitPointData
503 [ # # ][ # # ]: 0 : delete tmp_point;
504 : : }
505 [ # # ][ # # ]: 0 : delete point_list;
506 : : }
507 [ # # ]: 0 : return CUBIT_SUCCESS;
508 : : }
509 : : //-------------------------------------------------------------------
510 : : //Function: dist_point_data
511 : : //Computes the distance between the line segment and the vector position.
512 : : //This function is used to determine the nearest neigbhor search and
513 : : //gets passed to the AbstractTree.
514 : : //-------------------------------------------------------------------
515 : 0 : double GeomMeasureTool::dist_sq_point_data( CubitVector &curr_point,
516 : : GeomSeg *&curr_seg )
517 : : {
518 : : double node[3];
519 : : double point_0[3], point_1[3];
520 [ # # ]: 0 : node[0] = curr_point.x();
521 [ # # ]: 0 : node[1] = curr_point.y();
522 [ # # ]: 0 : node[2] = curr_point.z();
523 [ # # ][ # # ]: 0 : CubitVector start_v = curr_seg->get_start()->coordinates();
[ # # ]
524 [ # # ][ # # ]: 0 : CubitVector end_v = curr_seg->get_end()->coordinates();
[ # # ]
525 [ # # ]: 0 : point_0[0] = start_v.x();
526 [ # # ]: 0 : point_0[1] = start_v.y();
527 [ # # ]: 0 : point_0[2] = start_v.z();
528 [ # # ]: 0 : point_1[0] = end_v.x();
529 [ # # ]: 0 : point_1[1] = end_v.y();
530 [ # # ]: 0 : point_1[2] = end_v.z();
531 : :
532 [ # # ]: 0 : IntersectionTool new_tool(GEOMETRY_RESABS);
533 : : double t;
534 : : double dist = new_tool.distance_point_line(node, point_0,
535 [ # # ]: 0 : point_1, t);
536 [ # # ]: 0 : if ( dist < 0.0 )
537 : : {
538 : : //This happens if the point is beyond the line segment, in which
539 : : //case we just want the closer end point.
540 [ # # ]: 0 : if ( t < 0.0 )
541 : : {
542 [ # # ][ # # ]: 0 : dist = (curr_point -start_v).length_squared();
543 : : }
544 : : else
545 : : {
546 [ # # ][ # # ]: 0 : dist = (curr_point - end_v).length_squared();
547 : : }
548 : : }
549 : : else
550 : : {
551 : : //I hate to do this but everything else is in
552 : : //terms of distance squared.
553 : 0 : dist = dist*dist;
554 : : }
555 [ # # ]: 0 : return dist;
556 : : }
557 : :
558 : 0 : CubitStatus GeomMeasureTool::convert_to_lines( PointLoopList &boundary_point_loops,
559 : : SegLoopList &boundary_line_loops,
560 : : RefFace *ref_face )
561 : : {
562 : : //This does more than just converts the boundary points to line segments. It also
563 : : //Sets up a doubily linked list through the ImprintLineSegment data structure.
564 : : //Calling codes need to make sure all this data is deleted.
565 : : //This function also sets the PointType for each of the boundary points. This
566 : : //will depend also on the boundary_1 flag. If we are doing boundary_1 then,
567 : : //the flag will be true, otherwise it will be false.
568 : : int ii, jj;
569 : : PointList *point_list;
570 : : SegList *segment_list;
571 : 0 : GeomSeg *new_line, *prev = NULL;
572 [ # # ]: 0 : SegList allocated_segs;
573 : : RefEntity *entity_start, *entity_end, *seg_owner;
574 [ # # ]: 0 : boundary_point_loops.reset();
575 [ # # ][ # # ]: 0 : for ( ii = boundary_point_loops.size(); ii > 0; ii-- )
576 : : {
577 [ # # ]: 0 : point_list = boundary_point_loops.get_and_step();
578 [ # # ][ # # ]: 0 : segment_list = new SegList;
579 : 0 : prev = NULL;
580 : 0 : new_line = NULL;
581 : 0 : seg_owner = NULL;
582 [ # # ][ # # ]: 0 : for ( jj = point_list->size(); jj > 0; jj-- )
583 : : {
584 [ # # ][ # # ]: 0 : entity_start = point_list->get()->owner();
585 [ # # ][ # # ]: 0 : entity_end = point_list->next()->owner();
586 [ # # ][ # # ]: 0 : seg_owner = CAST_TO(entity_start, RefEdge);
587 [ # # ]: 0 : if ( seg_owner == NULL )
588 : : {
589 [ # # ][ # # ]: 0 : seg_owner = CAST_TO(entity_end, RefEdge);
590 [ # # ]: 0 : if ( seg_owner == NULL )
591 : : {
592 [ # # ]: 0 : RefVertex *ref_vert_end = CAST_TO(entity_end, RefVertex);
593 [ # # ]: 0 : RefVertex *ref_vert_start = CAST_TO(entity_start, RefVertex);
594 [ # # ]: 0 : DLIList <RefEdge*> common_edges;
595 : : ref_vert_start->common_ref_edges(ref_vert_end,
596 : : common_edges,
597 [ # # ]: 0 : ref_face);
598 [ # # ][ # # ]: 0 : if ( common_edges.size() == 0 )
599 : : {
600 [ # # ][ # # ]: 0 : PRINT_ERROR("GeomMeasureTool::convert_to_lines having problem finding owner \n"
[ # # ]
601 [ # # ]: 0 : " of boundary. Could be indicative of corrupt geometry.\n");
602 : : int ll;
603 [ # # ][ # # ]: 0 : for ( ll = boundary_line_loops.size(); ll > 0; ll-- )
604 [ # # ][ # # ]: 0 : delete boundary_line_loops.pop();
[ # # ]
605 [ # # ][ # # ]: 0 : for ( ll = allocated_segs.size(); ll > 0; ll-- )
606 [ # # ][ # # ]: 0 : delete allocated_segs.pop();
[ # # ]
607 [ # # ][ # # ]: 0 : delete segment_list;
608 : 0 : return CUBIT_FAILURE;
609 : : }
610 [ # # ][ # # ]: 0 : if ( common_edges.size() == 1 )
611 [ # # ][ # # ]: 0 : seg_owner = common_edges.get();
612 : : else
613 : : {
614 : : //Now we have to decide which of these edges is the one.
615 : : //Lets take a mid point on this segment and check the distances.
616 : : //First find the mid_point of the line segment.
617 [ # # ][ # # ]: 0 : CubitVector start = point_list->get()->coordinates();
[ # # ]
618 [ # # ][ # # ]: 0 : CubitVector end = point_list->next()->coordinates();
[ # # ]
619 [ # # ][ # # ]: 0 : CubitVector mid = (start+end)/2.0;
620 [ # # ]: 0 : CubitVector closest_point;
621 : :
622 : : //Now test the edges to see which is closest.
623 : 0 : RefEdge *closest_edge = NULL, *curr_ref_edge;
624 : 0 : double min_dist = CUBIT_DBL_MAX, dist;
625 : : int kk;
626 [ # # ][ # # ]: 0 : for ( kk = common_edges.size(); kk > 0; kk-- )
627 : : {
628 [ # # ]: 0 : curr_ref_edge = common_edges.get_and_step();
629 [ # # ]: 0 : curr_ref_edge->closest_point(mid, closest_point);
630 [ # # ][ # # ]: 0 : dist = (mid - closest_point).length_squared();
631 [ # # ]: 0 : if ( dist < min_dist )
632 : : {
633 : 0 : min_dist = dist;
634 : 0 : closest_edge = curr_ref_edge;
635 : : }
636 : : }
637 [ # # ]: 0 : if ( closest_edge == NULL )
638 : : {
639 [ # # ][ # # ]: 0 : PRINT_ERROR("Problems determining segment ownwership.\n"
[ # # ]
640 [ # # ]: 0 : "Internal problem with virtual imprinting.\n");
641 : : int ll;
642 [ # # ][ # # ]: 0 : for ( ll = boundary_line_loops.size(); ll > 0; ll-- )
643 [ # # ][ # # ]: 0 : delete boundary_line_loops.pop();
[ # # ]
644 [ # # ][ # # ]: 0 : for ( ll = allocated_segs.size(); ll > 0; ll-- )
645 [ # # ][ # # ]: 0 : delete allocated_segs.pop();
[ # # ]
646 [ # # ][ # # ]: 0 : delete segment_list;
647 : 0 : return CUBIT_FAILURE;
648 : : }
649 [ # # ][ # # ]: 0 : seg_owner = closest_edge;
[ # # ]
650 : 0 : }
651 : : }
652 : : }
653 [ # # ][ # # ]: 0 : new_line = new GeomSeg( point_list->get(), point_list->next(), seg_owner);
[ # # ][ # # ]
654 [ # # ]: 0 : allocated_segs.append(new_line);
655 [ # # ]: 0 : point_list->step();
656 [ # # ]: 0 : segment_list->append(new_line);
657 [ # # ]: 0 : if ( prev != NULL )
658 : : {
659 [ # # ]: 0 : prev->set_next(new_line);
660 [ # # ]: 0 : new_line->set_prev(prev);
661 : : }
662 : 0 : prev = new_line;
663 : : }
664 [ # # ]: 0 : if ( prev != NULL )
665 : : {
666 [ # # ]: 0 : segment_list->reset();
667 [ # # ][ # # ]: 0 : assert(prev == segment_list->prev());
668 [ # # ][ # # ]: 0 : segment_list->prev()->set_next(segment_list->get());
[ # # ]
669 [ # # ][ # # ]: 0 : segment_list->get()->set_prev(segment_list->prev());
[ # # ]
670 [ # # ][ # # ]: 0 : assert(segment_list->get()->get_next() != NULL );
[ # # ]
671 : : }
672 [ # # ][ # # ]: 0 : if ( segment_list->size() )
673 : : {
674 [ # # ]: 0 : boundary_line_loops.append(segment_list);
675 : : }
676 : : else
677 [ # # ][ # # ]: 0 : delete segment_list;
678 : : }
679 [ # # ]: 0 : return CUBIT_SUCCESS;
680 : : }
681 : :
682 : 0 : CubitStatus GeomMeasureTool::get_boundary_points( RefFace *ref_face,
683 : : PointLoopList &boundary_point_loops,
684 : : double seg_length_tol)
685 : : {
686 [ # # ]: 0 : DLIList<DLIList<CoEdge*> > co_edge_loops;
687 [ # # ]: 0 : ref_face->co_edge_loops(co_edge_loops);
688 : : int ii, jj;
689 [ # # ][ # # ]: 0 : PointList *new_point_loop_ptr, tmp_point_list;
690 : : RefEdge *ref_edge_ptr;
691 : : CoEdge *co_edge_ptr;
692 : : CubitStatus stat;
693 : : CubitSense sense;
694 : :
695 [ # # ][ # # ]: 0 : for ( ii = co_edge_loops.size(); ii > 0; ii-- )
696 : : {
697 [ # # ]: 0 : DLIList <CoEdge*> &co_edge_list_ptr = co_edge_loops.get_and_step();
698 [ # # ][ # # ]: 0 : new_point_loop_ptr = new PointList;
699 [ # # ][ # # ]: 0 : for ( jj = co_edge_list_ptr.size(); jj > 0; jj-- )
700 : : {
701 [ # # ]: 0 : co_edge_ptr = co_edge_list_ptr.get_and_step();
702 [ # # ]: 0 : ref_edge_ptr = co_edge_ptr->get_ref_edge_ptr();
703 [ # # ]: 0 : tmp_point_list.clean_out();
704 : : stat = get_curve_facets( ref_edge_ptr, tmp_point_list,
705 [ # # ]: 0 : seg_length_tol );
706 [ # # ]: 0 : if ( stat != CUBIT_SUCCESS )
707 : 0 : return CUBIT_FAILURE;
708 [ # # ][ # # ]: 0 : if ( tmp_point_list.size() == 0 )
709 : 0 : continue;
710 [ # # ]: 0 : tmp_point_list.reset();
711 : : //the points are in order from start vertex to end vertex.
712 : : //append them now according to the loop.
713 [ # # ]: 0 : sense = co_edge_ptr->get_sense();
714 [ # # ]: 0 : if ( CUBIT_FORWARD != sense )
715 [ # # ]: 0 : tmp_point_list.reverse();
716 : : //Now take off the last point as it is a duplicate with the
717 : : //other list...
718 [ # # ]: 0 : tmp_point_list.reset();
719 [ # # ][ # # ]: 0 : delete tmp_point_list.pop();
[ # # ]
720 [ # # ]: 0 : (*new_point_loop_ptr) += tmp_point_list;
721 : : }
722 [ # # ]: 0 : boundary_point_loops.append(new_point_loop_ptr);
723 : : }
724 : :
725 [ # # ]: 0 : return CUBIT_SUCCESS;
726 : : }
727 : :
728 : 0 : CubitStatus GeomMeasureTool::get_curve_facets( RefEdge* curve,
729 : : PointList &segments,
730 : : double seg_length_tol )
731 : : {
732 : : // const double COS_ANGLE_TOL = 0.965925826289068312213715; // cos(15)
733 : : // const double COS_ANGLE_TOL = 0.984807753012208020315654; // cos(10)
734 : : //const double COS_ANGLE_TOL = 0.996194698091745545198705; // cos(5)
735 [ # # ]: 0 : GMem curve_graphics;
736 : : //make this tol bigger than seg_length_tol, to
737 : : //make sure the segments are larger than the tolerance.
738 : 0 : const double dist_tol = seg_length_tol;// + .05*seg_length_tol;
739 : : //const double dist_tol_sqr = dist_tol*dist_tol;
740 [ # # ][ # # ]: 0 : if ( curve->get_curve_ptr() == NULL )
741 : : {
742 [ # # ][ # # ]: 0 : PRINT_ERROR("Curve %d had no geometry, this is a bug!\n", curve->id());
[ # # ][ # # ]
[ # # ]
743 : 0 : return CUBIT_FAILURE;
744 : : }
745 [ # # ][ # # ]: 0 : else if ( curve->get_curve_ptr()->get_geometry_query_engine() == NULL )
[ # # ]
746 : : {
747 [ # # ][ # # ]: 0 : PRINT_ERROR("Curve %d had no geometry engine, this is a bug!\n",
[ # # ][ # # ]
748 [ # # ]: 0 : curve->id());
749 : 0 : return CUBIT_FAILURE;
750 : : }
751 [ # # ]: 0 : curve->get_graphics( curve_graphics );
752 : :
753 [ # # ]: 0 : GPoint* gp = curve_graphics.point_list();
754 [ # # ]: 0 : if ( gp == NULL )
755 : : {
756 [ # # ][ # # ]: 0 : if ( curve->measure() < GEOMETRY_RESABS )
757 : : {
758 [ # # ][ # # ]: 0 : if( curve->geometry_type() != POINT_CURVE_TYPE )
759 : : {
760 [ # # ][ # # ]: 0 : PRINT_INFO("Curve %d has a zero length, and won't be used for loop measurements.\n",
[ # # ][ # # ]
761 [ # # ]: 0 : curve->id());
762 : : }
763 : : }
764 : : else
765 [ # # ][ # # ]: 0 : PRINT_ERROR("Curve %d had not faceting. Ignoring this curve.\n",
[ # # ][ # # ]
766 [ # # ]: 0 : curve->id());
767 : 0 : return CUBIT_SUCCESS;
768 : : }
769 [ # # ][ # # ]: 0 : GeomPoint *last = new GeomPoint( gp[0].x, gp[0].y, gp[0].z, curve );
[ # # ]
770 [ # # ][ # # ]: 0 : CubitVector lastv = last->coordinates();
771 : 0 : int num_points = curve_graphics.pointListCount;
772 [ # # ]: 0 : segments.append( last );
773 : : int ii;
774 : 0 : CubitBoolean remove_second_to_end = CUBIT_FALSE;
775 [ # # ]: 0 : for ( ii = 1; ii < num_points; ii++ )
776 : : {
777 [ # # ]: 0 : CubitVector pos( gp[ii].x, gp[ii].y, gp[ii].z );
778 [ # # ]: 0 : CubitVector step1 = (pos - lastv);
779 [ # # ]: 0 : double len1 = step1.length();
780 [ # # ][ # # ]: 0 : if( len1 < dist_tol && ii != num_points - 1)
781 : 0 : continue;
782 [ # # ][ # # ]: 0 : else if ( len1 < dist_tol && ii == num_points-1 )
783 : : {
784 : 0 : remove_second_to_end = CUBIT_TRUE;
785 : : }
786 [ # # ][ # # ]: 0 : last = new GeomPoint(pos,curve);
[ # # ]
787 [ # # ]: 0 : segments.append( last );
788 [ # # ][ # # ]: 0 : lastv = last->coordinates();
789 : : }
790 : : // Now check if the segment list is reversed wrt the curve direction.
791 [ # # ]: 0 : segments.reset();
792 [ # # ]: 0 : if ( remove_second_to_end )
793 : : {
794 [ # # ][ # # ]: 0 : if ( segments.size() == 2 )
795 : : {
796 : : //just leave it in, let it be small...
797 : : }
798 : : else
799 : : {
800 : : //Remove the second to last one. To do
801 : : //this efficiently (don't do remove), pop
802 : : //the last one, then save that and
803 : : //re-add it after poping the second one.
804 [ # # ]: 0 : GeomPoint *temp = segments.pop();
805 [ # # ]: 0 : segments.pop();
806 [ # # ]: 0 : segments.append(temp);
807 : : }
808 : : }
809 [ # # ]: 0 : segments.reset();
810 [ # # ][ # # ]: 0 : if( curve->start_vertex() != curve->end_vertex() )
[ # # ]
811 : : {
812 [ # # ][ # # ]: 0 : CubitVector start_vec, end_vec;
813 [ # # ][ # # ]: 0 : start_vec = curve->start_vertex()->coordinates();
[ # # ]
814 [ # # ][ # # ]: 0 : end_vec = curve->end_vertex()->coordinates();
[ # # ]
815 [ # # ][ # # ]: 0 : CubitVector start_seg = segments.get()->coordinates();
[ # # ]
816 [ # # ][ # # ]: 0 : double dist_1 = (start_seg - start_vec).length_squared();
817 [ # # ][ # # ]: 0 : double dist_2 = (start_seg - end_vec).length_squared();
818 [ # # ]: 0 : if ( dist_1 > dist_2 )
819 [ # # ]: 0 : segments.reverse();
820 : : }
821 : : else
822 : : {
823 : : double u1, u2;
824 [ # # ][ # # ]: 0 : u1 = curve->u_from_position( (segments.next(1)->coordinates()) );
[ # # ]
825 [ # # ][ # # ]: 0 : u2 = curve->u_from_position( (segments.next(2)->coordinates()) );
[ # # ]
826 [ # # ][ # # ]: 0 : if( (u2 < u1) && (curve->start_param() <= curve->end_param()) )
[ # # ][ # # ]
[ # # ]
827 [ # # ]: 0 : segments.reverse();
828 : : }
829 : : //clean up the periodic curve case (last seg may be too small.)
830 [ # # ][ # # ]: 0 : if ( curve->start_vertex() == curve->end_vertex() )
[ # # ]
831 : : {
832 [ # # ]: 0 : segments.reset();
833 [ # # ][ # # ]: 0 : CubitVector start_v = segments.get()->coordinates();
[ # # ]
834 [ # # ][ # # ]: 0 : CubitVector last_v = segments.prev()->coordinates();
[ # # ]
835 [ # # ][ # # ]: 0 : double dist = (start_v - last_v).length();
836 [ # # ]: 0 : if ( dist < dist_tol )
837 : : {
838 : : //remove the last one.
839 [ # # ]: 0 : segments.pop();
840 : : }
841 : : }
842 [ # # ][ # # ]: 0 : if ( segments.size() < 2 )
843 : : {
844 [ # # ][ # # ]: 0 : PRINT_ERROR("Problem faceting boundary.\n");
[ # # ][ # # ]
845 : 0 : return CUBIT_FAILURE;
846 : : }
847 [ # # ][ # # ]: 0 : segments.get()->owner(curve->start_vertex());
[ # # ][ # # ]
848 [ # # ][ # # ]: 0 : segments.prev()->owner(curve->end_vertex());
[ # # ][ # # ]
849 [ # # ]: 0 : return CUBIT_SUCCESS;
850 : : }
851 : 0 : CubitStatus GeomMeasureTool::interior_angle(GeomSeg *first_seg,
852 : : GeomSeg *next_seg,
853 : : RefFace *face,
854 : : double &angle )
855 : : {
856 [ # # ][ # # ]: 0 : if ( first_seg->get_end() != next_seg->get_start() )
[ # # ]
857 : : {
858 [ # # ][ # # ]: 0 : PRINT_ERROR("GeomMeasureTool::interior_angle expects segments\n"
[ # # ]
859 [ # # ]: 0 : "to be connected (Users: this is a bug, please submit.\n");
860 : 0 : return CUBIT_FAILURE;
861 : : }
862 [ # # ][ # # ]: 0 : CubitVector point = first_seg->get_end()->coordinates();
[ # # ]
863 [ # # ][ # # ]: 0 : CubitVector to_prev = first_seg->get_start()->coordinates();
[ # # ]
864 [ # # ]: 0 : to_prev -= point;
865 [ # # ][ # # ]: 0 : CubitVector to_next = next_seg->get_end()->coordinates();
[ # # ]
866 [ # # ]: 0 : to_next -= point;
867 [ # # ]: 0 : CubitVector surf_norm = face->normal_at(point);
868 [ # # ][ # # ]: 0 : if ( surf_norm.length_squared() < CUBIT_RESABS )
869 : : {
870 : : //Try getting it at one of the other nodes...
871 [ # # ][ # # ]: 0 : surf_norm = face->normal_at(first_seg->get_start()->coordinates() );
[ # # ][ # # ]
872 [ # # ][ # # ]: 0 : if (surf_norm.length_squared() < CUBIT_RESABS )
873 : : {
874 : : //Try getting it at one of the other nodes...
875 [ # # ][ # # ]: 0 : surf_norm = face->normal_at(next_seg->get_end()->coordinates() );
[ # # ][ # # ]
876 [ # # ][ # # ]: 0 : if (surf_norm.length_squared() < CUBIT_RESABS )
877 : : {
878 [ # # ][ # # ]: 0 : PRINT_ERROR("Trying to get normal at surf %d.\n"
[ # # ][ # # ]
879 : : " Normal length being returned equals zero.\n",
880 [ # # ]: 0 : face->id() );
881 : 0 : angle = CUBIT_DBL_MAX;
882 : 0 : return CUBIT_FAILURE;
883 : : }
884 : : }
885 : : }
886 [ # # ]: 0 : angle = surf_norm.vector_angle ( to_next, to_prev );
887 : 0 : return CUBIT_SUCCESS;
888 : : }
889 : :
890 : 0 : void GeomMeasureTool::measure_face_area (DLIList <RefEntity*> &entity_list,
891 : : double &smallest,
892 : : RefFace *&smallest_face,
893 : : double &largest,
894 : : RefFace *&largest_face,
895 : : double &average,
896 : : double &sum)
897 : : {
898 [ # # ]: 0 : DLIList<RefFace*> ref_faces;
899 [ # # ]: 0 : get_faces_from_list(entity_list, ref_faces);
900 : : measure_face_area(ref_faces, smallest, smallest_face,
901 [ # # ][ # # ]: 0 : largest, largest_face, average, sum);
902 : :
903 : 0 : }
904 : :
905 : 0 : void GeomMeasureTool::measure_face_area (DLIList <RefFace*> &ref_faces,
906 : : double &smallest,
907 : : RefFace *&smallest_face,
908 : : double &largest,
909 : : RefFace *&largest_face,
910 : : double &average,
911 : : double &sum)
912 : : {
913 : : int ii;
914 : 0 : double curr_area, total_area = 0.0;
915 : 0 : smallest = CUBIT_DBL_MAX;
916 : 0 : largest = 0.0;
917 : : RefFace *curr_face;
918 [ # # ]: 0 : for( ii = ref_faces.size(); ii > 0; ii-- )
919 : : {
920 : 0 : curr_face = ref_faces.get_and_step();
921 : 0 : curr_area = measure_area(curr_face);
922 [ # # ]: 0 : if ( curr_area < smallest )
923 : : {
924 : 0 : smallest = curr_area;
925 : 0 : smallest_face = curr_face;
926 : : }
927 [ # # ]: 0 : if( curr_area > largest )
928 : : {
929 : 0 : largest = curr_area;
930 : 0 : largest_face = curr_face;
931 : : }
932 : 0 : total_area += curr_area;
933 : : }
934 [ # # ]: 0 : if (ref_faces.size() != 0 )
935 : 0 : average = total_area/ref_faces.size();
936 : 0 : sum = total_area;
937 : :
938 : 0 : }
939 : :
940 : 0 : void GeomMeasureTool::measure_volume_volume (DLIList <RefEntity*> &entity_list,
941 : : double &smallest,
942 : : RefVolume *&smallest_volume,
943 : : double &largest,
944 : : RefVolume *&largest_volume,
945 : : double &average,
946 : : double &sum)
947 : : {
948 [ # # ]: 0 : DLIList<RefVolume*> ref_volumes;
949 [ # # ]: 0 : get_volumes_from_list(entity_list, ref_volumes);
950 : : measure_volume_volume(ref_volumes, smallest, smallest_volume,
951 [ # # ][ # # ]: 0 : largest, largest_volume, average, sum);
952 : :
953 : 0 : }
954 : :
955 : 0 : void GeomMeasureTool::measure_volume_volume (DLIList <RefVolume*> &ref_volumes,
956 : : double &smallest,
957 : : RefVolume *&smallest_volume,
958 : : double &largest,
959 : : RefVolume *&largest_volume,
960 : : double &average,
961 : : double &sum)
962 : : {
963 : : int ii;
964 : 0 : double curr_volume, total_volume = 0.0;
965 : 0 : smallest = CUBIT_DBL_MAX;
966 : 0 : largest = 0.0;
967 : : RefVolume *curr_solid;
968 [ # # ]: 0 : for ( ii = ref_volumes.size(); ii > 0; ii-- )
969 : : {
970 : 0 : curr_solid = ref_volumes.get_and_step();
971 : 0 : curr_volume = curr_solid->measure();
972 : :
973 [ # # ]: 0 : if ( curr_volume < smallest )
974 : : {
975 : 0 : smallest = curr_volume;
976 : 0 : smallest_volume = curr_solid;
977 : : }
978 [ # # ]: 0 : if ( curr_volume > largest )
979 : : {
980 : 0 : largest = curr_volume;
981 : 0 : largest_volume = curr_solid;
982 : : }
983 : 0 : total_volume += curr_volume;
984 : : }
985 [ # # ]: 0 : if (ref_volumes.size() != 0 )
986 : 0 : average = total_volume/ref_volumes.size();
987 : 0 : sum = total_volume;
988 : :
989 : 0 : }
990 : :
991 : 0 : void GeomMeasureTool::measure_face_area_and_hydraulic_radius(RefFace *curr_face,
992 : : double &face_area,
993 : : double &face_hydraulic_radius)
994 : : {
995 : : int ii;
996 : 0 : double total_edge_length = 0.0, curr_edge_length;
997 : : RefEdge *curr_edge;
998 [ # # ]: 0 : DLIList <CoEdge*> my_co_edges;
999 : :
1000 [ # # ]: 0 : face_area = measure_area(curr_face);
1001 [ # # ]: 0 : curr_face->co_edges(my_co_edges);
1002 [ # # ][ # # ]: 0 : for( ii = my_co_edges.size(); ii > 0; ii-- )
1003 : : {
1004 [ # # ][ # # ]: 0 : curr_edge = my_co_edges.get_and_step()->get_ref_edge_ptr();
1005 [ # # ]: 0 : curr_edge_length = curr_edge->measure();
1006 : 0 : total_edge_length += curr_edge_length;
1007 : : }
1008 [ # # ]: 0 : if (total_edge_length != 0)
1009 [ # # ]: 0 : face_hydraulic_radius = 4.0*(face_area / total_edge_length);
1010 : 0 : }
1011 : :
1012 : 0 : void GeomMeasureTool::measure_volume_volume_and_hydraulic_radius(RefVolume *curr_volume,
1013 : : double &volume_volume,
1014 : : double &volume_hydraulic_radius)
1015 : : {
1016 : : int ii;
1017 : 0 : double curr_face_area, total_surface_area = 0.0;
1018 [ # # ]: 0 : DLIList <RefFace*> ref_face_list;
1019 : : RefFace *curr_face;
1020 : :
1021 [ # # ]: 0 : volume_volume = curr_volume->measure();
1022 [ # # ]: 0 : curr_volume->ref_faces(ref_face_list);
1023 : :
1024 [ # # ][ # # ]: 0 : for ( ii = ref_face_list.size(); ii > 0; ii-- )
1025 : : {
1026 [ # # ]: 0 : curr_face = ref_face_list.get_and_step();
1027 [ # # ]: 0 : curr_face_area = measure_area(curr_face);
1028 : 0 : total_surface_area += curr_face_area;
1029 : : }
1030 [ # # ]: 0 : if (total_surface_area != 0)
1031 [ # # ]: 0 : volume_hydraulic_radius = 6.0*(volume_volume / total_surface_area);
1032 : :
1033 : 0 : }
1034 : :
1035 : 0 : void GeomMeasureTool::angles_between_volume_surfaces(RefVolume *curr_volume,
1036 : : double &min_angle,
1037 : : double &max_angle,
1038 : : RefFace *&face_min_1,
1039 : : RefFace *&face_min_2,
1040 : : RefFace *&face_max_1,
1041 : : RefFace *&face_max_2)
1042 : : {
1043 : 0 : int ii, jj, shared_angles = 0;
1044 : 0 : double common_angle, sum_of_angles = 0.0;
1045 : 0 : double smallest = CUBIT_DBL_MAX, largest = 0.0;
1046 [ # # ][ # # ]: 0 : DLIList <RefFace*> face_list_1, face_list_2;
[ # # ]
1047 : : RefFace *curr_face_1, *curr_face_2;
1048 : : RefEdge *common_edge;
1049 : :
1050 [ # # ]: 0 : curr_volume->ref_faces(face_list_1);
1051 [ # # ]: 0 : face_list_2 = face_list_1;
1052 : :
1053 [ # # ][ # # ]: 0 : for (ii = face_list_1.size(); ii > 0; ii--)
1054 : : {
1055 [ # # ]: 0 : curr_face_1 = face_list_1.get_and_step();
1056 [ # # ][ # # ]: 0 : for(jj = face_list_2.size(); jj > 0; jj--)
1057 : : {
1058 [ # # ]: 0 : curr_face_2 = face_list_2.get_and_step();
1059 : :
1060 [ # # ]: 0 : if(curr_face_1 == curr_face_2)
1061 : 0 : continue;
1062 : : else
1063 : : {
1064 [ # # ]: 0 : common_edge = curr_face_1->common_ref_edge(curr_face_2);
1065 [ # # ]: 0 : if( common_edge == NULL )
1066 : 0 : continue;
1067 : : else
1068 : : {
1069 : 0 : shared_angles++;
1070 : :
1071 [ # # ][ # # ]: 0 : if ( common_edge->get_curve_ptr()->geometry_type() != STRAIGHT_CURVE_TYPE )
[ # # ]
1072 : : {
1073 : : int kk;
1074 : 0 : double frac_pos = 0.00;
1075 [ # # ]: 0 : for ( kk = 0; kk < 4; kk++ )
1076 : : {
1077 : : common_angle = GeometryQueryTool::instance()->surface_angle(curr_face_1, curr_face_2,
1078 : : common_edge, curr_volume,
1079 [ # # ][ # # ]: 0 : frac_pos);
1080 : 0 : frac_pos += .25;
1081 [ # # ]: 0 : if( common_angle < smallest )
1082 : : {
1083 : 0 : min_angle = common_angle * (180 / CUBIT_PI);
1084 : 0 : smallest = common_angle;
1085 : 0 : face_min_1 = curr_face_1;
1086 : 0 : face_min_2 = curr_face_2;
1087 : : }
1088 [ # # ]: 0 : if( common_angle > largest )
1089 : : {
1090 : 0 : max_angle = common_angle * (180 / CUBIT_PI);
1091 : 0 : largest = common_angle;
1092 : 0 : face_max_1 = curr_face_1;
1093 : 0 : face_max_2 = curr_face_2;
1094 : : }
1095 : : }
1096 : : }
1097 : : else
1098 : : {
1099 : :
1100 : : common_angle = GeometryQueryTool::instance()->surface_angle(curr_face_1, curr_face_2,
1101 [ # # ][ # # ]: 0 : common_edge, curr_volume );
1102 [ # # ]: 0 : if( common_angle < smallest )
1103 : : {
1104 : 0 : min_angle = common_angle * (180 / CUBIT_PI);
1105 : 0 : smallest = common_angle;
1106 : 0 : face_min_1 = curr_face_1;
1107 : 0 : face_min_2 = curr_face_2;
1108 : : }
1109 [ # # ]: 0 : if( common_angle > largest )
1110 : : {
1111 : 0 : max_angle = common_angle * (180 / CUBIT_PI);
1112 : 0 : largest = common_angle;
1113 : 0 : face_max_1 = curr_face_1;
1114 : 0 : face_max_2 = curr_face_2;
1115 : : }
1116 : : }
1117 : :
1118 : 0 : sum_of_angles += common_angle;
1119 : : }
1120 : : }
1121 : : }
1122 [ # # ]: 0 : }
1123 : 0 : }
1124 : :
1125 : 0 : void GeomMeasureTool::merged_unmerged_surface_ratio(DLIList <RefVolume*> &ref_volumes,
1126 : : int &merged, int &unmerged,
1127 : : double &ratio)
1128 : :
1129 : : {
1130 : : int ii, jj;
1131 : : RefVolume *curr_volume_1;
1132 [ # # ][ # # ]: 0 : DLIList <RefFace*> surface_list_1, surface_list_2;
[ # # ]
1133 : : RefFace *curr_face_1;
1134 : 0 : int merged_surfaces = 0, unmerged_surfaces = 0;
1135 : :
1136 [ # # ][ # # ]: 0 : for( ii = ref_volumes.size(); ii > 0; ii-- )
1137 : : {
1138 [ # # ]: 0 : curr_volume_1 = ref_volumes.get_and_step();
1139 [ # # ]: 0 : surface_list_1.clean_out();
1140 : :
1141 [ # # ]: 0 : curr_volume_1->ref_faces(surface_list_1);
1142 [ # # ][ # # ]: 0 : for( jj = surface_list_1.size(); jj > 0; jj-- )
1143 : : {
1144 [ # # ]: 0 : curr_face_1 = surface_list_1.get_and_step();
1145 [ # # ][ # # ]: 0 : if ( curr_face_1->marked() )
1146 : 0 : continue;
1147 : : else
1148 : : {
1149 [ # # ]: 0 : curr_face_1->marked(1);
1150 [ # # ]: 0 : surface_list_2.append(curr_face_1);
1151 : : }
1152 [ # # ][ # # ]: 0 : if ( curr_face_1->num_ref_volumes() == 2 )
1153 : 0 : merged_surfaces++;
1154 : : else
1155 : 0 : unmerged_surfaces++;
1156 : : }
1157 : : }
1158 [ # # ][ # # ]: 0 : for ( ii = surface_list_2.size(); ii > 0; ii-- )
1159 : : {
1160 [ # # ][ # # ]: 0 : surface_list_2.get_and_step()->marked(0);
1161 : : }
1162 : 0 : merged = merged_surfaces;
1163 : 0 : unmerged = unmerged_surfaces;
1164 [ # # ]: 0 : if ( unmerged_surfaces == 0 )
1165 : : {
1166 : 0 : ratio = 100.0;
1167 : : }
1168 : : else
1169 [ # # ]: 0 : ratio = (double) ((double)merged_surfaces / (double)unmerged_surfaces);
1170 : 0 : }
1171 : :
1172 : 0 : void GeomMeasureTool::report_intersected_volumes(DLIList <RefVolume*> &ref_vols,
1173 : : DLIList <RefVolume*> &intersection_list)
1174 : : {
1175 [ # # ]: 0 : DLIList <RefVolume*> results;
1176 : : RefVolume *curr_vol;
1177 : : int i, j;
1178 : 0 : ProgressTool *progress_ptr = NULL;
1179 [ # # ]: 0 : int total_volumes = ref_vols.size();
1180 [ # # ]: 0 : if (total_volumes > 5)
1181 : : {
1182 [ # # ][ # # ]: 0 : progress_ptr = AppUtil::instance()->progress_tool();
1183 [ # # ]: 0 : assert(progress_ptr != NULL);
1184 : : progress_ptr->start(0, 100, "Overlapping Volumes Progress",
1185 [ # # ]: 0 : NULL, CUBIT_TRUE, CUBIT_TRUE);
1186 : : }
1187 : 0 : double curr_percent = 0.0;
1188 : :
1189 [ # # ][ # # ]: 0 : for( i = 0; i < ref_vols.size(); i++ )
1190 : : {
1191 [ # # ]: 0 : curr_vol = ref_vols.next(i);
1192 : :
1193 : : //is this body a multi-volume-body?
1194 [ # # ]: 0 : Body *single_volume_body = curr_vol->body();
1195 [ # # ]: 0 : DLIList<RefVolume*> body_vols;
1196 [ # # ]: 0 : single_volume_body->ref_volumes( body_vols );
1197 [ # # ][ # # ]: 0 : if( body_vols.size() > 1 )
1198 : 0 : single_volume_body = NULL;
1199 : :
1200 [ # # ][ # # ]: 0 : for( j = (i + 1); j < ref_vols.size(); j++ )
[ # # ][ # # ]
1201 : : {
1202 [ # # ]: 0 : RefVolume *curr_vol2 = ref_vols.next(j);
1203 [ # # ][ # # ]: 0 : if ( AppUtil::instance()->interrupt() )
[ # # ]
1204 : : {
1205 : : //interrpt. We need to exit.
1206 [ # # ]: 0 : if ( progress_ptr != NULL )
1207 : : {
1208 [ # # ]: 0 : progress_ptr->end();
1209 : : }
1210 : : //just leave what has been calculated...
1211 : 0 : return;
1212 : : }
1213 : :
1214 [ # # ]: 0 : Body *single_volume_body2 = curr_vol2->body();
1215 [ # # ]: 0 : DLIList<RefVolume*> body_vols2;
1216 [ # # ]: 0 : single_volume_body2->ref_volumes( body_vols2 );
1217 [ # # ][ # # ]: 0 : if( body_vols2.size() > 1 )
1218 : 0 : single_volume_body2 = NULL;
1219 : :
1220 : : //update the progress..
1221 [ # # ]: 0 : if ( progress_ptr != NULL )
1222 : : {
1223 : 0 : curr_percent = ((double)(i+1))/((double)(total_volumes));
1224 [ # # ]: 0 : progress_ptr->percent(curr_percent);
1225 : : }
1226 : :
1227 : : //if both are single-volume-bodies
1228 [ # # ][ # # ]: 0 : if( single_volume_body && single_volume_body2 )
1229 : : {
1230 [ # # ][ # # ]: 0 : if( GeometryQueryTool::instance()->bodies_overlap( single_volume_body,
1231 [ # # ]: 0 : single_volume_body2 ) )
1232 : : {
1233 [ # # ]: 0 : intersection_list.append( curr_vol );
1234 [ # # ]: 0 : intersection_list.append( curr_vol2 );
1235 : : }
1236 : : }
1237 [ # # ][ # # ]: 0 : else if( GeometryQueryTool::instance()->volumes_overlap( curr_vol, curr_vol2 ) )
[ # # ]
1238 : : {
1239 [ # # ]: 0 : intersection_list.append( curr_vol );
1240 [ # # ]: 0 : intersection_list.append( curr_vol2 );
1241 : : }
1242 [ # # ]: 0 : }
1243 : 0 : }
1244 : :
1245 [ # # ]: 0 : if ( progress_ptr != NULL )
1246 : : {
1247 [ # # ][ # # ]: 0 : progress_ptr->end();
[ # # ]
1248 : 0 : }
1249 : : }
1250 : :
1251 : 0 : void GeomMeasureTool::report_intersected_bodies(DLIList <Body*> &ref_bodies,
1252 : : DLIList <Body*> &intersection_list)
1253 : : {
1254 : : Body *curr_body, *curr_body_2;
1255 : : int ii, jj;
1256 : 0 : ProgressTool *progress_ptr = NULL;
1257 [ # # ]: 0 : int total_bodies = ref_bodies.size();
1258 [ # # ]: 0 : if (total_bodies > 5)
1259 : : {
1260 [ # # ][ # # ]: 0 : progress_ptr = AppUtil::instance()->progress_tool();
1261 [ # # ]: 0 : assert(progress_ptr != NULL);
1262 : : progress_ptr->start(0, 100, "Overlapping Volumes Progress",
1263 [ # # ]: 0 : NULL, CUBIT_TRUE, CUBIT_TRUE);
1264 : : }
1265 : 0 : double curr_percent = 0.0;
1266 : :
1267 : :
1268 [ # # ][ # # ]: 0 : for( ii = 0; ii < ref_bodies.size(); ii++ )
1269 : : {
1270 [ # # ]: 0 : curr_body = ref_bodies.next(ii);
1271 : :
1272 [ # # ][ # # ]: 0 : for( jj = (ii + 1); jj < ref_bodies.size(); jj++ )
1273 : : {
1274 [ # # ]: 0 : curr_body_2 = ref_bodies.next(jj);
1275 [ # # ][ # # ]: 0 : if ( AppUtil::instance()->interrupt() )
[ # # ]
1276 : : {
1277 : : //interrpt. We need to exit.
1278 [ # # ]: 0 : if ( progress_ptr != NULL )
1279 : : {
1280 [ # # ]: 0 : progress_ptr->end();
1281 : : }
1282 : : //just leave what has been calculated...
1283 : 0 : return;
1284 : : }
1285 : :
1286 [ # # ][ # # ]: 0 : if (GeometryQueryTool::instance()->bodies_overlap(curr_body,
1287 [ # # ]: 0 : curr_body_2) )
1288 : : {
1289 [ # # ]: 0 : intersection_list.append(curr_body);
1290 [ # # ]: 0 : intersection_list.append(curr_body_2);
1291 : : }
1292 : : }
1293 : : //update the progress..
1294 [ # # ]: 0 : if ( progress_ptr != NULL )
1295 : : {
1296 : 0 : curr_percent = ((double)(ii+1))/((double)(total_bodies));
1297 [ # # ]: 0 : progress_ptr->percent(curr_percent);
1298 : : }
1299 : : }
1300 [ # # ]: 0 : if ( progress_ptr != NULL )
1301 : : {
1302 [ # # ]: 0 : progress_ptr->end();
1303 : : }
1304 : : }
1305 : :
1306 : 0 : void GeomMeasureTool::face_list_from_volume_list( DLIList <RefVolume*> &input_vols,
1307 : : DLIList <RefFace*> &all_faces )
1308 : : {
1309 [ # # ]: 0 : DLIList <RefFace*> curr_faces;
1310 : : RefVolume *curr_vol;
1311 : : RefFace *curr_face;
1312 : : int ii, jj;
1313 : :
1314 : : //get the all RefFaces from input_vols.
1315 : : //put them into all_faces list.
1316 : :
1317 [ # # ][ # # ]: 0 : for ( ii = 0; ii < input_vols.size(); ii++ )
1318 : : {
1319 [ # # ]: 0 : curr_vol = input_vols.get_and_step();
1320 [ # # ]: 0 : curr_faces.clean_out();
1321 [ # # ]: 0 : curr_vol->ref_faces(curr_faces);
1322 : :
1323 [ # # ][ # # ]: 0 : for( jj = 0; jj < curr_faces.size(); jj++ )
1324 : : {
1325 [ # # ]: 0 : curr_face = curr_faces.get_and_step();
1326 [ # # ][ # # ]: 0 : if( curr_face->marked() )
1327 : 0 : continue;
1328 : : else
1329 : : {
1330 [ # # ]: 0 : curr_face->marked(1);
1331 [ # # ]: 0 : all_faces.append(curr_face);
1332 : : }
1333 : : }
1334 : : }
1335 [ # # ][ # # ]: 0 : for ( ii = all_faces.size();ii >0; ii-- )
1336 [ # # ][ # # ]: 0 : all_faces.get_and_step()->marked(0);
[ # # ]
1337 : 0 : }
1338 : :
1339 : 0 : RefFace* GeomMeasureTool::valid_start( DLIList <RefFace*> &all_faces )
1340 : : {
1341 : : int ii;
1342 : : RefFace *start_face;
1343 : :
1344 [ # # ]: 0 : for( ii = 0; ii < all_faces.size(); ii++ )
1345 : : {
1346 : 0 : start_face = all_faces.get_and_step();
1347 : :
1348 [ # # ][ # # ]: 0 : if( !start_face->marked() && start_face->num_ref_volumes()== 1 )
[ # # ]
1349 : 0 : return start_face;
1350 : : }
1351 : :
1352 : 0 : return NULL;
1353 : :
1354 : : }
1355 : :
1356 : 0 : void GeomMeasureTool::find_shells( DLIList <RefVolume*> &input_vols,
1357 : : RefGroup *&owner_groups,
1358 : : int &number_of_shells)
1359 : : {
1360 [ # # ]: 0 : DLIList <DLIList<RefEntity*>*> list_of_lists;
1361 : : DLIList <RefEntity*> *new_list;
1362 [ # # ][ # # ]: 0 : DLIList <RefFace*> all_faces, stack, related_faces;
[ # # ][ # # ]
[ # # ][ # # ]
1363 [ # # ][ # # ]: 0 : DLIList <RefEdge*> curr_edges;
1364 : : RefFace *start_face, *curr_face, *related_face;
1365 : : RefEdge *curr_edge;
1366 : : int ii, jj;
1367 : : RefEntity *tmp_ent;
1368 : 0 : number_of_shells = 0;
1369 [ # # ][ # # ]: 0 : DLIList <RefFace*> marked_faces;
1370 : :
1371 [ # # ]: 0 : face_list_from_volume_list( input_vols, all_faces );
1372 : :
1373 : : // all_faces all marked - need unmarked
1374 [ # # ][ # # ]: 0 : for (ii = 0; ii < all_faces.size(); ii++ )
1375 : : {
1376 [ # # ]: 0 : curr_face = all_faces.get_and_step();
1377 [ # # ]: 0 : curr_face->marked(0);
1378 : : }
1379 [ # # ][ # # ]: 0 : while ( (start_face = valid_start(all_faces) ) != NULL )
1380 : : {
1381 : : //create a list.
1382 [ # # ]: 0 : stack.clean_out();
1383 [ # # ][ # # ]: 0 : new_list = new DLIList<RefEntity*>;
1384 [ # # ]: 0 : stack.append(start_face);
1385 [ # # ]: 0 : start_face->marked(1);
1386 [ # # ]: 0 : marked_faces.append(start_face);
1387 : :
1388 [ # # ][ # # ]: 0 : while (stack.size() > 0 )
1389 : : {
1390 [ # # ]: 0 : curr_edges.clean_out();
1391 : :
1392 [ # # ]: 0 : curr_face = stack.pop(); // get last face added
1393 [ # # ]: 0 : tmp_ent = CAST_TO(curr_face, RefEntity);
1394 [ # # ]: 0 : new_list->append(tmp_ent); // append that face to the newest list
1395 [ # # ]: 0 : curr_face->ref_edges(curr_edges); // gets list of face's edges
1396 : :
1397 [ # # ][ # # ]: 0 : for( ii = 0; ii < curr_edges.size(); ii++ ) // loops edges
1398 : : {
1399 [ # # ]: 0 : related_faces.clean_out();
1400 : :
1401 [ # # ]: 0 : curr_edge = curr_edges.get_and_step(); // chooses next edge
1402 [ # # ]: 0 : curr_edge->ref_faces(related_faces); // finds edge's related faces
1403 [ # # ][ # # ]: 0 : for( jj = 0; jj < related_faces.size(); jj++ ) // loops faces
1404 : : {
1405 [ # # ]: 0 : related_face = related_faces.get_and_step(); // gets face
1406 [ # # ][ # # ]: 0 : if(!related_face->marked() && related_face->num_ref_volumes() == 1)
[ # # ][ # # ]
[ # # ]
1407 : : {
1408 [ # # ]: 0 : stack.append(related_face);
1409 [ # # ]: 0 : related_face->marked(1);
1410 [ # # ]: 0 : marked_faces.append(related_face);
1411 : : }
1412 : : }
1413 : : }
1414 : : }
1415 [ # # ]: 0 : list_of_lists.append(new_list);
1416 : 0 : number_of_shells++;
1417 : : }
1418 : :
1419 [ # # ][ # # ]: 0 : for (ii = 0; ii < marked_faces.size(); ii++ )
1420 : : {
1421 [ # # ]: 0 : curr_face = marked_faces.get_and_step();
1422 [ # # ]: 0 : curr_face->marked(0);
1423 : : }
1424 : :
1425 : : RefGroup *curr_group;
1426 [ # # ][ # # ]: 0 : owner_groups = RefEntityFactory::instance()->construct_RefGroup("volume_shells");
1427 [ # # ][ # # ]: 0 : for( ii = list_of_lists.size(); ii > 0; ii-- )
1428 : : {
1429 [ # # ]: 0 : new_list = list_of_lists.pop();
1430 [ # # ][ # # ]: 0 : curr_group = RefEntityFactory::instance()->construct_RefGroup(*new_list);
1431 : 0 : tmp_ent = CAST_TO(curr_group, RefEntity);
1432 [ # # ]: 0 : owner_groups->add_ref_entity(tmp_ent);
1433 [ # # ][ # # ]: 0 : delete new_list;
1434 [ # # ]: 0 : }
1435 : 0 : }
1436 : :
1437 : 0 : void GeomMeasureTool::print_surface_measure_summary( DLIList <RefFace*> &ref_faces )
1438 : :
1439 : : {
1440 : :
1441 : 0 : double min_dist_loops=CUBIT_DBL_MAX, min_dist_loop=CUBIT_DBL_MAX;
1442 : 0 : double curr_min_dist_loops=CUBIT_DBL_MAX, curr_min_dist_loop=CUBIT_DBL_MAX;
1443 : 0 : double min_angle=CUBIT_DBL_MAX, max_angle=-CUBIT_DBL_MAX;
1444 : 0 : double curr_min_angle=CUBIT_DBL_MAX, curr_max_angle=-CUBIT_DBL_MAX;
1445 : : double curr_face_area, curr_face_hydraulic_radius;
1446 : 0 : double min_face_area=CUBIT_DBL_MAX, min_face_hydraulic_radius=CUBIT_DBL_MAX;
1447 : 0 : double max_face_area=-CUBIT_DBL_MAX;
1448 : 0 : int counter = 0;
1449 : 0 : double total_area= 0.0;
1450 : 0 : double min_curve_length = CUBIT_DBL_MAX;
1451 : 0 : double max_curve_ratio = -CUBIT_DBL_MAX;
1452 : : double curve_length, curve_ratio;
1453 : : int ii;
1454 : :
1455 : : RefFace *curr_face;
1456 : 0 : RefFace *face_min_dist_loops=NULL, *face_min_dist_loop=NULL;
1457 : 0 : RefFace *face_min_angle=NULL, *face_max_angle=NULL;
1458 : 0 : RefFace *face_min_area=NULL, *face_min_hydraulic_radius=NULL;
1459 : 0 : RefFace *face_max_area=NULL;
1460 : 0 : RefFace *face_min_curve_length=NULL, *face_max_curve_ratio=NULL;
1461 : 0 : RefEdge *smallest_edge=NULL, *curr_small_edge=NULL;
1462 : :
1463 : :
1464 [ # # ][ # # ]: 0 : for( ii = 0; ii < ref_faces.size(); ii++ )
1465 : : {
1466 [ # # ]: 0 : curr_face = ref_faces.get_and_step();
1467 [ # # ][ # # ]: 0 : if ( curr_face->num_ref_edges() > 0 )
1468 : : {
1469 : : GeomMeasureTool::measure_face_loops(curr_face,
1470 : : curr_min_dist_loops,
1471 : : curr_min_dist_loop,
1472 : : curr_min_angle,
1473 : : curr_max_angle,
1474 [ # # ]: 0 : GEOMETRY_RESABS*500);
1475 : : GeomMeasureTool::measure_face_area_and_hydraulic_radius(curr_face,
1476 : : curr_face_area,
1477 [ # # ]: 0 : curr_face_hydraulic_radius);
1478 : : GeomMeasureTool::measure_face_curves(curr_face, curve_length,
1479 [ # # ]: 0 : curve_ratio, curr_small_edge);
1480 : : }
1481 : : else
1482 [ # # ]: 0 : curr_face_area = curr_face->measure();
1483 : :
1484 : 0 : total_area += curr_face_area;
1485 : 0 : counter++;
1486 [ # # ][ # # ]: 0 : if ( curr_face->num_ref_edges() > 0 )
1487 : : {
1488 [ # # ]: 0 : if ( curve_length < min_curve_length )
1489 : : {
1490 : 0 : min_curve_length = curve_length;
1491 : 0 : smallest_edge = curr_small_edge;
1492 : 0 : face_min_curve_length = curr_face;
1493 : : }
1494 [ # # ][ # # ]: 0 : if ( curve_ratio != -1.0 && curve_ratio > max_curve_ratio )
1495 : : {
1496 : 0 : max_curve_ratio = curve_ratio;
1497 : 0 : face_max_curve_ratio = curr_face;
1498 : : }
1499 [ # # ][ # # ]: 0 : if ( curr_min_dist_loops != -1.0 && curr_min_dist_loops < min_dist_loops )
1500 : : {
1501 : 0 : face_min_dist_loops = curr_face;
1502 : 0 : min_dist_loops = curr_min_dist_loops;
1503 : : }
1504 [ # # ]: 0 : if ( curr_min_dist_loop < min_dist_loop )
1505 : : {
1506 : 0 : face_min_dist_loop = curr_face;
1507 : 0 : min_dist_loop = curr_min_dist_loop;
1508 : : }
1509 [ # # ]: 0 : if ( curr_min_angle < min_angle )
1510 : : {
1511 : 0 : face_min_angle = curr_face;
1512 : 0 : min_angle = curr_min_angle;
1513 : : }
1514 [ # # ]: 0 : if ( curr_max_angle > max_angle )
1515 : : {
1516 : 0 : face_max_angle = curr_face;
1517 : 0 : max_angle = curr_max_angle;
1518 : : }
1519 : :
1520 [ # # ]: 0 : if ( curr_face_hydraulic_radius < min_face_hydraulic_radius )
1521 : : {
1522 : 0 : min_face_hydraulic_radius = curr_face_hydraulic_radius;
1523 : 0 : face_min_hydraulic_radius = curr_face;
1524 : : }
1525 : :
1526 : : }
1527 [ # # ]: 0 : if ( curr_face_area < min_face_area )
1528 : : {
1529 : 0 : min_face_area = curr_face_area;
1530 : 0 : face_min_area = curr_face;
1531 : : }
1532 [ # # ]: 0 : if ( curr_face_area > max_face_area )
1533 : : {
1534 : 0 : max_face_area = curr_face_area;
1535 : 0 : face_max_area = curr_face;
1536 : : }
1537 : : }
1538 [ # # ]: 0 : if ( counter > 0 )
1539 : : {
1540 [ # # ][ # # ]: 0 : PRINT_INFO("\n******Summary of Surface Measure Info*******\n\n");
[ # # ][ # # ]
1541 [ # # ][ # # ]: 0 : PRINT_INFO("Measured %d surfaces: Average Area: %f \n\n", counter, total_area/counter );
[ # # ][ # # ]
1542 [ # # ][ # # ]: 0 : PRINT_INFO("Minimum Surface Area is: %f on surface %d\n\n",
[ # # ][ # # ]
1543 [ # # ]: 0 : min_face_area, face_min_area->id());
1544 [ # # ][ # # ]: 0 : PRINT_INFO("Maximum Surface Area is: %f on surface %d\n\n",
[ # # ][ # # ]
1545 [ # # ]: 0 : max_face_area, face_max_area->id());
1546 [ # # ]: 0 : if ( face_min_hydraulic_radius )
1547 [ # # ][ # # ]: 0 : PRINT_INFO("Minimum Hydraulic Radius (Area/Perimeter) is: %f on surface %d\n\n",
[ # # ][ # # ]
1548 [ # # ]: 0 : min_face_hydraulic_radius, face_min_hydraulic_radius->id());
1549 [ # # ]: 0 : if ( smallest_edge )
1550 [ # # ][ # # ]: 0 : PRINT_INFO("Minimum Curve Length is: %f for curve %d on surface %d\n\n",
[ # # ][ # # ]
[ # # ]
1551 [ # # ]: 0 : min_curve_length, smallest_edge->id(), face_min_curve_length->id());
1552 [ # # ]: 0 : if ( face_max_curve_ratio )
1553 [ # # ][ # # ]: 0 : PRINT_INFO("Maximum Ratio of Adjacent Curve Lengths is: %f on surface %d\n\n",
[ # # ][ # # ]
1554 [ # # ]: 0 : max_curve_ratio, face_max_curve_ratio->id());
1555 [ # # ][ # # ]: 0 : if ( face_min_dist_loops && face_min_dist_loops->num_loops() > 1 )
[ # # ][ # # ]
1556 : : {
1557 [ # # ][ # # ]: 0 : PRINT_INFO("Minimum Distance Between Loops is: %f on surface %d\n\n",
[ # # ][ # # ]
1558 [ # # ]: 0 : min_dist_loops, face_min_dist_loops->id());
1559 : : }
1560 [ # # ]: 0 : if ( face_min_dist_loop )
1561 [ # # ][ # # ]: 0 : PRINT_INFO("Minimum Distance Between a Single Loop is: %f on surface %d\n\n",
[ # # ][ # # ]
1562 [ # # ]: 0 : min_dist_loop, face_min_dist_loop->id());
1563 [ # # ]: 0 : if ( face_min_angle )
1564 [ # # ][ # # ]: 0 : PRINT_INFO("Minimum Interior Angle Between Curves is: %f Degrees on surface %d\n\n",
[ # # ][ # # ]
1565 [ # # ]: 0 : min_angle, face_min_angle->id());
1566 [ # # ]: 0 : if ( face_max_angle )
1567 [ # # ][ # # ]: 0 : PRINT_INFO("Maximum Interior Angle Between Curves is: %f Degrees on surface %d\n\n",
[ # # ][ # # ]
1568 [ # # ]: 0 : max_angle, face_max_angle->id());
1569 [ # # ][ # # ]: 0 : center(ref_faces);
[ # # ]
1570 [ # # ][ # # ]: 0 : PRINT_INFO("************End of Summary***********\n\n");
[ # # ][ # # ]
1571 : : }
1572 : :
1573 : 0 : }
1574 : 0 : void GeomMeasureTool::find_adjacent_face_ratios(RefVolume *curr_volume, double &max_face_ratio,
1575 : : RefFace *&big_face,
1576 : : RefFace *&small_face)
1577 : : {
1578 : : //Loop over all the faces in the model. Find the maximum face area ratio.
1579 : : //(larger face area / smaller face area)
1580 : :
1581 [ # # ]: 0 : DLIList <Shell*> shells;
1582 [ # # ]: 0 : curr_volume->shells(shells);
1583 [ # # ][ # # ]: 0 : DLIList <RefFace*> ref_face_stack, adj_faces;
[ # # ][ # # ]
[ # # ][ # # ]
1584 : : Shell* curr_shell;
1585 : : RefFace *curr_ref_face, *adj_face;
1586 : : //AreaHashTuple is defined in the .hpp file.
1587 : : DLIList <AreaHashTuple*> *hash_table;
1588 : 0 : max_face_ratio = -CUBIT_DBL_MAX;
1589 : :
1590 : :
1591 : : int ii, jj, table_size;
1592 : : int hash_val;
1593 : : double tmp_area;
1594 : : double tmp_ratio;
1595 : :
1596 : : AreaHashTuple* curr_tuple, *adj_tuple;
1597 : :
1598 [ # # ][ # # ]: 0 : for ( ii = shells.size(); ii > 0; ii-- )
[ # # ][ # # ]
1599 : : {
1600 [ # # ]: 0 : curr_shell = shells.get_and_step();
1601 [ # # ]: 0 : ref_face_stack.clean_out();
1602 [ # # ]: 0 : curr_shell->ref_faces(ref_face_stack);
1603 [ # # ]: 0 : table_size = ref_face_stack.size();
1604 : : //build a hash table with the most simple form
1605 : : //of hashing based on the ref face id.
1606 : : //To get this more reliable, make table size a prime
1607 : : //number...
1608 : : //Do this so that we don't have to calculate the
1609 : : //areas more than once...
1610 [ # # ][ # # ]: 0 : hash_table = new DLIList<AreaHashTuple*> [table_size];
[ # # ]
[ # # # # ]
1611 [ # # ][ # # ]: 0 : for ( jj = 0; jj < ref_face_stack.size(); jj++ )
1612 : : {
1613 [ # # ]: 0 : curr_ref_face = ref_face_stack.get_and_step();
1614 [ # # ]: 0 : tmp_area = curr_ref_face->measure();
1615 [ # # ][ # # ]: 0 : curr_tuple = new AreaHashTuple();
1616 : 0 : curr_tuple->myFace = curr_ref_face;
1617 : 0 : curr_tuple->myArea = tmp_area;
1618 [ # # ]: 0 : hash_val = curr_ref_face->id() % table_size;
1619 [ # # ]: 0 : hash_table[hash_val].append(curr_tuple);
1620 : : }
1621 : :
1622 [ # # ][ # # ]: 0 : while ( ref_face_stack.size() )
1623 : : {
1624 [ # # ]: 0 : curr_ref_face = ref_face_stack.pop();
1625 : : //Now get the adjacent faces.
1626 [ # # ]: 0 : get_adjacent_faces(curr_ref_face, adj_faces);
1627 [ # # ]: 0 : find_index(hash_table, table_size, curr_ref_face, curr_tuple);
1628 [ # # ]: 0 : assert(curr_tuple != NULL);
1629 [ # # ]: 0 : if ( curr_tuple == NULL )
1630 [ # # ]: 0 : return;
1631 : 0 : CubitBoolean curr_is_big = CUBIT_TRUE;
1632 [ # # ][ # # ]: 0 : for ( jj = 0; jj < adj_faces.size(); jj++ )
1633 : : {
1634 [ # # ]: 0 : adj_face = adj_faces.get_and_step();
1635 [ # # ]: 0 : find_index(hash_table, table_size, adj_face, adj_tuple);
1636 [ # # ]: 0 : if ( adj_tuple == NULL )
1637 : 0 : continue;
1638 : 0 : curr_is_big = CUBIT_TRUE;
1639 [ # # ]: 0 : if ( curr_tuple->myArea < adj_tuple->myArea )
1640 : : {
1641 : 0 : tmp_ratio = adj_tuple->myArea / curr_tuple->myArea;
1642 : 0 : curr_is_big = CUBIT_FALSE;
1643 : : }
1644 : : else
1645 : 0 : tmp_ratio = curr_tuple->myArea / adj_tuple->myArea;
1646 [ # # ]: 0 : if ( tmp_ratio > max_face_ratio )
1647 : : {
1648 : 0 : max_face_ratio = tmp_ratio;
1649 [ # # ]: 0 : if ( curr_is_big )
1650 : : {
1651 : 0 : big_face = curr_ref_face;
1652 : 0 : small_face = adj_face;
1653 : : }
1654 : : else
1655 : : {
1656 : 0 : big_face = adj_face;
1657 : 0 : small_face = curr_ref_face;
1658 : : }
1659 : : }
1660 : : }
1661 : : }
1662 [ # # ]: 0 : for ( jj = 0; jj < table_size; jj++ )
1663 : : {
1664 : : //delete the area tuples.
1665 [ # # ][ # # ]: 0 : while ( hash_table[jj].size() > 0 )
1666 [ # # ][ # # ]: 0 : delete hash_table[jj].pop();
[ # # ]
1667 : : }
1668 : : //delete the hash_table.
1669 [ # # ][ # # ]: 0 : delete [] hash_table;
[ # # ]
1670 : 0 : }
1671 : : }
1672 : 0 : void GeomMeasureTool::find_index(DLIList<AreaHashTuple*> *hash_table,
1673 : : int table_size,
1674 : : RefFace *ref_face,
1675 : : AreaHashTuple *&curr_tuple )
1676 : : {
1677 : : int ii;
1678 : 0 : int hash_val = ref_face->id() % table_size;
1679 [ # # ]: 0 : if ( hash_table[hash_val].size() == 0 )
1680 : : {
1681 : : //this ref face isn't store here.
1682 : 0 : curr_tuple = NULL;
1683 : 0 : return;
1684 : : }
1685 : 0 : int curr_size = hash_table[hash_val].size();
1686 : : //resolve collisions by separate chaining method...
1687 [ # # ]: 0 : for ( ii = 0;ii < curr_size; ii++ )
1688 : : {
1689 [ # # ]: 0 : if ( hash_table[hash_val].next(ii)->myFace == ref_face )
1690 : : {
1691 : 0 : curr_tuple = hash_table[hash_val].next(ii);
1692 : 0 : return;
1693 : : }
1694 : : }
1695 : 0 : curr_tuple = NULL;
1696 : 0 : return;
1697 : : }
1698 : :
1699 : 0 : void GeomMeasureTool::get_adjacent_faces(RefFace* curr_face,
1700 : : DLIList<RefFace*> &adjacent_faces)
1701 : : {
1702 [ # # ]: 0 : DLIList <RefEdge*> ref_edges;
1703 [ # # ][ # # ]: 0 : DLIList <RefFace*> tmp_ref_faces;
1704 [ # # ]: 0 : curr_face->ref_edges(ref_edges);
1705 : : RefEdge *ref_edge;
1706 : : RefFace *tmp_ref_face;
1707 : : int ii, jj;
1708 [ # # ][ # # ]: 0 : for ( ii = 0; ii < ref_edges.size(); ii++ )
1709 : : {
1710 [ # # ]: 0 : ref_edge = ref_edges.get_and_step();
1711 [ # # ]: 0 : tmp_ref_faces.clean_out();
1712 [ # # ]: 0 : ref_edge->ref_faces(tmp_ref_faces);
1713 [ # # ][ # # ]: 0 : for ( jj = 0; jj < tmp_ref_faces.size(); jj++ )
1714 : : {
1715 [ # # ]: 0 : tmp_ref_face = tmp_ref_faces.get_and_step();
1716 [ # # ][ # # ]: 0 : if ( !tmp_ref_face->marked() && tmp_ref_face != curr_face )
[ # # ][ # # ]
1717 : : {
1718 [ # # ]: 0 : tmp_ref_face->marked(1);
1719 [ # # ]: 0 : adjacent_faces.append(tmp_ref_face);
1720 : : }
1721 : : else
1722 : 0 : continue;
1723 : : }
1724 : : }
1725 [ # # ][ # # ]: 0 : for ( ii = adjacent_faces.size(); ii > 0; ii-- )
1726 [ # # ][ # # ]: 0 : adjacent_faces.get_and_step()->marked(0);
[ # # ]
1727 : 0 : }
1728 : 0 : void GeomMeasureTool::print_volume_measure_summary(DLIList <RefVolume*> &ref_volumes)
1729 : : {
1730 : : int ii;
1731 : : RefVolume *curr_volume;
1732 : : RefFace *curr_face;
1733 [ # # ][ # # ]: 0 : DLIList <RefFace*> ref_faces, tmp_faces;
[ # # ]
1734 : : //First get a list of all the ref_faces.
1735 : : //Get them uniquely.
1736 [ # # ][ # # ]: 0 : for ( ii = 0; ii< ref_volumes.size(); ii++ )
1737 : : {
1738 [ # # ]: 0 : curr_volume = ref_volumes.get_and_step();
1739 [ # # ]: 0 : tmp_faces.clean_out();
1740 [ # # ]: 0 : curr_volume->ref_faces(tmp_faces);
1741 : : int jj;
1742 [ # # ][ # # ]: 0 : for ( jj = 0; jj < tmp_faces.size(); jj++ )
1743 : : {
1744 [ # # ]: 0 : curr_face = tmp_faces.get_and_step();
1745 [ # # ][ # # ]: 0 : if ( curr_face->marked() )
1746 : 0 : continue;
1747 : : else
1748 : : {
1749 [ # # ]: 0 : curr_face->marked(1);
1750 [ # # ]: 0 : ref_faces.append(curr_face);
1751 : : }
1752 : : }
1753 : : }
1754 : : //reset the mark.
1755 [ # # ][ # # ]: 0 : for ( ii = 0; ii< ref_faces.size(); ii++ )
1756 [ # # ][ # # ]: 0 : ref_faces.get_and_step()->marked(0);
1757 : :
1758 : : double volume_volume, volume_hydraulic_radius;
1759 : 0 : double min_angle=CUBIT_DBL_MAX, max_angle=-CUBIT_DBL_MAX;
1760 : 0 : double total_volume = 0.0, min_volume_hydraulic_radius = CUBIT_DBL_MAX;
1761 : 0 : double min_volume=CUBIT_DBL_MAX; //, max_volume=-CUBIT_DBL_MAX;
1762 : 0 : double curr_min_angle = 361.0, curr_max_angle =361.;
1763 : 0 : double max_face_ratio = -CUBIT_DBL_MAX, curr_face_ratio=CUBIT_DBL_MAX;
1764 : :
1765 : :
1766 : 0 : RefVolume *volume_min_volume = NULL, *volume_min_hydraulic_radius=NULL;
1767 : 0 : RefVolume *volume_min_angle=NULL, *volume_max_angle=NULL;
1768 : 0 : RefVolume *volume_face_ratio= NULL;
1769 : 0 : RefFace *max_small_face=NULL, *max_big_face=NULL;
1770 : 0 : RefFace *small_face=NULL, *big_face=NULL;
1771 : 0 : RefFace *face_min_1=NULL, *face_min_2=NULL;
1772 : 0 : RefFace *face_max_1=NULL, *face_max_2=NULL;
1773 : 0 : RefFace *face_min_angle_1=NULL, *face_min_angle_2=NULL;
1774 : 0 : RefFace *face_max_angle_1=NULL, *face_max_angle_2=NULL;
1775 : :
1776 : :
1777 : 0 : int counter = 0;
1778 : :
1779 [ # # ][ # # ]: 0 : for( ii = 0; ii< ref_volumes.size(); ii++ )
1780 : : {
1781 [ # # ]: 0 : curr_volume = ref_volumes.get_and_step();
1782 : : GeomMeasureTool::measure_volume_volume_and_hydraulic_radius(curr_volume,
1783 : : volume_volume,
1784 [ # # ]: 0 : volume_hydraulic_radius);
1785 [ # # ][ # # ]: 0 : if ( curr_volume->num_ref_faces() > 1 )
1786 : : {
1787 : : GeomMeasureTool::angles_between_volume_surfaces(curr_volume,
1788 : : curr_min_angle,
1789 : : curr_max_angle,
1790 : : face_min_1, face_min_2,
1791 [ # # ]: 0 : face_max_1, face_max_2);
1792 : : GeomMeasureTool::find_adjacent_face_ratios(curr_volume,
1793 : : curr_face_ratio,
1794 [ # # ]: 0 : big_face, small_face);
1795 : : }
1796 : 0 : total_volume += volume_volume;
1797 : 0 : counter++;
1798 [ # # ]: 0 : if ( volume_volume < min_volume )
1799 : : {
1800 : 0 : volume_min_volume = curr_volume;
1801 : 0 : min_volume = volume_volume;
1802 : : }
1803 [ # # ]: 0 : if ( volume_hydraulic_radius < min_volume_hydraulic_radius )
1804 : : {
1805 : 0 : volume_min_hydraulic_radius = curr_volume;
1806 : 0 : min_volume_hydraulic_radius = volume_hydraulic_radius;
1807 : : }
1808 [ # # ][ # # ]: 0 : if ( curr_volume->num_ref_faces() > 1 && curr_min_angle < min_angle )
[ # # ][ # # ]
1809 : : {
1810 : 0 : volume_min_angle = curr_volume;
1811 : 0 : face_min_angle_1 = face_min_1;
1812 : 0 : face_min_angle_2 = face_min_2;
1813 : 0 : min_angle = curr_min_angle;
1814 : : }
1815 [ # # ][ # # ]: 0 : if ( curr_volume->num_ref_faces() > 1 && curr_max_angle > max_angle )
[ # # ][ # # ]
1816 : : {
1817 : 0 : volume_max_angle = curr_volume;
1818 : 0 : max_angle = curr_max_angle;
1819 : 0 : face_max_angle_1 = face_max_1;
1820 : 0 : face_max_angle_2 = face_max_2;
1821 : : }
1822 [ # # ][ # # ]: 0 : if ( curr_volume->num_ref_faces() > 1 && curr_face_ratio > max_face_ratio )
[ # # ][ # # ]
1823 : : {
1824 : 0 : volume_face_ratio = curr_volume;
1825 : 0 : max_face_ratio = curr_face_ratio;
1826 : 0 : max_small_face = small_face;
1827 : 0 : max_big_face = big_face;
1828 : : }
1829 : : }
1830 [ # # ]: 0 : if ( counter > 0 )
1831 : : {
1832 [ # # ][ # # ]: 0 : PRINT_INFO("*************Volume Summary************\n\n");
[ # # ][ # # ]
1833 [ # # ][ # # ]: 0 : PRINT_INFO("Measured %d Volumes: Average Volume was %f.\n\n",
[ # # ]
1834 [ # # ]: 0 : counter, total_volume/counter);
1835 [ # # ][ # # ]: 0 : PRINT_INFO("Minimum Volume was %f in volume %d\n\n",
[ # # ][ # # ]
1836 [ # # ]: 0 : min_volume, volume_min_volume->id());
1837 [ # # ][ # # ]: 0 : PRINT_INFO("Minimum Volume Hydraulic Radius (volume/surface area) was %f in volume %d\n\n",
[ # # ][ # # ]
1838 [ # # ]: 0 : min_volume_hydraulic_radius, volume_min_hydraulic_radius->id());
1839 [ # # ]: 0 : if ( volume_min_angle )
1840 [ # # ][ # # ]: 0 : PRINT_INFO("Minimum Interior Angle Between Two Surfaces was %f,\n"
[ # # ][ # # ]
[ # # ][ # # ]
1841 : : "\tsurfaces %d and %d in volume %d\n\n",
1842 [ # # ]: 0 : min_angle, face_min_angle_1->id(), face_min_angle_2->id(), volume_min_angle->id());
1843 [ # # ]: 0 : if ( volume_max_angle )
1844 [ # # ][ # # ]: 0 : PRINT_INFO("Maximum Interior Angle Between Two Surfaces was %f,\n"
[ # # ][ # # ]
[ # # ][ # # ]
1845 : : "\tsurfaces %d and %d in volume %d\n\n",
1846 [ # # ]: 0 : max_angle, face_max_angle_1->id(), face_max_angle_2->id(), volume_max_angle->id());
1847 [ # # ]: 0 : if ( volume_face_ratio )
1848 [ # # ][ # # ]: 0 : PRINT_INFO("Maximum Area Ratios Between Adjacent Faces was %f,\n"
[ # # ][ # # ]
[ # # ][ # # ]
1849 : : "\tsurfaces %d and %d in volume %d.\n\n",
1850 [ # # ]: 0 : max_face_ratio, max_big_face->id(), max_small_face->id(), volume_face_ratio->id());
1851 : : int merged, unmerged;
1852 : : double ratio;
1853 [ # # ]: 0 : GeomMeasureTool::merged_unmerged_surface_ratio(ref_volumes, merged, unmerged, ratio);
1854 [ # # ][ # # ]: 0 : PRINT_INFO("Total number of merged surfaces:\t%d\n"
[ # # ]
1855 : : "Total number of unmerged surfaces:\t%d\n"
1856 [ # # ]: 0 : "Ratio of merged to unmerged surfaces:\t%f\n\n", merged, unmerged, ratio);
1857 : : RefGroup *group_of_shells;
1858 : : int number_shells;
1859 [ # # ]: 0 : GeomMeasureTool::find_shells(ref_volumes, group_of_shells, number_shells);
1860 [ # # ]: 0 : if ( number_shells > 0 )
1861 : : {
1862 [ # # ]: 0 : if ( number_shells == 1 )
1863 : : {
1864 [ # # ][ # # ]: 0 : PRINT_INFO("Found %d shell of connected surfaces.\n", number_shells);
[ # # ][ # # ]
1865 [ # # ][ # # ]: 0 : PRINT_INFO("These shell is contained in the group %s\n",
[ # # ][ # # ]
[ # # ][ # # ]
1866 [ # # ]: 0 : group_of_shells->entity_name().c_str());
1867 : : }
1868 : : else
1869 : : {
1870 [ # # ][ # # ]: 0 : PRINT_INFO("Found %d shells of connected surfaces.\n", number_shells);
[ # # ][ # # ]
1871 [ # # ][ # # ]: 0 : PRINT_INFO("These shells are contained in the group %s\n",
[ # # ][ # # ]
[ # # ][ # # ]
1872 [ # # ]: 0 : group_of_shells->entity_name().c_str());
1873 : : }
1874 : : }
1875 [ # # ][ # # ]: 0 : PRINT_INFO("\n\n");
[ # # ][ # # ]
1876 [ # # ][ # # ]: 0 : PRINT_INFO("Now Printing Summaries of Surfaces contained by these volumes.\n");
[ # # ][ # # ]
1877 [ # # ]: 0 : GeomMeasureTool::print_surface_measure_summary(ref_faces);
1878 : : }
1879 [ # # ]: 0 : return;
1880 : :
1881 : : }
1882 : :
1883 : : // Find all of the surfaces in the given volumes that have narrow regions.
1884 : 0 : void GeomMeasureTool::find_surfs_with_narrow_regions(DLIList <RefVolume*> &ref_vols,
1885 : : double tol,
1886 : : DLIList <RefFace*> &surfs_with_narrow_regions)
1887 : : {
1888 : : int j;
1889 : :
1890 : : int ii, jj;
1891 [ # # ][ # # ]: 0 : DLIList <RefFace*> ref_faces, temp_faces;
[ # # ][ # # ]
1892 : : RefVolume *ref_vol;
1893 : : RefFace *curr_face;
1894 [ # # ][ # # ]: 0 : for ( ii = 0; ii < ref_vols.size(); ii++ )
1895 : : {
1896 [ # # ]: 0 : DLIList<RefFace*> faces;
1897 [ # # ]: 0 : ref_vol = ref_vols.get_and_step();
1898 [ # # ]: 0 : ref_vol->ref_faces(faces);
1899 [ # # ][ # # ]: 0 : for ( jj = faces.size(); jj > 0; jj-- )
1900 : : {
1901 [ # # ]: 0 : curr_face = faces.get_and_step();
1902 [ # # ]: 0 : curr_face->marked(0);
1903 [ # # ]: 0 : temp_faces.append(curr_face);
1904 : : }
1905 [ # # ]: 0 : }
1906 : :
1907 : : //uniquely add the faces.
1908 [ # # ][ # # ]: 0 : for ( jj = temp_faces.size(); jj > 0; jj-- )
1909 : : {
1910 [ # # ]: 0 : curr_face = temp_faces.get_and_step();
1911 [ # # ][ # # ]: 0 : if ( curr_face->marked()== 0 )
1912 : : {
1913 [ # # ]: 0 : curr_face->marked(1);
1914 [ # # ]: 0 : ref_faces.append(curr_face);
1915 : : }
1916 : : }
1917 : :
1918 [ # # ]: 0 : int num_faces = ref_faces.size();
1919 : :
1920 : 0 : ProgressTool *progress_ptr = NULL;
1921 [ # # ]: 0 : if (num_faces > 20)
1922 : : {
1923 [ # # ][ # # ]: 0 : progress_ptr = AppUtil::instance()->progress_tool();
1924 [ # # ]: 0 : assert(progress_ptr != NULL);
1925 : : progress_ptr->start(0, 100, "Finding Surfaces with Narrow Regions",
1926 [ # # ]: 0 : NULL, CUBIT_TRUE, CUBIT_TRUE);
1927 : : }
1928 : :
1929 : 0 : int total_faces = 0;
1930 : 0 : double curr_percent = 0.0;
1931 : :
1932 [ # # ]: 0 : for(j=0; j<num_faces; j++)
1933 : : {
1934 [ # # ]: 0 : DLIList<CubitVector> split_pos1_list;
1935 [ # # ][ # # ]: 0 : DLIList<CubitVector> split_pos2_list;
[ # # ]
1936 [ # # ]: 0 : RefFace *cur_face = ref_faces.get_and_step();
1937 : 0 : total_faces++;
1938 [ # # ]: 0 : if ( progress_ptr != NULL )
1939 : : {
1940 : 0 : curr_percent = ((double)(total_faces))/((double)(num_faces));
1941 [ # # ]: 0 : progress_ptr->percent(curr_percent);
1942 : : }
1943 : :
1944 [ # # ][ # # ]: 0 : if ( AppUtil::instance()->interrupt() )
[ # # ]
1945 : : {
1946 : : //interrpt. We need to exit.
1947 [ # # ]: 0 : if ( progress_ptr != NULL )
1948 [ # # ]: 0 : progress_ptr->end();
1949 : : //just leave what has been calculated...
1950 : 0 : return;
1951 : : }
1952 : : find_split_points_for_narrow_regions(cur_face,
1953 [ # # ]: 0 : tol, split_pos1_list, split_pos2_list);
1954 [ # # ][ # # ]: 0 : if(split_pos1_list.size() > 0)
1955 [ # # ][ # # ]: 0 : surfs_with_narrow_regions.append_unique(cur_face);
[ # # ]
1956 : 0 : }
1957 : :
1958 [ # # ]: 0 : if ( progress_ptr != NULL )
1959 [ # # ][ # # ]: 0 : progress_ptr->end();
[ # # ]
1960 : : }
1961 : :
1962 : 0 : void GeomMeasureTool::get_narrow_regions(DLIList <RefVolume*> &ref_vols,
1963 : : double tol,
1964 : : DLIList <RefFace*> &surfs_with_narrow_regions)
1965 : : {
1966 : : int ii, jj;
1967 [ # # ][ # # ]: 0 : DLIList <RefFace*> ref_faces, temp_faces;
[ # # ][ # # ]
1968 : : RefVolume *ref_vol;
1969 : : RefFace *curr_face;
1970 [ # # ][ # # ]: 0 : for ( ii = 0; ii < ref_vols.size(); ii++ )
1971 : : {
1972 [ # # ]: 0 : DLIList<RefFace*> faces;
1973 [ # # ]: 0 : ref_vol = ref_vols.get_and_step();
1974 [ # # ]: 0 : ref_vol->ref_faces(faces);
1975 [ # # ][ # # ]: 0 : for ( jj = faces.size(); jj > 0; jj-- )
1976 : : {
1977 [ # # ]: 0 : curr_face = faces.get_and_step();
1978 [ # # ]: 0 : curr_face->marked(0);
1979 [ # # ]: 0 : temp_faces.append(curr_face);
1980 : : }
1981 [ # # ]: 0 : }
1982 : :
1983 : : //uniquely add the faces.
1984 [ # # ][ # # ]: 0 : for ( jj = temp_faces.size(); jj > 0; jj-- )
1985 : : {
1986 [ # # ]: 0 : curr_face = temp_faces.get_and_step();
1987 [ # # ][ # # ]: 0 : if ( curr_face->marked()== 0 )
1988 : : {
1989 [ # # ]: 0 : curr_face->marked(1);
1990 [ # # ]: 0 : ref_faces.append(curr_face);
1991 : : }
1992 : : }
1993 : :
1994 [ # # ]: 0 : int num_faces = ref_faces.size();
1995 : :
1996 : 0 : ProgressTool *progress_ptr = NULL;
1997 [ # # ]: 0 : if (num_faces > 20)
1998 : : {
1999 [ # # ][ # # ]: 0 : progress_ptr = AppUtil::instance()->progress_tool();
2000 [ # # ]: 0 : assert(progress_ptr != NULL);
2001 : : progress_ptr->start(0, 100, "Finding Surfaces with Narrow Regions",
2002 [ # # ]: 0 : NULL, CUBIT_TRUE, CUBIT_TRUE);
2003 : : }
2004 : :
2005 : 0 : int total_faces = 0;
2006 : 0 : double curr_percent = 0.0;
2007 : :
2008 [ # # ]: 0 : for(jj=0; jj<num_faces; jj++)
2009 : : {
2010 [ # # ]: 0 : RefFace *cur_face = ref_faces.get_and_step();
2011 : 0 : total_faces++;
2012 [ # # ]: 0 : if ( progress_ptr != NULL )
2013 : : {
2014 : 0 : curr_percent = ((double)(total_faces))/((double)(num_faces));
2015 [ # # ]: 0 : progress_ptr->percent(curr_percent);
2016 : : }
2017 : :
2018 [ # # ][ # # ]: 0 : if ( AppUtil::instance()->interrupt() )
[ # # ]
2019 : : {
2020 : : //interrpt. We need to exit.
2021 [ # # ]: 0 : if ( progress_ptr != NULL )
2022 [ # # ]: 0 : progress_ptr->end();
2023 : : //just leave what has been calculated...
2024 : 0 : return;
2025 : : }
2026 [ # # ][ # # ]: 0 : if(cur_face->num_loops() == 1)
2027 : : {
2028 [ # # ]: 0 : DLIList<CubitVector> split_pos1_list;
2029 [ # # ][ # # ]: 0 : DLIList<CubitVector> split_pos2_list;
2030 : : find_split_points_for_narrow_regions(cur_face,
2031 [ # # ]: 0 : tol, split_pos1_list, split_pos2_list);
2032 [ # # ][ # # ]: 0 : if(split_pos1_list.size() > 0)
2033 [ # # ][ # # ]: 0 : surfs_with_narrow_regions.append(cur_face);
2034 : : }
2035 [ # # ][ # # ]: 0 : else if(cur_face->num_loops() > 1)
2036 : : {
2037 [ # # ]: 0 : DLIList <RefEdge*> tmp_close_edges;
2038 [ # # ][ # # ]: 0 : DLIList <double> tmp_small_lengths;
2039 : : find_close_loops( cur_face, tmp_close_edges,
2040 [ # # ]: 0 : tmp_small_lengths, tol);
2041 [ # # ][ # # ]: 0 : if ( tmp_close_edges.size() > 0 )
2042 : : {
2043 [ # # ]: 0 : surfs_with_narrow_regions.append(cur_face);
2044 [ # # ]: 0 : }
2045 : : }
2046 : : }
2047 : :
2048 [ # # ]: 0 : if ( progress_ptr != NULL )
2049 [ # # ][ # # ]: 0 : progress_ptr->end();
[ # # ]
2050 : : }
2051 : :
2052 : 0 : bool GeomMeasureTool::is_surface_narrow(RefFace *face, double small_curve_size)
2053 : : {
2054 : 0 : bool ret = true;
2055 [ # # ]: 0 : DLIList<RefEdge*> edges;
2056 [ # # ]: 0 : face->ref_edges(edges);
2057 [ # # ]: 0 : RefVolume *vol = face->ref_volume();
2058 : : int i, j;
2059 : 0 : double dist_sq = small_curve_size*small_curve_size;
2060 : 0 : double proj_dist = 1.2 * small_curve_size;
2061 [ # # ][ # # ]: 0 : for(i=edges.size(); i>0 && ret == true; i--)
[ # # ]
2062 : : {
2063 [ # # ]: 0 : RefEdge *cur_edge = edges.get_and_step();
2064 [ # # ]: 0 : double edge_length = cur_edge->measure();
2065 [ # # ]: 0 : if(edge_length > small_curve_size)
2066 : : {
2067 : 0 : int num_incs = (int)(edge_length/small_curve_size) + 1;
2068 : : double start, end;
2069 [ # # ]: 0 : cur_edge->get_param_range(start, end);
2070 : 0 : double t = start;
2071 : 0 : bool one_bad = false;
2072 [ # # ][ # # ]: 0 : for(j=0; j<num_incs && ret == true; j++)
2073 : : {
2074 [ # # ][ # # ]: 0 : CubitVector pos1, tangent;
2075 [ # # ]: 0 : cur_edge->position_from_u(t, pos1);
2076 [ # # ]: 0 : cur_edge->tangent(pos1, tangent, face);
2077 [ # # ]: 0 : CubitVector norm = face->normal_at(pos1, vol);
2078 [ # # ]: 0 : CubitVector indir = norm * tangent;
2079 [ # # ]: 0 : indir.normalize();
2080 [ # # ][ # # ]: 0 : CubitVector new_pos = pos1 + proj_dist * indir;
2081 [ # # ]: 0 : CubitVector pt_on_surf;
2082 [ # # ][ # # ]: 0 : face->get_surface_ptr()->closest_point_trimmed(new_pos, pt_on_surf);
[ # # ]
2083 [ # # ][ # # ]: 0 : if((pt_on_surf-pos1).length_squared() < dist_sq)
[ # # ]
2084 : : {
2085 : 0 : one_bad = false;
2086 : : }
2087 : : else // we found one out of small_curve range
2088 : : {
2089 [ # # ]: 0 : if(one_bad) // if we had already found one out of range this makes two in a row
2090 : 0 : ret = false;
2091 : : else // this is the first one out of range
2092 : 0 : one_bad = true;
2093 : : }
2094 : : }
2095 : : }
2096 : : }
2097 : :
2098 [ # # ]: 0 : return ret;
2099 : : }
2100 : :
2101 : 0 : void GeomMeasureTool::find_split_points_for_narrow_regions(RefFace *face,
2102 : : double size,
2103 : : DLIList<CubitVector> &split_pos1_list,
2104 : : DLIList<CubitVector> &split_pos2_list)
2105 : : {
2106 : : int k, i, j;
2107 : 0 : double size_sq = size*size;
2108 [ # # ]: 0 : DLIList<RefEdge*> edges;
2109 [ # # ]: 0 : face->ref_edges(edges);
2110 [ # # ][ # # ]: 0 : while(edges.size() > 1)
2111 : : {
2112 [ # # ]: 0 : RefEdge *cur_edge = edges.extract();
2113 [ # # ][ # # ]: 0 : for(k=edges.size(); k--;)
2114 : : {
2115 [ # # ]: 0 : RefEdge *other_edge = edges.get_and_step();
2116 [ # # ][ # # ]: 0 : DLIList<CubitVector*> e1_pos_list, e2_pos_list;
[ # # ]
2117 [ # # ][ # # ]: 0 : DLIList<RefVertex*> e1_vert_list, e2_vert_list;
[ # # ][ # # ]
2118 [ # # ]: 0 : if(narrow_region_exists(cur_edge, other_edge, face, size,
2119 [ # # ]: 0 : e1_pos_list, e2_pos_list, e1_vert_list, e2_vert_list))
2120 : : {
2121 [ # # ]: 0 : e1_pos_list.reset();
2122 [ # # ]: 0 : e2_pos_list.reset();
2123 [ # # ]: 0 : e1_vert_list.reset();
2124 [ # # ]: 0 : e2_vert_list.reset();
2125 : :
2126 : : // Loop through each pair of positions defining a split.
2127 [ # # ][ # # ]: 0 : for(i=e1_pos_list.size(); i--;)
2128 : : {
2129 [ # # ]: 0 : RefVertex *e1_vert = e1_vert_list.get_and_step();
2130 [ # # ]: 0 : RefVertex *e2_vert = e2_vert_list.get_and_step();
2131 [ # # ]: 0 : CubitVector *e1_pos = e1_pos_list.get_and_step();
2132 [ # # ]: 0 : CubitVector *e2_pos = e2_pos_list.get_and_step();
2133 : :
2134 : : // Snap to existing vertices if we are not already at at vertex.
2135 [ # # ]: 0 : if(!e1_vert)
2136 : : {
2137 [ # # ][ # # ]: 0 : if((cur_edge->start_vertex()->coordinates() - *e1_pos).length_squared() < size_sq)
[ # # ][ # # ]
[ # # ]
2138 [ # # ]: 0 : e1_vert = cur_edge->start_vertex();
2139 [ # # ][ # # ]: 0 : else if((cur_edge->end_vertex()->coordinates() - *e1_pos).length_squared() < size_sq)
[ # # ][ # # ]
[ # # ]
2140 [ # # ]: 0 : e1_vert = cur_edge->end_vertex();
2141 : : }
2142 [ # # ]: 0 : if(!e2_vert)
2143 : : {
2144 [ # # ][ # # ]: 0 : if((other_edge->start_vertex()->coordinates() - *e2_pos).length_squared() < size_sq)
[ # # ][ # # ]
[ # # ]
2145 [ # # ]: 0 : e2_vert = other_edge->start_vertex();
2146 [ # # ][ # # ]: 0 : else if((other_edge->end_vertex()->coordinates() - *e2_pos).length_squared() < size_sq)
[ # # ][ # # ]
[ # # ]
2147 [ # # ]: 0 : e2_vert = other_edge->end_vertex();
2148 : : }
2149 : :
2150 : : // We may have multiple edges separating these two vertices but the accumulated
2151 : : // length of them may still be within our narrow size so check this. If this
2152 : : // is the case we will not want to consider this as a place to split and
2153 : : // will as a result discard these positions.
2154 [ # # ][ # # ]: 0 : if(e1_vert && e2_vert)
2155 : : {
2156 : 0 : double dist = size*sqrt(2.0);
2157 : 0 : RefVertex *cur_vert = e1_vert;
2158 : 0 : RefEdge *edge = cur_edge;
2159 : 0 : double length = 0.0;
2160 [ # # ][ # # ]: 0 : while(edge && cur_vert != e2_vert && length <= dist)
[ # # ]
2161 : : {
2162 [ # # ]: 0 : edge = edge->get_other_curve(cur_vert, face);
2163 [ # # ]: 0 : if(edge)
2164 : : {
2165 [ # # ]: 0 : length += edge->get_arc_length();
2166 [ # # ]: 0 : cur_vert = edge->other_vertex(cur_vert);
2167 : : }
2168 : : }
2169 [ # # ]: 0 : if(length > dist)
2170 : : {
2171 : : // We want to keep this split.
2172 [ # # ][ # # ]: 0 : split_pos1_list.append(e1_vert->coordinates());
2173 [ # # ][ # # ]: 0 : split_pos2_list.append(e2_vert->coordinates());
2174 : 0 : }
2175 : : }
2176 : : else
2177 : : {
2178 : : // We want to keep this split.
2179 [ # # ]: 0 : split_pos1_list.append(*e1_pos);
2180 [ # # ]: 0 : split_pos2_list.append(*e2_pos);
2181 : : }
2182 : : }
2183 : : }
2184 [ # # ][ # # ]: 0 : while(e1_pos_list.size())
2185 [ # # ]: 0 : delete e1_pos_list.pop();
2186 [ # # ][ # # ]: 0 : while(e2_pos_list.size())
2187 [ # # ]: 0 : delete e2_pos_list.pop();
2188 [ # # ]: 0 : }
2189 : : }
2190 : :
2191 : : // Make splits unique
2192 [ # # ][ # # ]: 0 : DLIList<CubitVector> unique_list1, unique_list2;
[ # # ][ # # ]
2193 [ # # ]: 0 : split_pos1_list.reset();
2194 [ # # ]: 0 : split_pos2_list.reset();
2195 [ # # ][ # # ]: 0 : for(i=split_pos1_list.size(); i--;)
2196 : : {
2197 [ # # ][ # # ]: 0 : CubitVector p1 = split_pos1_list.get_and_step();
2198 [ # # ][ # # ]: 0 : CubitVector p2 = split_pos2_list.get_and_step();
2199 : 0 : int unique = 1;
2200 [ # # ][ # # ]: 0 : for(j=unique_list1.size(); j>0 && unique; j--)
[ # # ]
2201 : : {
2202 [ # # ][ # # ]: 0 : CubitVector u1 = unique_list1.get_and_step();
2203 [ # # ][ # # ]: 0 : CubitVector u2 = unique_list2.get_and_step();
2204 [ # # ][ # # ]: 0 : if((p1.about_equal(u1) && p2.about_equal(u2)) ||
[ # # ][ # # ]
[ # # ][ # # ]
2205 [ # # ][ # # ]: 0 : (p1.about_equal(u2) && p2.about_equal(u1)))
[ # # ]
2206 : : {
2207 : 0 : unique = 0;
2208 : : }
2209 : : }
2210 [ # # ]: 0 : if(unique)
2211 : : {
2212 [ # # ]: 0 : unique_list1.append(p1);
2213 [ # # ]: 0 : unique_list2.append(p2);
2214 : : }
2215 : : }
2216 [ # # ]: 0 : split_pos1_list = unique_list1;
2217 [ # # ][ # # ]: 0 : split_pos2_list = unique_list2;
2218 : 0 : }
2219 : :
2220 : : // Checks to see if at the given position the two edges are close together and
2221 : : // have the same tangent.
2222 : 0 : int GeomMeasureTool::is_narrow_region_at_point(RefEdge *e1,
2223 : : RefFace *face,
2224 : : const CubitVector &pt_on_e1,
2225 : : RefEdge *e2,
2226 : : const double &tol_sq,
2227 : : CubitVector &closest)
2228 : : {
2229 : 0 : int ret = 0;
2230 : :
2231 [ # # ][ # # ]: 0 : CubitVector tan_1, tan_2;
2232 [ # # ]: 0 : e2->closest_point_trimmed(pt_on_e1, closest);
2233 : :
2234 : 0 : double dist_sq = CUBIT_DBL_MAX;
2235 : :
2236 : : // If the surface is not a plane lets project
2237 : : // the midpoint to the surface and fit a circular
2238 : : // arc through the 3 points and get the arc length
2239 : : // to approximate the acutal distance on the surface
2240 : : // between the 2 original points.
2241 [ # # ][ # # ]: 0 : if(PLANE_SURFACE_TYPE != face->geometry_type())
2242 : : {
2243 [ # # ]: 0 : CubitVector closest_mid;
2244 [ # # ]: 0 : CubitVector vec1 = closest-pt_on_e1;
2245 [ # # ]: 0 : double straight_length_sq = vec1.length_squared();
2246 [ # # ][ # # ]: 0 : CubitVector mid = pt_on_e1 + 0.5 * vec1;
2247 [ # # ][ # # ]: 0 : face->get_surface_ptr()->closest_point(mid, &closest_mid);
2248 [ # # ]: 0 : CubitVector mid_vec = mid-closest_mid;
2249 [ # # ]: 0 : double mid_length_sq = mid_vec.length_squared();
2250 : : // If we are dealing with very small distances or
2251 : : // it doesn't look like there is much curvature just use
2252 : : // the straight line distance.
2253 [ # # ][ # # ]: 0 : if(straight_length_sq < 1e-10 || mid_length_sq < 0.01*straight_length_sq)
2254 : : {
2255 : 0 : dist_sq = straight_length_sq;
2256 : : }
2257 : : else
2258 : : {
2259 : 0 : double mid_length = sqrt(mid_length_sq);
2260 : 0 : double half_length = sqrt(straight_length_sq)/2.0;
2261 : : // theta is the angle between the vector from the orig point to its projection
2262 : : // on the other edge and the vector from the orig point to the projected mid point.
2263 : 0 : double theta = atan(mid_length/half_length);
2264 : : // beta is the angle between the vector going from the circle center to
2265 : : // the orig point and the vector going from the circle center to the
2266 : : // projected mid point.
2267 : 0 : double beta = 2.0*theta;
2268 : : // Some trig to get the radius of the circle that goes through all 3 points
2269 : 0 : double radius = half_length/sin(beta);
2270 : 0 : dist_sq = 2.0*radius*beta;
2271 : 0 : dist_sq *= dist_sq;
2272 : : }
2273 : : }
2274 : : else
2275 : : {
2276 [ # # ][ # # ]: 0 : dist_sq = (pt_on_e1-closest).length_squared();
2277 : : }
2278 : :
2279 [ # # ]: 0 : if(dist_sq < tol_sq)
2280 : : {
2281 [ # # ]: 0 : DLIList<CoEdge*> coes;
2282 [ # # ]: 0 : e1->tangent(pt_on_e1, tan_1);
2283 [ # # ]: 0 : e2->tangent(closest, tan_2);
2284 [ # # ]: 0 : e1->get_co_edges(coes, face);
2285 [ # # ][ # # ]: 0 : if(coes.size() == 1)
2286 : : {
2287 [ # # ][ # # ]: 0 : if(coes.get()->get_sense() == CUBIT_REVERSED)
[ # # ]
2288 [ # # ]: 0 : tan_1 *= -1.0;
2289 [ # # ]: 0 : coes.clean_out();
2290 [ # # ]: 0 : e2->get_co_edges(coes, face);
2291 [ # # ][ # # ]: 0 : if(coes.size() == 1)
2292 : : {
2293 [ # # ][ # # ]: 0 : if(coes.get()->get_sense() == CUBIT_REVERSED)
[ # # ]
2294 [ # # ]: 0 : tan_2 *= -1.0;
2295 [ # # ]: 0 : tan_1.normalize();
2296 [ # # ]: 0 : tan_2.normalize();
2297 [ # # ][ # # ]: 0 : if(tan_1 % tan_2 < -0.9)
2298 : 0 : ret = 1;
2299 : : }
2300 [ # # ]: 0 : }
2301 : : }
2302 : 0 : return ret;
2303 : : }
2304 : :
2305 : 0 : int GeomMeasureTool::narrow_region_exists(RefFace *face,
2306 : : const double &tol)
2307 : : {
2308 : 0 : int k, ret = 0;
2309 [ # # ]: 0 : DLIList<RefEdge*> edges;
2310 [ # # ]: 0 : face->ref_edges(edges);
2311 [ # # ]: 0 : int num_curves = edges.size();
2312 : :
2313 : : // if the surface has no bounding edges then we won't consider
2314 : : // it narrow. This can happen with complete sphere surfaces.
2315 [ # # ]: 0 : if (0 == num_curves)
2316 : 0 : return 0;
2317 : :
2318 : 0 : int num_small_curves = 0;
2319 [ # # ][ # # ]: 0 : while(edges.size() > 1 && !ret)
[ # # ][ # # ]
2320 : : {
2321 : : // Remove the current edge each time so that we aren't
2322 : : // doing redundant comparisons.
2323 [ # # ]: 0 : RefEdge *cur_edge = edges.extract();
2324 [ # # ][ # # ]: 0 : if(cur_edge->get_arc_length() < tol)
2325 : 0 : num_small_curves++;
2326 : :
2327 : : // Compare this edge with the remaining edges on the face.
2328 [ # # ][ # # ]: 0 : for(k=edges.size(); k && !ret; k--)
[ # # ]
2329 : : {
2330 [ # # ]: 0 : RefEdge *other_edge = edges.get_and_step();
2331 : :
2332 [ # # ][ # # ]: 0 : DLIList<CubitVector*> e1_pos_list, e2_pos_list;
[ # # ]
2333 [ # # ][ # # ]: 0 : DLIList<RefVertex*> e1_vert_list, e2_vert_list;
[ # # ][ # # ]
2334 : : ret = narrow_region_exists(cur_edge, other_edge, face, tol,
2335 [ # # ]: 0 : e1_pos_list, e2_pos_list, e1_vert_list, e2_vert_list);
2336 [ # # ][ # # ]: 0 : while(e1_pos_list.size())
2337 [ # # ]: 0 : delete e1_pos_list.pop();
2338 [ # # ][ # # ]: 0 : while(e2_pos_list.size())
2339 [ # # ]: 0 : delete e2_pos_list.pop();
2340 [ # # ]: 0 : }
2341 : : }
2342 [ # # ]: 0 : if(!ret)
2343 : : {
2344 [ # # ][ # # ]: 0 : if(edges.size() == 1 && edges.get()->get_arc_length() < tol)
[ # # ][ # # ]
[ # # ][ # # ]
2345 : 0 : num_small_curves++;
2346 : : }
2347 : :
2348 [ # # ][ # # ]: 0 : ret = ret || (num_small_curves == num_curves);
2349 : :
2350 [ # # ]: 0 : return ret;
2351 : : }
2352 : :
2353 : 0 : int GeomMeasureTool::narrow_region_exists(RefFace *face,
2354 : : RefEdge *edge,
2355 : : const double &tol)
2356 : : {
2357 : 0 : int k, ret = 0;
2358 [ # # ]: 0 : DLIList<RefEdge*> edges;
2359 [ # # ]: 0 : face->ref_edges(edges);
2360 [ # # ][ # # ]: 0 : if(edges.move_to(edge))
2361 : : {
2362 [ # # ]: 0 : edges.extract();
2363 : :
2364 : : // Compare this edge with the remaining edges on the face.
2365 [ # # ][ # # ]: 0 : for(k=edges.size(); k && !ret; k--)
[ # # ]
2366 : : {
2367 [ # # ]: 0 : RefEdge *other_edge = edges.get_and_step();
2368 : :
2369 [ # # ][ # # ]: 0 : DLIList<CubitVector*> e1_pos_list, e2_pos_list;
[ # # ]
2370 [ # # ][ # # ]: 0 : DLIList<RefVertex*> e1_vert_list, e2_vert_list;
[ # # ][ # # ]
2371 : : ret = narrow_region_exists(edge, other_edge, face, tol,
2372 [ # # ]: 0 : e1_pos_list, e2_pos_list, e1_vert_list, e2_vert_list);
2373 [ # # ][ # # ]: 0 : while(e1_pos_list.size())
2374 [ # # ]: 0 : delete e1_pos_list.pop();
2375 [ # # ][ # # ]: 0 : while(e2_pos_list.size())
2376 [ # # ]: 0 : delete e2_pos_list.pop();
2377 [ # # ]: 0 : }
2378 : : }
2379 [ # # ]: 0 : return ret;
2380 : : }
2381 : :
2382 : : // Finds the start and stop locations between two "close" curves
2383 : : // that meet the narrow criteria. The lists that are returned
2384 : : // mark the beginning and ends of the narrow regions.
2385 : 0 : int GeomMeasureTool::narrow_region_exists(
2386 : : RefEdge *e1,
2387 : : RefEdge *e2,
2388 : : RefFace *face,
2389 : : const double &tol,
2390 : : DLIList<CubitVector*> &e1_pos_list,
2391 : : DLIList<CubitVector*> &e2_pos_list,
2392 : : DLIList<RefVertex*> &e1_vert_list,
2393 : : DLIList<RefVertex*> &e2_vert_list)
2394 : : {
2395 : 0 : int ret = 0;
2396 : 0 : double tol_sq = tol*tol;
2397 : 0 : double max_dist_sq = 0.0;
2398 [ # # ]: 0 : RefVertex *e1_start_vert = e1->start_vertex();
2399 [ # # ]: 0 : RefVertex *e1_end_vert = e1->end_vertex();
2400 : :
2401 [ # # ]: 0 : CubitVector closest;
2402 [ # # ][ # # ]: 0 : DLIList<RefVertex*> e1_verts, e2_verts;
[ # # ]
2403 : :
2404 [ # # ]: 0 : e1->ref_vertices(e1_verts);
2405 [ # # ]: 0 : e2->ref_vertices(e2_verts);
2406 [ # # ]: 0 : e1_verts.intersect_unordered(e2_verts);
2407 [ # # ]: 0 : int num_shared_verts = e1_verts.size();
2408 : 0 : RefVertex *shared_vert = NULL;
2409 : 0 : RefEdge *edge1 = NULL;
2410 : 0 : RefEdge *edge2 = NULL;
2411 [ # # ]: 0 : if(num_shared_verts == 1)
2412 : : {
2413 [ # # ]: 0 : shared_vert = e1_verts.get();
2414 [ # # ]: 0 : DLIList<CoEdge*> coes;
2415 [ # # ]: 0 : e1->get_co_edges(coes, face);
2416 [ # # ][ # # ]: 0 : if(coes.size() == 1)
2417 : : {
2418 [ # # ]: 0 : RefVolume *vol = face->ref_volume();
2419 [ # # ]: 0 : CubitSense facevol_sense = face->sense(vol);
2420 [ # # ][ # # ]: 0 : if((coes.get()->start_vertex() == shared_vert) ==
[ # # ]
2421 : : (facevol_sense == CUBIT_FORWARD))
2422 : : {
2423 : 0 : edge1 = e1;
2424 : 0 : edge2 = e2;
2425 : : }
2426 : : else
2427 : : {
2428 : 0 : edge1 = e2;
2429 : 0 : edge2 = e1;
2430 : : }
2431 [ # # ]: 0 : }
2432 : : }
2433 : :
2434 : : // Project cur endpoints onto other.
2435 : :
2436 : : // First check the endpoints of e1 agaisnt e2
2437 : 0 : int do_narrow_region_check = 1;
2438 [ # # ][ # # ]: 0 : if(num_shared_verts == 1 && shared_vert == e1_start_vert)
2439 : : {
2440 : : // Edges are next to each other. Check the angle between them
2441 : : // before doing anything else.
2442 [ # # ]: 0 : double interior_angle = edge1->angle_between(edge2, face);
2443 [ # # ]: 0 : if(interior_angle > CUBIT_PI/4.0)
2444 : 0 : do_narrow_region_check = 0;
2445 : : }
2446 [ # # ][ # # ]: 0 : if(do_narrow_region_check &&
[ # # ]
2447 [ # # ][ # # ]: 0 : is_narrow_region_at_point(e1, face, e1_start_vert->coordinates(), e2, tol_sq, closest))
[ # # ][ # # ]
2448 : : {
2449 [ # # ][ # # ]: 0 : max_dist_sq = (closest - e1_start_vert->coordinates()).length_squared();
[ # # ]
2450 [ # # ][ # # ]: 0 : e1_pos_list.append(new CubitVector(e1_start_vert->coordinates()));
[ # # ]
2451 [ # # ][ # # ]: 0 : e2_pos_list.append(new CubitVector(closest));
[ # # ]
2452 [ # # ]: 0 : e1_vert_list.append(e1_start_vert);
2453 [ # # ]: 0 : e2_vert_list.append(NULL);
2454 : : }
2455 : 0 : do_narrow_region_check = 1;
2456 [ # # ][ # # ]: 0 : if(num_shared_verts == 1 && shared_vert == e1_end_vert)
2457 : : {
2458 : : // Edges are next to each other. Check the angle between them
2459 : : // before doing anything else.
2460 [ # # ]: 0 : double interior_angle = edge1->angle_between(edge2, face);
2461 [ # # ]: 0 : if(interior_angle > CUBIT_PI/4.0)
2462 : 0 : do_narrow_region_check = 0;
2463 : : }
2464 [ # # ][ # # ]: 0 : if(do_narrow_region_check &&
[ # # ]
2465 [ # # ][ # # ]: 0 : is_narrow_region_at_point(e1, face, e1_end_vert->coordinates(), e2, tol_sq, closest))
[ # # ][ # # ]
2466 : : {
2467 [ # # ][ # # ]: 0 : double cur_dist_sq = (closest - e1_end_vert->coordinates()).length_squared();
[ # # ]
2468 [ # # ]: 0 : max_dist_sq = max_dist_sq > cur_dist_sq ? max_dist_sq : cur_dist_sq;
2469 [ # # ][ # # ]: 0 : e1_pos_list.append(new CubitVector(e1_end_vert->coordinates()));
[ # # ]
2470 [ # # ][ # # ]: 0 : e2_pos_list.append(new CubitVector(closest));
[ # # ]
2471 [ # # ]: 0 : e1_vert_list.append(e1_end_vert);
2472 [ # # ]: 0 : e2_vert_list.append(NULL);
2473 : : }
2474 : :
2475 [ # # ][ # # ]: 0 : if(e1_pos_list.size() < 2)
2476 : : {
2477 [ # # ]: 0 : RefVertex *e2_start_vert = e2->start_vertex();
2478 [ # # ]: 0 : RefVertex *e2_end_vert = e2->end_vertex();
2479 : 0 : do_narrow_region_check = 1;
2480 : : // Now check the end points of e2 against e1
2481 [ # # ][ # # ]: 0 : if(num_shared_verts == 1 && shared_vert == e2_start_vert)
2482 : : {
2483 : : // Edges are next to each other. Check the angle between them
2484 : : // before doing anything else.
2485 [ # # ]: 0 : double interior_angle = edge1->angle_between(edge2, face);
2486 [ # # ]: 0 : if(interior_angle > CUBIT_PI/4.0)
2487 : 0 : do_narrow_region_check = 0;
2488 : : }
2489 [ # # ][ # # ]: 0 : if(do_narrow_region_check &&
[ # # ]
2490 [ # # ][ # # ]: 0 : is_narrow_region_at_point(e2, face, e2_start_vert->coordinates(), e1, tol_sq, closest))
[ # # ][ # # ]
2491 : : {
2492 [ # # ][ # # ]: 0 : if(e1_pos_list.size() == 0 || !closest.about_equal(*e1_pos_list.get()))
[ # # ][ # # ]
[ # # ][ # # ]
2493 : : {
2494 [ # # ][ # # ]: 0 : double cur_dist_sq = (closest - e2_start_vert->coordinates()).length_squared();
[ # # ]
2495 [ # # ]: 0 : max_dist_sq = max_dist_sq > cur_dist_sq ? max_dist_sq : cur_dist_sq;
2496 [ # # ][ # # ]: 0 : e2_pos_list.append(new CubitVector(e2_start_vert->coordinates()));
[ # # ]
2497 [ # # ][ # # ]: 0 : e1_pos_list.append(new CubitVector(closest));
[ # # ]
2498 [ # # ]: 0 : e2_vert_list.append(e2_start_vert);
2499 [ # # ]: 0 : e1_vert_list.append(NULL);
2500 : : }
2501 : : }
2502 [ # # ][ # # ]: 0 : if(e1_pos_list.size() < 2)
2503 : : {
2504 : 0 : do_narrow_region_check = 1;
2505 [ # # ][ # # ]: 0 : if(num_shared_verts == 1 && shared_vert == e2_end_vert)
2506 : : {
2507 : : // Edges are next to each other. Check the angle between them
2508 : : // before doing anything else.
2509 [ # # ]: 0 : double interior_angle = edge1->angle_between(edge2, face);
2510 [ # # ]: 0 : if(interior_angle > CUBIT_PI/4.0)
2511 : 0 : do_narrow_region_check = 0;
2512 : : }
2513 [ # # ][ # # ]: 0 : if(do_narrow_region_check &&
[ # # ]
2514 [ # # ][ # # ]: 0 : is_narrow_region_at_point(e2, face, e2_end_vert->coordinates(), e1, tol_sq, closest))
[ # # ][ # # ]
2515 : : {
2516 [ # # ][ # # ]: 0 : if(e1_pos_list.size() == 0 || !closest.about_equal(*e1_pos_list.get()))
[ # # ][ # # ]
[ # # ][ # # ]
2517 : : {
2518 [ # # ][ # # ]: 0 : double cur_dist_sq = (closest - e2_end_vert->coordinates()).length_squared();
[ # # ]
2519 [ # # ]: 0 : max_dist_sq = max_dist_sq > cur_dist_sq ? max_dist_sq : cur_dist_sq;
2520 [ # # ][ # # ]: 0 : e2_pos_list.append(new CubitVector(e2_end_vert->coordinates()));
[ # # ]
2521 [ # # ][ # # ]: 0 : e1_pos_list.append(new CubitVector(closest));
[ # # ]
2522 [ # # ]: 0 : e2_vert_list.append(e2_end_vert);
2523 [ # # ]: 0 : e1_vert_list.append(NULL);
2524 : : }
2525 : : }
2526 : : }
2527 : : }
2528 : :
2529 : : // At this point we have projected each curves endpoints onto the other curve
2530 : : // and if the projection was "close" we have recorded these as in the lists
2531 : : // as close positions.
2532 : :
2533 : : // If we have two sets of narrow points check to see if the region
2534 : : // between them is all narrow.
2535 [ # # ][ # # ]: 0 : if(e1_pos_list.size() == 2)
2536 : : {
2537 : : int w;
2538 : 0 : int all_good = 1;
2539 : : // double dist_tol = sqrt(max_dist_sq)*5.0;
2540 [ # # ]: 0 : e1_pos_list.reset();
2541 [ # # ]: 0 : e2_pos_list.reset();
2542 [ # # ]: 0 : CubitVector *cur1 = e1_pos_list.get_and_step();
2543 [ # # ]: 0 : CubitVector *cur2 = e1_pos_list.get();
2544 [ # # ]: 0 : CubitVector *other1 = e2_pos_list.get_and_step();
2545 [ # # ]: 0 : CubitVector *other2 = e2_pos_list.get();
2546 : :
2547 [ # # ]: 0 : double len1 = e1->get_arc_length(*cur1, *cur2);
2548 : : //We have to check for periodic edges because the narrow points
2549 : : //will be the same when one or both of the edges is periodic.
2550 [ # # ][ # # ]: 0 : if(len1 > tol || (e1->is_periodic()|| e2->is_periodic()))
[ # # ][ # # ]
[ # # ][ # # ]
2551 : : {
2552 [ # # ]: 0 : double len2 = e2->get_arc_length(*other1, *other2);
2553 [ # # ][ # # ]: 0 : if(len2 > tol || (e1->is_periodic()|| e2->is_periodic()))
[ # # ][ # # ]
[ # # ][ # # ]
2554 : : {
2555 [ # # ]: 0 : double cur_param1 = e1->u_from_position(*cur1);
2556 [ # # ]: 0 : double cur_param2 = e1->u_from_position(*cur2);
2557 : 0 : int num_divisions = 2;
2558 [ # # ]: 0 : CubitVector cur_pos;
2559 : 0 : double param_step = (cur_param2-cur_param1)/num_divisions;
2560 : 0 : double cur_param = cur_param1 + param_step;
2561 [ # # ][ # # ]: 0 : for(w=1; w<num_divisions && all_good; w++)
2562 : : {
2563 [ # # ]: 0 : e1->position_from_u(cur_param, cur_pos);
2564 : 0 : cur_param += param_step;
2565 [ # # ][ # # ]: 0 : if(is_narrow_region_at_point(e1, face, cur_pos, e2, tol_sq, closest))
2566 : : {
2567 : : // Sanity check to make sure we aren't splitting off negative space.
2568 [ # # ][ # # ]: 0 : CubitVector mid = (cur_pos + closest)/2.0;
2569 [ # # ]: 0 : CubitVector tmp_pt;
2570 [ # # ][ # # ]: 0 : face->get_surface_ptr()->closest_point_trimmed(mid, tmp_pt);
[ # # ]
2571 : : // If it didn't move we are fine but if it did we need to check
2572 : : // a little more.
2573 [ # # ][ # # ]: 0 : if(!mid.about_equal(tmp_pt))
2574 : : {
2575 : : // It is possible that the midpoint between the two curves does not lie on the
2576 : : // surface. This would be the case in a blend surface. Check to see that
2577 : : // the projected point is just an offset along the normal of the surface
2578 : : // rather than a laterl movement because the space between the two
2579 : : // curves was actually negative space and not part of the surface.
2580 [ # # ]: 0 : CubitVector norm = face->normal_at(tmp_pt);
2581 [ # # ]: 0 : CubitVector dir(tmp_pt - mid);
2582 [ # # ]: 0 : dir.normalize();
2583 [ # # ][ # # ]: 0 : if(fabs(norm % dir) < .9)
2584 : 0 : all_good = 0;
2585 : : }
2586 : : }
2587 : : }
2588 : : }
2589 : : else
2590 : 0 : all_good = 0;
2591 : : }
2592 : : else
2593 : 0 : all_good = 0;
2594 : :
2595 [ # # ]: 0 : if(all_good)
2596 : 0 : ret = 1;
2597 : : else
2598 : : {
2599 [ # # ]: 0 : e1_pos_list.remove(cur1);
2600 [ # # ]: 0 : e1_pos_list.remove(cur2);
2601 [ # # ]: 0 : e2_pos_list.remove(other1);
2602 [ # # ]: 0 : e2_pos_list.remove(other2);
2603 : 0 : delete cur1;
2604 : 0 : delete cur2;
2605 : 0 : delete other1;
2606 : 0 : delete other2;
2607 : : }
2608 : : }
2609 : :
2610 : : // If we didn't find a continous region that was narrow we may curves
2611 : : // that start narrow at one or more of the ends and then move away from each other.
2612 : : // We need to find if there is a significant region that is narrow and identify
2613 : : // where the two curves start diverging. Add additional points to the lists
2614 : : // at the points where things start diverging.
2615 [ # # ][ # # ]: 0 : if(!ret && e1_pos_list.size() > 0)
[ # # ][ # # ]
2616 : : {
2617 : : int i;
2618 [ # # ]: 0 : e1_pos_list.reset();
2619 [ # # ]: 0 : e2_pos_list.reset();
2620 [ # # ]: 0 : e1_vert_list.reset();
2621 [ # # ]: 0 : e2_vert_list.reset();
2622 [ # # ][ # # ]: 0 : for(i=e1_pos_list.size(); i--;)
2623 : : {
2624 [ # # ]: 0 : RefVertex *e1_vert = e1_vert_list.get_and_step();
2625 [ # # ]: 0 : RefVertex *e2_vert = e2_vert_list.get_and_step();
2626 : :
2627 : 0 : RefVertex *cur_vert = NULL;
2628 : 0 : RefEdge *cur_edge = NULL, *other_edge = NULL;
2629 [ # # ]: 0 : if(e1_vert)
2630 : : {
2631 : 0 : cur_edge = e1;
2632 : 0 : other_edge = e2;
2633 : 0 : cur_vert = e1_vert;
2634 : : }
2635 [ # # ]: 0 : else if(e2_vert)
2636 : : {
2637 : 0 : cur_edge = e2;
2638 : 0 : other_edge = e1;
2639 : 0 : cur_vert = e2_vert;
2640 : : }
2641 [ # # ]: 0 : if(cur_vert)
2642 : : {
2643 [ # # ]: 0 : CubitVector next_pos;
2644 [ # # ]: 0 : CubitVector prev_pos = cur_vert->coordinates();
2645 : 0 : int num_incs = 20;
2646 [ # # ]: 0 : double step = cur_edge->get_arc_length()/(double)num_incs;
2647 : 0 : int still_good = 1;
2648 : 0 : int cntr = 0;
2649 [ # # ][ # # ]: 0 : double direction = (cur_vert == cur_edge->start_vertex() ? 1.0 : -1.0);
2650 : : // Do coarse traversal along curve to see where we start deviating from
2651 : : // narrow.
2652 [ # # ]: 0 : while(still_good)
2653 : : {
2654 [ # # ]: 0 : cur_edge->point_from_arc_length(prev_pos, step*direction, next_pos);
2655 [ # # ][ # # ]: 0 : if(is_narrow_region_at_point(cur_edge, face, next_pos, other_edge, tol_sq, closest) &&
[ # # ][ # # ]
2656 : : cntr < num_incs)
2657 : : {
2658 [ # # ]: 0 : prev_pos = next_pos;
2659 : 0 : cntr++;
2660 : : }
2661 : : else
2662 : 0 : still_good = 0;
2663 : : }
2664 [ # # ]: 0 : if(cntr < num_incs)
2665 : : {
2666 : 0 : cntr = 0;
2667 [ # # ]: 0 : double cur_arc_length = cur_edge->get_arc_length(prev_pos, next_pos);
2668 : : // Do bisection on remaining interval to zero in on point where
2669 : : // we go from narrow to non-narrow.
2670 [ # # ]: 0 : CubitVector mid_pos;
2671 : 0 : double close_enough = tol/20.0;
2672 [ # # ][ # # ]: 0 : while(cur_arc_length > close_enough && cntr < 100)
2673 : : {
2674 : 0 : cntr++; // prevent infinite looping
2675 [ # # ]: 0 : cur_edge->point_from_arc_length(prev_pos, cur_arc_length*direction/2.0, mid_pos);
2676 [ # # ][ # # ]: 0 : if(is_narrow_region_at_point(cur_edge, face, mid_pos, other_edge, tol_sq, closest))
2677 [ # # ]: 0 : prev_pos = mid_pos;
2678 : : else
2679 [ # # ]: 0 : next_pos = mid_pos;
2680 [ # # ]: 0 : cur_arc_length = cur_edge->get_arc_length(prev_pos, next_pos);
2681 : : }
2682 [ # # ][ # # ]: 0 : if(cur_edge->get_arc_length(cur_vert->coordinates(), prev_pos) > tol)
[ # # ]
2683 : : {
2684 : : // end up with the position that guarantees a new split curve that
2685 : : // is smaller than the small curve size.
2686 [ # # ]: 0 : other_edge->closest_point_trimmed(prev_pos, closest);
2687 [ # # ]: 0 : if(cur_edge == e1)
2688 : : {
2689 [ # # ][ # # ]: 0 : e1_pos_list.append(new CubitVector(prev_pos));
[ # # ]
2690 [ # # ][ # # ]: 0 : e2_pos_list.append(new CubitVector(closest));
[ # # ]
2691 : : }
2692 : : else
2693 : : {
2694 [ # # ][ # # ]: 0 : e2_pos_list.append(new CubitVector(prev_pos));
[ # # ]
2695 [ # # ][ # # ]: 0 : e1_pos_list.append(new CubitVector(closest));
[ # # ]
2696 : : }
2697 [ # # ]: 0 : e1_vert_list.append(NULL);
2698 [ # # ]: 0 : e2_vert_list.append(NULL);
2699 : 0 : ret = 1;
2700 : : }
2701 : : }
2702 : : }
2703 : : }
2704 : : }
2705 : :
2706 : : // Now remove and regions of close curves between which
2707 : : // there is negative space (not actually part of the surface).
2708 [ # # ]: 0 : if(ret)
2709 : : {
2710 : : int i, j;
2711 [ # # ]: 0 : e1_pos_list.reset();
2712 [ # # ]: 0 : e2_pos_list.reset();
2713 [ # # ]: 0 : e1_vert_list.reset();
2714 [ # # ]: 0 : e2_vert_list.reset();
2715 [ # # ][ # # ]: 0 : for(i=e1_pos_list.size(); i--;)
2716 : : {
2717 [ # # ]: 0 : CubitVector *e1_pos = e1_pos_list.get();
2718 [ # # ]: 0 : CubitVector *e2_pos = e2_pos_list.get();
2719 : 0 : int num_divisions = 6;
2720 [ # # ][ # # ]: 0 : CubitVector step = (*e2_pos - *e1_pos)/num_divisions;
2721 [ # # ]: 0 : CubitVector cur_pos = *e1_pos + step;
2722 : 0 : int removed = 0;
2723 [ # # ]: 0 : for(j=1; j<num_divisions; j++)
2724 : : {
2725 [ # # ]: 0 : CubitVector tmp_pt;
2726 [ # # ][ # # ]: 0 : face->get_surface_ptr()->closest_point_trimmed(cur_pos, tmp_pt);
[ # # ]
2727 [ # # ][ # # ]: 0 : if(!cur_pos.about_equal(tmp_pt))
2728 : : {
2729 [ # # ]: 0 : CubitVector norm = face->normal_at(tmp_pt);
2730 [ # # ]: 0 : CubitVector dir(tmp_pt - cur_pos);
2731 [ # # ]: 0 : dir.normalize();
2732 [ # # ][ # # ]: 0 : if(fabs(norm % dir) < .9)
2733 : : {
2734 : 0 : removed = 1;
2735 : 0 : j=num_divisions;
2736 [ # # ]: 0 : delete e1_pos_list.remove();
2737 [ # # ]: 0 : delete e2_pos_list.remove();
2738 [ # # ]: 0 : e1_vert_list.remove();
2739 [ # # ]: 0 : e2_vert_list.remove();
2740 : : }
2741 : : }
2742 : : else
2743 [ # # ]: 0 : cur_pos += step;
2744 : : }
2745 [ # # ]: 0 : if(!removed)
2746 : : {
2747 [ # # ]: 0 : e1_pos_list.step();
2748 [ # # ]: 0 : e2_pos_list.step();
2749 [ # # ]: 0 : e1_vert_list.step();
2750 [ # # ]: 0 : e2_vert_list.step();
2751 : : }
2752 : : }
2753 : :
2754 [ # # ][ # # ]: 0 : if(e1_pos_list.size() == 0)
2755 : 0 : ret = 0;
2756 : : }
2757 : :
2758 [ # # ]: 0 : return ret;
2759 : : }
2760 : :
2761 : 0 : void GeomMeasureTool::find_small_curves( DLIList <RefVolume*> &ref_vols,
2762 : : double tol,
2763 : : DLIList <RefEdge*> &small_curves,
2764 : : DLIList <double> &small_lengths)
2765 : : {
2766 : : int ii, jj;
2767 [ # # ][ # # ]: 0 : DLIList <RefEdge*> ref_edges, temp_edges;
[ # # ]
2768 : : RefVolume *ref_vol;
2769 : : RefEdge *curr_edge;
2770 [ # # ][ # # ]: 0 : for ( ii = 0; ii < ref_vols.size(); ii++ )
2771 : : {
2772 [ # # ]: 0 : ref_vol = ref_vols.get_and_step();
2773 [ # # ]: 0 : ref_vol->ref_edges(temp_edges);
2774 : : //uniquely add the edges.
2775 [ # # ][ # # ]: 0 : for ( jj = temp_edges.size(); jj > 0; jj-- )
2776 : : {
2777 [ # # ]: 0 : curr_edge = temp_edges.pop();
2778 [ # # ][ # # ]: 0 : if ( curr_edge->marked()== 0 )
2779 : : {
2780 [ # # ]: 0 : curr_edge->marked(1);
2781 [ # # ]: 0 : ref_edges.append(curr_edge);
2782 : : }
2783 : : }
2784 : : }
2785 : :
2786 [ # # ]: 0 : int num_curves = ref_edges.size();
2787 : 0 : ProgressTool *progress_ptr = NULL;
2788 [ # # ]: 0 : if (num_curves> 20)
2789 : : {
2790 [ # # ][ # # ]: 0 : progress_ptr = AppUtil::instance()->progress_tool();
2791 [ # # ]: 0 : assert(progress_ptr != NULL);
2792 : : progress_ptr->start(0, 100, "Finding Small Curves",
2793 [ # # ]: 0 : NULL, CUBIT_TRUE, CUBIT_TRUE);
2794 : : }
2795 : :
2796 : 0 : int total_curves = 0;
2797 : 0 : double curr_percent = 0.0;
2798 : : double length;
2799 : : //find the small curves and reset the marked flag.
2800 [ # # ][ # # ]: 0 : for ( ii = ref_edges.size(); ii > 0; ii-- )
2801 : : {
2802 : 0 : total_curves++;
2803 [ # # ]: 0 : if ( progress_ptr != NULL )
2804 : : {
2805 : 0 : curr_percent = ((double)(total_curves))/((double)(num_curves));
2806 [ # # ]: 0 : progress_ptr->percent(curr_percent);
2807 : : }
2808 [ # # ][ # # ]: 0 : if ( AppUtil::instance()->interrupt() )
[ # # ]
2809 : : {
2810 : : //interrpt. We need to exit.
2811 [ # # ]: 0 : if ( progress_ptr != NULL )
2812 [ # # ]: 0 : progress_ptr->end();
2813 : : //just leave what has been calculated...
2814 : 0 : return;
2815 : : }
2816 : :
2817 [ # # ]: 0 : curr_edge = ref_edges.get_and_step();
2818 [ # # ]: 0 : curr_edge->marked(0);
2819 : :
2820 : : //skip point curves
2821 [ # # ][ # # ]: 0 : if( curr_edge->geometry_type() == POINT_CURVE_TYPE )
2822 : 0 : continue;
2823 : :
2824 [ # # ]: 0 : length = curr_edge->measure();
2825 [ # # ]: 0 : if ( length <= tol )
2826 : : {
2827 [ # # ]: 0 : small_curves.append(curr_edge);
2828 [ # # ]: 0 : small_lengths.append(length);
2829 : : }
2830 : : }
2831 : :
2832 [ # # ]: 0 : if ( progress_ptr != NULL )
2833 [ # # ]: 0 : progress_ptr->end();
2834 : :
2835 [ # # ]: 0 : return;
2836 : : }
2837 : :
2838 : 0 : RefEdge* GeomMeasureTool::find_first_small_curve(RefVolume* vol,
2839 : : double tol)
2840 : : {
2841 : 0 : RefEdge *ret = NULL;
2842 : : int j;
2843 [ # # ]: 0 : DLIList <RefEdge*> ref_edges;
2844 [ # # ]: 0 : vol->ref_edges(ref_edges);
2845 [ # # ][ # # ]: 0 : for(j=ref_edges.size(); j > 0 && !ret; j--)
[ # # ]
2846 : : {
2847 [ # # ]: 0 : RefEdge *curr_edge = ref_edges.get_and_step();
2848 [ # # ][ # # ]: 0 : if(curr_edge->measure() <= tol)
2849 : 0 : ret = curr_edge;
2850 : : }
2851 [ # # ]: 0 : return ret;
2852 : : }
2853 : :
2854 : 0 : void GeomMeasureTool::find_narrow_faces(DLIList<RefVolume*> &ref_vols,
2855 : : double small_curve_size,
2856 : : DLIList<RefFace*> &narrow_faces,
2857 : : DLIList<RefFace*> &surfs_to_ignore)
2858 : : {
2859 : : int ii, jj;
2860 [ # # ][ # # ]: 0 : DLIList <RefFace*> ref_faces, temp_faces;
[ # # ]
2861 : : RefVolume *ref_vol;
2862 : : RefFace *curr_face;
2863 : :
2864 [ # # ][ # # ]: 0 : for ( ii = 0; ii < ref_vols.size(); ii++ )
2865 : : {
2866 [ # # ]: 0 : DLIList<RefFace*> faces;
2867 [ # # ]: 0 : ref_vol = ref_vols.get_and_step();
2868 [ # # ]: 0 : ref_vol->ref_faces(faces);
2869 [ # # ][ # # ]: 0 : for ( jj = faces.size(); jj > 0; jj-- )
2870 : : {
2871 [ # # ]: 0 : curr_face = faces.get_and_step();
2872 [ # # ]: 0 : curr_face->marked(0);
2873 [ # # ]: 0 : temp_faces.append(curr_face);
2874 : : }
2875 [ # # ]: 0 : }
2876 : :
2877 : : //uniquely add the faces.
2878 [ # # ][ # # ]: 0 : for ( jj = temp_faces.size(); jj > 0; jj-- )
2879 : : {
2880 [ # # ]: 0 : curr_face = temp_faces.get_and_step();
2881 [ # # ][ # # ]: 0 : if ( curr_face->marked()== 0 )
2882 : : {
2883 [ # # ]: 0 : curr_face->marked(1);
2884 [ # # ]: 0 : ref_faces.append(curr_face);
2885 : : }
2886 : : }
2887 : :
2888 [ # # ]: 0 : int num_faces = ref_faces.size();
2889 : 0 : ProgressTool *progress_ptr = NULL;
2890 [ # # ]: 0 : if (num_faces > 20)
2891 : : {
2892 [ # # ][ # # ]: 0 : progress_ptr = AppUtil::instance()->progress_tool();
2893 [ # # ]: 0 : assert(progress_ptr != NULL);
2894 : : progress_ptr->start(0, 100, "Finding Narrow Surfaces",
2895 [ # # ]: 0 : NULL, CUBIT_TRUE, CUBIT_TRUE);
2896 : : }
2897 : :
2898 : 0 : int total_faces = 0;
2899 : 0 : double curr_percent = 0.0;
2900 : :
2901 [ # # ][ # # ]: 0 : for ( ii = ref_faces.size(); ii > 0; ii-- )
2902 : : {
2903 : 0 : total_faces++;
2904 [ # # ]: 0 : if ( progress_ptr != NULL )
2905 : : {
2906 : 0 : curr_percent = ((double)(total_faces))/((double)(num_faces));
2907 [ # # ]: 0 : progress_ptr->percent(curr_percent);
2908 : : }
2909 : :
2910 [ # # ][ # # ]: 0 : if ( AppUtil::instance()->interrupt() )
[ # # ]
2911 : : {
2912 : : //interrpt. We need to exit.
2913 [ # # ]: 0 : if ( progress_ptr != NULL )
2914 [ # # ]: 0 : progress_ptr->end();
2915 : : //just leave what has been calculated...
2916 : 0 : return;
2917 : : }
2918 : :
2919 [ # # ]: 0 : curr_face = ref_faces.get_and_step();
2920 [ # # ][ # # ]: 0 : if(!surfs_to_ignore.is_in_list(curr_face))
2921 : : {
2922 [ # # ][ # # ]: 0 : if(narrow_region_exists(curr_face, small_curve_size))
2923 : : {
2924 [ # # ]: 0 : DLIList<CubitVector> split_pos1_list;
2925 [ # # ][ # # ]: 0 : DLIList<CubitVector> split_pos2_list;
2926 : : find_split_points_for_narrow_regions(curr_face,
2927 [ # # ]: 0 : small_curve_size, split_pos1_list, split_pos2_list);
2928 [ # # ][ # # ]: 0 : if(split_pos1_list.size() == 0)
2929 [ # # ][ # # ]: 0 : narrow_faces.append_unique(curr_face);
2930 : : }
2931 : : }
2932 : : }
2933 : :
2934 [ # # ]: 0 : if ( progress_ptr != NULL )
2935 [ # # ]: 0 : progress_ptr->end();
2936 : :
2937 [ # # ]: 0 : return;
2938 : : }
2939 : :
2940 : 0 : void GeomMeasureTool::find_small_faces( DLIList <RefVolume*> &ref_vols,
2941 : : double tol,
2942 : : DLIList <RefFace*> &small_faces)
2943 : : {
2944 : : int ii, jj;
2945 [ # # ][ # # ]: 0 : DLIList <RefFace*> ref_faces, temp_faces;
[ # # ]
2946 : : RefVolume *ref_vol;
2947 : : RefFace *curr_face;
2948 [ # # ][ # # ]: 0 : for ( ii = 0; ii < ref_vols.size(); ii++ )
2949 : : {
2950 [ # # ]: 0 : DLIList<RefFace*> faces;
2951 [ # # ]: 0 : ref_vol = ref_vols.get_and_step();
2952 [ # # ]: 0 : ref_vol->ref_faces(faces);
2953 [ # # ][ # # ]: 0 : for ( jj = faces.size(); jj > 0; jj-- )
2954 : : {
2955 [ # # ]: 0 : curr_face = faces.get_and_step();
2956 [ # # ]: 0 : curr_face->marked(0);
2957 [ # # ]: 0 : temp_faces.append(curr_face);
2958 : : }
2959 [ # # ]: 0 : }
2960 : :
2961 : : //uniquely add the faces.
2962 [ # # ][ # # ]: 0 : for ( jj = temp_faces.size(); jj > 0; jj-- )
2963 : : {
2964 [ # # ]: 0 : curr_face = temp_faces.get_and_step();
2965 [ # # ][ # # ]: 0 : if ( curr_face->marked()== 0 )
2966 : : {
2967 [ # # ]: 0 : curr_face->marked(1);
2968 [ # # ]: 0 : ref_faces.append(curr_face);
2969 : : }
2970 : : }
2971 : :
2972 [ # # ]: 0 : int num_faces = ref_faces.size();
2973 : 0 : ProgressTool *progress_ptr = NULL;
2974 [ # # ]: 0 : if (num_faces > 20)
2975 : : {
2976 [ # # ][ # # ]: 0 : progress_ptr = AppUtil::instance()->progress_tool();
2977 [ # # ]: 0 : assert(progress_ptr != NULL);
2978 : : progress_ptr->start(0, 100, "Finding Small Surfaces",
2979 [ # # ]: 0 : NULL, CUBIT_TRUE, CUBIT_TRUE);
2980 : : }
2981 : :
2982 : 0 : int total_faces = 0;
2983 : 0 : double curr_percent = 0.0;
2984 : : double area;
2985 : : //find the small curves and reset the marked flag.
2986 [ # # ][ # # ]: 0 : for ( ii = ref_faces.size(); ii > 0; ii-- )
2987 : : {
2988 : 0 : total_faces++;
2989 [ # # ]: 0 : if ( progress_ptr != NULL )
2990 : : {
2991 : 0 : curr_percent = ((double)(total_faces))/((double)(num_faces));
2992 [ # # ]: 0 : progress_ptr->percent(curr_percent);
2993 : : }
2994 : :
2995 [ # # ][ # # ]: 0 : if ( AppUtil::instance()->interrupt() )
[ # # ]
2996 : : {
2997 : : //interrpt. We need to exit.
2998 [ # # ]: 0 : if ( progress_ptr != NULL )
2999 [ # # ]: 0 : progress_ptr->end();
3000 : : //just leave what has been calculated...
3001 : 0 : return;
3002 : : }
3003 : :
3004 [ # # ]: 0 : curr_face = ref_faces.get_and_step();
3005 [ # # ]: 0 : area = measure_area(curr_face);
3006 [ # # ]: 0 : if ( area <= tol )
3007 [ # # ]: 0 : small_faces.append(curr_face);
3008 : : }
3009 : :
3010 [ # # ]: 0 : if ( progress_ptr != NULL )
3011 [ # # ]: 0 : progress_ptr->end();
3012 : :
3013 [ # # ]: 0 : return;
3014 : : }
3015 : :
3016 : 0 : void GeomMeasureTool::find_closed_narrow_faces( DLIList <RefVolume*> &ref_vols,
3017 : : double tol,
3018 : : DLIList <RefFace*> &face_list)
3019 : : {
3020 : : int ii, jj;
3021 [ # # ][ # # ]: 0 : DLIList <RefFace*> ref_faces, temp_faces;
[ # # ]
3022 : : RefVolume *ref_vol;
3023 : : RefFace *curr_face;
3024 [ # # ][ # # ]: 0 : for ( ii = 0; ii < ref_vols.size(); ii++ )
3025 : : {
3026 [ # # ]: 0 : DLIList<RefFace*> faces;
3027 [ # # ]: 0 : ref_vol = ref_vols.get_and_step();
3028 [ # # ]: 0 : ref_vol->ref_faces(faces);
3029 [ # # ][ # # ]: 0 : for ( jj = faces.size(); jj > 0; jj-- )
3030 : : {
3031 [ # # ]: 0 : curr_face = faces.get_and_step();
3032 [ # # ]: 0 : curr_face->marked(0);
3033 [ # # ]: 0 : temp_faces.append(curr_face);
3034 : : }
3035 [ # # ]: 0 : }
3036 : :
3037 : : //uniquely add the faces.
3038 [ # # ][ # # ]: 0 : for ( jj = temp_faces.size(); jj > 0; jj-- )
3039 : : {
3040 [ # # ]: 0 : curr_face = temp_faces.get_and_step();
3041 [ # # ][ # # ]: 0 : if ( curr_face->marked()== 0 )
3042 : : {
3043 [ # # ]: 0 : curr_face->marked(1);
3044 [ # # ]: 0 : ref_faces.append(curr_face);
3045 : : }
3046 : : }
3047 : :
3048 [ # # ]: 0 : int num_faces = ref_faces.size();
3049 : 0 : ProgressTool *progress_ptr = NULL;
3050 [ # # ]: 0 : if (num_faces > 20)
3051 : : {
3052 [ # # ][ # # ]: 0 : progress_ptr = AppUtil::instance()->progress_tool();
3053 [ # # ]: 0 : assert(progress_ptr != NULL);
3054 : : progress_ptr->start(0, 100, "Finding Small Surfaces",
3055 [ # # ]: 0 : NULL, CUBIT_TRUE, CUBIT_TRUE);
3056 : : }
3057 : :
3058 : 0 : int total_faces = 0;
3059 : 0 : double curr_percent = 0.0;
3060 [ # # ][ # # ]: 0 : for ( ii = ref_faces.size(); ii > 0; ii-- )
3061 : : {
3062 : 0 : total_faces++;
3063 [ # # ]: 0 : if ( progress_ptr != NULL )
3064 : : {
3065 : 0 : curr_percent = ((double)(total_faces))/((double)(num_faces));
3066 [ # # ]: 0 : progress_ptr->percent(curr_percent);
3067 : : }
3068 : :
3069 [ # # ][ # # ]: 0 : if ( AppUtil::instance()->interrupt() )
[ # # ]
3070 : : {
3071 : : //interrpt. We need to exit.
3072 [ # # ]: 0 : if ( progress_ptr != NULL )
3073 [ # # ]: 0 : progress_ptr->end();
3074 : : //just leave what has been calculated...
3075 : 0 : return;
3076 : : }
3077 : :
3078 [ # # ]: 0 : curr_face = ref_faces.get_and_step();
3079 [ # # ][ # # ]: 0 : if(curr_face->get_surface_ptr()->is_closed_in_U() || curr_face->get_surface_ptr()->is_closed_in_V())
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
3080 : : {
3081 [ # # ][ # # ]: 0 : if(curr_face->num_loops() == 2)
3082 : : {
3083 [ # # ]: 0 : DLIList<RefEdge*> ref_edge_list;
3084 [ # # ]: 0 : curr_face->ref_edges(ref_edge_list);
3085 [ # # ][ # # ]: 0 : if(ref_edge_list.size() == 2)
3086 : : {
3087 : 0 : int num_pts = 5;
3088 : : double start, end;
3089 [ # # ]: 0 : RefEdge *e1 = ref_edge_list.get_and_step();
3090 [ # # ]: 0 : RefEdge *e2 = ref_edge_list.get();
3091 [ # # ]: 0 : e1->get_param_range(start, end);
3092 : 0 : double dt = (end-start)/(double)(num_pts-1);
3093 : 0 : double t = start;
3094 : 0 : bool one_bad = false;
3095 : 0 : double dist_sq = tol*tol;
3096 [ # # ][ # # ]: 0 : for(jj=0; jj<num_pts && one_bad == false; jj++)
3097 : : {
3098 [ # # ][ # # ]: 0 : CubitVector pos1, pos2;
3099 [ # # ]: 0 : e1->position_from_u(t, pos1);
3100 [ # # ]: 0 : e2->closest_point_trimmed(pos1, pos2);
3101 [ # # ][ # # ]: 0 : if((pos1-pos2).length_squared() > dist_sq)
[ # # ]
3102 : 0 : one_bad = true;
3103 : 0 : t += dt;
3104 : : }
3105 [ # # ]: 0 : if(one_bad == false)
3106 : : {
3107 [ # # ]: 0 : face_list.append(curr_face);
3108 : : }
3109 [ # # ]: 0 : }
3110 : : }
3111 : : }
3112 : : }
3113 : :
3114 [ # # ]: 0 : if ( progress_ptr != NULL )
3115 [ # # ]: 0 : progress_ptr->end();
3116 : :
3117 [ # # ]: 0 : return;
3118 : : }
3119 : :
3120 : 0 : void GeomMeasureTool::find_small_faces_hydraulic_radius( DLIList <RefVolume*> &ref_vols,
3121 : : double tol,
3122 : : DLIList <RefFace*> &small_faces,
3123 : : DLIList <double> &small_hyd_rad,
3124 : : double &percent_planar,
3125 : : double &percent_pl_co)
3126 : : {
3127 : : int ii, jj;
3128 [ # # ][ # # ]: 0 : DLIList <RefFace*> ref_faces, temp_faces;
[ # # ]
3129 : : RefVolume *ref_vol;
3130 : : RefFace *curr_face;
3131 [ # # ][ # # ]: 0 : for ( ii = 0; ii < ref_vols.size(); ii++ )
3132 : : {
3133 [ # # ]: 0 : ref_vol = ref_vols.get_and_step();
3134 [ # # ]: 0 : ref_vol->ref_faces(temp_faces);
3135 : : //uniquely add the faces.
3136 [ # # ][ # # ]: 0 : for ( jj = temp_faces.size(); jj > 0; jj-- )
3137 : : {
3138 [ # # ]: 0 : curr_face = temp_faces.pop();
3139 [ # # ][ # # ]: 0 : if ( curr_face->marked()== 0 )
3140 : : {
3141 [ # # ]: 0 : curr_face->marked(1);
3142 [ # # ]: 0 : ref_faces.append(curr_face);
3143 : : }
3144 : : }
3145 : : }
3146 : : double area;
3147 : : double length;
3148 : 0 : int total_faces = 0;
3149 : 0 : int total_plane = 0;
3150 : 0 : int total_cone = 0;
3151 : 0 : double area_plane = 0.0;
3152 : 0 : double total_area = 0.0;
3153 : : //find the small curves and reset the marked flag.
3154 [ # # ][ # # ]: 0 : DLIList <CoEdge*> co_edges;
3155 [ # # ]: 0 : int num_faces = ref_faces.size();
3156 : 0 : ProgressTool *progress_ptr = NULL;
3157 [ # # ]: 0 : if (num_faces > 20)
3158 : : {
3159 [ # # ][ # # ]: 0 : progress_ptr = AppUtil::instance()->progress_tool();
3160 [ # # ]: 0 : assert(progress_ptr != NULL);
3161 : : progress_ptr->start(0, 100, "Small Surface Progress",
3162 [ # # ]: 0 : NULL, CUBIT_TRUE, CUBIT_TRUE);
3163 : : }
3164 : 0 : double curr_percent = 0.0;
3165 [ # # ][ # # ]: 0 : for ( ii = ref_faces.size(); ii > 0; ii-- )
3166 : : {
3167 [ # # ]: 0 : curr_face = ref_faces.get_and_step();
3168 [ # # ]: 0 : curr_face->marked(0);
3169 [ # # ]: 0 : area = measure_area(curr_face);
3170 : 0 : total_area += area;
3171 : 0 : total_faces++;
3172 : : //update the progress..
3173 [ # # ]: 0 : if ( progress_ptr != NULL )
3174 : : {
3175 : 0 : curr_percent = ((double)(total_faces))/((double)(num_faces));
3176 [ # # ]: 0 : progress_ptr->percent(curr_percent);
3177 : : }
3178 [ # # ][ # # ]: 0 : if ( AppUtil::instance()->interrupt() )
[ # # ]
3179 : : {
3180 : : //interrpt. We need to exit.
3181 [ # # ]: 0 : if ( progress_ptr != NULL )
3182 [ # # ]: 0 : progress_ptr->end();
3183 : : //just leave what has been calculated...
3184 : 0 : return;
3185 : : }
3186 [ # # ][ # # ]: 0 : if ( curr_face->geometry_type() == PLANE_SURFACE_TYPE )
3187 : : {
3188 : 0 : total_plane++;
3189 : 0 : area_plane += area;
3190 : : }
3191 [ # # ][ # # ]: 0 : else if ( curr_face->geometry_type() == CONE_SURFACE_TYPE )
3192 : 0 : total_cone++;
3193 [ # # ]: 0 : co_edges.clean_out();
3194 [ # # ]: 0 : curr_face->co_edges(co_edges);
3195 : 0 : length = 0.0;
3196 [ # # ][ # # ]: 0 : for ( jj = co_edges.size(); jj > 0; jj-- )
3197 : : {
3198 [ # # ][ # # ]: 0 : length += co_edges.get_and_step()->get_ref_edge_ptr()->measure();
[ # # ]
3199 : : }
3200 : : //reset the mark.
3201 [ # # ]: 0 : curr_face->marked(0);
3202 : : //compute the hydraulic radius 4*(A/P).
3203 [ # # ]: 0 : if ( length <= CUBIT_RESABS )
3204 : : {
3205 [ # # ][ # # ]: 0 : PRINT_INFO("Total Perimeter Length of Surface %d is less than tolerance.\n",
[ # # ][ # # ]
3206 [ # # ]: 0 : curr_face->id());
3207 : :
3208 : 0 : continue;
3209 : : }
3210 : 0 : area = 4.0*(area/length);
3211 [ # # ]: 0 : if ( area <= tol )
3212 : : {
3213 [ # # ]: 0 : small_faces.append(curr_face);
3214 [ # # ]: 0 : small_hyd_rad.append(area);
3215 : : }
3216 : : }
3217 [ # # ]: 0 : if ( total_faces > 0 )
3218 : : {
3219 : 0 : percent_planar = 100.0*area_plane/total_area;
3220 : 0 : percent_pl_co = 100.0*((double)total_plane+(double)total_cone)/(double)total_faces;
3221 : : }
3222 : : else
3223 : : {
3224 : 0 : percent_planar = 0.;
3225 : 0 : percent_pl_co = 0.;
3226 : : }
3227 [ # # ]: 0 : if ( progress_ptr != NULL )
3228 : : {
3229 [ # # ]: 0 : progress_ptr->end();
3230 : : }
3231 : :
3232 [ # # ]: 0 : return;
3233 : : }
3234 : 0 : void GeomMeasureTool::find_small_volumes( DLIList <RefVolume*> &ref_vols,
3235 : : double tol,
3236 : : DLIList <RefVolume*> &small_volumes)
3237 : : {
3238 : : int ii;
3239 : : RefVolume *ref_vol;
3240 : : double volume;
3241 : :
3242 [ # # ][ # # ]: 0 : for ( ii = 0; ii < ref_vols.size(); ii++ )
3243 : : {
3244 [ # # ]: 0 : ref_vol = ref_vols.get_and_step();
3245 [ # # ]: 0 : volume = ref_vol->measure();
3246 [ # # ]: 0 : if ( volume <= tol )
3247 [ # # ]: 0 : small_volumes.append(ref_vol);
3248 : : }
3249 : 0 : return;
3250 : : }
3251 : 0 : void GeomMeasureTool::find_small_volumes_hydraulic_radius( DLIList <RefVolume*> &ref_vols,
3252 : : double tol,
3253 : : DLIList <RefVolume*> &small_volumes,
3254 : : DLIList <double> &small_hyd_rad)
3255 : : {
3256 : : int ii, jj;
3257 [ # # ][ # # ]: 0 : DLIList <RefFace*> ref_faces, temp_faces;
[ # # ]
3258 : : RefVolume *ref_vol;
3259 : : RefFace *curr_face;
3260 : : double area;
3261 : : double hyd_volume;
3262 : :
3263 [ # # ][ # # ]: 0 : for ( ii = 0; ii < ref_vols.size(); ii++ )
3264 : : {
3265 [ # # ]: 0 : ref_vol = ref_vols.get_and_step();
3266 [ # # ]: 0 : ref_vol->ref_faces(temp_faces);
3267 : 0 : area = 0.0;
3268 [ # # ][ # # ]: 0 : for ( jj = temp_faces.size(); jj > 0; jj-- )
3269 : : {
3270 [ # # ]: 0 : curr_face = temp_faces.pop();
3271 [ # # ]: 0 : area += measure_area(curr_face);
3272 : : }
3273 [ # # ]: 0 : if ( area <= CUBIT_RESABS )
3274 : 0 : continue;
3275 [ # # ]: 0 : hyd_volume = 6.0*(ref_vol->measure() / area);
3276 [ # # ]: 0 : if ( hyd_volume <= tol )
3277 : : {
3278 [ # # ]: 0 : small_hyd_rad.append(hyd_volume);
3279 [ # # ]: 0 : small_volumes.append(ref_vol);
3280 : : }
3281 : : }
3282 [ # # ]: 0 : return;
3283 : : }
3284 : : ///
3285 : : /// Find the tangential meetings in the volume.
3286 : : /// This specifically looks for surfaces that meet tangentially
3287 : : /// that would be a problem. Usually these are surfaces that
3288 : : /// come into a side 180 degrees and on top there is a
3289 : : /// sharpe angle. Usually if there isn't a sharpe curve
3290 : : /// angle these meetings are not bad.
3291 : : /// Note that this function assumes that you are passing
3292 : : /// in sets of curve edges that have small interior angles between them.
3293 : : /// It also assumes that the edge pairs are ordered as they would
3294 : : /// be found in the surfaces (first edge then next edge).
3295 : : /// Basically, call the funciton, find_interior_curve_angles
3296 : : /// before calling this function, and pass this function those results.
3297 : : ///
3298 : 0 : void GeomMeasureTool::find_sharp_tangential_meets( RefVolume *ref_volume,
3299 : : DLIList <RefEdge*> &small_angle_edge_pairs,
3300 : : DLIList <RefFace*> &tangential_surface_pairs )
3301 : : {
3302 : : //Okay, given the small angle edge pairs. See if there are surfaces that meet tangentially.
3303 : : //I'm really looking for something spefic.
3304 : : RefEdge *ref_edge_1, *ref_edge_2;
3305 : : int ii, jj;
3306 [ # # ][ # # ]: 0 : DLIList <Loop*> loops_1, loops_2;
[ # # ]
3307 : : Loop *common_loop;
3308 : 0 : const double rad_to_deg = 180.0/CUBIT_PI;
3309 : : RefFace *ref_face;
3310 : :
3311 : : //loop over for each edge pair.
3312 [ # # ][ # # ]: 0 : for ( ii = 0; ii < small_angle_edge_pairs.size(); ii += 2 )
3313 : : {
3314 [ # # ]: 0 : ref_edge_1 = small_angle_edge_pairs.get_and_step();
3315 [ # # ]: 0 : ref_edge_2 = small_angle_edge_pairs.get_and_step();
3316 : : //find the loop that these edges are both on.
3317 [ # # ]: 0 : loops_1.clean_out();
3318 [ # # ]: 0 : loops_2.clean_out();
3319 [ # # ]: 0 : ref_edge_1->loops(loops_1);
3320 [ # # ]: 0 : ref_edge_2->loops(loops_2);
3321 : 0 : common_loop = NULL;
3322 [ # # ][ # # ]: 0 : for ( jj = loops_1.size(); jj > 0; jj-- )
3323 : : {
3324 [ # # ][ # # ]: 0 : if ( !loops_2.move_to(loops_1.get()) )
[ # # ]
3325 [ # # ]: 0 : loops_1.remove();
3326 : : else
3327 [ # # ]: 0 : loops_1.step();
3328 : : }
3329 [ # # ][ # # ]: 0 : if ( loops_1.size() == 1 )
3330 [ # # ]: 0 : common_loop = loops_1.get();
3331 : : else
3332 : : {
3333 : : //find the loop that has a co_edge from ref_edge_1
3334 : : //then a co_edge from ref_edge_2.
3335 [ # # ]: 0 : DLIList <CoEdge*> co_edges;
3336 : : Loop *tmp_loop;
3337 : : int kk;
3338 : : CoEdge *co_edge;
3339 [ # # ][ # # ]: 0 : for ( jj = loops_1.size(); jj > 0; jj-- )
3340 : : {
3341 [ # # ]: 0 : tmp_loop = loops_1.get_and_step();
3342 [ # # ]: 0 : co_edges.clean_out();
3343 [ # # ]: 0 : tmp_loop->ordered_co_edges(co_edges);
3344 [ # # ][ # # ]: 0 : for ( kk = co_edges.size(); kk > 0; kk-- )
3345 : : {
3346 [ # # ]: 0 : co_edge = co_edges.get_and_step();
3347 [ # # ][ # # ]: 0 : if ( co_edge->get_ref_edge_ptr() == ref_edge_1 )
3348 : : {
3349 [ # # ][ # # ]: 0 : if ( co_edges.get()->get_ref_edge_ptr() == ref_edge_2 )
[ # # ]
3350 : : {
3351 : 0 : common_loop = tmp_loop;
3352 : 0 : break;
3353 : : }
3354 : : else
3355 : : //not this loop..
3356 : 0 : break;
3357 : : }
3358 : : }
3359 [ # # ]: 0 : if ( common_loop != NULL )
3360 : 0 : break;
3361 [ # # ]: 0 : }
3362 : : }
3363 [ # # ]: 0 : assert ( common_loop != NULL );
3364 : : //now find surface.
3365 : : //Then see if there are surfaces that meet at 180 degrees that
3366 : : //are 90* rotated from here.
3367 [ # # ]: 0 : ref_face = common_loop->get_ref_face_ptr();
3368 : : //Okay, refface is the surface on which we have the bad angle.
3369 : : //One of these curves will have a concave angle and the other a
3370 : : //convex angle. The surface on the other side of the convex angle
3371 : : //we need to check to see if it comes tangentially into another
3372 : : //surface (dihedral angle of 180.)
3373 [ # # ]: 0 : RefFace *ref_face_1 = ref_edge_1->other_face(ref_face, ref_volume);
3374 [ # # ]: 0 : if( ref_face_1 == NULL )
3375 : 0 : continue;
3376 : :
3377 : : double surf_angle_1, surf_angle_2;
3378 : 0 : RefFace *tangential_face = NULL;
3379 : 0 : RefEdge *edge_next_to = NULL;
3380 : : surf_angle_1 = GeometryQueryTool::instance()->surface_angle(ref_face,
3381 : : ref_face_1,
3382 : : ref_edge_1,
3383 [ # # ][ # # ]: 0 : ref_volume);
3384 : 0 : surf_angle_1 *= rad_to_deg;
3385 : : RefFace *ref_face_2;
3386 [ # # ]: 0 : ref_face_2 = ref_edge_2->other_face(ref_face, ref_volume);
3387 [ # # ]: 0 : if( ref_face_2 == NULL )
3388 : 0 : continue;
3389 : : surf_angle_2 = GeometryQueryTool::instance()->surface_angle(ref_face,
3390 : : ref_face_2,
3391 : : ref_edge_2,
3392 [ # # ][ # # ]: 0 : ref_volume);
3393 : 0 : surf_angle_2 *= rad_to_deg;
3394 [ # # ][ # # ]: 0 : if ( surf_angle_1 < 180.0 && surf_angle_2 > 180.0 )
3395 : : {
3396 : 0 : tangential_face = ref_face_1;
3397 : 0 : edge_next_to = ref_edge_1;
3398 : : }
3399 [ # # ][ # # ]: 0 : else if ( surf_angle_2 < 180.0 && surf_angle_1 > 180.0 )
3400 : : {
3401 : 0 : tangential_face = ref_face_2;
3402 : 0 : edge_next_to = ref_edge_2;
3403 : : }
3404 [ # # ]: 0 : if ( tangential_face == NULL ) // This isn't the config we seek.
3405 : 0 : continue;
3406 : :
3407 : : //Now, on this face, there is an edge, next to edge_next_to,
3408 : : //that will have an interior angle of 180.0. If that is the
3409 : : //case then this is what we seek.
3410 : : RefVertex* ref_vert = ref_edge_1->common_ref_vertex(ref_edge_2,
3411 [ # # ]: 0 : ref_face);
3412 [ # # ]: 0 : DLIList <RefEdge*> tmp_ref_edges;
3413 [ # # ]: 0 : ref_vert->ref_edges(tmp_ref_edges);
3414 : : //Find the edge that is on tangential face and is not edge_next_to.
3415 : 0 : RefEdge *tangential_edge=NULL, *tmp_edge;
3416 [ # # ][ # # ]: 0 : for ( jj = tmp_ref_edges.size(); jj > 0; jj-- )
3417 : : {
3418 [ # # ]: 0 : tmp_edge = tmp_ref_edges.get_and_step();
3419 [ # # ][ # # ]: 0 : if ( tmp_edge != edge_next_to &&
[ # # ]
3420 [ # # ]: 0 : tmp_edge->is_directly_related(tangential_face) )
3421 : : {
3422 : 0 : tangential_edge = tmp_edge;
3423 : 0 : break;
3424 : : }
3425 : : }
3426 [ # # ]: 0 : if ( tangential_edge == NULL )
3427 : : //not what we are looking for.
3428 : 0 : continue;
3429 : : //Now get the other face and measure the dihedral angle.
3430 : : RefFace *other_face = tangential_edge->other_face(tangential_face,
3431 [ # # ]: 0 : ref_volume);
3432 : : double tan_angle;
3433 : : tan_angle = GeometryQueryTool::instance()->surface_angle(tangential_face,
3434 : : other_face,
3435 : : tangential_edge,
3436 [ # # ][ # # ]: 0 : ref_volume);
3437 : 0 : tan_angle *= rad_to_deg;
3438 : : //If they are within tolerance, then we have it...
3439 [ # # ][ # # ]: 0 : if ( tan_angle > 165.0 && tan_angle < 195.0 )
3440 : : {
3441 [ # # ]: 0 : tangential_surface_pairs.append(tangential_face);
3442 [ # # ][ # # ]: 0 : tangential_surface_pairs.append(other_face);
[ # # ]
3443 : : }
3444 [ # # ]: 0 : }
3445 : 0 : }
3446 : :
3447 : :
3448 : :
3449 : 0 : void GeomMeasureTool::find_interior_curve_angles( RefVolume *ref_volume,
3450 : : double upper_bound,
3451 : : double lower_bound,
3452 : : DLIList <RefEdge*> &large_edge_angles,
3453 : : DLIList <RefEdge*> &small_edge_angles,
3454 : : DLIList <double> &large_angles,
3455 : : DLIList <double> &small_angles,
3456 : : int &total_interior,
3457 : : int &total_fuzzy)
3458 : : {
3459 : : int ii, jj, kk;
3460 [ # # ]: 0 : DLIList <RefFace*> ref_faces;
3461 : : RefFace *curr_face;
3462 : 0 : total_interior = 0;
3463 : 0 : total_fuzzy = 0;
3464 [ # # ]: 0 : ref_volume->ref_faces(ref_faces);
3465 : :
3466 : : //Okay now loop over the edge loops of the reffaces
3467 : : //and find the interior angles.
3468 [ # # ][ # # ]: 0 : DLIList<Loop*> loops;
3469 : : Loop *curr_loop;
3470 [ # # ][ # # ]: 0 : DLIList <CoEdge*> co_edges;
3471 : : CoEdge *curr_edge, *next_edge;
3472 : 0 : double angle = 0.0;
3473 : 0 : const double RAD_TO_DEG = 180.0/CUBIT_PI;
3474 [ # # ][ # # ]: 0 : for ( ii = ref_faces.size(); ii > 0; ii-- )
3475 : : {
3476 [ # # ]: 0 : curr_face = ref_faces.get_and_step();
3477 [ # # ]: 0 : curr_face->loops(loops);
3478 : : //Now loop over these loops.
3479 [ # # ][ # # ]: 0 : for ( jj = loops.size(); jj > 0; jj-- )
3480 : : {
3481 [ # # ]: 0 : curr_loop = loops.pop();
3482 : : //now loop over the edges in this
3483 [ # # ]: 0 : co_edges.clean_out();
3484 [ # # ]: 0 : curr_loop->ordered_co_edges(co_edges);
3485 [ # # ][ # # ]: 0 : for ( kk = co_edges.size(); kk > 0; kk-- )
3486 : : {
3487 [ # # ]: 0 : curr_edge = co_edges.get_and_step();
3488 [ # # ]: 0 : next_edge = co_edges.get();
3489 : :
3490 [ # # ]: 0 : if ( curr_edge == next_edge )
3491 : : {
3492 : : //This is a hardpoint
3493 [ # # ][ # # ]: 0 : if ( curr_edge->get_ref_edge_ptr()->geometry_type() == POINT_CURVE_TYPE )
[ # # ]
3494 : : {
3495 : 0 : angle = 360.0;
3496 : : //for now ignore this..
3497 : 0 : continue;
3498 : : }
3499 : : else
3500 : : {
3501 [ # # ]: 0 : RefEdge *the_edge = curr_edge->get_ref_edge_ptr();
3502 : : //Get points 1% from the ends in both directions.
3503 [ # # ][ # # ]: 0 : CubitVector point_start, point_end;
3504 : : CubitStatus stat = the_edge->position_from_fraction(0.01,
3505 [ # # ]: 0 : point_start);
3506 [ # # ]: 0 : if ( stat != CUBIT_SUCCESS )
3507 : 0 : angle = 180.0;
3508 : : else
3509 : : {
3510 : : stat = the_edge->position_from_fraction(0.99,
3511 [ # # ]: 0 : point_end);
3512 [ # # ]: 0 : if ( stat != CUBIT_SUCCESS )
3513 : 0 : angle = 180.0;
3514 : : else
3515 : : {
3516 [ # # ]: 0 : CubitVector normal = curr_face->normal_at(point_start, NULL);
3517 [ # # ][ # # ]: 0 : CubitVector tangent_1, tangent_2;
3518 [ # # ]: 0 : stat = the_edge->tangent( point_start, tangent_1, curr_face);
3519 [ # # ]: 0 : CubitStatus stat2 = the_edge->tangent( point_end, tangent_2, curr_face);
3520 [ # # ][ # # ]: 0 : if ( stat != CUBIT_SUCCESS || stat2 != CUBIT_SUCCESS )
3521 : 0 : angle = 180.0;
3522 : : else
3523 : : {
3524 : : //one of the tangents will be pointing the wrong
3525 : : //direction, so reverse it based on the sense.
3526 [ # # ][ # # ]: 0 : if ( curr_edge->get_sense() == CUBIT_REVERSED )
3527 [ # # ][ # # ]: 0 : tangent_1 = -tangent_1;
3528 : : else
3529 [ # # ][ # # ]: 0 : tangent_2 = -tangent_2;
3530 [ # # ]: 0 : angle = normal.vector_angle(tangent_2, tangent_1);
3531 : 0 : angle *= RAD_TO_DEG;
3532 : : }
3533 : : }
3534 : : }
3535 : : }
3536 : : }
3537 [ # # ][ # # ]: 0 : else if ( curr_edge->get_ref_edge_ptr() == next_edge->get_ref_edge_ptr() )
[ # # ]
3538 : : {
3539 : : //This is the end of a hard line. Set this angle because
3540 : : //it is tricky to measure it.
3541 : 0 : angle = 360.0;
3542 : : }
3543 [ # # ]: 0 : else if ( curr_edge != next_edge )
3544 : : {
3545 : : angle =
3546 : : GeometryQueryTool::instance()->geometric_angle(curr_edge,
3547 [ # # ][ # # ]: 0 : next_edge);
3548 : 0 : angle *= RAD_TO_DEG;
3549 : : }
3550 : 0 : total_interior++;
3551 : : //count the number of angles that are fuzzy.
3552 [ # # ]: 0 : if ( angle <= GEOM_END_LOWER )
3553 : 0 : total_fuzzy++;
3554 [ # # ][ # # ]: 0 : else if ( angle >= GEOM_END_UPPER &&
3555 : 0 : angle <= GEOM_SIDE_LOWER )
3556 : 0 : total_fuzzy++;
3557 [ # # ][ # # ]: 0 : else if ( angle >= GEOM_SIDE_UPPER &&
3558 : 0 : angle <= GEOM_CORNER_LOWER )
3559 : 0 : total_fuzzy++;
3560 [ # # ]: 0 : else if ( angle >= GEOM_CORNER_UPPER )
3561 : 0 : total_fuzzy++;
3562 [ # # ]: 0 : if ( angle <= lower_bound )
3563 : : {
3564 [ # # ][ # # ]: 0 : small_edge_angles.append(curr_edge->get_ref_edge_ptr());
3565 [ # # ][ # # ]: 0 : small_edge_angles.append(next_edge->get_ref_edge_ptr());
3566 [ # # ]: 0 : small_angles.append(angle);
3567 : : }
3568 [ # # ]: 0 : if ( angle >= upper_bound )
3569 : : {
3570 [ # # ][ # # ]: 0 : large_edge_angles.append(curr_edge->get_ref_edge_ptr());
3571 [ # # ][ # # ]: 0 : large_edge_angles.append(next_edge->get_ref_edge_ptr());
3572 [ # # ]: 0 : large_angles.append(angle);
3573 : : }
3574 : : }
3575 : : }
3576 : : }
3577 [ # # ]: 0 : return;
3578 : : }
3579 : :
3580 : 0 : void GeomMeasureTool::find_dihedral_angles( DLIList <RefVolume*> &ref_vols,
3581 : : double upper_bound,
3582 : : double lower_bound,
3583 : : DLIList <RefFace*> &large_face_angles,
3584 : : DLIList <RefFace*> &small_face_angles,
3585 : : DLIList <double> &large_angles,
3586 : : DLIList <double> &small_angles,
3587 : : int &total_interior,
3588 : : int &total_fuzzy,
3589 : : int &total_not_flat)
3590 : : {
3591 : : int ii;
3592 : : RefVolume *ref_vol;
3593 : 0 : total_interior = 0;
3594 : 0 : total_fuzzy = 0;
3595 : 0 : total_not_flat = 0;
3596 [ # # ]: 0 : for ( ii = 0; ii < ref_vols.size(); ii++ )
3597 : : {
3598 : 0 : ref_vol = ref_vols.get_and_step();
3599 : : find_dihedral_angles(ref_vol, upper_bound,
3600 : : lower_bound,
3601 : : large_face_angles,
3602 : : small_face_angles,
3603 : : large_angles, small_angles,
3604 : 0 : total_interior, total_fuzzy, total_not_flat);
3605 : : }
3606 : 0 : return;
3607 : : }
3608 : 0 : void GeomMeasureTool::find_dihedral_angles(RefVolume *curr_volume,
3609 : : double upper_bound,
3610 : : double lower_bound,
3611 : : DLIList <RefFace*> &large_face_angles,
3612 : : DLIList <RefFace*> &small_face_angles,
3613 : : DLIList <double> &large_angles,
3614 : : DLIList <double> &small_angles,
3615 : : int &total_interior,
3616 : : int &total_fuzzy, int &total_not_flat)
3617 : : {
3618 : 0 : int ii, jj, shared_angles = 0;
3619 : : double common_angle;
3620 [ # # ]: 0 : DLIList <RefFace*> face_list;
3621 : : RefFace *curr_face_1, *curr_face_2;
3622 : : RefFace *tmp_face;
3623 : : RefEdge *common_edge;
3624 [ # # ][ # # ]: 0 : DLIList <RefVolume*> ref_vols;
3625 [ # # ][ # # ]: 0 : DLIList<RefEdge*> vol_edges;
3626 [ # # ]: 0 : curr_volume->ref_edges(vol_edges);
3627 : :
3628 : : //maybe the body is a sheet-body...don't print errors if so
3629 : 0 : bool is_sheet_body = false;
3630 [ # # ][ # # ]: 0 : if( curr_volume->measure() == 0 )
3631 : 0 : is_sheet_body = true;
3632 : :
3633 [ # # ][ # # ]: 0 : for ( ii = vol_edges.size(); ii > 0; ii-- )
3634 : : {
3635 [ # # ]: 0 : common_edge = vol_edges.get_and_step();
3636 : :
3637 : : //skip point curves
3638 [ # # ][ # # ]: 0 : if( common_edge->geometry_type() == POINT_CURVE_TYPE )
3639 : 0 : continue;
3640 : :
3641 : 0 : curr_face_1 = NULL;
3642 : 0 : curr_face_2 = NULL;
3643 [ # # ]: 0 : face_list.clean_out();
3644 [ # # ]: 0 : common_edge->ref_faces(face_list);
3645 : : //find the two faces that are part of this volume.
3646 [ # # ][ # # ]: 0 : for ( jj = face_list.size(); jj > 0; jj-- )
3647 : : {
3648 [ # # ]: 0 : tmp_face = face_list.get_and_step();
3649 [ # # ]: 0 : ref_vols.clean_out();
3650 [ # # ]: 0 : tmp_face->ref_volumes(ref_vols);
3651 [ # # ][ # # ]: 0 : if ( ref_vols.move_to(curr_volume) )
3652 : : {
3653 [ # # ]: 0 : if ( curr_face_1 == NULL )
3654 : 0 : curr_face_1 = tmp_face;
3655 [ # # ]: 0 : else if ( curr_face_2 == NULL )
3656 : : {
3657 : 0 : curr_face_2 = tmp_face;
3658 : 0 : break;
3659 : : }
3660 : : }
3661 : : }
3662 [ # # ][ # # ]: 0 : if ( curr_face_1 == NULL ||
3663 : 0 : curr_face_2 == NULL )
3664 : : {
3665 [ # # ]: 0 : if( is_sheet_body == false )
3666 [ # # ][ # # ]: 0 : PRINT_ERROR("Problems finding connected surfaces to a curve\n"
[ # # ]
3667 [ # # ]: 0 : "\tfor measuring dihedral angles.\n");
3668 : 0 : continue;
3669 : : }
3670 : 0 : shared_angles++;
3671 : : common_angle = GeometryQueryTool::instance()->surface_angle(curr_face_1,
3672 : : curr_face_2,
3673 : : common_edge,
3674 [ # # ][ # # ]: 0 : curr_volume);
3675 : 0 : common_angle *= 180.0/CUBIT_PI;
3676 : 0 : total_interior++;
3677 : : //use hard coded angles because we want these a little looser.
3678 [ # # ][ # # ]: 0 : if ( common_angle >= 200.0 ||
3679 : 0 : common_angle <= 160.0 )
3680 : 0 : total_not_flat++;
3681 : :
3682 [ # # ][ # # ]: 0 : if ( curr_face_1->geometry_type() != PLANE_SURFACE_TYPE ||
[ # # ][ # # ]
3683 [ # # ]: 0 : curr_face_2->geometry_type() != PLANE_SURFACE_TYPE )
3684 : 0 : total_fuzzy++;
3685 [ # # ]: 0 : else if ( common_angle <= GEOM_END_LOWER )
3686 : 0 : total_fuzzy++;
3687 [ # # ][ # # ]: 0 : else if ( common_angle >= GEOM_END_UPPER &&
3688 : 0 : common_angle <= GEOM_SIDE_LOWER )
3689 : 0 : total_fuzzy++;
3690 [ # # ][ # # ]: 0 : else if ( common_angle >= GEOM_SIDE_UPPER &&
3691 : 0 : common_angle <= GEOM_CORNER_LOWER )
3692 : 0 : total_fuzzy++;
3693 [ # # ]: 0 : else if ( common_angle >= GEOM_CORNER_UPPER )
3694 : 0 : total_fuzzy++;
3695 : :
3696 [ # # ]: 0 : if( common_angle <= lower_bound )
3697 : : {
3698 [ # # ]: 0 : small_face_angles.append(curr_face_1);
3699 [ # # ]: 0 : small_face_angles.append(curr_face_2);
3700 [ # # ]: 0 : small_angles.append(common_angle);
3701 : : }
3702 [ # # ]: 0 : if( common_angle >= upper_bound )
3703 : : {
3704 [ # # ]: 0 : large_face_angles.append(curr_face_1);
3705 [ # # ]: 0 : large_face_angles.append(curr_face_2);
3706 [ # # ]: 0 : large_angles.append(common_angle);
3707 : : }
3708 : : }
3709 : : //clean up the edge marks.
3710 [ # # ][ # # ]: 0 : for ( ii = vol_edges.size(); ii > 0; ii-- )
3711 [ # # ][ # # ]: 0 : vol_edges.get_and_step()->marked(0);
[ # # ]
3712 : 0 : }
3713 : 0 : void GeomMeasureTool::find_close_loops(DLIList <RefVolume*> &ref_vols,
3714 : : DLIList <RefEdge*> &close_edges,
3715 : : DLIList <RefFace*> &close_loop_faces,
3716 : : DLIList <double> &small_lengths,
3717 : : double tol)
3718 : : {
3719 : : int ii, jj;
3720 [ # # ][ # # ]: 0 : DLIList <RefFace*> ref_faces, temp_faces;
[ # # ]
3721 : : RefVolume *ref_vol;
3722 : : RefFace *curr_face;
3723 [ # # ][ # # ]: 0 : for ( ii = 0; ii < ref_vols.size(); ii++ )
3724 : : {
3725 [ # # ]: 0 : ref_vol = ref_vols.get_and_step();
3726 [ # # ]: 0 : ref_vol->ref_faces(temp_faces);
3727 : : //uniquely add the faces.
3728 [ # # ][ # # ]: 0 : for ( jj = temp_faces.size(); jj > 0; jj-- )
3729 : : {
3730 [ # # ]: 0 : curr_face = temp_faces.pop();
3731 [ # # ]: 0 : ref_faces.append(curr_face);
3732 : : }
3733 : : }
3734 [ # # ][ # # ]: 0 : DLIList <RefEdge*> tmp_close_edges;
3735 [ # # ][ # # ]: 0 : DLIList <double> tmp_small_lengths;
3736 : :
3737 [ # # ][ # # ]: 0 : for ( ii = ref_faces.size(); ii > 0; ii-- )
3738 : : {
3739 [ # # ]: 0 : curr_face = ref_faces.get_and_step();
3740 [ # # ]: 0 : curr_face->marked(0);
3741 [ # # ][ # # ]: 0 : if ( curr_face->num_loops() < 2 )
3742 : 0 : continue;
3743 [ # # ]: 0 : tmp_close_edges.clean_out();
3744 [ # # ]: 0 : tmp_small_lengths.clean_out();
3745 : : find_close_loops( curr_face, tmp_close_edges,
3746 [ # # ]: 0 : tmp_small_lengths, tol);
3747 [ # # ][ # # ]: 0 : if ( tmp_close_edges.size() > 0 )
3748 : : {
3749 [ # # ][ # # ]: 0 : assert(tmp_close_edges.size()%2 == 0 );
3750 [ # # ]: 0 : tmp_close_edges.reset();
3751 [ # # ]: 0 : tmp_small_lengths.reset();
3752 [ # # ][ # # ]: 0 : for ( jj = tmp_close_edges.size()/2; jj > 0; jj-- )
3753 : : {
3754 [ # # ][ # # ]: 0 : close_edges.append(tmp_close_edges.get_and_step());
3755 [ # # ][ # # ]: 0 : close_edges.append(tmp_close_edges.get_and_step());
3756 [ # # ][ # # ]: 0 : small_lengths.append(tmp_small_lengths.get_and_step());
3757 [ # # ]: 0 : close_loop_faces.append(curr_face);
3758 : : }
3759 : : }
3760 : : }
3761 [ # # ]: 0 : return;
3762 : : }
3763 : :
3764 : :
3765 : 0 : void GeomMeasureTool::find_close_loops(RefFace *face,
3766 : : DLIList <RefEdge*> &close_edges,
3767 : : DLIList <double> &small_lengths,
3768 : : double tol)
3769 : : {
3770 : : //only do faces with multiple loops since we are measuring the
3771 : : //distances between these loops.
3772 [ # # ][ # # ]: 0 : if ( face->num_loops() < 2 )
3773 : 0 : return;
3774 : : //This is the most tricky of these functions.
3775 : : //To do this I'm going to facet the edges, then use an AbstractTree to
3776 : : //find the minimum distance between the loops and between a single
3777 : : //loop.
3778 [ # # ]: 0 : PointLoopList boundary_point_loops;
3779 : : CubitStatus stat;
3780 [ # # ]: 0 : stat = get_boundary_points(face, boundary_point_loops, GEOMETRY_RESABS*100);
3781 [ # # ]: 0 : if ( stat != CUBIT_SUCCESS )
3782 : 0 : return;
3783 : :
3784 [ # # ][ # # ]: 0 : SegLoopList boundary_seg_loops;
3785 : : stat = convert_to_lines( boundary_point_loops,
3786 : : boundary_seg_loops,
3787 [ # # ]: 0 : face);
3788 [ # # ]: 0 : if ( stat != CUBIT_SUCCESS )
3789 : 0 : return;
3790 : :
3791 : : //Now add the points to the AbstractTree.
3792 [ # # ][ # # ]: 0 : DLIList<AbstractTree<GeomSeg*>*> atree_list;
3793 : : AbstractTree<GeomSeg*> *curr_tree;
3794 : : SegList *seg_list;
3795 : : GeomSeg *curr_seg;
3796 : : int ii,jj, kk;
3797 : : //const double angle_convert = 180.0/CUBIT_PI;
3798 [ # # ]: 0 : boundary_seg_loops.reset();
3799 : 0 : int num_segs = 0;
3800 [ # # ][ # # ]: 0 : for (ii = 0; ii < boundary_seg_loops.size(); ii++ )
3801 : : {
3802 [ # # ]: 0 : seg_list = boundary_seg_loops.get_and_step();
3803 [ # # ][ # # ]: 0 : curr_tree = new RTree<GeomSeg*>(GEOMETRY_RESABS);
3804 [ # # ][ # # ]: 0 : for ( jj = seg_list->size(); jj > 0; jj-- )
3805 : : {
3806 : : //build the r-tree.
3807 : 0 : num_segs++;
3808 [ # # ]: 0 : curr_seg = seg_list->get_and_step();
3809 [ # # ]: 0 : curr_tree->add(curr_seg);
3810 : : //calculate the interior angles.
3811 : : }
3812 [ # # ]: 0 : atree_list.append(curr_tree);
3813 : : }
3814 : : //determine the minimum distance between the loops.
3815 : : PointList *curr_points;
3816 : : GeomPoint *curr_point;
3817 [ # # ][ # # ]: 0 : DLIList <GeomSeg*> nearest_neighbors;
3818 : : RefEdge *closest_edge_1, *closest_edge_2;
3819 [ # # ]: 0 : CubitVector curr_loc;
3820 : : double closest_dist;
3821 : : double min_for_loop_squared;
3822 [ # # ]: 0 : atree_list.reset();
3823 : : // This searching was orignally coded to not be an n-squared
3824 : : // search but I changed it to be n-squared because the
3825 : : // way the loops are compared comparing loop 1 against loop 2 may
3826 : : // give a different result than comparing loop 2 against loop 1.
3827 [ # # ][ # # ]: 0 : for ( ii = 0; ii < atree_list.size(); ii++ )
3828 : : {
3829 [ # # ]: 0 : curr_points = boundary_point_loops.get_and_step();
3830 [ # # ][ # # ]: 0 : for ( jj = 1; jj < atree_list.size(); jj++ )
3831 : : {
3832 : 0 : min_for_loop_squared = CUBIT_DBL_MAX;
3833 : 0 : closest_edge_1 = NULL;
3834 : 0 : closest_edge_2 = NULL;
3835 [ # # ]: 0 : curr_tree = atree_list.next(ii+jj);
3836 : : //now for every point in curr_points, find it's closest_point
3837 : : //in the curr_tree.
3838 [ # # ][ # # ]: 0 : for ( kk = 0; kk < curr_points->size(); kk++ )
3839 : : {
3840 [ # # ]: 0 : curr_point = curr_points->get_and_step();
3841 [ # # ][ # # ]: 0 : curr_loc.set(curr_point->coordinates());
3842 [ # # ]: 0 : nearest_neighbors.clean_out();
3843 : : curr_tree->k_nearest_neighbor(curr_loc,
3844 : : 1, closest_dist, nearest_neighbors,
3845 [ # # ]: 0 : dist_sq_point_data);
3846 [ # # ][ # # ]: 0 : if ( nearest_neighbors.size() == 0)
3847 : : {
3848 : : //hmm, not sure what is wrong here.
3849 [ # # ][ # # ]: 0 : PRINT_ERROR("Can't find closest point between loops.\n");
[ # # ][ # # ]
3850 : : }
3851 [ # # ][ # # ]: 0 : if (closest_dist <= tol*tol && closest_dist < min_for_loop_squared )
3852 : : {
3853 : : //just store the smaller ones. Don't store
3854 [ # # ]: 0 : RefEntity *ref_ent = curr_point->owner();
3855 [ # # ]: 0 : GeomSeg *near_seg = nearest_neighbors.get();
3856 [ # # ]: 0 : RefEdge *ref_edge_1 = CAST_TO(ref_ent, RefEdge);
3857 [ # # ]: 0 : if ( ref_edge_1 == NULL )
3858 : : {
3859 : : //assume this is a vertex.
3860 [ # # ]: 0 : RefVertex *ref_vert = CAST_TO(ref_ent, RefVertex);
3861 [ # # ]: 0 : if ( ref_vert == NULL )
3862 : : {
3863 [ # # ][ # # ]: 0 : PRINT_ERROR("problem with point ownership in closest loops.\n");
[ # # ][ # # ]
3864 : 0 : continue;
3865 : : }
3866 [ # # ]: 0 : DLIList <RefEdge*> ref_edges;
3867 [ # # ]: 0 : ref_vert->ref_edges(ref_edges);
3868 : : int ll;
3869 : 0 : RefEdge *the_edge = NULL;
3870 [ # # ][ # # ]: 0 : for ( ll = ref_edges.size(); ll > 0; ll-- )
3871 : : {
3872 [ # # ][ # # ]: 0 : if ( ref_edges.get()->is_directly_related(face) )
[ # # ]
3873 : : {
3874 [ # # ]: 0 : the_edge = ref_edges.get();
3875 : 0 : break;
3876 : : }
3877 [ # # ]: 0 : ref_edges.step();
3878 : : }
3879 [ # # ]: 0 : if ( the_edge == NULL )
3880 : : {
3881 [ # # ][ # # ]: 0 : PRINT_ERROR("problem with point ownership in closest loops.\n");
[ # # ][ # # ]
3882 : 0 : continue;
3883 : : }
3884 [ # # ][ # # ]: 0 : ref_edge_1 = the_edge;
3885 : : }
3886 [ # # ]: 0 : ref_ent = near_seg->owner();
3887 [ # # ]: 0 : RefEdge *ref_edge_2 = CAST_TO(ref_ent, RefEdge);
3888 [ # # ]: 0 : if ( ref_edge_2 == NULL )
3889 : : {
3890 [ # # ][ # # ]: 0 : PRINT_ERROR("problem with point ownership in closest loops.\n");
[ # # ][ # # ]
3891 : 0 : continue;
3892 : : }
3893 : :
3894 : 0 : min_for_loop_squared = closest_dist;
3895 : 0 : closest_edge_1 = ref_edge_1;
3896 : 0 : closest_edge_2 = ref_edge_2;
3897 : : }
3898 : : }
3899 [ # # ]: 0 : if ( closest_edge_1 != NULL )
3900 : : {
3901 [ # # ]: 0 : close_edges.append(closest_edge_1);
3902 [ # # ]: 0 : close_edges.append(closest_edge_2);
3903 [ # # ]: 0 : small_lengths.append(sqrt(min_for_loop_squared));
3904 : : }
3905 : : }
3906 : : }
3907 : : //clean up the memory.
3908 : : int ll,mm;
3909 [ # # ]: 0 : atree_list.reset();
3910 [ # # ]: 0 : boundary_seg_loops.reset();
3911 [ # # ][ # # ]: 0 : for ( ll = boundary_seg_loops.size(); ll > 0; ll-- )
3912 : : {
3913 [ # # ][ # # ]: 0 : delete atree_list.pop();
[ # # ]
3914 [ # # ]: 0 : seg_list = boundary_seg_loops.pop();
3915 [ # # ][ # # ]: 0 : for ( mm = seg_list->size(); mm > 0; mm-- )
3916 [ # # ][ # # ]: 0 : delete seg_list->pop();
[ # # ]
3917 [ # # ][ # # ]: 0 : delete seg_list;
3918 : : }
3919 : :
3920 : : PointList *point_list;
3921 [ # # ][ # # ]: 0 : for ( ll = boundary_point_loops.size(); ll > 0; ll-- )
3922 : : {
3923 [ # # ]: 0 : point_list = boundary_point_loops.pop();
3924 [ # # ][ # # ]: 0 : for ( mm = point_list->size(); mm > 0; mm-- )
3925 : : {
3926 [ # # ]: 0 : GeomPoint *tmp_point = point_list->pop();
3927 : : //delete the CubitPointData
3928 [ # # ][ # # ]: 0 : delete tmp_point;
3929 : : }
3930 [ # # ][ # # ]: 0 : delete point_list;
3931 : : }
3932 [ # # ]: 0 : return;
3933 : : }
3934 : 720 : double GeomMeasureTool::measure_area(RefFace* curr_face)
3935 : : {
3936 : : double area;
3937 [ + - ]: 720 : GeomDataObserver *g_d_o = GeomDataObserver::get(curr_face);
3938 [ + + ]: 720 : if ( g_d_o == NULL )
3939 [ + - ]: 370 : g_d_o = GeomDataObserver::create(curr_face);
3940 : :
3941 [ - + ]: 720 : if ( g_d_o == NULL )
3942 : : {
3943 [ # # ]: 0 : assert(g_d_o != NULL );
3944 : 0 : return curr_face->measure();
3945 : : }
3946 [ + + ]: 720 : if ( !g_d_o->is_measure_set() )
3947 : : {
3948 : 370 : area = (curr_face->get_surface_ptr())->measure();
3949 : 370 : g_d_o->set_measure(area);
3950 : : }
3951 : 720 : area = g_d_o->get_measure();
3952 : 720 : return area;
3953 : : }
3954 : :
3955 : : ///
3956 : : /// This function simply gets the bad entities of the volume. This
3957 : : /// assumes the volume is from some solid modelar where this function
3958 : : /// is defined. If not, it will just be empty...
3959 : : ///
3960 : 0 : void GeomMeasureTool::find_bad_geometry(RefVolume *volume,
3961 : : DLIList <RefEntity*> &bad_ents)
3962 : : {
3963 [ # # ]: 0 : Lump *lump_ptr = volume->get_lump_ptr();
3964 [ # # ]: 0 : DLIList <TopologyEntity*> bad_top_ents;
3965 [ # # ][ # # ]: 0 : lump_ptr->validate(volume->entity_name(), bad_top_ents);
[ # # ]
3966 : : //Now go through and get a RefEnttiy for each entity.
3967 : : RefEntity *ref_ent;
3968 : : TopologyEntity *topo_ent;
3969 : : GroupingEntity *gr_ent;
3970 : : SenseEntity *se_ent;
3971 : :
3972 : : int ii;
3973 [ # # ][ # # ]: 0 : for (ii = bad_top_ents.size(); ii > 0; ii-- )
3974 : : {
3975 [ # # ]: 0 : topo_ent = bad_top_ents.pop();
3976 [ # # ]: 0 : ref_ent = CAST_TO(topo_ent, RefEntity);
3977 [ # # ]: 0 : if ( ref_ent != NULL )
3978 : : {
3979 [ # # ]: 0 : bad_ents.append(ref_ent);
3980 : 0 : continue;
3981 : : }
3982 [ # # ]: 0 : gr_ent = CAST_TO(topo_ent, GroupingEntity);
3983 [ # # ]: 0 : if ( gr_ent != NULL )
3984 : : {
3985 [ # # ]: 0 : Chain *ch = CAST_TO(gr_ent, Chain);
3986 [ # # ]: 0 : if ( ch != NULL )
3987 : : {
3988 [ # # ]: 0 : RefVertex *start_v = ch->start_vertex();
3989 [ # # ]: 0 : RefVertex *end_v = ch->end_vertex();
3990 [ # # ]: 0 : RefEdge *ref_edge = start_v->common_ref_edge(end_v);
3991 [ # # ][ # # ]: 0 : bad_ents.append(ref_edge);
3992 : 0 : continue;
3993 : : }
3994 [ # # ]: 0 : Loop *lo = CAST_TO(gr_ent, Loop);
3995 [ # # ]: 0 : if ( lo != NULL )
3996 : : {
3997 [ # # ]: 0 : RefFace *rf = lo->get_ref_face_ptr();
3998 [ # # ][ # # ]: 0 : bad_ents.append(rf);
3999 : 0 : continue;
4000 : : }
4001 [ # # ]: 0 : Shell *sh = CAST_TO(gr_ent, Shell);
4002 [ # # ]: 0 : if (sh != NULL )
4003 : : {
4004 [ # # ]: 0 : RefVolume *rv = sh->get_ref_volume_ptr();
4005 [ # # ][ # # ]: 0 : bad_ents.append(rv);
4006 : 0 : continue;
4007 : : }
4008 : : else
4009 : : {
4010 : : //this is incase there is some other entity we don't
4011 : : //know about, just get the body...
4012 [ # # ]: 0 : Body *body = topo_ent->body();
4013 [ # # ][ # # ]: 0 : bad_ents.append(body);
4014 : 0 : continue;
4015 : : }
4016 : : }
4017 [ # # ]: 0 : se_ent = CAST_TO(topo_ent, SenseEntity);
4018 [ # # ]: 0 : if ( se_ent != NULL )
4019 : : {
4020 [ # # ]: 0 : BasicTopologyEntity *be = se_ent->get_basic_topology_entity_ptr();
4021 [ # # ][ # # ]: 0 : bad_ents.append(be);
4022 : 0 : continue;
4023 : : }
4024 : : //If we are here we didn't get the right entity. Just get
4025 : : //the body associated with this topology entity.
4026 [ # # ]: 0 : Body *b = topo_ent->body();
4027 [ # # ][ # # ]: 0 : bad_ents.append(b);
4028 : : }
4029 [ # # ]: 0 : return;
4030 : : }
4031 : :
4032 : : ///
4033 : : /// Find the irregular vertex valences.
4034 : : /// Find things like vertices with valences greater than 4.
4035 : : /// Assume for now that the volumes are not merged..
4036 : : ///
4037 : 0 : void GeomMeasureTool::find_irregular_valence( DLIList <RefVolume*> &ref_volumes,
4038 : : DLIList <RefVertex*> &irregular_vertices)
4039 : : {
4040 : : RefVolume *ref_vol;
4041 : : int ii;
4042 [ # # ]: 0 : for ( ii = 0; ii < ref_volumes.size(); ii++ )
4043 : : {
4044 : 0 : ref_vol = ref_volumes.get_and_step();
4045 : 0 : find_irregular_valence(ref_vol, irregular_vertices);
4046 : : }
4047 : 0 : }
4048 : : ///
4049 : : /// Find the irregular vertex valences.
4050 : : /// Find things like vertices with valences greater than 4.
4051 : : /// Assume for now that the volumes are not merged..
4052 : : ///
4053 : 0 : void GeomMeasureTool::find_irregular_valence( RefVolume *ref_volume,
4054 : : DLIList <RefVertex*> &irregular_vertices)
4055 : : {
4056 : : RefVertex *ref_vert;
4057 [ # # ]: 0 : DLIList <RefVertex*> ref_vertices;
4058 [ # # ]: 0 : ref_volume->ref_vertices(ref_vertices);
4059 : : int ii;
4060 [ # # ][ # # ]: 0 : for ( ii = ref_vertices.size(); ii > 0; ii-- )
4061 : : {
4062 [ # # ]: 0 : ref_vert = ref_vertices.get_and_step();
4063 [ # # ][ # # ]: 0 : if ( ref_vert->num_ref_edges() > 4 )
4064 [ # # ]: 0 : irregular_vertices.append(ref_vert);
4065 [ # # ]: 0 : }
4066 : 0 : }
4067 : :
4068 : : ///
4069 : : /// Find fillets and rounds.
4070 : : ///
4071 : : #define FACE_BLEND 1
4072 : : #define VERTEX_BLEND 2
4073 : : #define BLEND_PROCESSED 3
4074 : :
4075 : 0 : void GeomMeasureTool::find_blends( RefVolume *ref_volume,
4076 : : DLIList <RefFace*> &blend_faces,
4077 : : DLIList <DLIList<RefFace*>*> &blend_groups )
4078 : : {
4079 : : //Assume for now that blends have cartesian angles between
4080 : : //all the attached faces and itself.
4081 : : //Also a blend cannot be planar. And directly accross from
4082 : : //one blend edge, there is usually another blended edge but
4083 : : //the angle between the two normals must be orthogonal. In other
4084 : : //words their must be some sort of transition.
4085 : :
4086 : : //mark all the faces as 0. The mark is used here to find the
4087 : : // blend groups. The function is_vertex_blend() marks faces
4088 : : // as being a vertex blend. The group of faces is then traversed
4089 : : // until the adjacent surface (across the cross curve) is either
4090 : : // a vertex blend or not a blend.
4091 [ # # ]: 0 : DLIList <RefFace*> ref_faces;
4092 [ # # ][ # # ]: 0 : DLIList <RefFace*> vertex_blends, face_blends;
[ # # ][ # # ]
4093 [ # # ]: 0 : ref_volume->ref_faces(ref_faces);
4094 : : int ii, jj;
4095 [ # # ][ # # ]: 0 : for ( ii =0; ii < ref_faces.size(); ii++ )
4096 [ # # ][ # # ]: 0 : ref_faces.get_and_step()->marked(0);
4097 : :
4098 : : //First go through each face and each edge on each face.
4099 [ # # ][ # # ]: 0 : DLIList <RefEdge*> ref_edges;
4100 : : RefFace *ref_face;
4101 : : RefEdge *ref_edge, *other_edge;
4102 : 0 : int num_vertex_blends = 0;
4103 : 0 : int num_face_blends = 0;
4104 [ # # ][ # # ]: 0 : for ( ii = ref_faces.size(); ii > 0; ii-- )
4105 : : {
4106 [ # # ]: 0 : ref_face = ref_faces.get_and_step();
4107 : : //Test the face to see if it is a face or vertex blend.
4108 : 0 : other_edge = NULL;
4109 : 0 : ref_edge = NULL;
4110 [ # # ][ # # ]: 0 : if ( is_face_blend(ref_face, ref_volume,
4111 : 0 : ref_edge, other_edge ) )
4112 : : {
4113 [ # # ]: 0 : face_blends.append(ref_face);
4114 [ # # ]: 0 : ref_face->marked(1);
4115 : 0 : num_face_blends++;
4116 : : }
4117 [ # # ][ # # ]: 0 : else if ( is_vertex_blend(ref_face, ref_volume) )
4118 : : {
4119 [ # # ]: 0 : vertex_blends.append(ref_face);
4120 [ # # ]: 0 : ref_face->marked(2);
4121 : 0 : num_vertex_blends++; // keep track of the number of vertex blends
4122 : : }
4123 : : }
4124 [ # # ][ # # ]: 0 : if ( face_blends.size() + vertex_blends.size() == 0 )
[ # # ]
4125 : : {
4126 : 0 : return;
4127 : : }
4128 : : //Find out how many different groups of surfaces there
4129 : : //are that share curves.
4130 : 0 : DLIList <RefFace*> *blend_group = NULL;
4131 [ # # ][ # # ]: 0 : DLIList <RefFace*> stack;
4132 : 0 : RefFace *start_face = NULL, *other_face;
4133 : :
4134 : : // continue while there are blends to process
4135 [ # # ][ # # ]: 0 : while ( vertex_blends.size() + face_blends.size() > 0 ||
[ # # ][ # # ]
[ # # ]
4136 : 0 : start_face != NULL)
4137 : : {
4138 : : // if we don't have a start_face, get a new one.
4139 [ # # ]: 0 : if (!start_face)
4140 : : {
4141 : : // this is the start of a new group
4142 [ # # ][ # # ]: 0 : blend_group = new DLIList <RefFace*>;
4143 [ # # ]: 0 : blend_groups.append(blend_group);
4144 : :
4145 : : // always prefer to start at a vertex blend if one exists
4146 [ # # ][ # # ]: 0 : if (vertex_blends.size() > 0 )
4147 : : {
4148 [ # # ]: 0 : start_face = vertex_blends.pop();
4149 : : }
4150 : : else
4151 : : {
4152 [ # # ]: 0 : start_face = face_blends.pop();
4153 : : }
4154 : : }
4155 : :
4156 [ # # ]: 0 : blend_group->append(start_face); // add ref_face to group
4157 [ # # ]: 0 : blend_faces.append(start_face); // add the ref_face to the returned list
4158 [ # # ]: 0 : start_face->marked(BLEND_PROCESSED);
4159 : :
4160 [ # # ]: 0 : ref_edges.clean_out();
4161 [ # # ]: 0 : start_face->ref_edges(ref_edges);
4162 [ # # ][ # # ]: 0 : for ( jj = 0; jj < ref_edges.size(); jj++ )
4163 : : {
4164 [ # # ]: 0 : ref_edge = ref_edges.get_and_step();
4165 [ # # ]: 0 : other_face = ref_edge->other_face(start_face, ref_volume);
4166 [ # # ]: 0 : if (other_face == NULL)
4167 : : {
4168 : 0 : start_face = NULL;
4169 : 0 : break;
4170 : : }
4171 : :
4172 : : // if this blend has been processed and isn't in the current group
4173 [ # # ][ # # ]: 0 : if (other_face->marked() == BLEND_PROCESSED &&
[ # # ][ # # ]
4174 [ # # ]: 0 : !blend_group->is_in_list(other_face) )
4175 : : {
4176 : 0 : start_face = NULL;
4177 : 0 : break; // reached an end of this loop
4178 : : }
4179 [ # # ][ # # ]: 0 : else if (other_face->marked() == VERTEX_BLEND)
4180 : : {
4181 [ # # ]: 0 : blend_group->append(other_face); // add the ref_face to the group
4182 [ # # ]: 0 : blend_faces.append(other_face); // add the ref_face to the returned list
4183 [ # # ]: 0 : vertex_blends.remove(other_face);
4184 [ # # ]: 0 : other_face->marked(BLEND_PROCESSED);
4185 : 0 : start_face = NULL;
4186 : 0 : break; // a vertex blend is also end of the line
4187 : : }
4188 [ # # ][ # # ]: 0 : else if (other_face->marked() == FACE_BLEND)
4189 : : {
4190 : 0 : start_face = other_face;
4191 [ # # ]: 0 : face_blends.remove(other_face);
4192 : 0 : break; // continue using this face as the new start face
4193 : : }
4194 : : }
4195 : : // if we traversed through all the edges of this blend without
4196 : : // finding another blend attached, this is the end of the chain
4197 : : // and we need to find another starting place.
4198 [ # # ][ # # ]: 0 : if ( jj >= ref_edges.size() )
4199 : : {
4200 : 0 : start_face = NULL;
4201 : : }
4202 : :
4203 : : }
4204 : :
4205 : : //cleanup marks.
4206 [ # # ][ # # ]: 0 : for ( ii =0; ii < ref_faces.size(); ii++ )
4207 [ # # ][ # # ]: 0 : ref_faces.get_and_step()->marked(0);
4208 [ # # ][ # # ]: 0 : for ( ii =0; ii < blend_faces.size(); ii++ )
4209 [ # # ][ # # ]: 0 : blend_faces.get_and_step()->marked(0);
4210 : : //Okay we should have it now.
4211 : :
4212 : : //REMEMBER TO DELETE the dllists in blend_faces.
4213 [ # # ]: 0 : return;
4214 : : }
4215 : :
4216 : : // struct type object private to the next function
4217 : : class NextBlend
4218 : : {
4219 : : public:
4220 : : RefEdge* ref_edge;
4221 : : RefFace* ref_face;
4222 : : };
4223 : :
4224 : 0 : void GeomMeasureTool::find_blends_from_edge( RefVolume* ref_volume,
4225 : : RefFace *start_face,
4226 : : RefEdge* start_edge,
4227 : : std::vector <RefFace*> &blend_faces)
4228 : : {
4229 : : // initialize the mark on all surfaces in the volume
4230 [ # # ]: 0 : DLIList <RefFace*> ref_faces;
4231 : : RefEdge *next_edge, *other_edge;
4232 [ # # ]: 0 : ref_volume->ref_faces(ref_faces);
4233 : : int ii;
4234 [ # # ][ # # ]: 0 : for ( ii =0; ii < ref_faces.size(); ii++ )
4235 [ # # ][ # # ]: 0 : ref_faces.get_and_step()->marked(0);
4236 : :
4237 [ # # ][ # # ]: 0 : std::stack<NextBlend> blend_stack;
[ # # ][ # # ]
[ # # ]
4238 : :
4239 : : NextBlend blend;
4240 : 0 : blend.ref_edge = start_edge;
4241 : 0 : blend.ref_face = start_face;
4242 [ # # ]: 0 : blend_faces.push_back(start_face);
4243 : :
4244 [ # # ]: 0 : blend_stack.push(blend);
4245 : :
4246 [ # # ][ # # ]: 0 : while (blend_stack.size() > 0)
4247 : : {
4248 : : // this is an oddity with std::stack. Get the top of the stack
4249 : : // and then you have to remove it from the stack with pop
4250 [ # # ]: 0 : NextBlend next_blend = blend_stack.top();
4251 [ # # ]: 0 : blend_stack.pop();
4252 : 0 : RefEdge* ref_edge = next_blend.ref_edge;
4253 : 0 : RefFace* ref_face = next_blend.ref_face;
4254 : :
4255 : : RefFace* next_face;
4256 [ # # ]: 0 : next_face = ref_edge->other_face(ref_face, ref_volume);
4257 : :
4258 : : // the the next face exists and it's a face blend, save the current blend,
4259 : : // create a new blend object and add it to the stack
4260 [ # # ][ # # ]: 0 : if ( next_face && is_face_blend(next_face, ref_volume, next_edge, other_edge ) )
[ # # ][ # # ]
4261 : : {
4262 : : // if the next face is already processed, the chain loops back on itself.
4263 [ # # ][ # # ]: 0 : if (next_face->marked() == BLEND_PROCESSED)
4264 : : {
4265 [ # # ][ # # ]: 0 : for ( ii =0; ii < ref_faces.size(); ii++ )
4266 [ # # ][ # # ]: 0 : ref_faces.get_and_step()->marked(0);
4267 : 0 : return;
4268 : : }
4269 : :
4270 [ # # ]: 0 : blend_faces.push_back(next_face);
4271 [ # # ]: 0 : next_face->marked(BLEND_PROCESSED);
4272 : :
4273 : : // the is_face_blend function assumes (poorly) rectangular surfaces
4274 : : // without any holes. It returns the spring curves and we want
4275 : : // the cross curves. So get all four edges and remove the two
4276 : : // spring curves returned by is_face_blend
4277 [ # # ]: 0 : DLIList <RefEdge*> ref_edges;
4278 [ # # ]: 0 : next_face->ref_edges(ref_edges);
4279 [ # # ]: 0 : ref_edges.remove(next_edge);
4280 [ # # ]: 0 : ref_edges.remove(other_edge);
4281 : :
4282 [ # # ][ # # ]: 0 : if (ref_edges.get() != ref_edge)
4283 : : {
4284 [ # # ]: 0 : next_blend.ref_edge = ref_edges.get();
4285 : : }
4286 : : else
4287 : : {
4288 [ # # ]: 0 : next_blend.ref_edge = ref_edges.next(1);
4289 : : }
4290 : 0 : next_blend.ref_face = next_face;
4291 [ # # ][ # # ]: 0 : blend_stack.push(next_blend);
4292 : : }
4293 [ # # ][ # # ]: 0 : else if ( next_face && is_vertex_blend(next_face, ref_volume) )
[ # # ][ # # ]
4294 : : {
4295 : : // we will stop the chain at a vertex blend
4296 [ # # ]: 0 : blend_faces.push_back(next_face);
4297 [ # # ]: 0 : next_face->marked(BLEND_PROCESSED);
4298 : : }
4299 : : }
4300 : :
4301 : : // clean up the marks
4302 [ # # ]: 0 : std::vector<RefFace*>::iterator iter;
4303 [ # # ][ # # ]: 0 : for ( iter = blend_faces.begin(); iter != blend_faces.end(); iter++)
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
4304 [ # # ][ # # ]: 0 : (*iter)->marked(0);
4305 : : }
4306 : :
4307 : : // given a starting blend surface find a chain of blends from
4308 : : // that surface.
4309 : : //
4310 : : // Note that this function intentionally does _not_
4311 : : // clear the blend_face list so that additional chains can be added.
4312 : 0 : CubitStatus GeomMeasureTool::find_blend_chains( RefFace *start_face,
4313 : : std::vector<std::vector< RefFace*> > &blend_chains)
4314 : : {
4315 : :
4316 [ # # ]: 0 : if (start_face == NULL)
4317 : : {
4318 : 0 : return CUBIT_FAILURE;
4319 : : }
4320 : :
4321 [ # # ]: 0 : std::vector <RefFace*> blend_faces;
4322 : :
4323 : : // get the owning volume of this blend
4324 [ # # ][ # # ]: 0 : DLIList<RefEntity*> entity_list;
4325 : : RefVolume* ref_volume;
4326 : : int ii;
4327 : :
4328 [ # # ]: 0 : start_face->get_parent_ref_entities(entity_list);
4329 : :
4330 : : // this indicates merged enitites and potential problems
4331 [ # # ][ # # ]: 0 : if (entity_list.size() > 1)
4332 : : {
4333 : 0 : return CUBIT_FAILURE;
4334 : : }
4335 : :
4336 : : // make sure we're at the beginning of the list and get the first
4337 : : // and only item on the list and cast it to a RefVolume
4338 [ # # ]: 0 : entity_list.reset();
4339 [ # # ][ # # ]: 0 : ref_volume = CAST_TO(entity_list.get(), RefVolume);
4340 : :
4341 [ # # ]: 0 : if (!ref_volume)
4342 : : {
4343 : 0 : return CUBIT_FAILURE;
4344 : : }
4345 : :
4346 : : // initialize the mark on all surfaces in the volume
4347 [ # # ][ # # ]: 0 : DLIList <RefFace*> ref_faces;
4348 [ # # ]: 0 : ref_volume->ref_faces(ref_faces);
4349 : :
4350 : : RefEdge *spring_curve1, *spring_curve2;
4351 [ # # ][ # # ]: 0 : if ( is_face_blend(start_face, ref_volume, spring_curve1, spring_curve2 ) )
4352 : : {
4353 : : // the is_face_blend function assumes (poorly) rectangular surfaces
4354 : : // without any holes. It returns the spring curves and we want
4355 : : // the cross curves. So get all four edges and remove the two
4356 : : // spring curves returned by is_face_blend
4357 [ # # ]: 0 : DLIList <RefEdge*> ref_edges;
4358 [ # # ]: 0 : start_face->ref_edges(ref_edges);
4359 [ # # ]: 0 : ref_edges.remove(spring_curve1);
4360 [ # # ]: 0 : ref_edges.remove(spring_curve2);
4361 : :
4362 : : // there is a special case where the blend is a periodic surface
4363 : : // meaning that there _are_ no cross curves
4364 [ # # ][ # # ]: 0 : if ( ref_edges.size() == 0 )
4365 : : {
4366 [ # # ]: 0 : blend_faces.push_back(start_face);
4367 : : }
4368 : : else
4369 : : {
4370 : : // now find additional blends extending from either side of the blend
4371 [ # # ]: 0 : blend_faces.clear();
4372 [ # # ][ # # ]: 0 : find_blends_from_edge( ref_volume, start_face, ref_edges.get(), blend_faces);
4373 [ # # ][ # # ]: 0 : find_blends_from_edge( ref_volume, start_face, ref_edges.next(1), blend_faces);
4374 : :
4375 : : // make sure that we have a unique list (the start surface is probably here twice)
4376 [ # # ]: 0 : std::vector<RefFace*>::iterator new_end;
4377 [ # # ][ # # ]: 0 : std::sort( blend_faces.begin(), blend_faces.end() );
[ # # ]
4378 [ # # ][ # # ]: 0 : new_end = std::unique( blend_faces.begin(), blend_faces.end() );
[ # # ]
4379 [ # # ][ # # ]: 0 : blend_faces.erase(new_end, blend_faces.end());
4380 : : }
4381 : :
4382 [ # # ][ # # ]: 0 : blend_chains.push_back(blend_faces);
4383 : : }
4384 [ # # ][ # # ]: 0 : else if ( is_vertex_blend(start_face, ref_volume) )
4385 : : {
4386 [ # # ]: 0 : DLIList<RefEdge*> ref_edges;
4387 [ # # ]: 0 : start_face->ref_edges(ref_edges);
4388 : :
4389 [ # # ][ # # ]: 0 : for (ii = 0; ii < ref_edges.size(); ii++)
4390 : : {
4391 [ # # ]: 0 : RefEdge* start_edge = ref_edges.get_and_step();
4392 [ # # ]: 0 : blend_faces.clear();
4393 [ # # ]: 0 : find_blends_from_edge( ref_volume, start_face, start_edge, blend_faces);
4394 : :
4395 [ # # ]: 0 : blend_chains.push_back(blend_faces);
4396 [ # # ]: 0 : }
4397 : : }
4398 : : else
4399 : : {
4400 : : // the given face is not a blend
4401 : 0 : return CUBIT_FAILURE;
4402 : : }
4403 : :
4404 [ # # ]: 0 : return CUBIT_SUCCESS;
4405 : : }
4406 : :
4407 : : //--------------------------------------------------------------------
4408 : : //Function: Public, is_face_blend
4409 : : //Description: Determines if a face is a blend surface, returns the
4410 : : // ref_edge on one side of the blend and other_edge on the opposite side.
4411 : : // For this type of blend, only ref_edge must be tangentially meeting
4412 : : // with another surface. Other_edge must be oriented orthogonally to
4413 : : // it and may or may not blend with another surface. This assumes
4414 : : // a rectangular blend surface, without holes.
4415 : : //---------------------------------------------------------------------
4416 : 0 : CubitBoolean GeomMeasureTool::is_face_blend(RefFace *ref_face,
4417 : : RefVolume *ref_volume,
4418 : : RefEdge *&ref_edge,
4419 : : RefEdge *&other_edge)
4420 : : {
4421 : : //first we know that blend surfaces are not planar.
4422 : : //so remove these first.
4423 : : //Also, don't look at faces with more than 2 loops.
4424 [ # # ][ # # ]: 0 : if ( ref_face->geometry_type() == PLANE_SURFACE_TYPE ||
[ # # ][ # # ]
4425 [ # # ]: 0 : ref_face->num_loops() > 2 )
4426 : 0 : return CUBIT_FALSE;
4427 : :
4428 : : CubitBoolean is_cartesian;
4429 [ # # ]: 0 : DLIList<RefEdge*> ref_edges;
4430 : 0 : ref_edge = NULL;
4431 : 0 : other_edge = NULL;
4432 : : RefFace *other_face;
4433 : : int jj;
4434 : : double angle;
4435 [ # # ]: 0 : ref_face->ref_edges(ref_edges);
4436 [ # # ][ # # ]: 0 : for ( jj = ref_edges.size(); jj > 0; jj-- )
4437 : : {
4438 [ # # ]: 0 : ref_edge = ref_edges.get_and_step();
4439 : :
4440 : : //Weed-out case where one edge is shared between more
4441 : : //than 2 surfaces of the same volume
4442 [ # # ]: 0 : DLIList<RefFace*> tmp_faces;
4443 [ # # ]: 0 : ref_edge->ref_faces( tmp_faces );
4444 : :
4445 [ # # ][ # # ]: 0 : if( tmp_faces.size() > 2 )
4446 : : {
4447 : : int kk;
4448 [ # # ][ # # ]: 0 : for(kk=tmp_faces.size(); kk--;)
4449 : : {
4450 [ # # ][ # # ]: 0 : if( !tmp_faces.get()->is_child( ref_volume ) )
[ # # ][ # # ]
4451 [ # # ]: 0 : tmp_faces.change_to(NULL);
4452 [ # # ]: 0 : tmp_faces.step();
4453 : : }
4454 [ # # ]: 0 : tmp_faces.remove_all_with_value( NULL );
4455 [ # # ][ # # ]: 0 : if( tmp_faces.size() > 2 )
4456 : : //this isn't the type of surface we are looking for...
4457 : 0 : continue;
4458 : : }
4459 : :
4460 [ # # ]: 0 : other_face = ref_edge->other_face(ref_face, ref_volume);
4461 [ # # ]: 0 : if ( other_face == NULL )
4462 : : {
4463 : : //this isn't the type of surface we are looking for...
4464 : 0 : break;
4465 : : }
4466 : : angle = GeometryQueryTool::instance()->surface_angle(ref_face,
4467 : : other_face,
4468 : : ref_edge,
4469 [ # # ][ # # ]: 0 : ref_volume);
4470 : 0 : angle *= 180.0/CUBIT_PI;
4471 : 0 : is_cartesian = CUBIT_TRUE;
4472 [ # # ][ # # ]: 0 : if ( angle <= GEOM_SIDE_LOWER ||
4473 : : angle >= GEOM_SIDE_UPPER )
4474 : 0 : is_cartesian = CUBIT_FALSE;
4475 : : //Okay, we have one major criteria achieved, this edge is a cartesian meet.
4476 : :
4477 [ # # ]: 0 : if ( !is_cartesian )
4478 : 0 : continue;
4479 : : //Now we need to check the radius of curvatures between these
4480 : : //two surfaces. I'm not totally sure about this but I think we
4481 : : //don't want the same radius of curvature.
4482 : : double k1_s1, k2_s1, k1_s2, k2_s2;
4483 [ # # ]: 0 : CubitVector mid_point;
4484 [ # # ]: 0 : ref_edge->mid_point(mid_point);
4485 [ # # ]: 0 : ref_face->get_principal_curvatures( mid_point, k1_s1, k2_s1, ref_volume);
4486 [ # # ]: 0 : other_face->get_principal_curvatures( mid_point, k1_s2, k2_s2, ref_volume);
4487 [ # # ][ # # ]: 0 : if (( is_equal(k1_s1, k1_s2) || is_equal(k1_s1, k2_s2) ) &&
[ # # ][ # # ]
[ # # ][ # # ]
4488 [ # # ][ # # ]: 0 : ( is_equal(k2_s1, k1_s2) || is_equal(k2_s1, k2_s2) ) )
[ # # ]
4489 : : //try a different edge.
4490 : 0 : continue;
4491 : :
4492 : : //Okay, this looks pretty good.
4493 : : //Now try and find an edge that is on the "opposite" side of
4494 : : // this surface. Sort of assume this is like a mapable surface.
4495 : : //check the oposite side.
4496 : 0 : other_edge = NULL;
4497 [ # # ]: 0 : CubitVector opp_point;
4498 [ # # ][ # # ]: 0 : if ( !find_opposite_edge( ref_edge, ref_face, other_edge, opp_point) ||
[ # # ][ # # ]
4499 : 0 : other_edge == NULL )
4500 : : //if we can't find an opposite edge, we need to not
4501 : : //continue checking this surface.
4502 : 0 : return CUBIT_FALSE;
4503 : :
4504 : : //Okay, we have the point opposite. If this is a blend surface
4505 : : //the normal of this point should be pointing 90 degrees from
4506 : : //us.
4507 [ # # ]: 0 : CubitVector normal_1 = ref_face->normal_at(mid_point, ref_volume);
4508 [ # # ]: 0 : CubitVector normal_2 = ref_face->normal_at(opp_point, ref_volume);
4509 [ # # ]: 0 : normal_1.normalize();
4510 [ # # ]: 0 : normal_2.normalize();
4511 [ # # ]: 0 : double dot_product = normal_1 % normal_2;
4512 [ # # ][ # # ]: 0 : if ( dot_product >= .5 || dot_product <= -.5 )
4513 : : //try a different edge.
4514 : 0 : continue;
4515 [ # # ][ # # ]: 0 : CubitVector tangent_1, tangent_2;
4516 [ # # ]: 0 : ref_edge->tangent(mid_point, tangent_1, ref_face);
4517 [ # # ]: 0 : other_edge->tangent(opp_point, tangent_2, ref_face);
4518 [ # # ]: 0 : tangent_1.normalize();
4519 [ # # ]: 0 : tangent_2.normalize();
4520 [ # # ]: 0 : dot_product = tangent_1 % tangent_2;
4521 : : //basically these edges should be somewhat parallel at
4522 : : //this point.
4523 [ # # ][ # # ]: 0 : if ( dot_product < .5 && dot_product > -.5 )
4524 : 0 : continue;
4525 : : //This was called but never checked, not sure why.
4526 : : // //check the curvature opposite.
4527 : : // double k1_s3, k2_s3;
4528 : : // ref_face->get_principal_curvatures( opp_point, k1_s3, k2_s3, ref_volume);
4529 : : //we are done with this face. It is a blend face.
4530 [ # # ]: 0 : return CUBIT_TRUE;
[ # # # ]
4531 : 0 : }
4532 [ # # ]: 0 : return CUBIT_FALSE;
4533 : : }
4534 : :
4535 : : //--------------------------------------------------------------------
4536 : : //Function: Public, is_vertex_blend
4537 : : //Description: Determines if a face is a vertex blend surface.
4538 : : // For this type of blend, all ref_edges must be meet tangentially
4539 : : // with another surface. This assumes blend surface with no holes.
4540 : : //---------------------------------------------------------------------
4541 : 0 : CubitBoolean GeomMeasureTool::is_vertex_blend(RefFace *ref_face,
4542 : : RefVolume* ref_volume)
4543 : : {
4544 : : //first we know that blend surfaces are not planar.
4545 : : //so remove these first.
4546 : : //Also, don't look at faces with more than 2 loops.
4547 [ # # ][ # # ]: 0 : if ( ref_face->geometry_type() == PLANE_SURFACE_TYPE ||
[ # # ][ # # ]
4548 [ # # ]: 0 : ref_face->num_loops() > 2 )
4549 : 0 : return CUBIT_FALSE;
4550 : :
4551 : : CubitBoolean is_cartesian;
4552 [ # # ]: 0 : DLIList<RefEdge*> ref_edges;
4553 : : RefFace *other_face;
4554 : 0 : RefEdge *ref_edge = NULL;
4555 : : int jj;
4556 : : double angle;
4557 [ # # ]: 0 : ref_face->ref_edges(ref_edges);
4558 [ # # ][ # # ]: 0 : for ( jj = ref_edges.size(); jj > 0; jj-- )
4559 : : {
4560 [ # # ]: 0 : ref_edge = ref_edges.get_and_step();
4561 : :
4562 : : //Weed-out case where one edge is shared between more
4563 : : //than 2 surfaces of the same volume
4564 [ # # ]: 0 : DLIList<RefFace*> tmp_faces;
4565 [ # # ]: 0 : ref_edge->ref_faces( tmp_faces );
4566 : :
4567 [ # # ][ # # ]: 0 : if( tmp_faces.size() > 2 )
4568 : : {
4569 : : int kk;
4570 [ # # ][ # # ]: 0 : for(kk=tmp_faces.size(); kk--;)
4571 : : {
4572 [ # # ][ # # ]: 0 : if( !tmp_faces.get()->is_child( ref_volume ) )
[ # # ][ # # ]
4573 [ # # ]: 0 : tmp_faces.change_to(NULL);
4574 [ # # ]: 0 : tmp_faces.step();
4575 : : }
4576 [ # # ]: 0 : tmp_faces.remove_all_with_value( NULL );
4577 [ # # ][ # # ]: 0 : if( tmp_faces.size() > 2 )
4578 : : //this isn't the type of surface we are looking for...
4579 : 0 : continue;
4580 : : }
4581 : :
4582 [ # # ]: 0 : other_face = ref_edge->other_face(ref_face, ref_volume);
4583 [ # # ]: 0 : if ( other_face == NULL )
4584 : : {
4585 : : //this isn't the type of surface we are looking for...
4586 : 0 : break;
4587 : : }
4588 : : angle = GeometryQueryTool::instance()->surface_angle(ref_face,
4589 : : other_face,
4590 : : ref_edge,
4591 [ # # ][ # # ]: 0 : ref_volume);
4592 : 0 : angle *= 180.0/CUBIT_PI;
4593 : 0 : is_cartesian = CUBIT_TRUE;
4594 [ # # ][ # # ]: 0 : if ( angle <= GEOM_SIDE_LOWER ||
4595 : : angle >= GEOM_SIDE_UPPER )
4596 : 0 : is_cartesian = CUBIT_FALSE;
4597 : : //Okay, we have one major criteria achieved, this edge is a cartesian meet.
4598 : :
4599 [ # # ]: 0 : if ( !is_cartesian )
4600 : 0 : return CUBIT_FALSE;
4601 : : //Now we need to check the radius of curvatures between these
4602 : : //two surfaces. I'm not totally sure about this but I think we
4603 : : // want the same radius of curvature.
4604 : : double k1_s1, k2_s1, k1_s2, k2_s2;
4605 [ # # ]: 0 : CubitVector mid_point;
4606 [ # # ]: 0 : ref_edge->mid_point(mid_point);
4607 [ # # ]: 0 : ref_face->get_principal_curvatures( mid_point, k1_s1, k2_s1, ref_volume);
4608 [ # # ]: 0 : other_face->get_principal_curvatures( mid_point, k1_s2, k2_s2, ref_volume);
4609 [ # # ][ # # ]: 0 : if (( is_equal(k1_s1, k1_s2) || is_equal(k1_s1, k2_s2) ) &&
[ # # ][ # # ]
[ # # ][ # # ]
4610 [ # # ][ # # ]: 0 : ( is_equal(k2_s1, k1_s2) || is_equal(k2_s1, k2_s2) ) )
[ # # ]
4611 : : //try a different edge.
4612 : 0 : continue;
4613 : : else
4614 [ # # ]: 0 : return CUBIT_FALSE;
[ # # # ]
4615 : 0 : }
4616 : :
4617 : : // if all edges are tangent and share curvatures then it must be a
4618 : : // vertex blend.
4619 [ # # ]: 0 : return CUBIT_TRUE;
4620 : : }
4621 : :
4622 : 0 : CubitBoolean GeomMeasureTool::find_opposite_edge( RefEdge* ref_edge,
4623 : : RefFace* ref_face,
4624 : : RefEdge *&other_edge,
4625 : : CubitVector &closest_point)
4626 : : {
4627 : : //Here we want to find the edge that is "opposite" to ref_edge.
4628 : : //Opposite is defined by assuming the surface is a square or cylinder and
4629 : : //finding the edge on the other side, so that there is a point closest
4630 : : //to the mid point on the ref_edge.
4631 : : //double need_to_turn = CUBIT_PI;
4632 : : int ii;
4633 [ # # ]: 0 : DLIList <Loop*> loops;
4634 [ # # ][ # # ]: 0 : DLIList <CoEdge*> co_edges;
4635 : : Loop *curr_loop;
4636 : : CoEdge *co_edge, *this_co_edge;
4637 [ # # ]: 0 : ref_edge->get_co_edges(co_edges, ref_face);
4638 [ # # ][ # # ]: 0 : if ( co_edges.size() != 1 )
4639 : 0 : return CUBIT_FALSE;
4640 [ # # ]: 0 : this_co_edge = co_edges.get();
4641 [ # # ]: 0 : co_edges.clean_out();
4642 [ # # ]: 0 : ref_face->loops(loops);
4643 [ # # ][ # # ]: 0 : if ( loops.size() > 2 )
4644 : 0 : return CUBIT_FALSE;
4645 : 0 : CubitBoolean found_loop = CUBIT_FALSE;
4646 : : //find the loop where this_co_edge is on.
4647 [ # # ][ # # ]: 0 : for(ii = loops.size(); ii > 0; ii-- )
4648 : : {
4649 [ # # ]: 0 : curr_loop = loops.get_and_step();
4650 [ # # ]: 0 : co_edges.clean_out();
4651 [ # # ]: 0 : curr_loop->ordered_co_edges(co_edges);
4652 [ # # ][ # # ]: 0 : if ( co_edges.move_to(this_co_edge) )
4653 : : {
4654 : 0 : found_loop = CUBIT_TRUE;
4655 : 0 : break;
4656 : : }
4657 : : }
4658 [ # # ]: 0 : if ( !found_loop )
4659 : 0 : return CUBIT_FALSE;
4660 : 0 : CoEdge *opp_co_edge = NULL;
4661 [ # # ][ # # ]: 0 : if ( loops.size() == 1 )
4662 : : {
4663 : : //This is the normal case, I hope.
4664 : : //this co_edge, go around the interior until
4665 : : //we turn twice. If there are angles greater than CUBIT_PI, this isn't
4666 : : //a traditional blend. Everything should be convex.
4667 [ # # ][ # # ]: 0 : if ( co_edges.size() == 4 )
4668 : : {
4669 : : //Just get the one opposite...
4670 [ # # ]: 0 : opp_co_edge = co_edges.next(2);
4671 : : }
4672 : : else
4673 : : {
4674 : : //double total_angle = 0.0;
4675 : 0 : int turn_counter = 0;
4676 : 0 : CoEdge *next_co_edge = NULL;
4677 [ # # ][ # # ]: 0 : for ( ii = co_edges.size(); ii > 0; ii-- )
4678 : : {
4679 [ # # ]: 0 : co_edge = co_edges.get_and_step();
4680 [ # # ]: 0 : next_co_edge = co_edges.get();
4681 [ # # ][ # # ]: 0 : double angle = GeometryQueryTool::instance()->geometric_angle(co_edge, next_co_edge);
4682 : 0 : angle *= 180.0/CUBIT_PI;
4683 : : //we don't deal with small or concave angles.
4684 [ # # ]: 0 : if ( angle < 10.0 )
4685 : 0 : return CUBIT_FALSE;
4686 [ # # ]: 0 : else if ( angle > 185.0 )
4687 : 0 : return CUBIT_FALSE;
4688 [ # # ]: 0 : else if ( angle < 140.0 )
4689 : 0 : turn_counter++;
4690 [ # # ]: 0 : if ( turn_counter == 2 )
4691 : : {
4692 : 0 : opp_co_edge = next_co_edge;
4693 : 0 : break;
4694 : : }
4695 : : }
4696 : : }
4697 : : }
4698 : : else
4699 : : {
4700 : : //Just get the other loop and get one coedge in it.
4701 [ # # ]: 0 : co_edges.clean_out();
4702 [ # # ]: 0 : curr_loop = loops.get();
4703 [ # # ]: 0 : curr_loop->ordered_co_edges(co_edges);
4704 [ # # ]: 0 : opp_co_edge = co_edges.get();
4705 : : }
4706 [ # # ]: 0 : if ( opp_co_edge == NULL )
4707 : 0 : return CUBIT_FALSE;
4708 : : //This is just here to test correctness to this point, it can be taken out
4709 : : //if need be.
4710 [ # # ][ # # ]: 0 : if ( !co_edges.move_to(opp_co_edge) )
4711 : : {
4712 [ # # ][ # # ]: 0 : PRINT_ERROR("logic messed-up in find_opposite edge\n");
[ # # ][ # # ]
4713 : 0 : assert(0);
4714 : : return CUBIT_FALSE;
4715 : : }
4716 : : //okay, we now have the co_edges in the correct position and
4717 : : //we have a canidate co_edge.
4718 : : //Search from the co_edge with the point that has closest point
4719 : : //to the mid point of this_co_edge.
4720 : 0 : other_edge = NULL;
4721 [ # # ]: 0 : CubitVector mid_point;
4722 [ # # ]: 0 : ref_edge->mid_point(mid_point);
4723 [ # # ]: 0 : CubitVector tmp_closest_point;
4724 : 0 : double min_dist_sq = CUBIT_DBL_MAX;
4725 : : double dist_sq;
4726 : : RefEdge *test_ref_edge;
4727 : : CoEdge *prev_co_edge;
4728 : 0 : CubitBoolean first = CUBIT_TRUE;
4729 [ # # ][ # # ]: 0 : for ( ii = co_edges.size(); ii > 0; ii-- )
4730 : : {
4731 [ # # ]: 0 : co_edge = co_edges.get_and_step();
4732 [ # # ]: 0 : prev_co_edge = co_edges.prev(2);
4733 [ # # ]: 0 : test_ref_edge = co_edge->get_ref_edge_ptr();
4734 : : //We don't want edges that are connected to ref edge.
4735 : : //If we have them, we have gone to far around the surface.
4736 [ # # ][ # # ]: 0 : if ( test_ref_edge->common_ref_vertex(ref_edge) )
4737 : 0 : break;
4738 [ # # ]: 0 : if ( !first )
4739 : : {
4740 : : //break out of the for loop if we turn again. We just want the closest
4741 : : //point opposite.
4742 : : double angle = GeometryQueryTool::instance()->
4743 [ # # ][ # # ]: 0 : geometric_angle(prev_co_edge, co_edge);
4744 : 0 : angle *= 180.0/CUBIT_PI;
4745 [ # # ][ # # ]: 0 : if ( angle > 195.0 || angle < 145.0 )
4746 : : break;
4747 : : }
4748 : : else
4749 : 0 : first = CUBIT_FALSE;
4750 : : //now find the closest point to the mid point of ref_edge.
4751 : : test_ref_edge->closest_point_trimmed( mid_point,
4752 [ # # ]: 0 : tmp_closest_point);
4753 [ # # ][ # # ]: 0 : dist_sq = (mid_point - closest_point).length_squared();
4754 : : //find and keep the closest one.
4755 [ # # ]: 0 : if ( dist_sq < min_dist_sq )
4756 : : {
4757 : 0 : other_edge = test_ref_edge;
4758 : 0 : min_dist_sq = dist_sq;
4759 [ # # ]: 0 : closest_point = tmp_closest_point;
4760 : : }
4761 : : }
4762 [ # # ]: 0 : if ( other_edge == NULL )
4763 : 0 : return CUBIT_FALSE;
4764 : :
4765 [ # # ]: 0 : return CUBIT_TRUE;
4766 : : }
4767 : 0 : CubitBoolean GeomMeasureTool::is_equal(double v1, double v2)
4768 : : {
4769 : 0 : double smallv = v1-v2;
4770 [ # # ]: 0 : if ( smallv < 0.0 )
4771 : : {
4772 [ # # ]: 0 : if ( smallv >= -CUBIT_RESABS )
4773 : 0 : return CUBIT_TRUE;
4774 : : else
4775 : 0 : return CUBIT_FALSE;
4776 : : }
4777 : : else
4778 : : {
4779 [ # # ]: 0 : if ( smallv <= CUBIT_RESABS )
4780 : 0 : return CUBIT_TRUE;
4781 : : else
4782 : 0 : return CUBIT_FALSE;
4783 : : }
4784 : : }
4785 : 0 : CubitStatus GeomMeasureTool::get_centroid( RefFace *ref_face, CubitVector ¢roid, double &tot_area )
4786 : : {
4787 [ # # ]: 0 : GMem g_mem;
4788 : 0 : unsigned short norm_tol = 5;
4789 : 0 : double dist_tol = -1.0;
4790 : :
4791 [ # # ]: 0 : ref_face->get_geometry_query_engine()->
4792 [ # # ][ # # ]: 0 : get_graphics(ref_face->get_surface_ptr(), &g_mem, norm_tol, dist_tol );
4793 : :
4794 [ # # ]: 0 : if(g_mem.fListCount < 1)
4795 : : {
4796 : : // Decrease tolerance and try again (we can get this for small features)
4797 : 0 : norm_tol /= 2;
4798 [ # # ]: 0 : ref_face->get_geometry_query_engine()->
4799 [ # # ][ # # ]: 0 : get_graphics(ref_face->get_surface_ptr(), &g_mem, norm_tol, dist_tol );
4800 : : }
4801 : :
4802 [ # # ]: 0 : if(g_mem.fListCount < 1)
4803 : : {
4804 : : // Lets give up
4805 [ # # ][ # # ]: 0 : PRINT_ERROR( "Unable to find the center of a surface\n" );
[ # # ][ # # ]
4806 : 0 : return CUBIT_FAILURE;
4807 : : }
4808 : :
4809 : : // Initialize
4810 : 0 : tot_area = 0.0;
4811 [ # # ]: 0 : centroid.set( 0.0, 0.0, 0.0 );
4812 : :
4813 : : // Loop through the triangles
4814 : : double tri_area;
4815 : : GPoint p[3];
4816 [ # # ]: 0 : GPoint* plist = g_mem.point_list();
4817 [ # # ]: 0 : int* facet_list = g_mem.facet_list();
4818 : 0 : int c = 0;
4819 [ # # ]: 0 : for( ; c < g_mem.fListCount; )
4820 : : {
4821 : 0 : p[0] = plist[facet_list[++c]];
4822 : 0 : p[2] = plist[facet_list[++c]];
4823 : 0 : p[1] = plist[facet_list[++c]];
4824 : 0 : c++;
4825 : :
4826 : : // Get centroid
4827 [ # # ]: 0 : CubitVector p1( p[0].x, p[0].y, p[0].z );
4828 [ # # ]: 0 : CubitVector p2( p[2].x, p[2].y, p[2].z );
4829 [ # # ]: 0 : CubitVector p3( p[1].x, p[1].y, p[1].z );
4830 : :
4831 [ # # ][ # # ]: 0 : CubitVector center = (p1 + p2 + p3)/3.0;
[ # # ]
4832 : :
4833 : : //Calculate area
4834 [ # # ]: 0 : CubitVector vec1 = (p2 - p1);
4835 [ # # ]: 0 : CubitVector vec2 = (p3 - p1);
4836 : :
4837 [ # # ]: 0 : CubitVector cross = vec1 * vec2;
4838 : :
4839 [ # # ][ # # ]: 0 : tri_area = 0.5* sqrt(cross.x() * cross.x() + cross.y() * cross.y() + cross.z() * cross.z());
[ # # ][ # # ]
[ # # ][ # # ]
4840 : :
4841 : :
4842 [ # # ][ # # ]: 0 : centroid += (tri_area * center);
4843 : :
4844 : 0 : tot_area += tri_area;
4845 : :
4846 : : }
4847 [ # # ]: 0 : if( tot_area == 0 )
4848 : 0 : return CUBIT_FAILURE;
4849 : :
4850 [ # # ]: 0 : centroid /= tot_area;
4851 [ # # ]: 0 : return CUBIT_SUCCESS;
4852 : : }
4853 : :
4854 : : CubitStatus
4855 : 0 : GeomMeasureTool::center( DLIList<RefFace*> ref_faces )
4856 : : {
4857 : : int ii,id;
4858 : : double surf_area;
4859 : 0 : double tot_area = 0.0;
4860 [ # # ]: 0 : CubitVector surf_centroid;
4861 [ # # ]: 0 : CubitVector centroid;
4862 [ # # ]: 0 : centroid.set( 0.0, 0.0, 0.0 );
4863 : :
4864 [ # # ][ # # ]: 0 : for ( ii = ref_faces.size(); ii > 0; ii-- )
4865 : : {
4866 [ # # ]: 0 : RefFace *ref_face = ref_faces.get_and_step();
4867 [ # # ][ # # ]: 0 : if( GeomMeasureTool::get_centroid( ref_face, surf_centroid, surf_area) != CUBIT_SUCCESS )
4868 : 0 : return CUBIT_FAILURE;
4869 [ # # ][ # # ]: 0 : centroid += (surf_area * surf_centroid);
4870 : 0 : tot_area += surf_area;
4871 [ # # ]: 0 : id = ref_face->id();
4872 : : }
4873 : :
4874 [ # # ]: 0 : centroid /= tot_area;
4875 : :
4876 [ # # ][ # # ]: 0 : if( ref_faces.size() > 1 )
4877 [ # # ][ # # ]: 0 : PRINT_INFO("Centroid of Composite surface located at: ( %f , %f , %f )\n\n",
[ # # ][ # # ]
[ # # ][ # # ]
4878 [ # # ]: 0 : centroid.x(), centroid.y(), centroid.z());
4879 : : else
4880 [ # # ][ # # ]: 0 : PRINT_INFO("Centroid of Surface %i located at: ( %f , %f , %f )\n\n",
[ # # ][ # # ]
[ # # ][ # # ]
4881 [ # # ]: 0 : id, centroid.x(), centroid.y(), centroid.z());
4882 : 0 : return CUBIT_SUCCESS;
4883 : : }
4884 : :
4885 : 0 : CubitStatus GeomMeasureTool::find_near_coincident_vertices(
4886 : : DLIList<RefVolume*> &ref_volumes,
4887 : : DLIList<RefVertex*> &ref_vertices_out,
4888 : : DLIList<double> &distances,
4889 : : double low_tol,
4890 : : double high_tol,
4891 : : bool filter_same_volume_cases)
4892 : : {
4893 [ # # ]: 0 : DLIList<RefVertex*> tmp_vert_list;
4894 [ # # ][ # # ]: 0 : DLIList<RefVertex*> ref_verts;
4895 : : int i,j;
4896 [ # # ][ # # ]: 0 : for( i=ref_volumes.size(); i--; )
4897 : : {
4898 [ # # ]: 0 : RefVolume *tmp_vol = ref_volumes.get_and_step();
4899 [ # # ]: 0 : tmp_vert_list.clean_out();
4900 [ # # ]: 0 : tmp_vol->ref_vertices( tmp_vert_list );
4901 [ # # ]: 0 : ref_verts += tmp_vert_list;
4902 : : }
4903 : :
4904 : : //put all the vertices in a tree
4905 [ # # ][ # # ]: 0 : AbstractTree <RefVertex*> *a_tree = new RTree<RefVertex*>( high_tol );
4906 [ # # ][ # # ]: 0 : for (i=ref_verts.size(); i--;)
4907 [ # # ][ # # ]: 0 : a_tree->add(ref_verts.get_and_step());
4908 : :
4909 [ # # ][ # # ]: 0 : std::multimap<double, dist_vert_struct> distance_vertex_map;
4910 : :
4911 : : //for each vertex
4912 [ # # ][ # # ]: 0 : for (i=ref_verts.size(); i--;)
4913 : : {
4914 [ # # ]: 0 : RefVertex *tmp_vert = ref_verts.get_and_step();
4915 [ # # ]: 0 : RefVolume *v1 = tmp_vert->ref_volume();
4916 [ # # ]: 0 : CubitVector vert_xyz = tmp_vert->coordinates();
4917 : :
4918 : : //get all close vertices
4919 [ # # ]: 0 : DLIList<RefVertex*> close_verts;
4920 [ # # ][ # # ]: 0 : a_tree->find(tmp_vert->bounding_box(), close_verts);
[ # # ]
4921 : :
4922 : : //if any vertex is between low_tol and high_tol
4923 : : //add it to the list
4924 [ # # ][ # # ]: 0 : DLIList<RefVertex*> near_coincident_verts;
4925 [ # # ][ # # ]: 0 : for( j=close_verts.size(); j--; )
4926 : : {
4927 [ # # ]: 0 : RefVertex *close_vert = close_verts.get_and_step();
4928 [ # # ]: 0 : if( close_vert == tmp_vert )
4929 : 0 : continue;
4930 : :
4931 [ # # ]: 0 : RefVolume *v2 = close_vert->ref_volume();
4932 : 0 : bool check_distance = true;
4933 [ # # ][ # # ]: 0 : if(filter_same_volume_cases && v1 && v2 && v1 == v2)
[ # # ][ # # ]
4934 : 0 : check_distance = false;
4935 [ # # ]: 0 : if(check_distance)
4936 : : {
4937 [ # # ][ # # ]: 0 : double distance = vert_xyz.distance_between( close_vert->coordinates() );
4938 [ # # ][ # # ]: 0 : if( distance >= low_tol && distance <= high_tol )
4939 : : {
4940 : : dist_vert_struct tmp_struct;
4941 : 0 : tmp_struct.dist = distance;
4942 : 0 : tmp_struct.v1 = tmp_vert;
4943 : 0 : tmp_struct.v2 = close_vert;
4944 : : distance_vertex_map.insert( std::multimap<double, dist_vert_struct>::
4945 [ # # ][ # # ]: 0 : value_type( distance, tmp_struct ));
4946 : : }
4947 : : }
4948 : : }
4949 : :
4950 [ # # ]: 0 : a_tree->remove( tmp_vert );
4951 [ # # ]: 0 : }
4952 : :
4953 [ # # ]: 0 : std::multimap<double, dist_vert_struct>::reverse_iterator iter;
4954 : :
4955 [ # # ]: 0 : iter = distance_vertex_map.rbegin();
4956 [ # # ][ # # ]: 0 : for(; iter!=distance_vertex_map.rend(); iter++ )
[ # # ][ # # ]
4957 : : {
4958 [ # # ][ # # ]: 0 : distances.append( (*iter).second.dist );
4959 [ # # ][ # # ]: 0 : ref_vertices_out.append( (*iter).second.v1 );
4960 [ # # ][ # # ]: 0 : ref_vertices_out.append( (*iter).second.v2 );
4961 : : }
4962 : :
4963 [ # # ][ # # ]: 0 : delete a_tree;
4964 : :
4965 [ # # ]: 0 : return CUBIT_SUCCESS;
4966 : : }
4967 : :
4968 : : // This function is similar to find_near_coincident_vertices except for the
4969 : : // fact that it will only find the closest vertex in a given volume for
4970 : : // a vertex in another volume to be close to. This tries to exclude the case where
4971 : : // you would attempt to merge one vertex from one volume to two different
4972 : : // vertices in another volume.
4973 : 0 : CubitStatus GeomMeasureTool::find_near_coincident_vertices_unique(
4974 : : DLIList<RefVolume*> &ref_volumes,
4975 : : double high_tol,
4976 : : std::map <RefVertex*, DLIList<dist_vert_struct*>*> &vert_dist_map)
4977 : : {
4978 [ # # ]: 0 : DLIList<RefVertex*> tmp_vert_list;
4979 [ # # ][ # # ]: 0 : DLIList<RefVertex*> ref_verts;
4980 : : int i,j;
4981 [ # # ][ # # ]: 0 : for( i=ref_volumes.size(); i--; )
4982 : : {
4983 [ # # ]: 0 : RefVolume *tmp_vol = ref_volumes.get_and_step();
4984 [ # # ]: 0 : tmp_vert_list.clean_out();
4985 [ # # ]: 0 : tmp_vol->ref_vertices( tmp_vert_list );
4986 [ # # ]: 0 : ref_verts += tmp_vert_list;
4987 : : }
4988 : :
4989 : : //put all the vertices in a tree
4990 [ # # ][ # # ]: 0 : AbstractTree <RefVertex*> *a_tree = new RTree<RefVertex*>( high_tol );
4991 [ # # ][ # # ]: 0 : for (i=ref_verts.size(); i--;)
4992 [ # # ][ # # ]: 0 : a_tree->add(ref_verts.get_and_step());
4993 : :
4994 : : //for each vertex
4995 [ # # ][ # # ]: 0 : for (i=ref_verts.size(); i--;)
4996 : : {
4997 [ # # ]: 0 : RefVertex *tmp_vert = ref_verts.get_and_step();
4998 [ # # ]: 0 : RefVolume *vol1 = tmp_vert->ref_volume();
4999 [ # # ]: 0 : CubitVector vert_xyz = tmp_vert->coordinates();
5000 : :
5001 : : //get all close vertices
5002 [ # # ]: 0 : DLIList<RefVertex*> close_verts;
5003 [ # # ][ # # ]: 0 : a_tree->find(tmp_vert->bounding_box(), close_verts);
[ # # ]
5004 : :
5005 : : //if any vertex is between low_tol and high_tol
5006 : : //add it to the list
5007 : 0 : DLIList<dist_vert_struct*> *near_coincident_verts = NULL;
5008 [ # # ][ # # ]: 0 : for( j=close_verts.size(); j--; )
5009 : : {
5010 [ # # ]: 0 : RefVertex *close_vert = close_verts.get_and_step();
5011 [ # # ]: 0 : if( close_vert == tmp_vert )
5012 : 0 : continue;
5013 : :
5014 [ # # ]: 0 : RefVolume *vol2 = close_vert->ref_volume();
5015 [ # # ][ # # ]: 0 : if(vol1 && vol2 && vol1 != vol2)
[ # # ]
5016 : : {
5017 [ # # ]: 0 : if(!near_coincident_verts)
5018 : : {
5019 [ # # ][ # # ]: 0 : near_coincident_verts = new DLIList<dist_vert_struct*>;
5020 [ # # ]: 0 : vert_dist_map[tmp_vert] = near_coincident_verts;
5021 : : }
5022 [ # # ][ # # ]: 0 : double distance = vert_xyz.distance_between( close_vert->coordinates() );
5023 : : int h;
5024 : 0 : bool found_entry_with_same_vol = false;
5025 [ # # ][ # # ]: 0 : for(h=near_coincident_verts->size(); h>0 && !found_entry_with_same_vol; h--)
[ # # ]
5026 : : {
5027 [ # # ]: 0 : dist_vert_struct* vds = near_coincident_verts->get_and_step();
5028 [ # # ]: 0 : if(vds->vol2 == vol2)
5029 : : {
5030 : 0 : found_entry_with_same_vol = true;
5031 [ # # ]: 0 : if(distance < vds->dist)
5032 : : {
5033 : 0 : vds->dist = distance;
5034 : 0 : vds->vol2 = vol2;
5035 : 0 : vds->v2 = close_vert;
5036 : : }
5037 : : }
5038 : : }
5039 [ # # ]: 0 : if(!found_entry_with_same_vol)
5040 : : {
5041 [ # # ]: 0 : dist_vert_struct *new_vds = new dist_vert_struct;
5042 : 0 : new_vds->dist = distance;
5043 : 0 : new_vds->v2 = close_vert;
5044 : 0 : new_vds->vol2 = vol2;
5045 [ # # ]: 0 : near_coincident_verts->append(new_vds);
5046 : : }
5047 : : }
5048 : : }
5049 [ # # ]: 0 : a_tree->remove( tmp_vert );
5050 [ # # ]: 0 : }
5051 : :
5052 [ # # ][ # # ]: 0 : delete a_tree;
5053 : :
5054 [ # # ]: 0 : return CUBIT_SUCCESS;
5055 : : }
5056 : :
5057 : : struct dist_vert_vert_struct
5058 : : {
5059 : : double dist;
5060 : : RefVertex *vert1;
5061 : : RefVertex *vert2;
5062 : : };
5063 : :
5064 : : struct dist_vert_curve_struct
5065 : : {
5066 : : double dist;
5067 : : RefVertex *vert;
5068 : : RefEdge *edge;
5069 : : // bool operator<( const dist_vert_curve_struct& b ) const
5070 : : // {
5071 : : // return this->dist < b.dist;
5072 : : // }
5073 : : };
5074 : :
5075 : : struct vert_curve_dist_sort
5076 : : {
5077 : : bool operator()( const dist_vert_curve_struct& a, const dist_vert_curve_struct& b ) const
5078 : : {
5079 : : return a.dist < b.dist;
5080 : : }
5081 : : };
5082 : :
5083 : : struct vert_curve_dist_sort_ptr
5084 : : {
5085 : 0 : bool operator()( dist_vert_curve_struct *a, dist_vert_curve_struct *b ) const
5086 : : {
5087 : 0 : return a->dist < b->dist;
5088 : : }
5089 : : };
5090 : :
5091 : : struct vert_vert_dist_sort_ptr
5092 : : {
5093 : 0 : bool operator()( dist_vert_vert_struct *a, dist_vert_vert_struct *b ) const
5094 : : {
5095 : 0 : return a->dist < b->dist;
5096 : : }
5097 : : };
5098 : :
5099 : 0 : CubitStatus GeomMeasureTool::find_closest_vertex_curve_pairs(
5100 : : DLIList<RefVolume*> &vol_list,
5101 : : int &num_to_return,
5102 : : DLIList<RefVertex*> &vert_list,
5103 : : DLIList<RefEdge*> &curve_list,
5104 : : DLIList<double> &distances)
5105 : : {
5106 [ # # ]: 0 : DLIList<RefFace*> surfs;
5107 : :
5108 : 0 : int i, total_num_entries = 0;
5109 [ # # ][ # # ]: 0 : for( i=vol_list.size(); i--; )
5110 : : {
5111 [ # # ]: 0 : RefVolume *tmp_vol = vol_list.get_and_step();
5112 [ # # ]: 0 : tmp_vol->ref_faces( surfs );
5113 : : }
5114 : :
5115 [ # # ][ # # ]: 0 : std::set<dist_vert_curve_struct*,vert_curve_dist_sort_ptr> distance_vertex_curve_set;
5116 : :
5117 [ # # ][ # # ]: 0 : for(i=surfs.size(); i>0; i--)
5118 : : {
5119 [ # # ]: 0 : RefFace *surf = surfs.get_and_step();
5120 [ # # ]: 0 : DLIList<RefVertex*> surf_verts;
5121 [ # # ]: 0 : surf->ref_vertices(surf_verts);
5122 [ # # ][ # # ]: 0 : DLIList<RefEdge*> surf_curves;
5123 [ # # ]: 0 : surf->ref_edges(surf_curves);
5124 : :
5125 : : int j;
5126 [ # # ][ # # ]: 0 : for(j=surf_verts.size(); j>0; j--)
5127 : : {
5128 [ # # ]: 0 : RefVertex *tmp_vert = surf_verts.get_and_step();
5129 [ # # ]: 0 : CubitVector vert_xyz = tmp_vert->coordinates();
5130 [ # # ]: 0 : CubitVector closest_pt;
5131 : : int k;
5132 [ # # ][ # # ]: 0 : for(k=surf_curves.size(); k>0; k--)
5133 : : {
5134 [ # # ]: 0 : RefEdge *cur_edge = surf_curves.get_and_step();
5135 [ # # ][ # # ]: 0 : if(cur_edge->start_vertex() != tmp_vert &&
[ # # ][ # # ]
5136 [ # # ]: 0 : cur_edge->end_vertex() != tmp_vert)
5137 : : {
5138 [ # # ]: 0 : cur_edge->closest_point_trimmed(vert_xyz, closest_pt);
5139 [ # # ][ # # ]: 0 : if(!closest_pt.about_equal(cur_edge->start_coordinates()) &&
[ # # ][ # # ]
[ # # ]
[ # # # # ]
5140 [ # # ][ # # ]: 0 : !closest_pt.about_equal(cur_edge->end_coordinates()))
[ # # ][ # # ]
5141 : : {
5142 [ # # ]: 0 : double dist_sq = vert_xyz.distance_between_squared(closest_pt);
5143 [ # # ]: 0 : dist_vert_curve_struct *tmp_struct = new dist_vert_curve_struct;
5144 : 0 : tmp_struct->dist = dist_sq;
5145 : 0 : tmp_struct->vert = tmp_vert;
5146 : 0 : tmp_struct->edge = cur_edge;
5147 [ # # ]: 0 : distance_vertex_curve_set.insert( tmp_struct );
5148 : 0 : total_num_entries++;
5149 : : }
5150 : : }
5151 : : }
5152 : : }
5153 [ # # ]: 0 : }
5154 : :
5155 [ # # ][ # # ]: 0 : std::set<dist_vert_curve_struct*, vert_curve_dist_sort_ptr>::iterator iter, upper_iter;
5156 : :
5157 : 0 : int local_num_to_return = num_to_return;
5158 [ # # ]: 0 : if(num_to_return == -1)
5159 : : {
5160 : 0 : local_num_to_return = total_num_entries;
5161 : : }
5162 : 0 : int cntr = 0;
5163 [ # # ]: 0 : iter = distance_vertex_curve_set.begin();
5164 [ # # ][ # # ]: 0 : for(; iter!=distance_vertex_curve_set.end() && cntr < local_num_to_return; iter++ )
[ # # ][ # # ]
[ # # ][ # # ]
[ # # # # ]
5165 : : {
5166 [ # # ][ # # ]: 0 : distances.append( sqrt((*iter)->dist) );
5167 [ # # ][ # # ]: 0 : vert_list.append( (*iter)->vert );
5168 [ # # ][ # # ]: 0 : curve_list.append( (*iter)->edge );
5169 : 0 : cntr++;
5170 : : }
5171 : :
5172 [ # # ]: 0 : iter = distance_vertex_curve_set.begin();
5173 [ # # ][ # # ]: 0 : for(; iter!=distance_vertex_curve_set.end(); iter++ )
[ # # ][ # # ]
5174 : : {
5175 [ # # ]: 0 : delete *iter;
5176 : : }
5177 : :
5178 [ # # ]: 0 : return CUBIT_SUCCESS;
5179 : : }
5180 : :
5181 : 0 : CubitStatus GeomMeasureTool::find_closest_vertex_vertex_pairs(
5182 : : DLIList<RefVolume*> &vol_list,
5183 : : int &num_to_return,
5184 : : DLIList<RefVertex*> &vert_list1,
5185 : : DLIList<RefVertex*> &vert_list2,
5186 : : DLIList<double> &distances)
5187 : : {
5188 [ # # ]: 0 : std::set<dist_vert_vert_struct*,vert_vert_dist_sort_ptr> distance_vertex_vertex_set;
5189 : :
5190 : 0 : int i, total_num_entries = 0;
5191 [ # # ][ # # ]: 0 : for( i=vol_list.size(); i--; )
5192 : : {
5193 [ # # ]: 0 : RefVolume *tmp_vol = vol_list.get_and_step();
5194 [ # # ]: 0 : DLIList<RefVertex*> vol_verts;
5195 [ # # ]: 0 : tmp_vol->ref_vertices(vol_verts);
5196 [ # # ][ # # ]: 0 : while(vol_verts.size() > 1)
5197 : : {
5198 [ # # ]: 0 : RefVertex *vert1 = vol_verts.pop();
5199 [ # # ]: 0 : CubitVector vert1_xyz = vert1->coordinates();
5200 : : int j;
5201 [ # # ][ # # ]: 0 : for(j=vol_verts.size(); j>0; j--)
5202 : : {
5203 [ # # ]: 0 : RefVertex *vert2 = vol_verts.get_and_step();
5204 [ # # ][ # # ]: 0 : double dist_sq = vert2->coordinates().distance_between_squared(vert1_xyz);
5205 [ # # ]: 0 : dist_vert_vert_struct *tmp_struct = new dist_vert_vert_struct;
5206 : 0 : tmp_struct->dist = dist_sq;
5207 : 0 : tmp_struct->vert1 = vert1;
5208 : 0 : tmp_struct->vert2 = vert2;
5209 [ # # ]: 0 : distance_vertex_vertex_set.insert( tmp_struct );
5210 : 0 : total_num_entries++;
5211 : : }
5212 : : }
5213 [ # # ]: 0 : }
5214 : :
5215 [ # # ][ # # ]: 0 : std::set<dist_vert_vert_struct*, vert_vert_dist_sort_ptr>::iterator iter, upper_iter;
5216 : :
5217 : 0 : int local_num_to_return = num_to_return;
5218 [ # # ]: 0 : if(num_to_return == -1)
5219 : 0 : local_num_to_return = total_num_entries;
5220 : 0 : int cntr = 0;
5221 [ # # ]: 0 : iter = distance_vertex_vertex_set.begin();
5222 [ # # ][ # # ]: 0 : for(; iter!=distance_vertex_vertex_set.end() && cntr < local_num_to_return; iter++ )
[ # # ][ # # ]
[ # # ][ # # ]
[ # # # # ]
5223 : : {
5224 [ # # ][ # # ]: 0 : distances.append( sqrt((*iter)->dist) );
5225 [ # # ][ # # ]: 0 : vert_list1.append( (*iter)->vert1 );
5226 [ # # ][ # # ]: 0 : vert_list2.append( (*iter)->vert2 );
5227 : 0 : cntr++;
5228 : : }
5229 : :
5230 [ # # ]: 0 : iter = distance_vertex_vertex_set.begin();
5231 [ # # ][ # # ]: 0 : for(; iter!=distance_vertex_vertex_set.end(); iter++ )
[ # # ][ # # ]
5232 : : {
5233 [ # # ]: 0 : delete *iter;
5234 : : }
5235 : :
5236 [ # # ]: 0 : return CUBIT_SUCCESS;
5237 : : }
5238 : :
5239 : 0 : CubitStatus GeomMeasureTool::find_near_coincident_vertex_curve_pairs(
5240 : : DLIList<RefVolume*> &ref_vols,
5241 : : DLIList<RefEdge*> &ref_edges,
5242 : : DLIList<RefVertex*> &ref_verts,
5243 : : DLIList<double> &distances,
5244 : : double low_tol,
5245 : : double high_tol,
5246 : : bool filter_same_volume_cases)
5247 : : {
5248 : : //get all the curves and vertices of volumes in list
5249 [ # # ]: 0 : DLIList<RefVertex*> verts;
5250 [ # # ][ # # ]: 0 : DLIList<RefEdge*> curves;
5251 : :
5252 [ # # ][ # # ]: 0 : RTree<RefEdge*> a_tree(high_tol);
5253 : :
5254 : : int i,j;
5255 [ # # ][ # # ]: 0 : for( i=ref_vols.size(); i--; )
5256 : : {
5257 [ # # ]: 0 : RefVolume *tmp_vol = ref_vols.get_and_step();
5258 [ # # ]: 0 : tmp_vol->ref_vertices( verts );
5259 : :
5260 [ # # ]: 0 : curves.clean_out();
5261 [ # # ]: 0 : tmp_vol->ref_edges( curves );
5262 [ # # ][ # # ]: 0 : for( j=curves.size(); j--; )
5263 : : {
5264 [ # # ]: 0 : RefEdge *tmp_edge = curves.get_and_step();
5265 [ # # ]: 0 : a_tree.add( tmp_edge );
5266 : : }
5267 : : }
5268 : :
5269 : 0 : ProgressTool *progress_ptr = NULL;
5270 [ # # ]: 0 : int total_verts = verts.size();
5271 [ # # ]: 0 : if (total_verts > 5)
5272 : : {
5273 [ # # ][ # # ]: 0 : progress_ptr = AppUtil::instance()->progress_tool();
5274 [ # # ]: 0 : assert(progress_ptr != NULL);
5275 : : progress_ptr->start(0, 100, "Finding Near Coincident Vertex-Curve Pairs",
5276 [ # # ]: 0 : NULL, CUBIT_TRUE, CUBIT_TRUE);
5277 : : }
5278 : :
5279 : 0 : double curr_percent = 0.0;
5280 : 0 : int processed_verts = 0;
5281 [ # # ][ # # ]: 0 : std::multimap<double, dist_vert_curve_struct> distance_vertex_curve_map;
5282 : :
5283 : : //for each vertex
5284 [ # # ][ # # ]: 0 : for( i=verts.size(); i--; )
5285 : : {
5286 : 0 : processed_verts++;
5287 [ # # ]: 0 : if ( progress_ptr != NULL )
5288 : : {
5289 : 0 : curr_percent = ((double)(processed_verts))/((double)(total_verts));
5290 [ # # ]: 0 : progress_ptr->percent(curr_percent);
5291 : : }
5292 : :
5293 [ # # ]: 0 : RefVertex *tmp_vert = verts.get_and_step();
5294 [ # # ]: 0 : RefVolume *v1 = tmp_vert->ref_volume();
5295 [ # # ][ # # ]: 0 : CubitBox vertex_box ( tmp_vert->coordinates(), tmp_vert->coordinates() );
[ # # ]
5296 [ # # ][ # # ]: 0 : DLIList<RefEdge*> close_curves;
5297 [ # # ]: 0 : a_tree.find( vertex_box, close_curves );
5298 : :
5299 [ # # ]: 0 : CubitVector vertex_xyz = tmp_vert->coordinates();
5300 : :
5301 [ # # ][ # # ]: 0 : for( j=close_curves.size(); j--; )
5302 : : {
5303 [ # # ]: 0 : RefEdge *tmp_edge = close_curves.get_and_step();
5304 [ # # ]: 0 : RefVolume *v2 = tmp_edge->ref_volume();
5305 : :
5306 : 0 : bool check_distance = true;
5307 [ # # ][ # # ]: 0 : if(filter_same_volume_cases && v1 && v2 && v1 == v2)
[ # # ][ # # ]
5308 : 0 : check_distance = false;
5309 [ # # ]: 0 : if(check_distance)
5310 : : {
5311 [ # # ]: 0 : CubitVector closest_location;
5312 [ # # ]: 0 : tmp_edge->closest_point_trimmed( vertex_xyz, closest_location );
5313 [ # # ]: 0 : double distance = closest_location.distance_between( vertex_xyz );
5314 : :
5315 [ # # ][ # # ]: 0 : if( distance >= low_tol && distance <= high_tol )
5316 : : {
5317 : : dist_vert_curve_struct tmp_struct;
5318 : 0 : tmp_struct.dist = distance;
5319 : 0 : tmp_struct.vert = tmp_vert;
5320 : 0 : tmp_struct.edge = tmp_edge;
5321 : :
5322 : : distance_vertex_curve_map.insert( std::multimap<double, dist_vert_curve_struct>::
5323 [ # # ][ # # ]: 0 : value_type( distance, tmp_struct ));
5324 : : }
5325 : : }
5326 : : }
5327 [ # # ]: 0 : }
5328 : :
5329 [ # # ]: 0 : if ( progress_ptr != NULL )
5330 [ # # ]: 0 : progress_ptr->end();
5331 : :
5332 : : //std::set<dist_vert_curve_struct, vert_curve_dist_sort>::iterator iter, upper_iter;
5333 [ # # ]: 0 : std::multimap<double, dist_vert_curve_struct>::reverse_iterator iter;
5334 : :
5335 [ # # ]: 0 : iter = distance_vertex_curve_map.rbegin();
5336 [ # # ][ # # ]: 0 : for(; iter!=distance_vertex_curve_map.rend(); iter++ )
[ # # ][ # # ]
5337 : : {
5338 [ # # ][ # # ]: 0 : distances.append( (*iter).second.dist );
5339 [ # # ][ # # ]: 0 : ref_verts.append( (*iter).second.vert );
5340 [ # # ][ # # ]: 0 : ref_edges.append( (*iter).second.edge );
5341 : : }
5342 : :
5343 [ # # ]: 0 : return CUBIT_SUCCESS;
5344 : : }
5345 : :
5346 : :
5347 : : struct dist_vert_surf_struct
5348 : : {
5349 : : double dist;
5350 : : RefVertex *vert;
5351 : : RefFace *face;
5352 : : };
5353 : :
5354 : : struct vert_surf_dist_sort
5355 : : {
5356 : : bool operator()( dist_vert_surf_struct a, dist_vert_surf_struct b ) const
5357 : : {
5358 : : if( a.dist < b.dist )
5359 : : return true;
5360 : : else if( a.dist > b.dist )
5361 : : return false;
5362 : : else
5363 : : {
5364 : : if( a.vert < b.vert )
5365 : : return true;
5366 : : else if( a.vert > b.vert )
5367 : : return false;
5368 : : else if( a.face < b.face )
5369 : : return true;
5370 : : else if( a.face > b.face )
5371 : : return false;
5372 : : }
5373 : : return false;
5374 : : }
5375 : : };
5376 : :
5377 : :
5378 : 0 : CubitStatus GeomMeasureTool::find_near_coincident_vertex_surface_pairs(
5379 : : DLIList<RefVolume*> &ref_vols,
5380 : : DLIList<RefFace*> &ref_faces,
5381 : : DLIList<RefVertex*> &ref_verts,
5382 : : DLIList<double> &distances,
5383 : : double low_tol,
5384 : : double high_tol,
5385 : : bool filter_same_volume_cases)
5386 : : {
5387 : : //get all the curves and vertices of volumes in list
5388 [ # # ]: 0 : DLIList<RefVertex*> verts;
5389 [ # # ][ # # ]: 0 : DLIList<RefFace*> faces;
5390 : :
5391 [ # # ][ # # ]: 0 : AbstractTree<RefFace*> *a_tree = new RTree<RefFace*>( high_tol );
5392 : :
5393 : : int i,j;
5394 [ # # ][ # # ]: 0 : for( i=ref_vols.size(); i--; )
5395 : : {
5396 [ # # ]: 0 : RefVolume *tmp_vol = ref_vols.get_and_step();
5397 [ # # ]: 0 : tmp_vol->ref_vertices( verts );
5398 : :
5399 [ # # ]: 0 : faces.clean_out();
5400 [ # # ]: 0 : tmp_vol->ref_faces( faces );
5401 : : // Populate the Surface AbstractTree
5402 [ # # ][ # # ]: 0 : for( j=faces.size(); j--; )
5403 : : {
5404 [ # # ]: 0 : RefFace *tmp_face = faces.get_and_step();
5405 [ # # ]: 0 : a_tree->add( tmp_face );
5406 : : }
5407 : : }
5408 : :
5409 : 0 : ProgressTool *progress_ptr = NULL;
5410 [ # # ]: 0 : int total_verts = verts.size();
5411 [ # # ]: 0 : if (total_verts > 50)
5412 : : {
5413 [ # # ][ # # ]: 0 : progress_ptr = AppUtil::instance()->progress_tool();
5414 [ # # ]: 0 : assert(progress_ptr != NULL);
5415 : : progress_ptr->start(0, 100, "Finding Near Coincident Vertex-Surface Pairs",
5416 [ # # ]: 0 : NULL, CUBIT_TRUE, CUBIT_TRUE);
5417 : : }
5418 : 0 : double curr_percent = 0.0;
5419 : 0 : int processed_verts = 0;
5420 : :
5421 [ # # ][ # # ]: 0 : std::multimap<double, dist_vert_surf_struct> distance_vertex_surface_map;
5422 : :
5423 : : //for each vertex
5424 [ # # ][ # # ]: 0 : for( i=verts.size(); i--; )
5425 : : {
5426 : 0 : processed_verts++;
5427 [ # # ]: 0 : if ( progress_ptr != NULL )
5428 : : {
5429 : 0 : curr_percent = ((double)(processed_verts))/((double)(total_verts));
5430 [ # # ]: 0 : progress_ptr->percent(curr_percent);
5431 : : }
5432 : :
5433 [ # # ]: 0 : RefVertex *tmp_vert = verts.get_and_step();
5434 [ # # ]: 0 : RefVolume *v1 = tmp_vert->ref_volume();
5435 [ # # ][ # # ]: 0 : CubitBox vertex_box ( tmp_vert->coordinates(), tmp_vert->coordinates() );
[ # # ]
5436 [ # # ][ # # ]: 0 : DLIList<RefFace*> close_faces;
5437 [ # # ]: 0 : a_tree->find( vertex_box, close_faces);
5438 : :
5439 [ # # ]: 0 : CubitVector vertex_xyz = tmp_vert->coordinates();
5440 : :
5441 [ # # ][ # # ]: 0 : for( j=close_faces.size(); j--; )
5442 : : {
5443 [ # # ]: 0 : RefFace *tmp_face = close_faces.get_and_step();
5444 [ # # ]: 0 : RefVolume *v2 = tmp_face->ref_volume();
5445 : :
5446 : 0 : bool check = true;
5447 [ # # ][ # # ]: 0 : if(filter_same_volume_cases && v1 && v2 && v1 == v2)
[ # # ][ # # ]
5448 : 0 : check = false;
5449 : :
5450 [ # # ]: 0 : if(check)
5451 : : {
5452 [ # # ]: 0 : DLIList<RefVertex*> tmp_verts;
5453 [ # # ]: 0 : tmp_face->ref_vertices( tmp_verts );
5454 [ # # ][ # # ]: 0 : if( tmp_verts.is_in_list( tmp_vert ) )
5455 : 0 : continue;
5456 : :
5457 [ # # ]: 0 : CubitVector closest_location;
5458 [ # # ][ # # ]: 0 : tmp_face->find_closest_point_trimmed( vertex_xyz, closest_location );
5459 [ # # ]: 0 : double distance = closest_location.distance_between( vertex_xyz );
5460 : :
5461 [ # # ][ # # ]: 0 : if( distance > low_tol && distance < high_tol )
5462 : : {
5463 : : dist_vert_surf_struct tmp_struct;
5464 : 0 : tmp_struct.dist = distance;
5465 : 0 : tmp_struct.vert = tmp_vert;
5466 : 0 : tmp_struct.face = tmp_face;
5467 : : distance_vertex_surface_map.insert( std::multimap<double, dist_vert_surf_struct>::
5468 [ # # ][ # # ]: 0 : value_type( distance, tmp_struct ));
[ # # ][ # # ]
5469 : 0 : }
5470 : : }
5471 : : }
5472 [ # # ]: 0 : }
5473 : :
5474 [ # # ]: 0 : if ( progress_ptr != NULL )
5475 [ # # ]: 0 : progress_ptr->end();
5476 : :
5477 [ # # ]: 0 : std::multimap<double, dist_vert_surf_struct>::reverse_iterator iter;
5478 : :
5479 [ # # ]: 0 : iter = distance_vertex_surface_map.rbegin();
5480 [ # # ][ # # ]: 0 : for(; iter!=distance_vertex_surface_map.rend(); iter++ )
[ # # ][ # # ]
5481 : : {
5482 [ # # ][ # # ]: 0 : distances.append( (*iter).second.dist );
5483 [ # # ][ # # ]: 0 : ref_verts.append( (*iter).second.vert );
5484 [ # # ][ # # ]: 0 : ref_faces.append( (*iter).second.face);
5485 : : }
5486 : :
5487 [ # # ][ # # ]: 0 : delete a_tree;
5488 : :
5489 [ # # ]: 0 : return CUBIT_SUCCESS;
5490 [ + - ][ + - ]: 6540 : }
5491 : :
5492 : :
5493 : :
5494 : :
5495 : :
|