LCOV - code coverage report
Current view: top level - geom - GeomMeasureTool.cpp (source / functions) Hit Total Coverage
Test: coverage_sk.info Lines: 11 2834 0.4 %
Date: 2020-06-30 00:58:45 Functions: 3 76 3.9 %
Branches: 9 6544 0.1 %

           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 &centroid, 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                 :            : 

Generated by: LCOV version 1.11