LCOV - code coverage report
Current view: top level - geom/facet - FacetProjectTool.cpp (source / functions) Hit Total Coverage
Test: coverage_sk.info Lines: 1 814 0.1 %
Date: 2020-06-30 00:58:45 Functions: 2 28 7.1 %
Branches: 2 1760 0.1 %

           Branch data     Line data    Source code
       1                 :            : #include "FacetProjectTool.hpp"
       2                 :            : #include "PST_Data.hpp"
       3                 :            : #include "GeometryDefines.h"
       4                 :            : #include "CubitMessage.hpp"
       5                 :            : #include "CubitPlane.hpp"
       6                 :            : 
       7                 :            : #include "GfxDebug.hpp" /* for debugging output */
       8                 :            : 
       9                 :            : const int VG_FACET_DEBUG = 145;
      10                 :            : const int VG_FACET_BOUNDARY_COLOR = CUBIT_RED_INDEX;
      11                 :            : const int VG_FACET_FACET_COLOR = CUBIT_GREEN_INDEX;
      12                 :            : const int VG_FACET_IMPRINT_COLOR = CUBIT_WHITE_INDEX;
      13                 :            : const int VG_FACET_SEGMENT_COLOR = CUBIT_CYAN_INDEX;
      14                 :            : #define VG_FACET_PRINT PRINT_DEBUG(VG_FACET_DEBUG)
      15                 :            : 
      16                 :            : 
      17                 :            : //-------------------------------------------------------------------------
      18                 :            : // Purpose       : Constructor
      19                 :            : //
      20                 :            : // Special Notes :  
      21                 :            : //
      22                 :            : // Creator       : Jason Kraftcheck
      23                 :            : //
      24                 :            : // Creation Date : 05/11/02
      25                 :            : //-------------------------------------------------------------------------
      26 [ #  # ][ #  # ]:          0 : FacetProjectTool::FacetProjectTool( ) 
         [ #  # ][ #  # ]
                 [ #  # ]
      27                 :          0 : { }
      28                 :            : 
      29                 :            : 
      30                 :          0 : static int parent_compare_facets( PST_Face*& f1, PST_Face*& f2 )
      31                 :            : {
      32                 :          0 :   return (f1->parent < f2->parent) ? -1 :
      33 [ #  # ][ #  # ]:          0 :          (f1->parent > f2->parent) ?  1 : 0;
      34                 :            : }
      35                 :          0 : static int sequence_compare_pts( PST_Point*& p1, PST_Point*& p2 )
      36                 :            : {
      37                 :          0 :   return (p1->sequence < p2->sequence) ? -1 :
      38 [ #  # ][ #  # ]:          0 :          (p1->sequence > p2->sequence) ?  1 : 0;
      39                 :            : }
      40                 :            : 
      41                 :            : //-------------------------------------------------------------------------
      42                 :            : // Purpose       : takes a list of edge segments and a surface and returns
      43                 :            : //                 the new facets, dudded facets, new points, and new edges
      44                 :            : // Special Notes :  
      45                 :            : //                 
      46                 :            : //
      47                 :            : // Creator       : John Fowler
      48                 :            : //
      49                 :            : // Creation Date : 12/03/02
      50                 :            : //-------------------------------------------------------------------------
      51                 :          0 : CubitStatus FacetProjectTool::project(
      52                 :            :     DLIList<CubitVector*>& segments,                  // in
      53                 :            :     const std::vector<double>& coordinates,           // in
      54                 :            :     const std::vector<int>& connections,              // in
      55                 :            :     std::vector<int>& duddedFacets,                   // out
      56                 :            :     std::vector<int>& newFacets,                      // out
      57                 :            :     std::vector<int>& newFacetsIndex,         // out
      58                 :            :     std::vector<double>& newPoints,                   // out
      59                 :            :     std::vector<int>& edges,                          // out
      60                 :            :     std::vector<int>& segmentPoints,
      61                 :            :     const double *tolerance_length
      62                 :            :  )
      63                 :            : {
      64                 :            :   int i;
      65                 :            : //   const double TOL_SQR = GEOMETRY_RESABS*GEOMETRY_RESABS; 
      66                 :            :                      
      67 [ #  # ][ #  # ]:          0 :   assert(connections.size()%3 == 0);  //  For triangles these must be triples
      68 [ #  # ][ #  # ]:          0 :   assert(coordinates.size()%3 == 0);  //  Coordinates must come in triples   
      69         [ #  # ]:          0 :   DLIList<PST_Edge*> facet_edges;  
      70                 :            : 
      71                 :            :     // make the PST edges and faces from the coordinates and connections.
      72         [ #  # ]:          0 :   PST_Edge::make_facets( coordinates, connections, GEOMETRY_RESABS, facet_edges );
      73 [ #  # ][ #  # ]:          0 :   DLIList<PST_Face*> faces;
      74                 :            : 
      75                 :          0 :   CubitStatus success = CUBIT_SUCCESS;
      76 [ #  # ][ #  # ]:          0 :   if(facet_edges.size() > 0)
      77                 :            :   {
      78                 :            : 
      79         [ #  # ]:          0 :     PST_Edge::faces( facet_edges, faces );
      80         [ #  # ]:          0 :     populate_data(faces);
      81                 :            : 
      82                 :            :       // Order the orignal points by sequence number.  New points
      83                 :            :       // will be appended in order.
      84         [ #  # ]:          0 :     pointList.sort(&sequence_compare_pts);
      85                 :            :         
      86                 :            :       // Do the work
      87                 :            :     CubitBoolean point_changed;
      88         [ #  # ]:          0 :     success = do_projection(segments, point_changed, tolerance_length);
      89                 :            :     
      90                 :          0 :     bool debug = false;
      91         [ #  # ]:          0 :     if( debug )
      92                 :            :     {
      93         [ #  # ]:          0 :       GfxDebug::clear();
      94 [ #  # ][ #  # ]:          0 :       for( int j=0; j<facetList.size(); j++ )
      95 [ #  # ][ #  # ]:          0 :         facetList.get_and_step()->debug_draw( CUBIT_CYAN_INDEX );
      96         [ #  # ]:          0 :       GfxDebug::mouse_xforms();
      97                 :            :     }
      98                 :            : 
      99                 :            :       // fill in segmentPoints
     100                 :            : //    assert (segPoints.size() == segments.size());
     101 [ #  # ][ #  # ]:          0 :     segmentPoints.resize( segPoints.size() );
     102         [ #  # ]:          0 :     segPoints.reset();
     103 [ #  # ][ #  # ]:          0 :     for ( i = 0; i < segPoints.size(); i++ )
     104                 :            :     {
     105         [ #  # ]:          0 :       PST_Point* pt = segPoints.get_and_step();     
     106 [ #  # ][ #  # ]:          0 :       segmentPoints[i] = pt ? pt->sequence : -1;
     107         [ #  # ]:          0 :       if (point_changed)
     108                 :          0 :         success = CUBIT_FAILURE;
     109                 :            :     }
     110                 :            :   }
     111                 :            :   else
     112                 :          0 :     success = CUBIT_FAILURE;
     113                 :            :   
     114         [ #  # ]:          0 :   if (!success)
     115                 :            :   {
     116         [ #  # ]:          0 :      cleanup();
     117                 :          0 :      return success;
     118                 :            :   }
     119                 :            :                                                                                 
     120                 :            :     //  Now put the points with sequence > coordinates.size()/3 in newPoints.
     121         [ #  # ]:          0 :   int orig_num_points = coordinates.size()/3;
     122         [ #  # ]:          0 :   int num_new_points = pointList.size() - orig_num_points;
     123         [ #  # ]:          0 :   pointList.reset();
     124         [ #  # ]:          0 :   pointList.step(orig_num_points);
     125         [ #  # ]:          0 :   newPoints.resize(num_new_points*3);
     126         [ #  # ]:          0 :   std::vector<double>::iterator ditor = newPoints.begin();
     127         [ #  # ]:          0 :   while( num_new_points-- ) {
     128         [ #  # ]:          0 :     PST_Point* pt = pointList.get_and_step();
     129 [ #  # ][ #  # ]:          0 :     *ditor++ = pt->x();
                 [ #  # ]
     130 [ #  # ][ #  # ]:          0 :     *ditor++ = pt->y();
                 [ #  # ]
     131 [ #  # ][ #  # ]:          0 :     *ditor++ = pt->z();
                 [ #  # ]
     132                 :            :   }
     133                 :            : 
     134 [ #  # ][ #  # ]:          0 :   if ( facetList.size() > 1 ) {  //  If only one facet, skip finding dudded facets
     135                 :            :     // Sort (group) facets by parent.
     136         [ #  # ]:          0 :     facetList.sort(&parent_compare_facets);
     137                 :            : 
     138                 :            :     // Fill in the duddedFacets, newFacets, and newFacetsIndex vectors.  
     139                 :            : 
     140                 :            : #ifndef NDEBUG
     141         [ #  # ]:          0 :     int orig_num_facets = connections.size()/3;
     142                 :            : #endif
     143                 :          0 :     int new_facet_index = 0;
     144         [ #  # ]:          0 :     DLIList<PST_Point*> facet_pts(3);
     145                 :            : 
     146         [ #  # ]:          0 :     facetList.reset();
     147         [ #  # ]:          0 :     duddedFacets.clear();
     148         [ #  # ]:          0 :     newFacetsIndex.clear();
     149         [ #  # ]:          0 :     newFacets.clear();
     150                 :            : 
     151 [ #  # ][ #  # ]:          0 :     for ( i = facetList.size(); i > 0; ) {
     152                 :          0 :       PST_Face* dudded_facet = 0;
     153 [ #  # ][ #  # ]:          0 :       if( facetList.get()->parent != facetList.next()->parent ) {
                 [ #  # ]
     154                 :            : 
     155                 :            :           // unmodified original facet - skip it
     156                 :            : #ifndef NDEBUG
     157         [ #  # ]:          0 :         PST_Face* facet = facetList.get();
     158         [ #  # ]:          0 :         assert(facet->sequence < orig_num_facets &&
     159         [ #  # ]:          0 :                facet->sequence == facet->parent);
     160                 :            : #endif
     161         [ #  # ]:          0 :         facetList.step();
     162                 :          0 :         i--;
     163                 :            :       } 
     164                 :            :       else {
     165                 :            :           // new facets
     166                 :            :         
     167                 :            :           // put all new facets split from the
     168                 :            :           // same original facet (having same parent),
     169                 :            :           // including the orignal facet which was 
     170                 :            :           // recycled, into newFacets
     171                 :          0 :         PST_Face* facet = 0;
     172         [ #  # ]:          0 :         do {
     173         [ #  # ]:          0 :           facet = facetList.get_and_step();
     174                 :          0 :           i--;
     175                 :            :         
     176         [ #  # ]:          0 :           if ( facet->parent == facet->sequence ) {
     177         [ #  # ]:          0 :             assert(!dudded_facet);
     178                 :          0 :             dudded_facet = facet;
     179                 :            :           }
     180                 :            :       
     181         [ #  # ]:          0 :           facet_pts.clean_out();
     182         [ #  # ]:          0 :           facet->append_points(facet_pts);
     183         [ #  # ]:          0 :           facet_pts.reset();
     184 [ #  # ][ #  # ]:          0 :           newFacets.push_back(facet_pts.get_and_step()->sequence);
     185 [ #  # ][ #  # ]:          0 :           newFacets.push_back(facet_pts.get_and_step()->sequence);
     186 [ #  # ][ #  # ]:          0 :           newFacets.push_back(facet_pts.get_and_step()->sequence);
     187                 :          0 :           new_facet_index += 3;
     188 [ #  # ][ #  # ]:          0 :         } while ( (facet->parent == facetList.get()->parent) && (i > 0) );
                 [ #  # ]
     189                 :            :       
     190                 :            :           // add replaced facet to duddedFacets
     191 [ #  # ][ #  # ]:          0 :         assert(dudded_facet && dudded_facet->sequence < orig_num_facets);
     192         [ #  # ]:          0 :         duddedFacets.push_back(dudded_facet->sequence);
     193                 :            :           // add end position in new_facets for the
     194                 :            :           // set of replacement facets to newFacetsIndex
     195         [ #  # ]:          0 :         newFacetsIndex.push_back(new_facet_index);
     196                 :            :       }
     197         [ #  # ]:          0 :     }  
     198                 :            :   }
     199                 :            :   
     200 [ #  # ][ #  # ]:          0 :   DLIList<PST_CoEdge*> coedge_list;
     201         [ #  # ]:          0 :   edges.clear();
     202         [ #  # ]:          0 :   finalize_results();
     203 [ #  # ][ #  # ]:          0 :   while( get_result_set(coedge_list) ) {
     204                 :            : 
     205                 :            :       // add count and first point
     206         [ #  # ]:          0 :     coedge_list.reset();
     207 [ #  # ][ #  # ]:          0 :     edges.push_back(coedge_list.size() + 1);
     208 [ #  # ][ #  # ]:          0 :     PST_Point* pt = coedge_list.get()->start_point();
     209         [ #  # ]:          0 :     edges.push_back(pt->sequence);
     210                 :            :     
     211                 :            :       // add all other points
     212 [ #  # ][ #  # ]:          0 :     for( i = coedge_list.size(); i--; ) {
     213 [ #  # ][ #  # ]:          0 :       pt = coedge_list.get_and_step()->end_point();
     214         [ #  # ]:          0 :       edges.push_back(pt->sequence);
     215                 :            :     }
     216                 :            :   
     217                 :            :       // clean up for next iteration
     218         [ #  # ]:          0 :     coedge_list.clean_out();
     219                 :            :   }
     220         [ #  # ]:          0 :   edges.push_back(0);  //  terminating zero for next segment length      
     221                 :            :   
     222         [ #  # ]:          0 :   cleanup();
     223         [ #  # ]:          0 :   return CUBIT_SUCCESS;
     224                 :            : }
     225                 :            : 
     226                 :            :  
     227                 :            : //-------------------------------------------------------------------------
     228                 :            : // Purpose       : fills in the data
     229                 :            : //
     230                 :            : // Special Notes : populate private data lists and set marks on facet 
     231                 :            : //                 entities
     232                 :            : //
     233                 :            : // Creator       : Jason Kraftcheck, modified by John Fowler --
     234                 :            : //                 used to be the class constructor
     235                 :            : //
     236                 :            : // Creation Date : 05/11/02, 12/03/02
     237                 :            : //-------------------------------------------------------------------------
     238                 :          0 : CubitStatus FacetProjectTool::populate_data( const DLIList<PST_Face*>& facets )
     239                 :            : {
     240                 :          0 :   facetList = facets;
     241                 :            :   int i;
     242                 :            :   
     243                 :            :     // Mark all connected edges with a 3, and initialize 
     244                 :            :     // parent number to sequence number.
     245                 :          0 :   facetList.last();
     246         [ #  # ]:          0 :   for( i = facetList.size(); i--; )
     247                 :            :   {
     248                 :          0 :     PST_Face* face = facetList.step_and_get();
     249                 :          0 :     face->parent = face->sequence;
     250                 :          0 :     PST_CoEdge* coe = face->first_coedge();
     251         [ #  # ]:          0 :     do
     252                 :            :     {
     253                 :          0 :       coe->edge()->mark = 3;
     254                 :          0 :       coe = coe->next();
     255                 :          0 :     } while( coe != face->first_coedge() );
     256                 :            :   }
     257                 :            :   
     258                 :            :     // Decrement the edge mark by one for each
     259                 :            :     // face that contains the edge.
     260         [ #  # ]:          0 :   for( i = facetList.size(); i--; )
     261                 :            :   {
     262                 :          0 :     PST_Face* face = facetList.step_and_get();
     263                 :          0 :     PST_CoEdge* coe = face->first_coedge();
     264         [ #  # ]:          0 :     do
     265                 :            :     {
     266                 :          0 :       coe->edge()->mark--;
     267                 :          0 :       coe = coe->next();
     268                 :          0 :     } while( coe != face->first_coedge() );
     269                 :            :   }
     270                 :            :   
     271                 :            :     // Populate edgeList and boundaryList with edges
     272         [ #  # ]:          0 :   for( i = facetList.size(); i--; )
     273                 :            :   {
     274                 :          0 :     PST_Face* face = facetList.step_and_get();
     275                 :          0 :     PST_CoEdge* coe = face->first_coedge();
     276         [ #  # ]:          0 :     do
     277                 :            :     {
     278         [ #  # ]:          0 :       PST_Edge* edge = coe->edge();
     279                 :            :         // If mark is 2, edge was only in one face in the
     280                 :            :         // passed list, and is thus on the boundary of the
     281                 :            :         // passed patch of faces.
     282         [ #  # ]:          0 :       if( edge->mark == 2 )
     283                 :            :       {
     284         [ #  # ]:          0 :         boundaryList.append( edge );
     285         [ #  # ]:          0 :         edgeList.append( edge );
     286                 :          0 :         edge->mark = 0;
     287                 :            :       }
     288                 :            :         // If mark is 1, the edge is an interior edge in the
     289                 :            :         // patch of faces
     290         [ #  # ]:          0 :       else if( edge->mark == 1 )
     291                 :            :       {
     292         [ #  # ]:          0 :         edgeList.append( edge );
     293                 :          0 :         edge->mark = 0;
     294                 :            :       }
     295                 :            :         // If the mark on the edge is zero, we have already
     296                 :            :         // added it to the list(s).
     297                 :            :       else
     298                 :            :       {
     299         [ #  # ]:          0 :         assert( edge->mark == 0 );  
     300                 :            :       }
     301                 :            :       
     302         [ #  # ]:          0 :       coe = coe->next();
     303                 :          0 :     } while( coe != face->first_coedge() );
     304                 :            :   }
     305                 :            :   
     306                 :            :     // Get all the points
     307                 :          0 :   PST_Edge::points( edgeList, pointList );
     308                 :            :   
     309                 :            :     // Clear marks on all faces connected to our edge
     310                 :            :     // list (the passed faces and any faces connected
     311                 :            :     // at the boundary edges.)
     312         [ #  # ]:          0 :   for( i = edgeList.size(); i--; )
     313                 :            :   {
     314                 :          0 :     PST_Edge* edge = edgeList.step_and_get();
     315                 :          0 :     edge->mark = 0;
     316         [ #  # ]:          0 :     if( edge->forward()->face() )
     317                 :          0 :       edge->forward()->face()->mark = 0;
     318         [ #  # ]:          0 :     if( edge->reverse()->face() )
     319                 :          0 :       edge->reverse()->face()->mark = 0;
     320                 :            :   }
     321                 :            : 
     322                 :            :     // clear marks on faces
     323         [ #  # ]:          0 :   for( i = facetList.size(); i--; )
     324                 :          0 :     facetList.step_and_get()->mark = 0;
     325                 :            :     // Set mark to 1 on boundary edges
     326         [ #  # ]:          0 :   for( i = boundaryList.size(); i--; )
     327                 :          0 :     boundaryList.step_and_get()->mark = 1;
     328                 :            :     
     329         [ #  # ]:          0 :   if( DEBUG_FLAG( VG_FACET_DEBUG ) )
     330                 :            :   {
     331                 :            : //    PST_Face::draw_faces( facetList, VG_FACET_FACET_COLOR, false );
     332                 :          0 :     PST_Edge::debug_draw_edges( boundaryList, VG_FACET_BOUNDARY_COLOR );
     333                 :            :   }
     334                 :            : 
     335                 :          0 :   return CUBIT_SUCCESS;
     336                 :            : } 
     337                 :            :  
     338                 :            : //-------------------------------------------------------------------------
     339                 :            : // Purpose       : Find the face for which the projection of the passed
     340                 :            : //                 position onto the face is closest to the passed
     341                 :            : //                 position. 
     342                 :            : //
     343                 :            : // Special Notes : 
     344                 :            : //
     345                 :            : // Creator       : Jason Kraftcheck
     346                 :            : //
     347                 :            : // Creation Date : 05/11/02
     348                 :            : //-------------------------------------------------------------------------
     349                 :          0 : PST_Face* FacetProjectTool::closest_face( const CubitVector& position )
     350                 :            : {
     351                 :          0 :   PST_Face* result = 0;
     352                 :          0 :   double dist_sqr = 0;
     353         [ #  # ]:          0 :   CubitVector projected;
     354                 :            :   
     355 [ #  # ][ #  # ]:          0 :   for( int i = facetList.size(); i--; )
     356                 :            :   {
     357         [ #  # ]:          0 :     PST_Face* facet = facetList.step_and_get();
     358 [ #  # ][ #  # ]:          0 :     if( project_to_face( facet, position, projected ) )
     359                 :            :     {
     360 [ #  # ][ #  # ]:          0 :       double d = (projected - position).length_squared();
     361 [ #  # ][ #  # ]:          0 :       if( !result || d < dist_sqr )
     362                 :            :       {
     363                 :          0 :         result = facet;
     364                 :          0 :         dist_sqr = d;
     365                 :            :       }
     366                 :            :     }
     367                 :            :   }
     368                 :            :   
     369                 :          0 :   return result;
     370                 :            : }
     371                 :            : 
     372                 :            : 
     373                 :            : //-------------------------------------------------------------------------
     374                 :            : // Purpose       : Find the edge for which the projection of the passed
     375                 :            : //                 position onto the edge is closest to the passed
     376                 :            : //                 position.
     377                 :            : //
     378                 :            : // Special Notes : 
     379                 :            : //
     380                 :            : // Creator       : Jason Kraftcheck
     381                 :            : //
     382                 :            : // Creation Date : 05/11/02
     383                 :            : //-------------------------------------------------------------------------
     384                 :          0 : PST_Edge* FacetProjectTool::closest_edge( const CubitVector& position )
     385                 :            : {
     386                 :          0 :   PST_Edge* result = 0;
     387                 :          0 :   double dist_sqr = 0;
     388                 :            :   
     389         [ #  # ]:          0 :   for( int i = edgeList.size(); i--; )
     390                 :            :   {
     391                 :          0 :     PST_Edge* edge = edgeList.step_and_get();
     392                 :            :     
     393                 :          0 :     double t = edge->closest_on_line( position );
     394 [ #  # ][ #  # ]:          0 :     if( (t > -CUBIT_RESABS) && (t < (1.0 + CUBIT_RESABS)) )
     395                 :            :     {
     396 [ #  # ][ #  # ]:          0 :       double d = (edge->position(t) - position).length_squared();
     397 [ #  # ][ #  # ]:          0 :       if( !result || d < dist_sqr )
     398                 :            :       {
     399                 :          0 :         result = edge;
     400                 :          0 :         dist_sqr = d;
     401                 :            :       }
     402                 :            :     }
     403                 :            :   }
     404                 :            : 
     405                 :          0 :   return result;
     406                 :            : }
     407                 :            : 
     408                 :            : //-------------------------------------------------------------------------
     409                 :            : // Purpose       : Find the point closest to the passed position.
     410                 :            : //
     411                 :            : // Special Notes : 
     412                 :            : //
     413                 :            : // Creator       : Jason Kraftcheck
     414                 :            : //
     415                 :            : // Creation Date : 05/11/02
     416                 :            : //-------------------------------------------------------------------------
     417                 :          0 : PST_Point* FacetProjectTool::closest_point( const CubitVector& position )
     418                 :            : {
     419                 :          0 :   PST_Point* result = 0;
     420                 :          0 :   double dist_sqr = 0;
     421                 :            :   
     422         [ #  # ]:          0 :   for( int i = pointList.size(); i--; )
     423                 :            :   {
     424                 :          0 :     PST_Point* pt = pointList.step_and_get();
     425         [ #  # ]:          0 :     double d = (position - *pt).length_squared();
     426 [ #  # ][ #  # ]:          0 :     if( !result || d < dist_sqr )
     427                 :            :     {
     428                 :          0 :       dist_sqr = d;
     429                 :          0 :       result = pt;
     430                 :            :     }
     431                 :            :   }
     432                 :            :   
     433                 :          0 :   return result;
     434                 :            : }
     435                 :            : 
     436                 :            : 
     437                 :            : //-------------------------------------------------------------------------
     438                 :            : // Purpose       : Project the passed position onto the plane of the 
     439                 :            : //                 passed facet.  Returns false if projection is outside
     440                 :            : //                 the facet.
     441                 :            : //
     442                 :            : // Special Notes : "result" is unchanged if false is returned.
     443                 :            : //
     444                 :            : // Creator       : Jason Kraftcheck
     445                 :            : //
     446                 :            : // Creation Date : 05/11/02
     447                 :            : //-------------------------------------------------------------------------
     448                 :          0 : bool FacetProjectTool::project_to_face( PST_Face* triangle,
     449                 :            :                                         const CubitVector& position,
     450                 :            :                                         CubitVector& result )
     451                 :            : {
     452                 :            :     // First check if projection of the point will be within
     453                 :            :     // the bounds of the triangle.  
     454         [ #  # ]:          0 :   if( ! inside_face( triangle, position ) )
     455                 :          0 :     return false;
     456                 :            :   
     457                 :            :     // Calculate the actual projection
     458         [ #  # ]:          0 :   result = triangle->plane().project( position );
     459                 :          0 :   return true;
     460                 :            : }
     461                 :            : 
     462                 :            : //-------------------------------------------------------------------------
     463                 :            : // Purpose       : Destructor.  Clear marks on all facet entities.
     464                 :            : //
     465                 :            : // Special Notes : 
     466                 :            : //
     467                 :            : // Creator       : Jason Kraftcheck
     468                 :            : //
     469                 :            : // Creation Date : 05/11/02
     470                 :            : //-------------------------------------------------------------------------
     471 [ #  # ][ #  # ]:          0 : FacetProjectTool::~FacetProjectTool()
         [ #  # ][ #  # ]
                 [ #  # ]
     472                 :            : {
     473         [ #  # ]:          0 :   cleanup();
     474                 :          0 : }
     475                 :            : 
     476                 :            : 
     477                 :            : //-------------------------------------------------------------------------
     478                 :            : // Purpose       : clean out internal data
     479                 :            : //
     480                 :            : // Special Notes : 
     481                 :            : //
     482                 :            : // Creator       : Jason Kraftcheck
     483                 :            : //
     484                 :            : // Creation Date : 02/13/03
     485                 :            : //-------------------------------------------------------------------------
     486                 :          0 : void FacetProjectTool::cleanup()
     487                 :            : {
     488         [ #  # ]:          0 :   while( pointList.size() )
     489         [ #  # ]:          0 :     delete pointList.pop();
     490                 :          0 :   facetList.clean_out();
     491                 :          0 :   edgeList.clean_out();
     492                 :          0 :   boundaryList.clean_out();
     493                 :          0 :   imprintResult.clean_out();
     494                 :          0 :   segPoints.clean_out();
     495                 :          0 : }
     496                 :            : 
     497                 :            : 
     498                 :            : //-------------------------------------------------------------------------
     499                 :            : // Purpose       : Inset a point in the interior of a facet.
     500                 :            : //
     501                 :            : // Special Notes : Assumes input facet is a triangle, and splits facet
     502                 :            : //                 as necessary to ensure that resulting facets are tris.
     503                 :            : //
     504                 :            : // Creator       : Jason Kraftcheck
     505                 :            : //
     506                 :            : // Creation Date : 05/11/02
     507                 :            : //-------------------------------------------------------------------------
     508                 :          0 : PST_Point* FacetProjectTool::insert_in_face( PST_Face* face, 
     509                 :            :                                              const CubitVector& position )
     510                 :            : {
     511 [ #  # ][ #  # ]:          0 :   PST_Point* new_point = new PST_Point( position );
     512         [ #  # ]:          0 :   PST_CoEdge* ce1 = face->first_coedge();
     513         [ #  # ]:          0 :   PST_CoEdge* ce2 = ce1->next();
     514         [ #  # ]:          0 :   PST_CoEdge* ce3 = ce2->next();
     515                 :            : 
     516                 :            :     // insert non-mainifold edge in face after ce1
     517         [ #  # ]:          0 :   PST_Edge* edge1 = PST_Edge::insert_in_face( new_point, ce1 );
     518         [ #  # ]:          0 :   if( ! edge1 )
     519                 :            :   {
     520 [ #  # ][ #  # ]:          0 :     delete new_point;
     521                 :          0 :     return 0;
     522                 :            :   }
     523         [ #  # ]:          0 :   new_point->sequence = pointList.size();
     524         [ #  # ]:          0 :   pointList.append(new_point);
     525         [ #  # ]:          0 :   edgeList.append( edge1 );
     526 [ #  # ][ #  # ]:          0 :   if( DEBUG_FLAG( VG_FACET_DEBUG ) )
                 [ #  # ]
     527         [ #  # ]:          0 :     edge1->debug_draw( VG_FACET_FACET_COLOR );
     528                 :            :   
     529                 :            :     // connect non-manifold edge to opposite side of the face
     530                 :            :     // to make manifold topology.
     531         [ #  # ]:          0 :   PST_Edge* edge2 = PST_Edge::split_face( ce2, edge1->start_point() == new_point ?
     532 [ #  # ][ #  # ]:          0 :                                                edge1->reverse() : edge1->forward() );   
         [ #  # ][ #  # ]
     533         [ #  # ]:          0 :   if( ! edge2 ) return new_point;
     534         [ #  # ]:          0 :   edgeList.append( edge2 );
     535         [ #  # ]:          0 :   PST_Face* new_face = edge2->other(face);
     536         [ #  # ]:          0 :   new_face->sequence = facetList.size();
     537                 :          0 :   new_face->parent = face->parent;
     538         [ #  # ]:          0 :   facetList.append( new_face );
     539 [ #  # ][ #  # ]:          0 :   if( face->owner() )
     540 [ #  # ][ #  # ]:          0 :     face->owner()->notify_split( face, new_face );
     541                 :            :     
     542 [ #  # ][ #  # ]:          0 :   if( DEBUG_FLAG( VG_FACET_DEBUG ) )
                 [ #  # ]
     543         [ #  # ]:          0 :     edge2->debug_draw( VG_FACET_FACET_COLOR );
     544                 :            :   
     545                 :            :     // Split face so that all faces are triangles.
     546         [ #  # ]:          0 :   PST_Face* split_face = ce3->face();
     547 [ #  # ][ #  # ]:          0 :   PST_Edge* edge3 = PST_Edge::split_face( new_point, ce3->end_point(), split_face );
     548         [ #  # ]:          0 :   if( edge3 )
     549                 :            :   {
     550         [ #  # ]:          0 :     edgeList.append( edge3 );
     551         [ #  # ]:          0 :     new_face = edge3->other(split_face);
     552         [ #  # ]:          0 :     new_face->sequence = facetList.size();
     553                 :          0 :     new_face->parent = face->parent;
     554         [ #  # ]:          0 :     facetList.append( new_face );
     555 [ #  # ][ #  # ]:          0 :     if( split_face->owner() )
     556 [ #  # ][ #  # ]:          0 :       split_face->owner()->notify_split( split_face, new_face );
     557                 :            :   }
     558                 :            :   
     559                 :          0 :   return new_point;
     560                 :            : }
     561                 :            : 
     562                 :            : 
     563                 :            : //-------------------------------------------------------------------------
     564                 :            : // Purpose       : Add a point where the passed position is projected
     565                 :            : //                 into the facet patch.
     566                 :            : //
     567                 :            : // Special Notes : May return NULL if projection does not lie within 
     568                 :            : //                 facet patch.
     569                 :            : //
     570                 :            : // Creator       : Jason Kraftcheck
     571                 :            : //
     572                 :            : // Creation Date : 05/11/02
     573                 :            : //-------------------------------------------------------------------------
     574                 :          0 : PST_Point* FacetProjectTool::project( const CubitVector& pos,
     575                 :            :                                       const double* tolerance_length )
     576                 :            : {
     577         [ #  # ]:          0 :   PST_Point* point = closest_point( pos );
     578         [ #  # ]:          0 :   PST_Edge *  edge = closest_edge ( pos );
     579         [ #  # ]:          0 :   PST_Face *  face = closest_face ( pos );
     580                 :            :   
     581                 :            :     // find closest facet
     582                 :          0 :   double face_dist = CUBIT_DBL_MAX;
     583         [ #  # ]:          0 :   CubitVector face_pos;
     584         [ #  # ]:          0 :   if( face )
     585                 :            :   {
     586         [ #  # ]:          0 :     project_to_face( face, pos, face_pos );
     587 [ #  # ][ #  # ]:          0 :     face_dist = (pos - face_pos).length_squared();
     588                 :            :   }
     589                 :            :   
     590                 :            :     // find closest edge
     591                 :          0 :   double edge_dist = CUBIT_DBL_MAX;
     592                 :          0 :   double edge_pos  = CUBIT_DBL_MAX;
     593         [ #  # ]:          0 :   if( edge )
     594                 :            :   {
     595         [ #  # ]:          0 :     edge_pos = edge->closest_on_edge( pos );
     596 [ #  # ][ #  # ]:          0 :     edge_dist = (pos - edge->position(edge_pos)).length_squared();
                 [ #  # ]
     597                 :            :   }
     598                 :            :   
     599                 :            :     // find closest point
     600                 :          0 :   double point_dist = CUBIT_DBL_MAX;
     601         [ #  # ]:          0 :   if( point )
     602                 :            :   {
     603 [ #  # ][ #  # ]:          0 :     point_dist = (pos - *point).length_squared();
     604                 :            :   }
     605                 :            :   
     606                 :            :     // if the position is closer to a facet than a point or edge...
     607 [ #  # ][ #  # ]:          0 :   if( face && (face_dist < point_dist) && (face_dist < edge_dist) )
                 [ #  # ]
     608                 :            :   {
     609                 :            :       // get a tolerance based on a sample face size. I attempted
     610                 :            :       // to do this with a representative facet size but still 
     611                 :            :       // ended up with problems.  While this is slower is more
     612                 :            :       // robust.  KGM
     613                 :            :     double facet_length;
     614                 :            : 
     615         [ #  # ]:          0 :     if(tolerance_length)
     616                 :            :     {
     617                 :          0 :       facet_length = *tolerance_length;
     618                 :            :     }
     619                 :            :     else
     620                 :            :     {
     621         [ #  # ]:          0 :       facet_length = face->bounding_length();
     622                 :            :     }
     623                 :            : 
     624                 :            :     // use the square of the facet length times an arbitrary factor to
     625                 :            :     // determine the tolerance
     626                 :          0 :     double tol_sqr = facet_length*facet_length*.00001;
     627                 :            : 
     628                 :            :       // check if projected position is within tolerance of
     629                 :            :       // any bounding edge of the face.
     630         [ #  # ]:          0 :     PST_CoEdge* coe = face->first_coedge();
     631                 :          0 :     bool insert = true;
     632         [ #  # ]:          0 :     do {
     633         [ #  # ]:          0 :       PST_Edge* e = coe->edge();
     634 [ #  # ][ #  # ]:          0 :       CubitVector p = e->position( e->closest_on_line( face_pos ) );
     635 [ #  # ][ #  # ]:          0 :       double d = (p - face_pos).length_squared();
     636                 :            : 
     637                 :            :       // use a relative tolerance here - KGM
     638         [ #  # ]:          0 :       if( d < tol_sqr ) 
     639                 :            :       {
     640                 :          0 :         edge = e;
     641         [ #  # ]:          0 :         edge_pos = edge->closest_on_edge( pos );
     642                 :          0 :         face_dist = d;
     643                 :          0 :         edge_dist = d;
     644                 :          0 :         insert = false;
     645                 :            :       }
     646         [ #  # ]:          0 :       coe = coe->next();
     647         [ #  # ]:          0 :     } while( coe != face->first_coedge() );
     648                 :            :     
     649                 :            :       // If projected position was sufficiently far from the edges
     650                 :            :       // of the facet, insert an interior point in the facet.  Otherwise
     651                 :            :       // fall through and split edge.
     652         [ #  # ]:          0 :     if( insert )
     653                 :            :     {
     654         [ #  # ]:          0 :       return insert_in_face( face, face_pos );
     655                 :            :     }
     656                 :            :   }
     657                 :            :   
     658                 :            :     // If the point was closer to an edge than a point
     659 [ #  # ][ #  # ]:          0 :   if( edge && (edge_dist <= point_dist) )
     660                 :            :   {
     661                 :            :       // If within tolerance of an end point of the edge, return
     662                 :            :       // the end point.
     663         [ #  # ]:          0 :     CubitVector pt = edge->position( edge_pos );
     664 [ #  # ][ #  # ]:          0 :     if( (pt - *edge->start_point()).length_squared() < GEOMETRY_RESABS*GEOMETRY_RESABS )
         [ #  # ][ #  # ]
     665         [ #  # ]:          0 :       point = edge->start_point();
     666 [ #  # ][ #  # ]:          0 :     else if( (pt - *edge->end_point()).length_squared() < GEOMETRY_RESABS*GEOMETRY_RESABS )
         [ #  # ][ #  # ]
     667         [ #  # ]:          0 :       point = edge->end_point();
     668                 :            :       // Otherwise split the edge at the projected position
     669         [ #  # ]:          0 :     else point = split_edge( edge, edge_pos );
     670                 :            :   }
     671                 :            :   
     672 [ #  # ][ #  # ]:          0 :   if( DEBUG_FLAG( VG_FACET_DEBUG ) && point )
         [ #  # ][ #  # ]
                 [ #  # ]
     673         [ #  # ]:          0 :     point->debug_draw( VG_FACET_IMPRINT_COLOR );
     674                 :            :   
     675                 :            :     // If this was not set in the above if-block, then it is either
     676                 :            :     // the closest point in the facet patch or NULL if the position
     677                 :            :     // projected outside the facet patch.
     678                 :          0 :   return point;
     679                 :            : }    
     680                 :            :   
     681                 :            : //-------------------------------------------------------------------------
     682                 :            : // Purpose       : Split an edge at the specified parameter value on the
     683                 :            : //                 edge.  Splits connected facets to maintain triangular
     684                 :            : //                 facets.
     685                 :            : //
     686                 :            : // Special Notes : 
     687                 :            : //
     688                 :            : // Creator       : Jason Kraftcheck
     689                 :            : //
     690                 :            : // Creation Date : 05/11/02
     691                 :            : //-------------------------------------------------------------------------
     692                 :          0 : PST_Point* FacetProjectTool::split_edge( PST_Edge* edge, double t )
     693                 :            : {
     694 [ #  # ][ #  # ]:          0 :   assert( t > 0.0 && t < 1.0 );
     695                 :            :   
     696                 :            :     // create point
     697 [ #  # ][ #  # ]:          0 :   PST_Point* point = new PST_Point( edge->position(t) );
                 [ #  # ]
     698                 :            :   
     699                 :            :     // get connected faces 
     700 [ #  # ][ #  # ]:          0 :   PST_Face* face1 = edge->forward()->face();
     701 [ #  # ][ #  # ]:          0 :   PST_Face* face2 = edge->reverse()->face();
     702                 :            :   
     703                 :            :     // point on each triangle opposite the edge to be split
     704 [ #  # ][ #  # ]:          0 :   PST_Point* face1_pt = face1 ? edge->forward()->next()->end_point() : 0;
         [ #  # ][ #  # ]
     705 [ #  # ][ #  # ]:          0 :   PST_Point* face2_pt = face2 ? edge->reverse()->next()->end_point() : 0;
         [ #  # ][ #  # ]
     706                 :            : 
     707                 :          0 :   PST_Edge* face1_edge = 0, *face2_edge = 0;
     708                 :            :   
     709                 :            :     // split edge edge
     710         [ #  # ]:          0 :   PST_Edge* split_edge = edge->split( point );
     711 [ #  # ][ #  # ]:          0 :   if( edge->owner() )
     712 [ #  # ][ #  # ]:          0 :     edge->owner()->notify_split( edge, split_edge );
     713                 :            :     // if we split a boundary edge, put the new edge in the
     714                 :            :     // list of boundary edges too.
     715         [ #  # ]:          0 :   if( edge->mark )
     716                 :            :   {
     717                 :          0 :     split_edge->mark = edge->mark;
     718         [ #  # ]:          0 :     boundaryList.append( split_edge );
     719                 :            :   }
     720                 :            :     // add edge to our list of edges
     721         [ #  # ]:          0 :   edgeList.append( split_edge );
     722                 :            :     // If the first face was not a boundary face (different
     723                 :            :     // than the boundary of our patch of facets), then split
     724                 :            :     // it so that it remains a triangle.
     725         [ #  # ]:          0 :   if( face1 ) 
     726                 :            :   {
     727         [ #  # ]:          0 :     face1_edge = PST_Edge::split_face( point, face1_pt, face1 );
     728                 :            :     
     729         [ #  # ]:          0 :     if( face1_edge )
     730                 :            :     {
     731 [ #  # ][ #  # ]:          0 :       if( DEBUG_FLAG( VG_FACET_DEBUG ) )
                 [ #  # ]
     732         [ #  # ]:          0 :         face1_edge->debug_draw( VG_FACET_FACET_COLOR );
     733                 :            : 
     734         [ #  # ]:          0 :       edgeList.append( face1_edge );
     735         [ #  # ]:          0 :             PST_Face* new_face = face1_edge->other(face1);
     736         [ #  # ]:          0 :       new_face->sequence = facetList.size();
     737                 :          0 :       new_face->parent = face1->parent;
     738         [ #  # ]:          0 :       facetList.append(new_face );
     739                 :            :       
     740 [ #  # ][ #  # ]:          0 :       if( face1->owner() )
     741 [ #  # ][ #  # ]:          0 :         face1->owner()->notify_split( face1, face1_edge->other(face1) );
                 [ #  # ]
     742                 :            :     }
     743                 :            :   }
     744                 :            :     // If the second face is not a boundary face, split it
     745                 :            :     // so that we still have triangles.
     746         [ #  # ]:          0 :   if( face2 )
     747                 :            :   {
     748         [ #  # ]:          0 :     face2_edge = PST_Edge::split_face( point, face2_pt, face2 );
     749         [ #  # ]:          0 :     if( face2_edge )
     750                 :            :     {
     751 [ #  # ][ #  # ]:          0 :       if( DEBUG_FLAG( VG_FACET_DEBUG ) )
                 [ #  # ]
     752         [ #  # ]:          0 :         face2_edge->debug_draw( VG_FACET_FACET_COLOR );
     753                 :            : 
     754         [ #  # ]:          0 :       edgeList.append( face2_edge );
     755         [ #  # ]:          0 :             PST_Face* new_face = face2_edge->other(face2);
     756         [ #  # ]:          0 :       new_face->sequence = facetList.size();
     757                 :          0 :       new_face->parent = face2->parent;
     758         [ #  # ]:          0 :       facetList.append( new_face );
     759                 :            :       
     760 [ #  # ][ #  # ]:          0 :       if( face2->owner() )
     761 [ #  # ][ #  # ]:          0 :         face2->owner()->notify_split( face2, face2_edge->other(face2) );
                 [ #  # ]
     762                 :            :     }
     763                 :            :   }
     764         [ #  # ]:          0 :   point->sequence = pointList.size();
     765         [ #  # ]:          0 :   pointList.append(point);
     766                 :            :   
     767                 :          0 :   return point;
     768                 :            : }
     769                 :            : 
     770                 :            : //-------------------------------------------------------------------------
     771                 :            : // Purpose       : This is the main or outer-loop function for the
     772                 :            : //                 polyline projection.  It is called after the input data
     773                 :            : //                 is converted to the working representation.  The passed
     774                 :            : //                 list of CubitVectors is the polyline.
     775                 :            : //
     776                 :            : // Special Notes : 
     777                 :            : //
     778                 :            : // Creator       : Jason Kraftcheck
     779                 :            : //
     780                 :            : // Creation Date : ??
     781                 :            : //-------------------------------------------------------------------------
     782                 :            : 
     783                 :            : CubitStatus 
     784                 :          0 : FacetProjectTool::do_projection( const DLIList<CubitVector*>& passed_list, 
     785                 :            :                                  CubitBoolean & point_changed,
     786                 :            :                                  const double *tolerance_length)
     787                 :            : {
     788                 :          0 :   const double TOL_SQR = GEOMETRY_RESABS*GEOMETRY_RESABS;
     789                 :          0 :   point_changed = CUBIT_FALSE;
     790         [ #  # ]:          0 :   DLIList<CubitVector*> segments( passed_list );  
     791                 :            :   
     792                 :          0 :   bool first_and_last_points_coincident = false;  
     793 [ #  # ][ #  # ]:          0 :   if( segments[0]->distance_between_squared( *(segments[ segments.size()-1]) ) < TOL_SQR )
         [ #  # ][ #  # ]
                 [ #  # ]
     794                 :          0 :     first_and_last_points_coincident = true; 
     795                 :            : 
     796         [ #  # ]:          0 :   segments.reset();
     797 [ #  # ][ #  # ]:          0 :   CubitVector end = *(segments.get_and_step());
     798                 :          0 :   PST_Point* last_point = 0;
     799                 :            : 
     800                 :          0 :   bool did_any_projection = false;
     801                 :            :   
     802                 :            :   int where_is_last_pt;
     803                 :            :   int where_is_end_pt;
     804                 :            :   
     805                 :          0 :   bool debug = false;  
     806                 :            :   
     807 [ #  # ][ #  # ]:          0 :   for( int i = segments.size(); i > 1; i-- )
     808                 :            :   {
     809         [ #  # ]:          0 :     CubitVector start(end);
     810 [ #  # ][ #  # ]:          0 :     end = *(segments.get_and_step());
     811                 :            :     
     812         [ #  # ]:          0 :     if( debug )
     813                 :            :     {
     814         [ #  # ]:          0 :       GfxDebug::clear();       
     815 [ #  # ][ #  # ]:          0 :       for( int j=facetList.size(); j--; )
     816 [ #  # ][ #  # ]:          0 :         facetList.get_and_step()->debug_draw( CUBIT_CYAN_INDEX+j, false );        
     817         [ #  # ]:          0 :       GfxDebug::draw_point( start, CUBIT_GREEN_INDEX );
     818         [ #  # ]:          0 :       GfxDebug::draw_point( end, CUBIT_RED_INDEX );
     819         [ #  # ]:          0 :       GfxDebug::flush();
     820         [ #  # ]:          0 :       GfxDebug::mouse_xforms();      
     821                 :            :     }
     822                 :            : 
     823 [ #  # ][ #  # ]:          0 :     if( DEBUG_FLAG( VG_FACET_DEBUG ) )
                 [ #  # ]
     824                 :            :     {
     825                 :            :       GfxDebug::draw_line( 
     826 [ #  # ][ #  # ]:          0 :         (float)start.x(), (float)start.y(), (float)start.z(),
                 [ #  # ]
     827 [ #  # ][ #  # ]:          0 :         (float)end.x()  , (float)end.y()  , (float)end.z(),
                 [ #  # ]
     828         [ #  # ]:          0 :         VG_FACET_SEGMENT_COLOR );     
     829         [ #  # ]:          0 :       GfxDebug::flush();
     830         [ #  # ]:          0 :       GfxDebug::mouse_xforms();
     831                 :            :     }
     832                 :            : 
     833         [ #  # ]:          0 :     double facet_dist_tol = start.distance_between_squared( end );
     834                 :          0 :     facet_dist_tol *= 0.0001;
     835                 :            : 
     836                 :            :     //determine if start is on/off/on-boundary of facets
     837         [ #  # ]:          0 :     if( !last_point )
     838                 :            :     {
     839         [ #  # ]:          0 :       where_is_last_pt = point_on_facets( &start, facet_dist_tol );
     840                 :            : 
     841 [ #  # ][ #  # ]:          0 :       if( 1 == where_is_last_pt || 
     842                 :            :           2 == where_is_last_pt  )
     843                 :            :       {
     844         [ #  # ]:          0 :         last_point = project( start, tolerance_length );
     845                 :            :         
     846         [ #  # ]:          0 :         segPoints.append(last_point); 
     847         [ #  # ]:          0 :         start = *last_point;
     848                 :            : 
     849         [ #  # ]:          0 :         if( first_and_last_points_coincident )
     850 [ #  # ][ #  # ]:          0 :           *(segments[segments.size()-1]) = start;
                 [ #  # ]
     851                 :            :       }
     852                 :            :       else
     853         [ #  # ]:          0 :         segPoints.append(NULL);  //it's not on the facets
     854                 :            :     } 
     855                 :            : 
     856         [ #  # ]:          0 :     where_is_end_pt = point_on_facets( &end, facet_dist_tol );
     857                 :            : 
     858                 :            :     //both points off the facets
     859                 :            :     //or one-on, one-off
     860                 :          0 :     PST_Point *end_pt = NULL;
     861                 :            : 
     862                 :            :     //both points off
     863                 :            :     //one-point-on && one-point-off
     864 [ #  # ][ #  # ]:          0 :     if( (0 == where_is_last_pt && 0 == where_is_end_pt ) || 
                 [ #  # ]
     865 [ #  # ][ #  # ]:          0 :         (0 == where_is_last_pt && 1 == where_is_end_pt ) ||
     866         [ #  # ]:          0 :         (1 == where_is_last_pt && 0 == where_is_end_pt ) )
     867                 :            :     {
     868                 :            :       //see if segment intersects boundary
     869         [ #  # ]:          0 :       CubitVector int_pt;
     870         [ #  # ]:          0 :       CubitStatus my_status = find_closest_int_point_with_boundary( start, end, int_pt );
     871         [ #  # ]:          0 :       if( CUBIT_FAILURE == my_status )      
     872                 :            :       {
     873         [ #  # ]:          0 :         segPoints.append( NULL );
     874                 :          0 :         continue;
     875                 :            :       }      
     876                 :            : 
     877         [ #  # ]:          0 :       if( 0 == where_is_last_pt )
     878                 :            :       {
     879         [ #  # ]:          0 :         last_point = project( int_pt, tolerance_length );
     880                 :            : 
     881         [ #  # ]:          0 :         if( 0 == where_is_end_pt )
     882                 :            :         {
     883         [ #  # ]:          0 :           my_status = find_closest_int_point_with_boundary( end, *last_point, int_pt );
     884         [ #  # ]:          0 :           if( CUBIT_SUCCESS == my_status )
     885                 :            :           {
     886         [ #  # ]:          0 :             end_pt = project( int_pt, tolerance_length );
     887                 :          0 :             i++;
     888         [ #  # ]:          0 :             segments.back();
     889                 :            :           }          
     890                 :            :         } 
     891                 :            :         else
     892                 :            :         {
     893         [ #  # ]:          0 :           end_pt = project( end, tolerance_length );
     894         [ #  # ]:          0 :           segPoints.append( end_pt );
     895                 :            :         }
     896                 :            :       }
     897         [ #  # ]:          0 :       else if( 0 == where_is_end_pt )
     898                 :            :       {
     899         [ #  # ]:          0 :         end_pt = project( int_pt, tolerance_length );
     900                 :          0 :         i++;
     901         [ #  # ]:          0 :         segments.back();
     902                 :          0 :       }      
     903                 :            :     }
     904 [ #  # ][ #  # ]:          0 :     else if( (1 == where_is_last_pt || 2 == where_is_last_pt) && 
                 [ #  # ]
     905         [ #  # ]:          0 :              (1 == where_is_end_pt || 2 == where_is_end_pt) )
     906                 :            :     {
     907         [ #  # ]:          0 :       end_pt = project( end, tolerance_length );
     908         [ #  # ]:          0 :       segPoints.append( end_pt );
     909                 :            :     }         
     910 [ #  # ][ #  # ]:          0 :     else if( (0 == where_is_last_pt && 2 == where_is_end_pt ) || 
                 [ #  # ]
     911         [ #  # ]:          0 :              (2 == where_is_last_pt && 0 == where_is_end_pt ) )
     912                 :            :     {
     913 [ #  # ][ #  # ]:          0 :       if( 0 == where_is_last_pt && 2 == where_is_end_pt )
     914                 :            :       {
     915                 :            :         //see if segment intersects boundary
     916         [ #  # ]:          0 :         CubitVector int_pt;
     917         [ #  # ]:          0 :         CubitStatus my_status = find_closest_int_point_with_boundary( start, end, int_pt );
     918         [ #  # ]:          0 :         if( CUBIT_SUCCESS == my_status )
     919                 :            :         {
     920         [ #  # ]:          0 :           end_pt = project( end, tolerance_length );
     921         [ #  # ]:          0 :           last_point = project( int_pt, tolerance_length );
     922         [ #  # ]:          0 :           segPoints.append( end_pt );
     923                 :            :         }
     924                 :            :         else
     925                 :            :         {
     926         [ #  # ]:          0 :           segPoints.append(NULL);
     927                 :          0 :           continue;
     928                 :          0 :         }
     929                 :            :       }
     930                 :            :       else
     931                 :            :       {
     932                 :            :         //see if segment intersects boundary
     933         [ #  # ]:          0 :         CubitVector int_pt;
     934         [ #  # ]:          0 :         CubitStatus my_status = find_closest_int_point_with_boundary( end, start, int_pt );      
     935                 :            : 
     936         [ #  # ]:          0 :         if( CUBIT_SUCCESS == my_status )
     937                 :            :         {
     938         [ #  # ]:          0 :           end_pt = project( int_pt, tolerance_length );                        
     939         [ #  # ]:          0 :           segPoints.append( NULL );
     940                 :            :         }
     941                 :            :         else
     942                 :            :         {
     943         [ #  # ]:          0 :           segPoints.append( NULL );
     944                 :          0 :           continue;
     945                 :            :         }
     946                 :            :       }
     947                 :            :     }
     948                 :            : 
     949                 :            :         
     950                 :          0 :     PST_Point* start_point = last_point;
     951                 :          0 :     PST_Point* end_point = end_pt;
     952                 :            : 
     953         [ #  # ]:          0 :     if( debug )
     954                 :            :     {
     955         [ #  # ]:          0 :       GfxDebug::draw_line( *last_point, *end_pt, CUBIT_MAGENTA_INDEX );
     956         [ #  # ]:          0 :       GfxDebug::flush();
     957         [ #  # ]:          0 :       GfxDebug::mouse_xforms();
     958                 :            :     }
     959                 :            : 
     960 [ #  # ][ #  # ]:          0 :     if(project( last_point, end_pt ) == CUBIT_SUCCESS)
     961                 :            :     {
     962                 :          0 :       did_any_projection = true;
     963 [ #  # ][ #  # ]:          0 :       if ((*start_point - *last_point).length_squared() > TOL_SQR)
                 [ #  # ]
     964                 :            :       {
     965         [ #  # ]:          0 :         segPoints.move_to(start_point);
     966         [ #  # ]:          0 :         segPoints.change_to(last_point);
     967                 :          0 :         point_changed = CUBIT_TRUE;
     968                 :            :       }
     969 [ #  # ][ #  # ]:          0 :       if ((*end_pt - *end_point).length_squared() > TOL_SQR)
                 [ #  # ]
     970                 :            :       {
     971         [ #  # ]:          0 :         segPoints.move_to(end_point);
     972         [ #  # ]:          0 :         segPoints.change_to(end_pt);
     973                 :          0 :         point_changed = CUBIT_TRUE;
     974                 :            :       }    
     975                 :            :     }
     976                 :            : 
     977                 :          0 :     last_point = end_pt;
     978                 :          0 :     where_is_last_pt = where_is_end_pt;    
     979                 :            :   
     980                 :            :   } // end for( i = segments )
     981                 :            :   
     982         [ #  # ]:          0 :   if( !did_any_projection )
     983                 :          0 :     return CUBIT_FAILURE;
     984                 :            : 
     985         [ #  # ]:          0 :   return CUBIT_SUCCESS;
     986                 :            : }
     987                 :            : 
     988                 :            : //-------------------------------------------------------------------------
     989                 :            : // Purpose       : Determines if a position is off/on/on-boundary of the
     990                 :            : //                 facets in this tool.  For off/on/on-boundary returns
     991                 :            : //                 0, 1, and 2 respectively.  The passed in tolerance_sq is 
     992                 :            : //                 used as a coincidence tolerance.
     993                 :            : //
     994                 :            : // Special Notes : 
     995                 :            : //
     996                 :            : // Creator       : Corey Ernst
     997                 :            : //
     998                 :            : // Creation Date : 24-April-2013
     999                 :            : //-------------------------------------------------------------------------
    1000                 :            : 
    1001                 :          0 : int FacetProjectTool::point_on_facets( 
    1002                 :            :   CubitVector *pos,  
    1003                 :            :   double tolerance_sq )
    1004                 :            : {
    1005                 :            :   //Return Values:
    1006                 :            :   //0 is outside of facets
    1007                 :            :   //1 is inside of facets
    1008                 :            :   //2 is on boundary of facets
    1009                 :            : 
    1010         [ #  # ]:          0 :   PST_Point* point = closest_point( *pos );
    1011         [ #  # ]:          0 :   PST_Edge *  edge = closest_edge ( *pos );
    1012         [ #  # ]:          0 :   PST_Face *  face = closest_face ( *pos );
    1013                 :            : 
    1014                 :            :   // find closest facet
    1015                 :          0 :   double face_dist = CUBIT_DBL_MAX;
    1016         [ #  # ]:          0 :   CubitVector face_pos;
    1017         [ #  # ]:          0 :   if( face )
    1018                 :            :   {
    1019         [ #  # ]:          0 :     project_to_face( face, *pos, face_pos );
    1020 [ #  # ][ #  # ]:          0 :     face_dist = (*pos - face_pos).length_squared();
    1021                 :            :   }
    1022                 :            : 
    1023                 :            :   // find closest edge
    1024                 :          0 :   double edge_dist = CUBIT_DBL_MAX;
    1025                 :          0 :   double edge_pos  = CUBIT_DBL_MAX;
    1026         [ #  # ]:          0 :   if( edge )
    1027                 :            :   {
    1028         [ #  # ]:          0 :     edge_pos = edge->closest_on_edge( *pos );
    1029 [ #  # ][ #  # ]:          0 :     edge_dist = (*pos - edge->position(edge_pos)).length_squared();
                 [ #  # ]
    1030                 :            :   }
    1031                 :            : 
    1032                 :            :   // find closest point
    1033                 :          0 :   double point_dist = CUBIT_DBL_MAX;
    1034         [ #  # ]:          0 :   if( point )
    1035                 :            :   {
    1036 [ #  # ][ #  # ]:          0 :     point_dist = (*pos - *point).length_squared();
    1037                 :            :   }  
    1038                 :            : 
    1039                 :            :   // if the position is closer to a facet than a point or edge...
    1040 [ #  # ][ #  # ]:          0 :   if( face && (face_dist < point_dist) && (face_dist < edge_dist) )
                 [ #  # ]
    1041                 :            :   {
    1042                 :            :     // check if projected position is within tolerance of
    1043                 :            :     // any bounding edge of the face.
    1044         [ #  # ]:          0 :     PST_CoEdge* coe = face->first_coedge();
    1045                 :          0 :     bool edge_closer = false;
    1046         [ #  # ]:          0 :     do {
    1047         [ #  # ]:          0 :       PST_Edge* e = coe->edge();
    1048 [ #  # ][ #  # ]:          0 :       CubitVector p = e->position( e->closest_on_line( face_pos ) );
    1049 [ #  # ][ #  # ]:          0 :       double d = (p - face_pos).length_squared();
    1050                 :            : 
    1051         [ #  # ]:          0 :       if( d < tolerance_sq ) 
    1052                 :            :       {
    1053                 :          0 :         edge = e;
    1054         [ #  # ]:          0 :         edge_pos = edge->closest_on_edge( *pos );
    1055                 :          0 :         face_dist = d;
    1056                 :          0 :         edge_dist = d;
    1057                 :          0 :         edge_closer = true;
    1058                 :            :       }
    1059         [ #  # ]:          0 :       coe = coe->next();
    1060         [ #  # ]:          0 :     } while( coe != face->first_coedge() );
    1061                 :            :     
    1062         [ #  # ]:          0 :     if( edge_closer )
    1063                 :            :     {      
    1064 [ #  # ][ #  # ]:          0 :       if( boundaryList.is_in_list( edge ) )
    1065                 :          0 :         return 2;
    1066                 :            :       else
    1067                 :          0 :         return 1;    
    1068                 :            :     }      
    1069                 :            :     else
    1070                 :          0 :       return 1;    
    1071                 :            :     
    1072                 :            :     return 0;
    1073                 :            :   }
    1074                 :            : 
    1075                 :            :   // If the point was closer to an edge than a point
    1076 [ #  # ][ #  # ]:          0 :   if( edge && (edge_dist < point_dist) )
    1077                 :            :   {
    1078         [ #  # ]:          0 :     if( edge_dist < tolerance_sq )
    1079                 :            :     {
    1080 [ #  # ][ #  # ]:          0 :       if( boundaryList.is_in_list( edge ) )
    1081                 :          0 :         return 2;
    1082                 :            :       else
    1083                 :          0 :         return 1;
    1084                 :            :     }
    1085                 :            :     else
    1086                 :          0 :       return 0;
    1087                 :            :   }
    1088                 :            : 
    1089         [ #  # ]:          0 :   PST_Edge *first_edge = point->edge();
    1090                 :          0 :   PST_Edge *tmp_edge = first_edge;
    1091         [ #  # ]:          0 :   if( point_dist < tolerance_sq )
    1092                 :            :   {
    1093         [ #  # ]:          0 :     do
    1094                 :            :     {
    1095 [ #  # ][ #  # ]:          0 :       if( boundaryList.is_in_list( tmp_edge ) )
    1096                 :          0 :         return 2;
    1097         [ #  # ]:          0 :       tmp_edge = point->next( tmp_edge );
    1098                 :            :     }
    1099                 :          0 :     while( first_edge != tmp_edge );
    1100                 :            : 
    1101                 :          0 :     return 1;
    1102                 :            :   }
    1103                 :          0 :   return 0;
    1104                 :            : }
    1105                 :            : 
    1106                 :            : 
    1107                 :            : //-------------------------------------------------------------------------
    1108                 :            : // Purpose       : Finds the closest intersection point to 'start_pt' 
    1109                 :            : //                 between the boundary facet edges in this tool and a line
    1110                 :            : //                 segement defined by 'start_pt' and 'end_pt'.  The 
    1111                 :            : //                 intersection must be at or between the two end points
    1112                 :            : //                 of the segment.
    1113                 :            : //
    1114                 :            : // Special Notes : 
    1115                 :            : //
    1116                 :            : // Creator       : Corey Ernst
    1117                 :            : //
    1118                 :            : // Creation Date : 24-April-2013
    1119                 :            : //-------------------------------------------------------------------------
    1120                 :          0 : CubitStatus FacetProjectTool::find_closest_int_point_with_boundary( 
    1121                 :            :   CubitVector &start_pt, CubitVector &end_pt, CubitVector &closest_pt  )
    1122                 :            : {
    1123         [ #  # ]:          0 :   CubitVector seg_direction = end_pt - start_pt;   
    1124         [ #  # ]:          0 :   double seg_length_sq = seg_direction.length_squared();
    1125                 :          0 :   double shortest_length = CUBIT_DBL_MAX;    
    1126                 :            :   
    1127                 :          0 :   const double TOL_SQR = GEOMETRY_RESABS*GEOMETRY_RESABS;
    1128                 :            : 
    1129                 :          0 :   bool debug = false;
    1130                 :            :   
    1131                 :            :   //find the farthest boundary edge that is on the line segment    
    1132         [ #  # ]:          0 :   CubitVector split_position;
    1133 [ #  # ][ #  # ]:          0 :   for( int k=boundaryList.size(); k--; )
    1134                 :            :   {
    1135         [ #  # ]:          0 :     PST_Edge *tmp_edge = boundaryList.get_and_step();
    1136                 :            : 
    1137                 :            :     //if lines are parallel
    1138         [ #  # ]:          0 :     CubitVector tmp_vec1 = end_pt - start_pt;
    1139 [ #  # ][ #  # ]:          0 :     CubitVector tmp_vec2 = tmp_edge->end_coord() - tmp_edge->start_coord();
                 [ #  # ]
    1140         [ #  # ]:          0 :     tmp_vec1 *= tmp_vec2;
    1141 [ #  # ][ #  # ]:          0 :     if( tmp_vec1.length_squared() < TOL_SQR )
    1142                 :          0 :       continue;
    1143                 :            : 
    1144 [ #  # ][ #  # ]:          0 :     double t1 = tmp_edge->closest_on_line( start_pt, end_pt - start_pt );
    1145                 :            :     
    1146                 :            :     //ignore points that are coincident with start_pt or end_pt
    1147         [ #  # ]:          0 :     CubitVector position_on_edge = tmp_edge->position( t1 );
    1148         [ #  # ]:          0 :     double dist_sq_start = position_on_edge.distance_between_squared( start_pt );
    1149         [ #  # ]:          0 :     double dist_sq_end = position_on_edge.distance_between_squared( end_pt );
    1150 [ #  # ][ #  # ]:          0 :     if( dist_sq_start < TOL_SQR || dist_sq_end < TOL_SQR )      
    1151                 :          0 :       continue;
    1152                 :            : 
    1153 [ #  # ][ #  # ]:          0 :     if( t1 >= 0 && t1 <= 1 )    
    1154                 :            :     {       
    1155         [ #  # ]:          0 :       if( debug )
    1156                 :            :       {
    1157         [ #  # ]:          0 :         GfxDebug::draw_line( start_pt, end_pt, CUBIT_MAGENTA_INDEX );      
    1158 [ #  # ][ #  # ]:          0 :         PRINT_INFO("t1 = %f\n", t1 );
         [ #  # ][ #  # ]
    1159         [ #  # ]:          0 :         tmp_edge->debug_draw( CUBIT_YELLOW_INDEX ); 
    1160                 :            :       }
    1161                 :            :   
    1162         [ #  # ]:          0 :       CubitVector tmp_pos = tmp_edge->position( t1 );
    1163                 :            : 
    1164                 :            :       //This checks if the intersection between the edge and segment
    1165                 :            :       //is not within the segment.
    1166 [ #  # ][ #  # ]:          0 :       if( tmp_pos.distance_between_squared( start_pt ) > seg_length_sq || 
         [ #  # ][ #  # ]
    1167         [ #  # ]:          0 :           tmp_pos.distance_between_squared( end_pt ) > seg_length_sq )      
    1168                 :          0 :         continue;              
    1169                 :            :       
    1170         [ #  # ]:          0 :       if( debug )
    1171                 :            :       {
    1172         [ #  # ]:          0 :         GfxDebug::draw_point( tmp_pos, CUBIT_RED_INDEX );        
    1173         [ #  # ]:          0 :         GfxDebug::flush();
    1174         [ #  # ]:          0 :         GfxDebug::mouse_xforms(); 
    1175                 :            :       }
    1176                 :            : 
    1177         [ #  # ]:          0 :       double tmp_dist = tmp_pos.distance_between( start_pt );
    1178                 :            :       
    1179         [ #  # ]:          0 :       if( tmp_dist < shortest_length )
    1180                 :            :       {
    1181                 :          0 :         shortest_length = tmp_dist;        
    1182         [ #  # ]:          0 :         closest_pt = tmp_pos;
    1183                 :            :       }    
    1184                 :            :     }
    1185                 :            :   }
    1186                 :            : 
    1187         [ #  # ]:          0 :   if( shortest_length == CUBIT_DBL_MAX )
    1188                 :          0 :     return CUBIT_FAILURE;
    1189                 :            : 
    1190                 :          0 :   return CUBIT_SUCCESS;
    1191                 :            : }
    1192                 :            : 
    1193                 :            : 
    1194                 :            : //-------------------------------------------------------------------------
    1195                 :            : // Purpose       : Given two existing points in a triangulation, add edges
    1196                 :            : //                 to the triangulation to connect those two points by the
    1197                 :            : //                 most direct path that does not leave the triangulation.
    1198                 :            : //
    1199                 :            : // Special Notes : Thisis the second step of the facet-polyline projection
    1200                 :            : //                 algorithm.  First each point of the polyline is 
    1201                 :            : //                 projected onto the facetting.  Second this function is
    1202                 :            : //                 called to find/create the set of facet edges connecting
    1203                 :            : //                 those points.
    1204                 :            : //
    1205                 :            : // Creator       : Jason Kraftcheck
    1206                 :            : //
    1207                 :            : // Creation Date : ??
    1208                 :            : //-------------------------------------------------------------------------
    1209                 :          0 : CubitStatus FacetProjectTool::project( PST_Point* &start, PST_Point* &end )
    1210                 :            : {
    1211                 :          0 :   PST_Edge* edge,* closest_edge, *last_closest_edge=NULL;
    1212                 :            :   PST_Face* closest_face;
    1213                 :            :   PST_Point* point;
    1214                 :          0 :   PST_Point* start_point = start;  
    1215                 :            :   CubitStatus stat;
    1216                 :            :   
    1217                 :          0 :   const double TOL_SQR = GEOMETRY_RESABS*GEOMETRY_RESABS;
    1218                 :            : 
    1219         [ #  # ]:          0 :   while( start_point != end )
    1220                 :            :   {
    1221                 :            :       // If the points share an edge, that edge is the result.
    1222                 :            :       // Return it.
    1223                 :            :     CubitBoolean is_boundary_edge;
    1224 [ #  # ][ #  # ]:          0 :     if( (edge = start_point->common( end )) )
    1225                 :            :     {
    1226         [ #  # ]:          0 :       PST_CoEdge* coedge = edge->end_point() == end ? 
    1227 [ #  # ][ #  # ]:          0 :                            edge->forward() : edge->reverse();
                 [ #  # ]
    1228         [ #  # ]:          0 :       imprintResult.append( coedge );
    1229                 :            : 
    1230 [ #  # ][ #  # ]:          0 :       if( DEBUG_FLAG( VG_FACET_DEBUG ) )
                 [ #  # ]
    1231                 :            :       {
    1232         [ #  # ]:          0 :         edge->debug_draw( VG_FACET_IMPRINT_COLOR );        
    1233                 :            :       }
    1234                 :            :         
    1235                 :          0 :       return CUBIT_SUCCESS;
    1236                 :            :     }    
    1237                 :            : 
    1238                 :            :       // Draw the current segment
    1239 [ #  # ][ #  # ]:          0 :     if( DEBUG_FLAG( VG_FACET_DEBUG ) )
                 [ #  # ]
    1240                 :            :     {
    1241                 :            :       GfxDebug::draw_line( 
    1242 [ #  # ][ #  # ]:          0 :         (float)start_point->x(), (float)start_point->y(), 
    1243         [ #  # ]:          0 :         (float)start_point->z(),
    1244 [ #  # ][ #  # ]:          0 :         (float)end->x()  , (float)end->y()  , (float)end->z(),
                 [ #  # ]
    1245         [ #  # ]:          0 :         VG_FACET_SEGMENT_COLOR );
    1246         [ #  # ]:          0 :       GfxDebug::flush();
    1247         [ #  # ]:          0 :       GfxDebug::mouse_xforms();
    1248                 :            :     }
    1249                 :            :     
    1250                 :            :       // Get face or edge adjacent to start and closest to the polyline segment
    1251                 :            :     stat = next_around_point( start_point, *end, closest_face, closest_edge, 
    1252         [ #  # ]:          0 :                               is_boundary_edge, last_closest_edge );
    1253                 :            :     
    1254         [ #  # ]:          0 :     if(closest_edge)    
    1255                 :          0 :       last_closest_edge = closest_edge;    
    1256                 :            : 
    1257 [ #  # ][ #  # ]:          0 :     if (!stat || (closest_face && closest_edge))
                 [ #  # ]
    1258                 :            :     {
    1259                 :            :  //     assert(false);
    1260                 :          0 :       return stat;
    1261                 :            :     }
    1262                 :            : 
    1263         [ #  # ]:          0 :     const CubitVector seg_tan = *end - *start_point;
    1264                 :          0 :     double t_seg = 0.0;
    1265                 :          0 :     point = 0;
    1266                 :            :     
    1267         [ #  # ]:          0 :     if (closest_face)
    1268                 :            :     {
    1269                 :            :         // calculate intersection with triangle edge opposite
    1270                 :            :         // 'start_point'.
    1271                 :            :       double t_edge;
    1272         [ #  # ]:          0 :       edge = closest_face->opposite(start_point);
    1273         [ #  # ]:          0 :       PST_Point* edge_start = edge->start_point();
    1274         [ #  # ]:          0 :       PST_Point* edge_end   = edge->end_point();
    1275         [ #  # ]:          0 :       closest_on_lines( *edge_start, *edge_end - *edge_start,
    1276         [ #  # ]:          0 :                         *start_point,  seg_tan, t_edge, t_seg);
    1277                 :            :       
    1278 [ #  # ][ #  # ]:          0 :       const CubitVector  seg_pt = *start_point + t_seg  *  seg_tan;
    1279         [ #  # ]:          0 :       const CubitVector edge_pt = (1.0 - t_edge) * *edge_start
    1280 [ #  # ][ #  # ]:          0 :                                        + t_edge  * *edge_end;
    1281                 :            :       
    1282                 :            :         // if line segment intersects opposite edge of triangle...
    1283 [ #  # ][ #  # ]:          0 :       if ( (t_seg < 1.0) || ((seg_pt - edge_pt).length_squared() < TOL_SQR) )
         [ #  # ][ #  # ]
                 [ #  # ]
           [ #  #  #  # ]
    1284                 :            :       {
    1285                 :            :           // Check if intersection is near start of opposite edge
    1286 [ #  # ][ #  # ]:          0 :         if ((t_edge <= 0.0) || 
    1287 [ #  # ][ #  # ]:          0 :             ((*edge_start - edge_pt).length_squared() < TOL_SQR) ||
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    1288 [ #  # ][ #  # ]:          0 :             ((*edge_start - seg_pt ).length_squared() < TOL_SQR) )
         [ #  # ][ #  # ]
    1289                 :          0 :           point = edge_start;
    1290                 :            :           // Check if intersection is near end of opposite edge
    1291 [ #  # ][ #  # ]:          0 :         else if ((t_edge >= 1.0) || 
    1292 [ #  # ][ #  # ]:          0 :                  ((*edge_end - edge_pt).length_squared() < TOL_SQR) ||
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    1293 [ #  # ][ #  # ]:          0 :                  ((*edge_end -  seg_pt).length_squared() < TOL_SQR))
         [ #  # ][ #  # ]
    1294                 :          0 :           point = edge_end;
    1295                 :            :           // Otherwise intersection is in the interior of the edge
    1296                 :            :         else
    1297         [ #  # ]:          0 :           point = split_edge(edge, t_edge);
    1298                 :            :       }
    1299                 :            :         // otherwise segment end is inside triangle
    1300                 :            :       else
    1301                 :            :       {
    1302                 :          0 :         t_seg = 1.0;
    1303 [ #  # ][ #  # ]:          0 :         const CubitVector proj = closest_face->plane().project(*end);
    1304                 :            :         PST_Edge *edge1, *edge2;
    1305         [ #  # ]:          0 :         closest_face->two_edges (start_point, edge1, edge2);
    1306                 :            :           // Too close to start position - skip segment
    1307 [ #  # ][ #  # ]:          0 :         if ( (*start_point - proj).length_squared() < TOL_SQR )
                 [ #  # ]
    1308                 :          0 :           point = start_point;
    1309                 :            :           // If close to side of triangle, fall through to edge
    1310                 :            :           // handling code
    1311 [ #  # ][ #  # ]:          0 :         else if (within_tolerance(edge1, *end, GEOMETRY_RESABS) ||
         [ #  # ][ #  # ]
    1312         [ #  # ]:          0 :                  within_tolerance(edge1, proj, GEOMETRY_RESABS))
    1313                 :          0 :           closest_edge = edge1;
    1314                 :            :           // If close to side of triangle, fall through to edge
    1315                 :            :           // handling code
    1316 [ #  # ][ #  # ]:          0 :         else if (within_tolerance(edge2, *end, GEOMETRY_RESABS) ||
         [ #  # ][ #  # ]
    1317         [ #  # ]:          0 :                  within_tolerance(edge2, proj, GEOMETRY_RESABS))
    1318                 :          0 :           closest_edge = edge2;
    1319                 :            :           // Insert new point in triangle interior...
    1320                 :            :         else
    1321         [ #  # ]:          0 :           point = insert_in_face (closest_face, proj);
    1322                 :            :       }
    1323                 :            :     } // if(closest_face)
    1324                 :            :     
    1325         [ #  # ]:          0 :     if (closest_edge)
    1326                 :            :     {
    1327         [ #  # ]:          0 :       PST_Point *const edge_end = closest_edge->other(start_point);
    1328                 :            :         // If edge and segment ends are equal...
    1329 [ #  # ][ #  # ]:          0 :       if ( (*edge_end - *end).length_squared() < TOL_SQR )
                 [ #  # ]
    1330                 :            :       {
    1331                 :          0 :         point = edge_end;
    1332                 :          0 :         edge = closest_edge;
    1333         [ #  # ]:          0 :         if (is_boundary_edge)
    1334                 :          0 :           end = edge_end;
    1335                 :            :       }
    1336                 :            :         // Otherwise calculate closest point
    1337                 :            :       else
    1338                 :            :       {
    1339                 :            :           // edge and segment share a start point so just need
    1340                 :            :           // to calculate the projection of each on the other.
    1341         [ #  # ]:          0 :         const CubitVector edge_tan = *edge_end - *start_point;
    1342         [ #  # ]:          0 :         const double dot_prod = seg_tan % edge_tan;
    1343         [ #  # ]:          0 :         const double t_seg  = dot_prod /  seg_tan.length_squared();
    1344         [ #  # ]:          0 :         const double t_edge = dot_prod / edge_tan.length_squared();
    1345                 :            :         
    1346 [ #  # ][ #  # ]:          0 :         const CubitVector  seg_pt = *start_point + t_seg  *  seg_tan;
    1347 [ #  # ][ #  # ]:          0 :         const CubitVector edge_pt = *start_point + t_edge * edge_tan;
    1348                 :            :         
    1349                 :            :           // Too close to start point -- skip segment
    1350 [ #  # ][ #  # ]:          0 :         if (t_edge <= 0.0 || t_seg <= 0.0 ||
                 [ #  # ]
    1351 [ #  # ][ #  # ]:          0 :             (*start_point - edge_pt).length_squared() < TOL_SQR ||
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    1352 [ #  # ][ #  # ]:          0 :             (*start_point -  seg_pt).length_squared() < TOL_SQR )
         [ #  # ][ #  # ]
    1353                 :          0 :           point = start_point;
    1354                 :            :           // If segment end is near or passed edge end, 
    1355                 :            :           // then the edge end is the intersection with this triangle
    1356 [ #  # ][ #  # ]:          0 :         else if (t_edge > 1.0 || 
    1357 [ #  # ][ #  # ]:          0 :                  (*edge_end - edge_pt).length_squared() < TOL_SQR ||
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    1358 [ #  # ][ #  # ]:          0 :                  (*edge_end -  seg_pt).length_squared() < TOL_SQR)
         [ #  # ][ #  # ]
    1359                 :            :         {
    1360                 :            :           //make sure the facet edge is not a boundary edge.
    1361 [ #  # ][ #  # ]:          0 :           if (is_boundary_edge && start_point == start)
    1362                 :          0 :             start =  edge_end;
    1363                 :          0 :           point = edge_end;
    1364                 :            :         }
    1365                 :            :           // Otherwise closest point to segment end is in the interior
    1366                 :            :           // of the edge -- split the edge.
    1367                 :            :         else
    1368                 :            :         {
    1369 [ #  # ][ #  # ]:          0 :           if(start_point != closest_edge->start_point())
    1370         [ #  # ]:          0 :             point = split_edge( closest_edge, 1.0 - t_edge );
    1371                 :            :           else
    1372         [ #  # ]:          0 :             point = split_edge( closest_edge, t_edge );
    1373                 :            :         }
    1374                 :            :       }
    1375                 :            :     } // if(closest_edge)
    1376                 :            : 
    1377         [ #  # ]:          0 :     if (point == start_point) // skip perpendicular or very short segment
    1378                 :          0 :       continue;
    1379                 :            : 
    1380         [ #  # ]:          0 :     edge = start_point->common( point );
    1381         [ #  # ]:          0 :     if (!edge)
    1382                 :            :     {
    1383                 :          0 :       assert(false);
    1384                 :            :       continue;
    1385                 :            :     }
    1386                 :            :     
    1387 [ #  # ][ #  # ]:          0 :     if ( !is_boundary_edge || start_point != start )
    1388                 :            :     { 
    1389         [ #  # ]:          0 :        PST_CoEdge* coedge = edge->end_point() == point ?
    1390 [ #  # ][ #  # ]:          0 :                             edge->forward() : edge->reverse();
                 [ #  # ]
    1391         [ #  # ]:          0 :        imprintResult.append(coedge);
    1392                 :            :     }
    1393                 :            : 
    1394 [ #  # ][ #  # ]:          0 :     if( DEBUG_FLAG( VG_FACET_DEBUG ) )
                 [ #  # ]
    1395                 :            :     {
    1396         [ #  # ]:          0 :       edge->debug_draw( VG_FACET_IMPRINT_COLOR );
    1397         [ #  # ]:          0 :       point->debug_draw( VG_FACET_IMPRINT_COLOR );
    1398                 :            :     }    
    1399                 :          0 :     start_point = point;
    1400                 :            :   }
    1401                 :            :   
    1402                 :          0 :   return CUBIT_SUCCESS;
    1403                 :            : }
    1404                 :            : 
    1405                 :            : //-------------------------------------------------------------------------
    1406                 :            : // Purpose       : Check if a point is within the passed tolerance
    1407                 :            : //                 of a bounded edge.
    1408                 :            : //
    1409                 :            : // Special Notes : 
    1410                 :            : //
    1411                 :            : // Creator       : Jason Kraftcheck
    1412                 :            : //
    1413                 :            : // Creation Date : 09/04/03
    1414                 :            : //-------------------------------------------------------------------------
    1415                 :          0 : bool FacetProjectTool::within_tolerance( PST_Edge* edge,
    1416                 :            :                                          const CubitVector& point,
    1417                 :            :                                          double tolerance )
    1418                 :            : {
    1419         [ #  # ]:          0 :   const double t_edge = edge->closest_on_edge( point );
    1420         [ #  # ]:          0 :   const CubitVector edge_pos = edge->position(t_edge);
    1421 [ #  # ][ #  # ]:          0 :   return (edge_pos - point).length_squared() < tolerance*tolerance;
    1422                 :            : }
    1423                 :            : 
    1424                 :            : //-------------------------------------------------------------------------
    1425                 :            : // Purpose       : Given a line segment beginning at a point in the
    1426                 :            : //                 triangulation, find the face or edge adjacent to the
    1427                 :            : //                 point and closest to the line segment.
    1428                 :            : //
    1429                 :            : // Special Notes : 
    1430                 :            : //
    1431                 :            : // Creator       : Jason Kraftcheck
    1432                 :            : //
    1433                 :            : // Creation Date : 09/04/03
    1434                 :            : //-------------------------------------------------------------------------
    1435                 :          0 : CubitStatus FacetProjectTool::next_around_point ( PST_Point*& start,
    1436                 :            :                                         const CubitVector& seg_end,
    1437                 :            :                                         PST_Face*& closest_face,
    1438                 :            :                                         PST_Edge*& closest_edge,
    1439                 :            :                                         CubitBoolean & is_boundary_edge,
    1440                 :            :                                         PST_Edge *last_closest_edge)
    1441                 :            : {
    1442         [ #  # ]:          0 :   DLIList<PST_Face*> face_list;
    1443 [ #  # ][ #  # ]:          0 :   DLIList<PST_Edge*> boundary_edges;
    1444                 :          0 :   is_boundary_edge = CUBIT_FALSE; 
    1445                 :          0 :   double shortest_dist_sqr = CUBIT_DBL_MAX;
    1446                 :          0 :   closest_face = 0;
    1447                 :          0 :   closest_edge = 0;
    1448                 :            :   
    1449                 :            :   //const double TOL_SQR = GEOMETRY_RESABS*GEOMETRY_RESABS;
    1450                 :            :   
    1451         [ #  # ]:          0 :   const CubitVector tangent = seg_end - *start;
    1452                 :            :    
    1453                 :            :     // To traverse the edges in clockwise order about the point,
    1454                 :            :     // it is necessary to start with the appropriate boundary edge
    1455                 :            :     // if there is one.  If this point is not on the boundary of 
    1456                 :            :     // the facet patch, any edge is acceptable.
    1457                 :            : 
    1458                 :            :     // First mark all faces adjacent to the vertex.  This is to make
    1459                 :            :     // sure disjoint sets of faces (sets of faces with no edges in
    1460                 :            :     // common) are not missed when traversing edge-face adjacencies.
    1461         [ #  # ]:          0 :   start->faces( &face_list );
    1462 [ #  # ][ #  # ]:          0 :   for (int i = face_list.size(); i--; )  
    1463         [ #  # ]:          0 :     face_list.step_and_get()->mark = true;
    1464                 :            :   
    1465                 :            :     // Loop until all faces in face_list have been un-marked
    1466         [ #  # ]:          0 :   boundary_edges.clean_out();
    1467                 :          0 :   closest_edge = 0;
    1468                 :          0 :   closest_face = 0; 
    1469 [ #  # ][ #  # ]:          0 :   while (face_list.size())
    1470                 :            :   {
    1471         [ #  # ]:          0 :     PST_Face* face = face_list.pop();
    1472         [ #  # ]:          0 :     if (!face->mark)
    1473                 :          0 :       continue;
    1474                 :            : 
    1475         [ #  # ]:          0 :     PST_CoEdge* coedge = face->first_coedge();
    1476 [ #  # ][ #  # ]:          0 :     if (coedge->edge()->other(start) == 0)
                 [ #  # ]
    1477         [ #  # ]:          0 :       coedge = coedge->next();
    1478                 :            : 
    1479                 :            :       // search for the 'first' coedge in the clockwise list.
    1480                 :          0 :     PST_CoEdge* first = coedge;
    1481 [ #  # ][ #  # ]:          0 :     while (coedge->face())
    1482                 :            :     {
    1483 [ #  # ][ #  # ]:          0 :       if (coedge->end_point() == start)
    1484         [ #  # ]:          0 :         coedge = coedge->other();
    1485                 :            :       else
    1486         [ #  # ]:          0 :         coedge = coedge->previous();
    1487                 :            : 
    1488         [ #  # ]:          0 :       if (coedge == first) // no start, point is not on boundary
    1489                 :          0 :         break;
    1490                 :            :     }
    1491                 :            : 
    1492                 :            :       // keep boundary edges encountered for later
    1493 [ #  # ][ #  # ]:          0 :     if (!coedge->face())
    1494 [ #  # ][ #  # ]:          0 :       boundary_edges.append(coedge->edge());
    1495                 :            : 
    1496                 :            :       // Of the two edges on the face that are adjacent to the
    1497                 :            :       // point, begin with the one that is first in clockwise
    1498                 :            :       // order around the point.
    1499 [ #  # ][ #  # ]:          0 :     if (coedge->start_point() == start)
    1500         [ #  # ]:          0 :       coedge = coedge->other();
    1501                 :          0 :     first = coedge;
    1502                 :            : 
    1503                 :            :       // Traverse adjacent facets in clockwise order
    1504                 :            :       // around point.
    1505                 :          0 :     bool clockwise_of_prev = false;
    1506 [ #  # ][ #  # ]:          0 :     while ( (face = coedge->face()) )
    1507                 :            :     {
    1508                 :          0 :       face->mark = false;
    1509                 :            : 
    1510                 :            :         // get vectors for edges of face pointing outwards
    1511                 :            :         // from vertex.
    1512 [ #  # ][ #  # ]:          0 :       assert(coedge->end_point() == start && coedge->next()->start_point() == start);
         [ #  # ][ #  # ]
                 [ #  # ]
    1513 [ #  # ][ #  # ]:          0 :       CubitVector prev = coedge->other()->direction();
    1514 [ #  # ][ #  # ]:          0 :       CubitVector next = coedge->next()->direction();
    1515                 :            : 
    1516                 :            :         // calculate if segment is to the 'inside' of each
    1517                 :            :         // adjacent edge.
    1518         [ #  # ]:          0 :       CubitVector normal = next * prev;  // ccw 
    1519 [ #  # ][ #  # ]:          0 :       bool inside_prev = ((tangent * prev) % normal) >= 0.0;
    1520 [ #  # ][ #  # ]:          0 :       bool inside_next = ((next * tangent) % normal) >= 0.0;
    1521                 :            : 
    1522                 :            :         // If edge is inside face, check distance from face
    1523 [ #  # ][ #  # ]:          0 :       if( (inside_prev && inside_next) )
    1524                 :            :       {
    1525                 :            :         // calculate distance from end point to plane of face
    1526         [ #  # ]:          0 :         const double plane_coeff = normal % *start;
    1527         [ #  # ]:          0 :         const double end_coeff = normal % seg_end;
    1528                 :          0 :         const double numerator = end_coeff - plane_coeff;
    1529         [ #  # ]:          0 :         const double dist_sqr = (numerator * numerator) / normal.length_squared();         
    1530                 :            :         
    1531         [ #  # ]:          0 :         if (dist_sqr < shortest_dist_sqr)
    1532                 :            :         {
    1533                 :          0 :           closest_face = face;
    1534                 :          0 :           closest_edge = 0;
    1535                 :          0 :           shortest_dist_sqr = dist_sqr;
    1536                 :            :         }
    1537                 :            : 
    1538                 :          0 :         clockwise_of_prev = false;
    1539                 :            :       }
    1540                 :            :         // If the edge is above a peak formed by the shared edge of two faces
    1541 [ #  # ][ #  # ]:          0 :       else if (inside_next && clockwise_of_prev)
    1542                 :            :       {
    1543                 :            :           // calculate distance from end of segment to line of facet edge
    1544         [ #  # ]:          0 :         const double dot_prod = tangent % prev;
    1545                 :            :         const double dist_sqr = 
    1546 [ #  # ][ #  # ]:          0 :           tangent.length_squared() - dot_prod * dot_prod / prev.length_squared();
    1547                 :            : 
    1548 [ #  # ][ #  # ]:          0 :         if (dist_sqr <= shortest_dist_sqr && coedge->edge() != last_closest_edge)
         [ #  # ][ #  # ]
    1549                 :            :         {
    1550                 :          0 :           closest_face = 0;
    1551         [ #  # ]:          0 :           closest_edge = coedge->edge();
    1552                 :          0 :           shortest_dist_sqr = dist_sqr;
    1553                 :            :         }
    1554                 :          0 :         clockwise_of_prev = false;
    1555                 :            :       }
    1556                 :            :         // If clockwise of the face, note for next iteration
    1557         [ #  # ]:          0 :       else if (inside_prev)
    1558                 :            :       {
    1559                 :          0 :         clockwise_of_prev = true;
    1560                 :            :       }
    1561                 :            :       else
    1562                 :            :       {
    1563                 :          0 :         clockwise_of_prev = false;
    1564                 :            :       }  
    1565                 :            : 
    1566 [ #  # ][ #  # ]:          0 :       coedge = coedge->next()->other();
    1567         [ #  # ]:          0 :       if (coedge == first)
    1568                 :          0 :         break;
    1569                 :            :     } // while(coedge->face())
    1570                 :            :     
    1571 [ #  # ][ #  # ]:          0 :     if (!coedge->face())
    1572 [ #  # ][ #  # ]:          0 :       boundary_edges.append(coedge->edge());
    1573                 :            :   
    1574                 :            :   } // while(face_list.size())
    1575                 :            :   
    1576                 :            :     // If a closest entity was found, then done.
    1577 [ #  # ][ #  # ]:          0 :   if (closest_face || closest_edge)
    1578                 :          0 :     return CUBIT_SUCCESS;
    1579                 :            :     
    1580                 :            : 
    1581                 :            :   //Here we try to intersect the segment with the boundary 
    1582                 :            :   //facet edge closest to 'start' (farthest from 'end')
    1583                 :          0 :   bool debug = false;
    1584         [ #  # ]:          0 :   if( !closest_edge )
    1585                 :            :   {
    1586         [ #  # ]:          0 :     CubitVector seg_direction = seg_end - *start;   
    1587         [ #  # ]:          0 :     double seg_length = seg_direction.length();
    1588                 :          0 :     double longest_length = 0;            
    1589                 :            :     
    1590         [ #  # ]:          0 :     if( debug )
    1591                 :            :     {
    1592         [ #  # ]:          0 :       GfxDebug::clear(); 
    1593         [ #  # ]:          0 :       start->debug_draw(CUBIT_GREEN_INDEX);
    1594         [ #  # ]:          0 :       GfxDebug::draw_point( seg_end, CUBIT_RED_INDEX );
    1595 [ #  # ][ #  # ]:          0 :       for( int j=facetList.size(); j--; )
    1596 [ #  # ][ #  # ]:          0 :         facetList.get_and_step()->debug_draw( CUBIT_CYAN_INDEX );
    1597         [ #  # ]:          0 :       GfxDebug::mouse_xforms(); 
    1598                 :            :     }
    1599                 :            :     
    1600                 :            :     //find the farthest boundary edge that is on the line segment    
    1601         [ #  # ]:          0 :     CubitVector split_position;
    1602 [ #  # ][ #  # ]:          0 :     for( int k=boundaryList.size(); k--; )
    1603                 :            :     {
    1604         [ #  # ]:          0 :       PST_Edge *tmp_edge = boundaryList.get_and_step();
    1605                 :            : 
    1606 [ #  # ][ #  # ]:          0 :       if( tmp_edge->start_point() == start ||
         [ #  # ][ #  # ]
    1607         [ #  # ]:          0 :           tmp_edge->end_point() == start )
    1608                 :          0 :           continue;      
    1609                 :            : 
    1610 [ #  # ][ #  # ]:          0 :       double t1 = tmp_edge->closest_on_line( *start, seg_end - *start );
    1611                 :            :       
    1612 [ #  # ][ #  # ]:          0 :       if( t1 > 1e-6 && t1 < 1 )
    1613                 :            :       { 
    1614         [ #  # ]:          0 :         CubitVector tmp_pos = tmp_edge->position( t1 );
    1615                 :            : 
    1616         [ #  # ]:          0 :         if( debug )
    1617                 :            :         {
    1618         [ #  # ]:          0 :           GfxDebug::draw_line( *start, seg_end, CUBIT_MAGENTA_INDEX );
    1619 [ #  # ][ #  # ]:          0 :           PRINT_INFO("t1 = %f\n", t1 );
         [ #  # ][ #  # ]
    1620         [ #  # ]:          0 :           tmp_edge->debug_draw( CUBIT_YELLOW_INDEX );
    1621         [ #  # ]:          0 :           GfxDebug::draw_point( tmp_pos, CUBIT_RED_INDEX );        
    1622         [ #  # ]:          0 :           GfxDebug::flush();
    1623         [ #  # ]:          0 :           GfxDebug::mouse_xforms(); 
    1624                 :            :         }
    1625                 :            : 
    1626         [ #  # ]:          0 :         double tmp_dist = tmp_pos.distance_between( seg_end );
    1627                 :            : 
    1628 [ #  # ][ #  # ]:          0 :         if( tmp_dist > longest_length && tmp_dist < seg_length )
    1629                 :            :         {
    1630                 :          0 :           longest_length = tmp_dist;
    1631                 :          0 :           closest_edge = tmp_edge;
    1632         [ #  # ]:          0 :           split_position = tmp_pos;
    1633                 :            :         }
    1634                 :            :       }
    1635                 :            :     }
    1636                 :            :     
    1637         [ #  # ]:          0 :     if( closest_edge )
    1638                 :            :     {
    1639         [ #  # ]:          0 :       start = project( split_position );    
    1640                 :            : 
    1641                 :            :       CubitStatus my_stat = next_around_point( start, seg_end, closest_face, 
    1642         [ #  # ]:          0 :         closest_edge, is_boundary_edge, last_closest_edge );
    1643                 :            : 
    1644         [ #  # ]:          0 :       if( CUBIT_FAILURE == my_stat )
    1645                 :          0 :         return CUBIT_FAILURE;
    1646                 :            :      
    1647         [ #  # ]:          0 :       return closest_face ? CUBIT_SUCCESS : CUBIT_FAILURE;      
    1648                 :            :     }   
    1649                 :            :   } 
    1650                 :            :   
    1651 [ #  # ][ #  # ]:          0 :   return closest_edge ? CUBIT_SUCCESS : CUBIT_FAILURE;
    1652                 :            : }
    1653                 :            : 
    1654                 :            :   
    1655                 :            :   
    1656                 :            :     
    1657                 :            :   
    1658                 :            : 
    1659                 :            : //-------------------------------------------------------------------------
    1660                 :            : // Purpose       : Remove duplciate edges from results if input polyline
    1661                 :            : //                 was self-intersecting.
    1662                 :            : //
    1663                 :            : // Special Notes : 
    1664                 :            : //
    1665                 :            : // Creator       : Jason Kraftcheck
    1666                 :            : //
    1667                 :            : // Creation Date : ??
    1668                 :            : //-------------------------------------------------------------------------
    1669                 :          0 : void FacetProjectTool::finalize_results()
    1670                 :            : {
    1671                 :          0 :   imprintResult.reset();
    1672         [ #  # ]:          0 :   for ( int i = imprintResult.size(); i--; )
    1673                 :            :   {
    1674                 :          0 :     PST_Edge* edge = imprintResult.step_and_get()->edge();
    1675         [ #  # ]:          0 :     if (edge->mark)
    1676                 :          0 :       imprintResult.change_to(0);
    1677                 :            :     else
    1678                 :          0 :       edge->mark = 1;
    1679                 :            :   }
    1680         [ #  # ]:          0 :   imprintResult.remove_all_with_value(0);
    1681                 :          0 :   imprintResult.reset();
    1682                 :          0 : }
    1683                 :            : 
    1684                 :            : //-------------------------------------------------------------------------
    1685                 :            : // Purpose       : Return non-intersecting chains of result edges, in the
    1686                 :            : //                 same sequence as the input polyline and with the same
    1687                 :            : //                 orientation.
    1688                 :            : //
    1689                 :            : // Special Notes : This is called after the projection is done to get the
    1690                 :            : //                 resulting facet edge chains.
    1691                 :            : //
    1692                 :            : // Creator       : Jason Kraftcheck
    1693                 :            : //
    1694                 :            : // Creation Date : 09/04/03
    1695                 :            : //-------------------------------------------------------------------------
    1696                 :          0 : CubitStatus FacetProjectTool::get_result_set( DLIList<PST_CoEdge*>& coedges )
    1697                 :            : {
    1698 [ #  # ][ #  # ]:          0 :   if ( !imprintResult.size() )
    1699                 :          0 :     return CUBIT_FAILURE;
    1700                 :            :   
    1701         [ #  # ]:          0 :   imprintResult.reset();
    1702         [ #  # ]:          0 :   PST_CoEdge* prev = imprintResult.get();
    1703         [ #  # ]:          0 :   imprintResult.change_to(0);
    1704         [ #  # ]:          0 :   coedges.append(prev);
    1705                 :            :   
    1706 [ #  # ][ #  # ]:          0 :   for ( int i = imprintResult.size() - 1; i--; )
    1707                 :            :   {
    1708         [ #  # ]:          0 :     PST_CoEdge* coedge = imprintResult.step_and_get();
    1709         [ #  # ]:          0 :     PST_Point* pt = prev->end_point();
    1710 [ #  # ][ #  # ]:          0 :     if (pt != coedge->start_point())
    1711                 :          0 :       break;
    1712                 :            :     
    1713                 :          0 :     int count = 1;
    1714 [ #  # ][ #  # ]:          0 :     for (PST_Edge* pt_edge = pt->next(coedge->edge());
         [ #  # ][ #  # ]
    1715         [ #  # ]:          0 :          pt_edge != coedge->edge();
    1716                 :            :          pt_edge = pt->next(pt_edge))
    1717                 :            :     {
    1718         [ #  # ]:          0 :       if (pt_edge->mark)
    1719                 :          0 :         count++;
    1720                 :            :     }
    1721                 :            :      
    1722         [ #  # ]:          0 :     if (count != 2)
    1723                 :          0 :       break;
    1724                 :            :     
    1725         [ #  # ]:          0 :     coedges.append(coedge);
    1726                 :          0 :     prev = coedge;
    1727         [ #  # ]:          0 :     imprintResult.change_to(0);
    1728                 :            :   }
    1729                 :            :   
    1730         [ #  # ]:          0 :   imprintResult.remove_all_with_value(0);
    1731                 :          0 :   return CUBIT_SUCCESS;
    1732                 :            : }
    1733                 :            : 
    1734                 :            : 
    1735                 :          0 : double FacetProjectTool::closest_on_line( const CubitVector& B,
    1736                 :            :                                       const CubitVector& M,
    1737                 :            :                                       const CubitVector& P ) 
    1738                 :            : { 
    1739                 :          0 :   const double dist_tol_sqr = GEOMETRY_RESABS*GEOMETRY_RESABS;
    1740                 :          0 :   double D = M.length_squared();
    1741 [ #  # ][ #  # ]:          0 :   return (D < dist_tol_sqr ) ? 0.0 : (M % (P - B)) / D;
         [ #  # ][ #  # ]
                 [ #  # ]
    1742                 :            : }
    1743                 :            : 
    1744                 :            : 
    1745                 :          0 : void FacetProjectTool::closest_on_lines( const CubitVector& B1,
    1746                 :            :                                      const CubitVector& M1,
    1747                 :            :                                      const CubitVector& B2,
    1748                 :            :                                      const CubitVector& M2,
    1749                 :            :                                      double& t1, double& t2 ) 
    1750                 :            : {
    1751 [ #  # ][ #  # ]:          0 :   CubitVector N = M2 * (M2 * M1);
    1752         [ #  # ]:          0 :   double d = N % M1;
    1753         [ #  # ]:          0 :   if( fabs(d) < CUBIT_RESABS ) //parallel lines
    1754                 :          0 :     t1 = 0.0;
    1755                 :            :   else
    1756 [ #  # ][ #  # ]:          0 :     t1 = ((N % B2) - (N % B1)) / d;
    1757                 :            : 
    1758 [ #  # ][ #  # ]:          0 :   t2 = closest_on_line( B2, M2, B1 + t1 * M1 );
                 [ #  # ]
    1759                 :          0 : }
    1760                 :            :   
    1761                 :            :       
    1762                 :          0 : bool FacetProjectTool::inside_face( PST_Face* face, const CubitVector& pos )
    1763                 :            : {      
    1764                 :            :     // This code checks if the position is in the interior of 
    1765                 :            :     // the prism formed by sweeping the facet infinetly in the
    1766                 :            :     // direction of, and opposite direction of the facet normal.
    1767                 :          0 :   PST_CoEdge* coe = face->first_coedge();
    1768         [ #  # ]:          0 :   do {
    1769         [ #  # ]:          0 :     CubitVector vect( pos );
    1770 [ #  # ][ #  # ]:          0 :     vect -= *coe->start_point();
    1771 [ #  # ][ #  # ]:          0 :     vect *= coe->direction();
    1772 [ #  # ][ #  # ]:          0 :     if( vect % face->normal() > -CUBIT_RESABS )
                 [ #  # ]
    1773                 :          0 :       return false;
    1774         [ #  # ]:          0 :     coe = coe->next();
    1775                 :          0 :   } while( coe != face->first_coedge() );
    1776                 :          0 :   return true;
    1777                 :            : }
    1778                 :            : 
    1779                 :            : /*
    1780                 :            : static void draw_pt( const std::vector<double>& list, int index, int color )
    1781                 :            : {
    1782                 :            :   GfxDebug::draw_point( 
    1783                 :            :     (float)list[index], (float)list[index+1], (float)list[index+2], color );
    1784                 :            : }
    1785                 :            : 
    1786                 :            : static void draw_edge( const std::vector<double>& list, int i1, int i2, int color )
    1787                 :            : {
    1788                 :            :   i1 *= 3; i2 *= 3;
    1789                 :            :   GfxDebug::draw_line(
    1790                 :            :     (float)list[i1], (float)list[i1+1], (float)list[i1+2],
    1791                 :            :     (float)list[i2], (float)list[i2+1], (float)list[i2+2],
    1792                 :            :     color );
    1793                 :            : }
    1794                 :            : 
    1795                 :            : static void draw_tri( const std::vector<double>& pts,
    1796                 :            :                       const std::vector<int>& tris, int index, 
    1797                 :            :                       const std::vector<int>& seq, int color )
    1798                 :            : {
    1799                 :            :   for ( int i = 0; i < 3; i++ )
    1800                 :            :   {
    1801                 :            :     int i1 = tris[index + i];
    1802                 :            :     int i2 = tris[index + (i + 1) % 3];
    1803                 :            :     if ( !seq[i1] || !seq[i2] || abs(seq[i1]-seq[i2]) != 1 )
    1804                 :            :       draw_edge( pts, i1, i2, color );
    1805                 :            :   }
    1806                 :            : }
    1807                 :            : */
    1808                 :            : 
    1809                 :          0 : void FacetProjectTool::debug( DLIList<CubitVector*>& segments,
    1810                 :            :                               std::vector<double>& coordinates,
    1811                 :            :                               std::vector<int>& connections )
    1812                 :            : {
    1813                 :            : #if 1 /* test with old interface */  
    1814         [ #  # ]:          0 :   DLIList<PST_Edge*> edges;
    1815         [ #  # ]:          0 :   PST_Edge::make_facets(coordinates, connections, GEOMETRY_RESABS, edges);
    1816                 :            :   
    1817 [ #  # ][ #  # ]:          0 :   DLIList<PST_Face*> faces;
    1818         [ #  # ]:          0 :   PST_Edge::faces( edges, faces );
    1819         [ #  # ]:          0 :   populate_data(faces);
    1820                 :            :   
    1821                 :            :   CubitBoolean point_changed;
    1822         [ #  # ]:          0 :   do_projection( segments, point_changed );
    1823                 :            :   
    1824         [ #  # ]:          0 :   PST_Edge::debug_draw_edges( edgeList, CUBIT_BLUE_INDEX );
    1825                 :            :   
    1826 [ #  # ][ #  # ]:          0 :   DLIList<PST_CoEdge*> coedges;
    1827         [ #  # ]:          0 :   finalize_results();
    1828 [ #  # ][ #  # ]:          0 :   while( get_result_set( coedges ) ) {
    1829         [ #  # ]:          0 :     edges.clean_out();
    1830         [ #  # ]:          0 :     coedges.reverse();
    1831 [ #  # ][ #  # ]:          0 :     while (coedges.size()) edges.append(coedges.pop()->edge());
         [ #  # ][ #  # ]
                 [ #  # ]
    1832         [ #  # ]:          0 :     PST_Edge::debug_draw_edges( edges, CUBIT_WHITE_INDEX );
    1833         [ #  # ]:          0 :     PST_Edge::debug_draw_points( edges, CUBIT_WHITE_INDEX );
    1834                 :            :   }
    1835                 :            : 
    1836                 :            : #else /* test with new interface */
    1837                 :            : 
    1838                 :            :   int i, j;
    1839                 :            : 
    1840                 :            :     // do projection
    1841                 :            :   std::vector<double> new_pts;
    1842                 :            :   std::vector<int> dudded, new_facets, facet_index, polyline;
    1843                 :            :   if( !project( segments, coordinates, connections, dudded, 
    1844                 :            :                 new_facets, facet_index, new_pts, polyline ) )
    1845                 :            :   {
    1846                 :            :     PRINT_ERROR("FacetProjectTool::project returned CUBIT_FAILURE\n");
    1847                 :            :     return;
    1848                 :            :   } 
    1849                 :            :   
    1850                 :            :   assert( connections.size() % 3 == 0 );
    1851                 :            :   assert( coordinates.size() % 3 == 0 );
    1852                 :            :   assert( new_facets.size() % 3 == 0 );
    1853                 :            :   assert( new_pts.size() % 3 == 0 );
    1854                 :            :   assert( dudded.size() == facet_index.size() );
    1855                 :            :   int num_old_tri = connections.size() / 3;
    1856                 :            :   int num_new_tri = new_facets.size() / 3;
    1857                 :            :   int num_old_pts = coordinates.size() / 3;
    1858                 :            :   int num_new_pts = new_pts.size() / 3;
    1859                 :            :   int num_tot_tri = num_new_tri + num_old_tri;
    1860                 :            :   int num_tot_pts = num_new_pts + num_old_pts;
    1861                 :            :   
    1862                 :            :   PRINT_INFO("%d input triangles using %d points.\n", num_old_tri, num_old_pts );
    1863                 :            :   PRINT_INFO("%d new triangles and %d new poitns.\n", num_new_tri, num_new_pts );
    1864                 :            :   PRINT_INFO("%d total triangles using %d total points.\n", num_tot_tri, num_tot_pts );
    1865                 :            :   PRINT_INFO("connections.size() = %d\n", (int)connections.size());
    1866                 :            :   PRINT_INFO("coordinates.size() = %d\n", (int)coordinates.size());
    1867                 :            :   PRINT_INFO("dudded.size() = %d\n", (int)dudded.size());
    1868                 :            :   PRINT_INFO("new_facets.size() = %d\n", (int)new_facets.size());
    1869                 :            :   PRINT_INFO("facet_index.size() = %d\n", (int)facet_index.size());
    1870                 :            :   PRINT_INFO("new_pts.size() = %d\n", (int)new_pts.size());
    1871                 :            :   PRINT_INFO("polyline.size() = %d\n", (int)polyline.size());
    1872                 :            :   
    1873                 :            :   for ( i = 0; i < (int)new_facets.size(); i++ )
    1874                 :            :     if ( new_facets[i] >= num_tot_pts || new_facets[i] < 0 )
    1875                 :            :       PRINT_ERROR("Invalid value %d at new_facets[%d]\n", new_facets[i], i);
    1876                 :            :   for ( i = 0; i < (int)dudded.size(); i++ )
    1877                 :            :     if ( dudded[i] >= num_old_tri || dudded[i] < 0 )
    1878                 :            :       PRINT_ERROR("Invalid value %d at dudded[%d]\n", dudded[i], i);
    1879                 :            :   for ( i = 0; i < (int)polyline.size()-1; )
    1880                 :            :   {
    1881                 :            :     int count = polyline[i];
    1882                 :            :     if ( count < 2 )
    1883                 :            :       PRINT_ERROR("Invalid polyline length %d at polyline[%d]\n", count, i );
    1884                 :            :     i++;
    1885                 :            :     for ( j = 0; j < count; j++, i++ )
    1886                 :            :     {
    1887                 :            :       if( i >= (int)polyline.size() )
    1888                 :            :         PRINT_ERROR("Ran out of indices in polyline.\n");
    1889                 :            :       if ( polyline[i] >= num_tot_pts || polyline[i] < 0 )
    1890                 :            :         PRINT_ERROR("Invalid value %d at dudded[%d]\n", dudded[i], i);
    1891                 :            :     }
    1892                 :            :   }
    1893                 :            :   
    1894                 :            :     // draw original points
    1895                 :            :   for ( i = 0; i < (int)coordinates.size(); i += 3 )
    1896                 :            :     draw_pt( coordinates, i, CUBIT_BLUE_INDEX );
    1897                 :            : /*  
    1898                 :            :     // draw new points
    1899                 :            :   for ( i = 0; i < (int)new_pts.size(); i += 3 )
    1900                 :            :     draw_pt( new_pts, i, CUBIT_RED_INDEX ); 
    1901                 :            : */  
    1902                 :            :     // concatenate point lists
    1903                 :            :   for ( i = 0; i < (int)new_pts.size(); i++ )
    1904                 :            :     coordinates.push_back(new_pts[i]);
    1905                 :            :   
    1906                 :            :     // make reverse mapping for dudded facets
    1907                 :            :   std::vector<bool> dead(connections.size()/3);
    1908                 :            :   for ( i = 0; i < (int)dead.size(); i++ )
    1909                 :            :     dead[i] = false;
    1910                 :            :   for ( i = 0; i < (int)dudded.size(); i++ )
    1911                 :            :     dead[dudded[i]] = true;
    1912                 :            :     
    1913                 :            :     // make polyline sequence list (this won't work quite
    1914                 :            :     // right for self-intersecting polylines -- *shrug*)
    1915                 :            :   std::vector<int> sequence(coordinates.size() / 3);
    1916                 :            :   for ( i = 0; i < (int)sequence.size(); i++ )
    1917                 :            :     sequence[i] = 0;
    1918                 :            :   j = 0;
    1919                 :            :   for ( i = 0; i < (int)polyline.size(); i++ )
    1920                 :            :     sequence[polyline[i]] = ++j;
    1921                 :            :   
    1922                 :            :   
    1923                 :            :     // draw orginal facets
    1924                 :            :   for ( i = 0; i < (int)dead.size(); i++ )
    1925                 :            :     if( ! dead[i] )
    1926                 :            :       draw_tri( coordinates, connections, 3*i, sequence, CUBIT_BLUE_INDEX );
    1927                 :            :   
    1928                 :            :     // draw new facets
    1929                 :            :   for ( i = 0; i < (int)new_facets.size(); i += 3 )
    1930                 :            :     draw_tri( coordinates, new_facets, i, sequence, CUBIT_RED_INDEX );
    1931                 :            :   
    1932                 :            :     // draw polyline
    1933                 :            :   for ( i = 0; i < (int)polyline.size()-1; i++)
    1934                 :            :   {
    1935                 :            :     int count = polyline[i];
    1936                 :            :     if ( count < 2 )
    1937                 :            :       PRINT_ERROR("Invalid polyline length %d at polyline[%d]\n", count, i );
    1938                 :            :     int first = ++i;
    1939                 :            :     for ( j = 0; j < count-1; j++, i++ )
    1940                 :            :     {
    1941                 :            :       draw_edge( coordinates, polyline[i], polyline[i+1], CUBIT_WHITE_INDEX );
    1942                 :            :     }
    1943                 :            :     if( polyline[first] == polyline[i] )
    1944                 :            :       PRINT_INFO("Polyline is closed.\n");
    1945                 :            :   }
    1946                 :            : 
    1947                 :            :   GfxDebug::flush();
    1948                 :            : #endif
    1949 [ #  # ][ #  # ]:          0 :   cleanup();  
    1950 [ +  - ][ +  - ]:       6540 : }
    1951                 :            : 

Generated by: LCOV version 1.11