cgma
CurveFacetEvalTool.cpp
Go to the documentation of this file.
00001 //- Class: CurveFacetEvalTool
00002 //- Description:  The CurveFacetEvalTool is a tool to perform generic geometric 
00003 //-               operations on a set of facets.
00004 //- Assumptions:  All of the facets are connected topologically correct.
00005 //-
00006 //- Owner: Steve J. Owen
00007 //- Checked by: 
00008 
00009 #include "CubitVector.hpp"
00010 #include "CubitPoint.hpp"
00011 #include "CubitFacet.hpp"
00012 #include "CubitFacetEdge.hpp"
00013 #include "CubitFacetEdgeData.hpp"
00014 #include "CubitBox.hpp"
00015 #include "DLIList.hpp"
00016 #include "CurveFacetEvalTool.hpp"
00017 #include "FacetEvalTool.hpp"
00018 #include "GeometryDefines.h"
00019 #include "CastTo.hpp"
00020 #include "GfxDebug.hpp"
00021 #include "CubitFileIOWrapper.hpp"
00022 #include "Cholla.h"
00023 #include "FacetDataUtil.hpp"
00024 
00025 //===========================================================================
00026 //Function Name: initialize
00027 //
00028 //Member Type:  PUBLIC
00029 //Description:  initialize a CurveFacetEvalTool - uses end locations of the curve
00030 //              (does geometric comparisons to match facet points)
00031 //===========================================================================
00032 CubitStatus CurveFacetEvalTool::initialize(
00033   FacetEvalTool *surf_eval_tool,   // the adjacent surface facet eval tool
00034   CubitVector &start, CubitVector &end,  // begin and end vertex  
00035   CubitSense orientation_wrt_surface )  // direction wrt the surface  
00036 {
00037 //   static int counter = 0;
00038   output_id = -1;
00039   myBBox = NULL;
00040 
00041   surfFacetEvalTool = surf_eval_tool;  
00042 
00043   CubitStatus stat = get_segments_from_loops( surfFacetEvalTool->loops(), start, end, 
00044                            myEdgeList, myPointList, orientation_wrt_surface );
00045   goodCurveData = (stat == CUBIT_SUCCESS) ? CUBIT_TRUE : CUBIT_FALSE;
00046   if( !goodCurveData )
00047   {
00048     PRINT_ERROR( "Unable to initialize Curve Evaluation Tool for Faceted Geometry.\n" );
00049     return CUBIT_FAILURE;
00050   }
00051 
00052   interpOrder = surfFacetEvalTool->interp_order();
00053   curvSense = find_curv_sense( start );
00054   bounding_box();
00055   return CUBIT_SUCCESS;
00056 }
00057 
00058 CubitStatus CurveFacetEvalTool::initialize(
00059   FacetEvalTool *surf_eval_tool,   // the adjacent surface facet eval tool
00060   CubitVector &start, // begin vertex  
00061   std::vector<CubitVector> &positions )  
00062 {
00063 //   static int counter = 0;
00064   output_id = -1;
00065   myBBox = NULL;
00066 
00067   surfFacetEvalTool = surf_eval_tool;  
00068   
00069   CubitStatus stat = get_segments_from_positions( positions, start,
00070                            myEdgeList, myPointList ); 
00071 
00072   goodCurveData = (stat == CUBIT_SUCCESS) ? CUBIT_TRUE : CUBIT_FALSE;
00073   if( !goodCurveData )
00074   {
00075     PRINT_ERROR( "Unable to initialize Curve Evaluation Tool for Faceted Geometry.\n" );
00076     return CUBIT_FAILURE;
00077   }
00078   
00079   interpOrder = surfFacetEvalTool->interp_order();
00080   curvSense = find_curv_sense( start );
00081   bounding_box();
00082   return CUBIT_SUCCESS;
00083 }
00084 
00085 //===========================================================================
00086 //Function Name: initialize
00087 //
00088 //Member Type:  PUBLIC
00089 //Description:  initialize a CurveFacetEvalTool - uses end point pointers of the curve
00090 //===========================================================================
00091 CubitStatus CurveFacetEvalTool::initialize(
00092   FacetEvalTool *surf_eval_tool,             // the adjacent surface facet eval tool
00093   CubitPoint *start_pt, CubitPoint *end_pt,  // begin and end points  
00094   CubitSense orientation_wrt_surf )          // direction wrt the surface
00095 {
00096 //   static int counter = 0;
00097   output_id = -1;
00098 
00099   myBBox = NULL;
00100   surfFacetEvalTool = surf_eval_tool;
00101   CubitStatus stat = get_segments_from_loops( surfFacetEvalTool->loops(), 
00102                                               start_pt, end_pt, 
00103                                               myEdgeList, myPointList,
00104                                               orientation_wrt_surf );
00105   goodCurveData = (stat == CUBIT_SUCCESS) ? CUBIT_TRUE : CUBIT_FALSE;
00106   if( !goodCurveData )
00107   {
00108     PRINT_ERROR( "Unable to initialize Curve Evaluation Tool for Faceted Geometry.\n" );
00109     return CUBIT_FAILURE;
00110   }
00111   interpOrder = surfFacetEvalTool->interp_order();
00112   curvSense = find_curv_sense( start_pt );
00113   bounding_box();
00114   return CUBIT_SUCCESS;
00115 }
00116 
00117 //===========================================================================
00118 //Function Name: CurveFacetEvalTool
00119 //
00120 //Member Type:  PUBLIC
00121 //Description:  initialize a CurveFacetEvalTool - uses an existing set of
00122 //              ordered facet edges to define curve
00123 //===========================================================================
00124 CubitStatus CurveFacetEvalTool::initialize(
00125   DLIList<CubitFacetEdge*> &edge_list, // the ordered facet edges on this curve
00126   DLIList<CubitPoint*> &point_list, FacetEvalTool* surf_eval)    // the ordered points on this curve
00127 {
00128 //   static int counter = 0;
00129   output_id = -1;
00130   myBBox = NULL;
00131   curvSense = CUBIT_FORWARD;
00132   surfFacetEvalTool = surf_eval;
00133   myEdgeList = edge_list;
00134   myPointList = point_list;
00135   set_length();
00136   
00137   CubitStatus status = fix_point_edge_order();
00138 
00139   if( CUBIT_SUCCESS != status )
00140     return status;
00141 
00142   interpOrder = 0;
00143   if(surf_eval)
00144     interpOrder = surf_eval->interp_order();
00145   bounding_box();
00146   goodCurveData = CUBIT_TRUE;
00147   return CUBIT_SUCCESS;
00148 }
00149 
00150 CurveFacetEvalTool::CurveFacetEvalTool()
00151 {
00152   static int counter = 0;
00153   toolID = counter++;
00154   myBBox = NULL;
00155   goodCurveData = CUBIT_TRUE;
00156   
00157 }
00158 //===========================================================================
00159 //Function Name: ~CurveFacetEvalTool
00160 //
00161 //Member Type:  PUBLIC
00162 //Description:  destructor
00163 //===========================================================================
00164 CurveFacetEvalTool::~CurveFacetEvalTool()
00165 {
00166   if ( myBBox ) delete myBBox;
00167   destroy_facets();
00168 }
00169 
00170 //===========================================================================
00171 //Function Name: get_segments_from_loops
00172 //
00173 //Member Type:  PRIVATE
00174 //Description:  extract the facet edges from the loops list that are 
00175 //              used for the current curve.  Uses CubitVectors at curve
00176 //              ends to determine curve -- has to do geometric comaprisons
00177 //              so it may be less reliable than the overloaded function
00178 // assumption: the sense (orientation) of the RefFace is the same as that of 
00179 //             the facets and the facetedge loop list
00180 //===========================================================================
00181 CubitStatus CurveFacetEvalTool::get_segments_from_loops(
00182   DLIList<DLIList<CubitFacetEdge*>*> *facet_loop_list,  // lists of boundary edges
00183   CubitVector &start, CubitVector &end,        // begin and end vertex
00184   DLIList<CubitFacetEdge*> &edge_list,            // return the edges used for this curve
00185   DLIList<CubitPoint*> &point_list,              // return the points used for this curve
00186   CubitSense orientation_wrt_surf )
00187 {
00188   CubitStatus stat = CUBIT_SUCCESS;
00189   int ii, jj;
00190   int mydebug = 0;
00191   
00192   CubitBoolean done = CUBIT_FALSE;
00193   DLIList<CubitFacetEdge*> *facet_loop;
00194   CubitFacetEdge *edge, *startedge = NULL;
00195   CubitPoint *pt0, *pt1;
00196   CubitVector loc_pt0, loc_pt1;
00197   double edge_length;
00198 
00199   facetLength = 0.0e0;
00200 
00201   int tool_id = surfFacetEvalTool->tool_id();
00202     //loop over the "loops"
00203   for (ii=0; ii<facet_loop_list->size() && !done && stat == CUBIT_SUCCESS; ii++) {
00204       //get the next facet loop
00205     facet_loop = facet_loop_list->get_and_step();   
00206 
00207       // now loop over the edges in that loop
00208     for (jj=0; jj<facet_loop->size() && !done; jj++) {
00209         //get the start edge... we will 
00210         //traverse the list forwards, if the surface is oriented forward
00211         //otherwise, traverse it backwards
00212       startedge =
00213         (orientation_wrt_surf == CUBIT_FORWARD) ? facet_loop->get_and_step() :
00214         facet_loop->get_and_back();
00215       
00216       if (startedge->get_flag() == 0) {
00217         if (orientation_wrt_surf == CUBIT_FORWARD) {
00218           startedge->boundary_edge_points( pt0, pt1, tool_id );
00219         }
00220         else {
00221           startedge->boundary_edge_points( pt1, pt0, tool_id );
00222         }
00223         loc_pt0 = pt0->coordinates();
00224         loc_pt1 = pt1->coordinates();
00225         if (loc_pt0.within_tolerance( start, GEOMETRY_RESABS )) {
00226           startedge->set_flag( 1 );
00227           edge = startedge;
00228           if (mydebug) draw_edge( edge, CUBIT_GREEN_INDEX );
00229           while (!done) {
00230             edge_list.append( edge );
00231             point_list.append( pt0 );
00232             edge_length = loc_pt0.distance_between( loc_pt1 );
00233             facetLength += edge_length;
00234               //if the other end of the edge is at the begginning of the
00235               //loop, then we're done.
00236             if (loc_pt1.within_tolerance( end, GEOMETRY_RESABS )) {
00237               done = CUBIT_TRUE;
00238               point_list.append( pt1 );
00239             }
00240             else {//otherwise...
00241               if (orientation_wrt_surf == CUBIT_FORWARD) {
00242                 edge = facet_loop->get_and_step();
00243                 edge->boundary_edge_points( pt0, pt1, tool_id );
00244               }
00245               else {
00246                 edge = facet_loop->get_and_back();
00247                 edge->boundary_edge_points( pt1, pt0, tool_id );
00248               }
00249               loc_pt0 = pt0->coordinates();
00250               loc_pt1 = pt1->coordinates();
00251               if (mydebug) draw_edge( edge, CUBIT_BLUE_INDEX );
00252                 //if we got back to the startedge without the
00253                 // other end of an edge getting to the start vertex,
00254                 // we have a problem....
00255               if (edge == startedge)
00256               {
00257                 stat = CUBIT_FAILURE;  // this shouldn't happen
00258                 done = CUBIT_TRUE;
00259               }//end edge == startedge
00260             }//end else not within tolerance
00261           }//end while not done
00262         }//end if within tolerance
00263       }//end if not marked
00264     }//end loop over edges in facet loop
00265   }//end loop over facet loops
00266   if(done!=CUBIT_TRUE)
00267   {
00268     PRINT_ERROR("Can't define curve representation in mesh-based geometry\n");
00269     stat = CUBIT_FAILURE;
00270   }
00271   return stat;
00272   
00273 }
00274 
00275 //===========================================================================
00276 //Function Name: get_segments_from_loops
00277 //
00278 //Member Type:  PRIVATE
00279 //Description:  extract the facet edges from the loops list that are 
00280 //              used for the current curve.  Uses the CubitPoints at
00281 //              the ends of the curve to determine curve
00282 // assumption: the sense (orientation) of the RefFace is the same as that of 
00283 //             the facets and the facetedge loop list
00284 //===========================================================================
00285 CubitStatus CurveFacetEvalTool::get_segments_from_loops(
00286   DLIList<DLIList<CubitFacetEdge*>*> *facet_loop_list,  // lists of boundary edges
00287   CubitPoint *start_pt, CubitPoint *end_pt,   // begin and end point
00288   DLIList<CubitFacetEdge*> &edge_list,            // return the edges used for this curve
00289   DLIList<CubitPoint*> &point_list,               // return the points used for this curve
00290   CubitSense orientation_wrt_surf )
00291 {
00292   CubitStatus stat = CUBIT_SUCCESS;
00293   int ii, jj;
00294   int mydebug = DEBUG_FLAG(181);  
00295   CubitBoolean done = CUBIT_FALSE;
00296   DLIList<CubitFacetEdge*> *facet_loop;
00297   CubitFacetEdge *edge, *startedge = NULL;
00298   CubitPoint *pt0, *pt1;
00299   CubitVector loc_pt0, loc_pt1;
00300   double edge_length;
00301   DLIList<CubitFacetEdge*> temp_edge_list;
00302   DLIList<CubitPoint*> temp_point_list;
00303   
00304   if (mydebug)
00305   {
00306     GfxDebug::draw_point( start_pt->x(),
00307                           start_pt->y(),
00308                           start_pt->z(),
00309                           CUBIT_RED_INDEX );
00310     GfxDebug::draw_point( end_pt->x(),
00311                           end_pt->y(),
00312                           end_pt->z(),
00313                           CUBIT_GREEN_INDEX );
00314     GfxDebug::flush();
00315   }
00316 
00317   int tool_id = surfFacetEvalTool->tool_id();
00318     //loop over the list of facet loops
00319   for (ii=0; ii<facet_loop_list->size() && !done && stat == CUBIT_SUCCESS; ii++) {
00320       //get the next facet loop
00321     facet_loop = facet_loop_list->get_and_step();
00322       //now loop over the edges in that facet loop
00323     for (jj=0; jj<facet_loop->size() && !done; jj++) {
00324         //get the start edge... we will 
00325         //traverse the list forwards, if the surface is oriented forward
00326         //otherwise, traverse it backwards
00327       startedge =
00328         (orientation_wrt_surf == CUBIT_FORWARD) ? facet_loop->get_and_step() :
00329         facet_loop->get_and_back();
00330         //if startedge isn't marked
00331       if (startedge->get_flag() == 0) {
00332           //get the points from the start edge in the appropriate order
00333         if (orientation_wrt_surf == CUBIT_FORWARD) {
00334           startedge->boundary_edge_points( pt0, pt1, tool_id );
00335         }
00336         else {
00337           startedge->boundary_edge_points( pt1, pt0, tool_id );
00338         }
00339           //convert to CubitVector
00340         loc_pt0 = pt0->coordinates();
00341         loc_pt1 = pt1->coordinates();
00342           //if the first point on the edge is the start_pt... otherwise step
00343         if (pt0 == start_pt) {
00344             //mark the startedge
00345           CubitFacetEdge* marked_edge = NULL;
00346           edge = startedge;
00347           if (mydebug) draw_edge( edge, CUBIT_GREEN_INDEX );//draw the start edge
00348             //loop until we have reached an end or no more choices
00349           while (!done) {
00350               //if the first point is at the start, we are either
00351               // just starting, or we have looped back onto the
00352               // start point.  The latter _may_ be ok.  In case
00353               // the latter is the case, clean out the temporary
00354               // lists and (re)initialize the length.  Also, unmark
00355               // the edge that we marked the last time we started,
00356               // if we previously marked an edge.
00357             if (pt0 == start_pt){
00358               temp_point_list.clean_out();
00359               temp_edge_list.clean_out();
00360               facetLength = 0.0;
00361               if(marked_edge)
00362                 marked_edge->set_flag(0);
00363               marked_edge=edge;
00364               edge->set_flag(1);
00365             }
00366               //add the current edge to the edge list
00367             temp_edge_list.append( edge );
00368               //add the current start point to the point list
00369             temp_point_list.append( pt0 );
00370               //measure the edge... essentially
00371             edge_length = loc_pt0.distance_between( loc_pt1 );
00372               //keep a running tally of the curve length
00373             facetLength += edge_length;
00374               
00375               //if the second point is at the end, we're done
00376             if (pt1 == end_pt ) {
00377               done = CUBIT_TRUE;
00378               temp_point_list.append( pt1 );
00379             }
00380               //otherwise, we need to step forward
00381             else {
00382               if (orientation_wrt_surf == CUBIT_FORWARD) {
00383                 edge = facet_loop->get_and_step();
00384                 edge->boundary_edge_points( pt0, pt1, tool_id );
00385               }
00386               else {
00387                 edge = facet_loop->get_and_back();
00388                 edge->boundary_edge_points( pt1, pt0, tool_id );
00389               }
00390                 //convert point to CubitVector, as above
00391               loc_pt0 = pt0->coordinates();
00392               loc_pt1 = pt1->coordinates();
00393               if (mydebug) draw_edge( edge, CUBIT_BLUE_INDEX );
00394               if (edge == startedge)
00395               {
00396                 stat = CUBIT_FAILURE;  // this shouldn't happen
00397                 done = CUBIT_TRUE;
00398               }
00399             }//end else (ie, if not pt1==end_pt)
00400           }//end while !done
00401         }//end if pt0 == start_pt
00402       }//end if start edge isn't marked
00403     }//end loop over edges in the loop
00404   }//end loop over facet loops
00405 
00406     //now put the temporary list entries onto the end of the list we return.
00407   point_list += temp_point_list;
00408   edge_list += temp_edge_list;
00409   
00410   if(done!=CUBIT_TRUE || stat == CUBIT_FAILURE)
00411   {
00412     stat = CUBIT_FAILURE;
00413     PRINT_WARNING("Can't define curve representation in mesh-based geometry\n");
00414     PRINT_INFO("  Hint: Try importing as a free mesh and examining nodes and attached\n");
00415     PRINT_INFO("        elements near the following locations:\n");
00416     PRINT_INFO("        Start curve = %f %f %f\n", start_pt->x(), start_pt->y(), start_pt->z());
00417     PRINT_INFO("        End curve = %f %f %f\n", end_pt->x(), end_pt->y(), end_pt->z());
00418     if (mydebug)
00419     {
00420       surfFacetEvalTool->debug_draw_facets( CUBIT_YELLOW_INDEX );
00421       int i, j;
00422       for (i=0; i<facet_loop_list->size(); i++)
00423       {
00424         DLIList<CubitFacetEdge*> *my_facet_loop = facet_loop_list->get_and_step();
00425         for (j=0; j<my_facet_loop->size(); j++)
00426         {
00427           draw_edge( my_facet_loop->get_and_step(), CUBIT_RED_INDEX );
00428         }
00429       }
00430       GfxDebug::mouse_xforms();
00431     }
00432   }
00433   return stat;
00434 }
00435 
00436 //===========================================================================
00437 //Function Name: get_segments_from_positions
00438 //
00439 //Member Type:  PRIVATE
00440 //Description:  extract the facet edges from the facets of the parent surface.
00441 //              This function is used exclusively for hardlines.  
00442 //===========================================================================
00443 CubitStatus CurveFacetEvalTool::get_segments_from_positions(
00444   std::vector<CubitVector> &positions,   // postions of points on curve
00445   CubitVector &start,                    // begin point
00446   DLIList<CubitFacetEdge*> &edge_list,   // return the edges used for this curve
00447   DLIList<CubitPoint*> &point_list )     // return the points used for this curve  
00448 {  
00449   DLIList<CubitPoint*> surface_pts;
00450   surfFacetEvalTool->get_points( surface_pts );  
00451 
00452   facetLength = 0;
00453 
00454   double smallest_dist = CUBIT_DBL_MAX;
00455   CubitPoint *start_pt = NULL;
00456   //find the closest point to 'start'
00457   for( int k=surface_pts.size(); k--; )
00458   {
00459     double tmp_dist = surface_pts.get()->coordinates().distance_between_squared( start );
00460 
00461     if( tmp_dist < smallest_dist )
00462     {
00463       smallest_dist = tmp_dist;
00464       start_pt = surface_pts.get();
00465     }
00466     surface_pts.get_and_step();
00467   }
00468 
00469   myPointList.append( start_pt );
00470 
00471   CubitPoint *current_pt = start_pt;
00472   CubitPoint *next_pt = NULL;
00473   for (size_t k = 1; k < positions.size(); k++ )
00474   {
00475     CubitVector current_pos = positions[k];
00476 
00477     //find the CubitPoint attached to this point via an edge
00478     double smallest_dist = CUBIT_DBL_MAX;    
00479     CubitFacetEdge *next_edge;
00480 
00481     DLIList<CubitFacetEdge*> adj_edges;
00482     current_pt->edges( adj_edges );
00483 
00484     for( int m=adj_edges.size(); m--; )
00485     {
00486       CubitFacetEdge *tmp_edge = adj_edges.get_and_step();
00487       CubitPoint *other_pt = tmp_edge->other_point( current_pt );
00488 
00489       double tmp_dist = current_pos.distance_between_squared(  other_pt->coordinates() );
00490       if( tmp_dist < smallest_dist )
00491       {
00492         smallest_dist = tmp_dist;
00493         next_pt = other_pt;
00494         next_edge = tmp_edge;
00495       }
00496     }
00497 
00498     current_pt = next_pt;
00499     
00500     facetLength += next_edge->length();
00501 
00502     myEdgeList.append( next_edge );
00503     myPointList.append( current_pt );    
00504   }
00505 
00506   if ((size_t)myPointList.size() != positions.size() ||
00507       (size_t)myEdgeList.size() != positions.size() - 1 )
00508     return CUBIT_FAILURE;
00509 
00510   return CUBIT_SUCCESS;
00511 }
00512 
00513 //===========================================================================
00514 //Function Name: find_curv_sense
00515 //
00516 //Member Type:  PRIVATE
00517 //Description:  Determines 'curvSense' depending on the CubitFacetEdges 
00518 //              in 'myEdgeList'  Assumption is that all edges
00519 //              are oriented the same in the curve
00520 //===========================================================================
00521 CubitSense CurveFacetEvalTool::find_curv_sense( CubitPoint *start_pt )
00522 {
00523   myEdgeList.reset();
00524   CubitFacetEdge *edge_ptr = myEdgeList.get();
00525   CubitPoint *pt0 = edge_ptr->point(0);
00526   CubitPoint *pt1 = edge_ptr->point(1);
00527   CubitSense sense;
00528 
00529   if (start_pt == pt0)
00530   {
00531     sense = CUBIT_FORWARD;
00532   }
00533   else if (start_pt == pt1)
00534   {
00535     sense = CUBIT_REVERSED;
00536   }
00537   else
00538   {
00539     sense = CUBIT_UNKNOWN;
00540   }
00541   return sense;
00542 }
00543 
00544 //===========================================================================
00545 //Function Name: find_curv_sense 
00546 //
00547 //Member Type:  PRIVATE
00548 //Description:  Determines 'curvSense' depending on the CubitFacetEdges 
00549 //              in 'myEdgeList' Assumption is that all edges
00550 //              are oriented the same in the curve
00551 //===========================================================================
00552 
00553 CubitSense CurveFacetEvalTool::find_curv_sense( CubitVector &start )
00554 {
00555   myEdgeList.reset();
00556   CubitFacetEdge* temp_edge = myEdgeList.get();
00557  
00558   CubitVector temp_vector = temp_edge->point(1)->coordinates() - 
00559                             temp_edge->point(0)->coordinates();
00560   
00561   double tol = temp_vector.length() / 100.0; 
00562   //if point(0) of first edge in list == start, it is CUBIT_FORWARD 
00563   if(start.within_tolerance(temp_edge->point(0)->coordinates(), tol ) )
00564     return CUBIT_FORWARD;
00565   //if point(1) of first edge in list == start, it is CUBIT_REVERSED 
00566   else if(start.within_tolerance(temp_edge->point(1)->coordinates(), tol ) )
00567     return CUBIT_REVERSED;
00568   else
00569     return CUBIT_UNKNOWN; 
00570 }
00571 
00572 //===========================================================================
00573 //Function Name: bounding_box
00574 //
00575 //Member Type:  PUBLIC
00576 //Description:  Calculates the bounding box of the curve.
00577 //===========================================================================
00578 CubitBox CurveFacetEvalTool::bounding_box()
00579 {
00580   if ( !myBBox )
00581   {
00582     int ii;
00583     CubitPoint *point_ptr;
00584     double x, y, z;
00585     double x_min = CUBIT_DBL_MAX, x_max = -CUBIT_DBL_MAX;
00586     double y_min = CUBIT_DBL_MAX, y_max = -CUBIT_DBL_MAX;
00587     double z_min = CUBIT_DBL_MAX, z_max = -CUBIT_DBL_MAX;
00588     for ( ii = myPointList.size(); ii > 0; ii-- )
00589     {
00590       point_ptr = myPointList.get_and_step();
00591       x = point_ptr->x();
00592       y = point_ptr->y();
00593       z = point_ptr->z();
00594       if ( x < x_min )
00595         x_min = x;
00596       if ( y < y_min )
00597         y_min = y;
00598       if ( z < z_min )
00599         z_min = z;
00600       if ( x > x_max )
00601         x_max = x;
00602       if ( y > y_max )
00603         y_max = y;
00604       if ( z > z_max )
00605         z_max = z;
00606     }
00607     CubitVector min_v(x_min, y_min, z_min );
00608     CubitVector max_v(x_max, y_max, z_max );
00609     myBBox = new CubitBox( min_v, max_v );
00610   }
00611   return *(myBBox);
00612 }
00613 
00614 //===========================================================================
00615 //Function Name: position_from_fraction
00616 //
00617 //Member Type:  PUBLIC
00618 //Description:  evaluates the location a fraction of the way along the curve
00619 //              based on the sum of the lengths of the facet edges on this curve
00620 //===========================================================================
00621 CubitStatus CurveFacetEvalTool::position_from_fraction( 
00622   double fraction, // between 0 and 1
00623   CubitVector &location_on_curve )
00624 {
00625   CubitStatus status = CUBIT_SUCCESS;
00626   CubitBoolean done = CUBIT_FALSE;
00627   double length, curlength, targetlength, lastlength;
00628   CubitFacetEdge *edge = NULL;
00629   CubitPoint *pt0=NULL, *pt1=NULL;
00630   CubitVector loc_pt0, loc_pt1;
00631   CubitVector eval_location;
00632   myEdgeList.reset();
00633 
00634   myPointList.reset();
00635   pt0 = myPointList.get();
00636   if (fraction <= 0.0) {
00637     edge = myEdgeList.get_and_step();
00638     location_on_curve = pt0->coordinates();
00639     return status;
00640   }
00641   curlength = lastlength = 0.0e0;
00642   targetlength = fraction * facetLength;
00643   assert(myEdgeList.size() > 0);
00644   int ii = 0;
00645   for ( ; ii<myEdgeList.size() && !done; ii++) {
00646     edge = myEdgeList.get_and_step();
00647     loc_pt0 = edge->point( 0 )->coordinates();
00648     loc_pt1 = edge->point( 1 )->coordinates();
00649     length = loc_pt0.distance_between( loc_pt1 );
00650     curlength += length;
00651     if ( edge->point(0) == pt0 ){
00652       pt1 = edge->point(1);
00653     }
00654     else{
00655       pt1 = edge->point(0);
00656     }
00657     if (targetlength <= curlength) {
00658       done = CUBIT_TRUE;
00659       
00660       loc_pt0 = pt0->coordinates();
00661       loc_pt1 = pt1->coordinates();
00662       double local_fraction = (targetlength - lastlength) / length;
00663       eval_location = loc_pt0 + local_fraction * (loc_pt1 - loc_pt0); 
00664       if (interpOrder == 0 || !surfFacetEvalTool) {
00665         location_on_curve = eval_location;
00666       }
00667       else {
00668       //  evaluate Bezier edge
00669         int index0 = 0;        
00670         int index1 = 1;
00671         if ( pt1 == edge->point(0) ) {
00672             //switching the indices causes evaluate_bezier_edge to compute the 
00673             //wrong location, so I'm removing the switch (mbrewer)
00674           //index0 = 1;
00675           //index1 = 0;
00676           local_fraction = 1. - local_fraction;
00677         }
00678         status = evaluate_bezier_edge(edge,index0,index1,local_fraction,
00679                                         location_on_curve,0);
00680       }
00681     }
00682     else {
00683       lastlength = curlength;
00684     }
00685     if ( edge->point(0) == pt0 )
00686         pt0 = edge->point(1);
00687     else 
00688         pt0 = edge->point(0);
00689   }
00690   
00691   if (!done) {
00692     if(pt1 == NULL){
00693       PRINT_ERROR("Opposite point not found while evaluating a curve.\n");
00694       location_on_curve.set(0.0,0.0,0.0);
00695       return CUBIT_FAILURE;
00696     }
00697     location_on_curve = pt1->coordinates();
00698   }
00699   return status;
00700 }
00701 
00702 //===========================================================================
00703 //Function Name: evaluate_bezier_edge
00704 //
00705 //Member Type:  PRIVATE
00706 //Description:  evaluates a fractional length onto a Bezier edge 
00707 //===========================================================================
00708 CubitStatus CurveFacetEvalTool::evaluate_bezier_edge(CubitFacetEdge *edge,
00709                                         int index0,
00710                                         int index1,
00711                                         double fraction,
00712                                         CubitVector &location_on_curve,
00713                                         double* tangent)
00714 {
00715 CubitStatus status;
00716 int numEdge, numVert, numLocs;
00717 int edgeVert[2];
00718 //int order;
00719 double vert[6], edgeCtrlPts[9], location[3];
00720 CubitVector *edge_ctrl_pts;
00721  double scaled_parameter;
00722  
00723   numEdge = 1;
00724   numVert = 2;
00725   numLocs = 1;
00726   edgeVert[0] = 0; edgeVert[1] = 1;
00727   vert[0] = edge->point(index0)->x();
00728   vert[1] = edge->point(index0)->y();
00729   vert[2] = edge->point(index0)->z();
00730   vert[3] = edge->point(index1)->x();
00731   vert[4] = edge->point(index1)->y();
00732   vert[5] = edge->point(index1)->z();
00733   
00734     edge_ctrl_pts = edge->control_points();
00735     edgeCtrlPts[0] = edge_ctrl_pts[0].x();  
00736     edgeCtrlPts[1] = edge_ctrl_pts[0].y();  
00737     edgeCtrlPts[2] = edge_ctrl_pts[0].z();  
00738     edgeCtrlPts[3] = edge_ctrl_pts[1].x();  
00739     edgeCtrlPts[4] = edge_ctrl_pts[1].y();  
00740     edgeCtrlPts[5] = edge_ctrl_pts[1].z();  
00741     edgeCtrlPts[6] = edge_ctrl_pts[2].x();  
00742     edgeCtrlPts[7] = edge_ctrl_pts[2].y();  
00743     edgeCtrlPts[8] = edge_ctrl_pts[2].z();  
00744 
00745       //evalBezierEdge takes a parameter in the range of -1 to 1.
00746       // evalBezierEdge calls functions which  convert back to
00747       // a range of 0 to 1,
00748       // but we must convert to -1 to 1, before sending it.
00749     scaled_parameter = (2.0 * fraction) - 1.0;
00750     
00751   //  static function in Cholla.cpp
00752     evalBezierEdge(numEdge,numVert,edgeVert,vert,edgeCtrlPts,numLocs,
00753                    &scaled_parameter, location,tangent);
00754   
00755   location_on_curve.x(location[0]); 
00756   location_on_curve.y(location[1]); 
00757   location_on_curve.z(location[2]); 
00758    
00759   status = CUBIT_SUCCESS;
00760   
00761   return status;
00762 }
00763                                          
00764 //===========================================================================
00765 //Function Name: u_from_arc_length
00766 //
00767 //Member Type:  PUBLIC
00768 //Description:  see notes in FacetCurve::u_from_arc_length
00769 //===========================================================================
00770 double CurveFacetEvalTool::u_from_arc_length ( double root_param,
00771                                                double arc_length )
00772 {
00773   if( facetLength == 0 )
00774     return 0;
00775 
00776   double u = root_param + arc_length / facetLength;
00777 
00778   return u;
00779 
00780 }
00781 
00782 //===========================================================================
00783 //Function Name: length_from_u
00784 //
00785 //Member Type:  PUBLIC
00786 //Description:  return length along curve from u parameter
00787 //===========================================================================
00788 double CurveFacetEvalTool::length_from_u ( double root_param,
00789                                            double end_param )
00790 {
00791   double length = (end_param - root_param) * facetLength;
00792 
00793   return length;
00794 }
00795 
00796 //===========================================================================
00797 //Function Name: closest_point
00798 //
00799 //Member Type:  PUBLIC
00800 //Description:  Finds the closest point from the vector (this_point) to the
00801 //              set of facets that lies on the set of facets.  If the point
00802 //              lies outside this set, the closest point will be on the plane
00803 //              of the closest facet.  The closest_point is set to be that point.
00804 //===========================================================================
00805 CubitStatus CurveFacetEvalTool::closest_point(CubitVector &this_point,
00806                                               CubitVector &closest_point,
00807                                               CubitVector *tangent_ptr,
00808                                               CubitVector *curvature_ptr,
00809                                               double *param )
00810 {
00811   CubitStatus stat = CUBIT_SUCCESS;
00812 //  int outside;
00813   int mydebug = 0;
00814   if (mydebug)
00815   {
00816     draw_location(this_point, CUBIT_RED_INDEX);
00817   }
00818 /*
00819   if (surfFacetEvalTool == NULL)
00820   {
00821     stat = project_to_linear_facet_edge( this_point, closest_point,
00822                                          tangent_ptr, curvature_ptr,
00823                                          param, &outside );
00824   }
00825   else
00826   {
00827     stat = project_to_facet_edge( this_point, closest_point, 
00828                                   tangent_ptr, curvature_ptr, param, &outside );
00829   }
00830   */
00831   int i;
00832   CubitVector test_pt_v, closest_pt_v, pt0_v, pt1_v;
00833   double distance2, closest_distance2; //  distance squared
00834   CubitFacetEdge *edge, *best_edge = NULL;
00835 
00836   myEdgeList.reset();
00837   closest_distance2 = CUBIT_DBL_MAX;
00838   for ( i = myEdgeList.size(); i > 0; i-- ) {  
00839     edge = myEdgeList.get_and_step();
00840     pt0_v = edge->point(0)->coordinates();
00841     pt1_v = edge->point(1)->coordinates();
00842     test_pt_v = FacetDataUtil::squared_distance_to_segment(this_point,
00843                      pt0_v,pt1_v,distance2);
00844     if ( distance2 < closest_distance2 ) {
00845       closest_distance2 = distance2;
00846       closest_pt_v = test_pt_v;
00847       best_edge = edge;
00848       if ( distance2 < GEOMETRY_RESABS*GEOMETRY_RESABS ) break;
00849     }
00850   }
00851 
00852 
00853   if (mydebug)
00854   {
00855     myEdgeList.reset();
00856     for ( i = myEdgeList.size(); i > 0; i-- ) {  
00857       edge = myEdgeList.get_and_step();
00858       pt0_v = edge->point(0)->coordinates();
00859       pt1_v = edge->point(1)->coordinates();
00860       GfxDebug::draw_point(pt0_v, CUBIT_GREEN_INDEX );
00861       GfxDebug::draw_point(pt1_v, CUBIT_RED_INDEX );
00862       GfxDebug::flush();
00863     }
00864   }
00865   
00866   if ( interpOrder == 0 ) {
00867     closest_point = closest_pt_v;
00868     if (tangent_ptr) {
00869       CubitVector tangent;
00870       if (best_edge->edge_tangent( closest_point, tangent ) != CUBIT_SUCCESS) {
00871         return CUBIT_FAILURE;
00872       }
00873       if (curvSense == CUBIT_REVERSED)
00874         tangent = -tangent;
00875       *tangent_ptr = tangent;
00876     } 
00877     // evaluate the curvature if required
00878     if (curvature_ptr) 
00879     {
00880       if( myEdgeList.size() == 1 )
00881         (*curvature_ptr).set( 0, 0, 0); 
00882       else
00883       {
00884         CubitVector curvature;
00885         myEdgeList.move_to( best_edge );
00886         int index = myEdgeList.get_index();
00887 
00888         //"best_edge" could be last or first on curve 
00889         CubitFacetEdge* prev_edge = NULL; 
00890         myEdgeList.back();
00891         if( (index - 1) == myEdgeList.get_index() ) 
00892           prev_edge = myEdgeList.get();
00893 
00894         CubitFacetEdge* next_edge = NULL; 
00895         myEdgeList.step(2);
00896         if( (index + 1) == myEdgeList.get_index() ) 
00897           next_edge = myEdgeList.get();
00898 
00899 
00900         CubitFacetEdge *closest_edge;
00901         //determine which adjacent edge is closest to "best_point"
00902         if( prev_edge && next_edge )
00903         {
00904           CubitVector tmp_vec;
00905           double prev_dist, next_dist;
00906           tmp_vec = (prev_edge->point(0)->coordinates() + 
00907                      prev_edge->point(1)->coordinates() ) / 2;
00908           prev_dist = closest_point.distance_between( tmp_vec ); 
00909 
00910           tmp_vec = (next_edge->point(0)->coordinates() + 
00911                      next_edge->point(1)->coordinates() ) / 2;
00912           next_dist = closest_point.distance_between( tmp_vec ); 
00913         
00914           if( prev_dist < next_dist )
00915             closest_edge = prev_edge;
00916           else
00917             closest_edge = next_edge;
00918         }
00919         else if( prev_edge )
00920           closest_edge = prev_edge;
00921         else
00922           closest_edge = next_edge;
00923 
00924         if (best_edge->edge_curvature( closest_point, curvature, closest_edge ) != CUBIT_SUCCESS) {
00925           return CUBIT_FAILURE;
00926         }
00927         if (curvSense == CUBIT_REVERSED)
00928           curvature = -curvature;
00929         *curvature_ptr = curvature;
00930       }
00931     }
00932   } else if ( interpOrder == 4 ) { 
00933     double t_value;    
00934     double tangent[3];
00935     stat = project_to_bezier_edge(best_edge,this_point,
00936                                   closest_point,tangent,&t_value);
00937     if(curvSense == CUBIT_REVERSED){
00938       tangent[0]= -tangent[0];
00939       tangent[1]= -tangent[1];
00940       tangent[2]= -tangent[2];
00941     }
00942     
00943     if ( tangent_ptr ) {                                    
00944       tangent_ptr->x(tangent[0]);
00945       tangent_ptr->y(tangent[1]);
00946       tangent_ptr->z(tangent[2]);
00947     }
00948 
00949     if ( curvature_ptr ) {
00950     //  The idea here is to get the planes normal to two points on the curve
00951     //  on either side of the closest_point, and also to get the plane through 
00952     //  these three points.  The point of intersection of these three planes
00953     //  should be a good approximation of the center of curvature, from which
00954     //  the curvature vector is readily found.
00955     //  tan1 and tan2 are the normals to the two planes for the endpoints;
00956     //  norm3 is the normal for the plane through the three points. 
00957       CubitVector tan1, tan2, point_1,  point_2;
00958       CubitVector *tan1_ptr = &tan1;
00959       CubitVector *tan2_ptr = &tan2;
00960 //       CubitVector *point_1_ptr = &point_1;
00961       CubitVector *point_2_ptr = &point_2;
00962       t_value -= 0.01;
00963       best_edge->evaluate_single_tangent(t_value,tan1_ptr);
00964       t_value += 0.02;
00965       best_edge->evaluate_single(t_value,tan2_ptr);
00966       best_edge->evaluate_single_tangent(t_value,point_2_ptr);
00967       tan1.normalize();
00968       tan2.normalize();
00969       //  Get the plane through the point and normal to the tangent for the two 
00970       //  points at the end.
00971       //  Get the plane for the three points.
00972       CubitVector arm1 = point_1 - closest_point;
00973       CubitVector arm2 = point_2 - closest_point;
00974       CubitVector norm3 = arm1*arm2;
00975       norm3.normalize();
00976       double denominator;
00977       
00978       denominator = tan1 % ( tan2 * norm3 );  
00979 
00980       if ( fabs(denominator) < GEOMETRY_RESABS ) { // planes are parallel; 
00981                                                     // curvature is infinite
00982         curvature_ptr->x(CUBIT_DBL_MAX);
00983         curvature_ptr->y(CUBIT_DBL_MAX);
00984         curvature_ptr->z(CUBIT_DBL_MAX);
00985       
00986       } else {
00987         CubitVector IntersectionPoint;
00988         IntersectionPoint = ( (point_1%tan1)*(norm3*tan2) + 
00989                               (closest_point%norm3)*(tan2*tan1) +
00990                               (point_2%tan2)*(tan1*norm3) )/denominator;
00991       
00992         curvature_ptr->x(closest_point.x() - IntersectionPoint.x());
00993         curvature_ptr->y(closest_point.y() - IntersectionPoint.y());
00994         curvature_ptr->z(closest_point.z() - IntersectionPoint.z());
00995         
00996       }
00997               
00998     }  
00999   } else {
01000     PRINT_ERROR("Error:  Only curves or order 0 or 4 are supported.\n");
01001     return CUBIT_FAILURE;    
01002   }
01003   
01004 
01005   
01006   if (param)
01007   {
01008     *param = u_on_facet_edge( best_edge, closest_point );
01009   }
01010    
01011   if (mydebug)
01012   {
01013     draw_location(closest_point, CUBIT_GREEN_INDEX);
01014   }
01015   return stat;
01016 
01017 }
01018 
01019 //===========================================================================
01020 //Function Name: project_to_bezier_edge
01021 //
01022 //Member Type:  PRIVATE
01023 //Description:  projects a point onto a Bezier edge 
01024 //===========================================================================
01025 CubitStatus CurveFacetEvalTool::project_to_bezier_edge(CubitFacetEdge *edge,
01026                         CubitVector &point, CubitVector &projected_point,
01027                         double *tangent, double *tval)
01028 {
01029 CubitStatus stat;
01030 int numEdge, numVert, edgeVert[2], numLocs;
01031 double vert[6], edgeCtrlPts[9], xyz[3], xyzOnEdge[3];
01032 CubitVector *edge_ctrl_pts;
01033 
01034   stat = CUBIT_SUCCESS;
01035 
01036   numEdge = 1;
01037   numVert = 2;
01038   numLocs = 1;
01039   edgeVert[0] = 0; edgeVert[1] = 1;
01040   vert[0] = edge->point(0)->x();
01041   vert[1] = edge->point(0)->y();
01042   vert[2] = edge->point(0)->z();
01043   vert[3] = edge->point(1)->x();
01044   vert[4] = edge->point(1)->y();
01045   vert[5] = edge->point(1)->z();
01046   
01047     edge_ctrl_pts = edge->control_points();
01048     edgeCtrlPts[0] = edge_ctrl_pts[0].x();  
01049     edgeCtrlPts[1] = edge_ctrl_pts[0].y();  
01050     edgeCtrlPts[2] = edge_ctrl_pts[0].z();  
01051     edgeCtrlPts[3] = edge_ctrl_pts[1].x();  
01052     edgeCtrlPts[4] = edge_ctrl_pts[1].y();  
01053     edgeCtrlPts[5] = edge_ctrl_pts[1].z();  
01054     edgeCtrlPts[6] = edge_ctrl_pts[2].x();  
01055     edgeCtrlPts[7] = edge_ctrl_pts[2].y();  
01056     edgeCtrlPts[8] = edge_ctrl_pts[2].z();  
01057   xyz[0] = point.x();
01058   xyz[1] = point.y(); 
01059   xyz[2] = point.z();
01060   projToBezierEdge( numEdge,numVert,edgeVert,vert,edgeCtrlPts,
01061                        numLocs,xyz,xyzOnEdge,tangent,tval );
01062 
01063   projected_point.x(xyzOnEdge[0]);
01064   projected_point.y(xyzOnEdge[1]);
01065   projected_point.z(xyzOnEdge[2]);
01066   
01067   return stat;
01068 }
01069 /*
01070 //===========================================================================
01071 //Function Name: project_to_facet_edge
01072 //
01073 //Member Type:  PRIVATE
01074 //Description:  project the point to the facets defining this curve
01075 //===========================================================================
01076 CubitStatus CurveFacetEvalTool::project_to_facet_edge(CubitVector &this_point,
01077                                                       CubitVector &closest_point,
01078                                                       CubitVector *tangent_ptr,
01079                                                       CubitVector *curvature_ptr,
01080                                                       double *param,
01081                                                       int *outside )
01082 {
01083   int trim = 0;
01084   int ncheck, ii, nincr=0;
01085   static int calls=0;
01086   static int nncheck=0;
01087   static int ntol=0;
01088   static int mydebug=0;
01089   CubitBoolean outside_facet, best_outside_facet;
01090   CubitVector boxmin, boxmax, p0, p1;
01091   CubitVector close_point, best_point, best_areacoord;
01092   CubitFacetEdge *best_edge, *edge;
01093   CubitFacet *best_facet, *facet;
01094 
01095   double tol = surfFacetEvalTool->compare_tol();
01096   double facet_tol = 1.0e-3 * surfFacetEvalTool->compare_tol();
01097   double mindist = 0.0e0;
01098   CubitVector pt_on_edge;
01099   CubitBoolean done = CUBIT_FALSE;
01100   while(!done) {
01101 
01102     // define a bounding box around the point
01103 
01104     CubitVector ptmin( this_point.x() - tol, 
01105                        this_point.y() - tol, 
01106                        this_point.z() - tol );
01107    
01108     CubitVector ptmax( this_point.x() + tol, 
01109                        this_point.y() + tol, 
01110                        this_point.z() + tol );
01111 
01112     mindist = CUBIT_DBL_MAX;
01113     ncheck = 0;
01114     best_outside_facet = CUBIT_TRUE;
01115     myEdgeList.reset();
01116     for ( ii = myEdgeList.size(); ii > 0 && !done; ii-- ) {
01117         edge = myEdgeList.get_and_step();
01118       p0 = edge->point( 0 )->coordinates();
01119       p1 = edge->point( 1 )->coordinates();
01120 
01121       // Try to trivially reject this facet with a bounding box test
01122 
01123       boxmin.x( CUBIT_MIN( p0.x(), p1.x() ) );
01124       boxmax.x( CUBIT_MAX( p0.x(), p1.x() ) );
01125       if (ptmax.x() < boxmin.x() ||
01126                       ptmin.x() > boxmax.x()) {
01127         continue;
01128       }
01129       boxmin.y( CUBIT_MIN( p0.y(), p1.y() ) );
01130       boxmax.y( CUBIT_MAX( p0.y(), p1.y() ) );
01131       if (ptmax.y() < boxmin.y() ||
01132               ptmin.y() > boxmax.y()) {
01133         continue;
01134       }
01135       boxmin.z( CUBIT_MIN( p0.z(), p1.z() ) );
01136       boxmax.z( CUBIT_MAX( p0.z(), p1.z() ) );
01137       if (ptmax.z() < boxmin.z() ||
01138               ptmin.z() > boxmax.z()) {
01139         continue;
01140       }
01141 
01142       // Only facets that pass the bounding box test will get past here!
01143 
01144       // Project point to plane of the facet and determine its area coordinates
01145 
01146       ncheck++;
01147       CubitVector pt_on_plane;
01148       double dist_to_plane;
01149       facet = edge->adj_facet( 0 );
01150       if (!facet) {
01151         facet = edge->adj_facet( 1 );
01152       }
01153       project_to_edge_line( edge, this_point, pt_on_plane, dist_to_plane );
01154       CubitVector areacoord;
01155       pt_on_edge = pt_on_plane;
01156       surfFacetEvalTool->facet_area_coordinate( facet, pt_on_plane, areacoord );
01157 
01158       // If sign of areacoords are all positive then its inside the triangle
01159       // and we are done - go interpolate the point. (use an absolute
01160       // tolerance since the coordinates arenormalized)
01161 
01162       if (areacoord.x() > -GEOMETRY_RESABS && 
01163           areacoord.y() > -GEOMETRY_RESABS && 
01164           areacoord.z() > -GEOMETRY_RESABS) {
01165         if (interpOrder == 0 && dist_to_plane < facet_tol) {
01166           outside_facet = CUBIT_FALSE;
01167           close_point = this_point;
01168         }
01169         else {
01170           if (surfFacetEvalTool->eval_facet( facet, this_point, areacoord, 
01171                           close_point, outside_facet ) 
01172             != CUBIT_SUCCESS) {
01173             return CUBIT_FAILURE;
01174           }
01175         }
01176       }
01177 
01178       // otherwise find the closest vertex or edge to the projected point
01179 
01180       else if (areacoord.x() < GEOMETRY_RESABS) 
01181       {
01182         outside_facet = CUBIT_TRUE;
01183         if (areacoord.y() < GEOMETRY_RESABS) 
01184         {
01185           if (surfFacetEvalTool->eval_point( facet, 2, close_point ) 
01186             != CUBIT_SUCCESS) {
01187             return CUBIT_FAILURE;
01188           }
01189         }
01190         else if(areacoord.z() < GEOMETRY_RESABS) 
01191         {
01192           if (surfFacetEvalTool->eval_point( facet, 1, close_point ) 
01193             != CUBIT_SUCCESS) {
01194             return CUBIT_FAILURE;
01195           }
01196         }
01197         else 
01198         {
01199           if (surfFacetEvalTool->project_to_facetedge( facet, 1, 2, this_point, pt_on_plane, 
01200                          close_point, outside_facet ) !=CUBIT_SUCCESS) {
01201             return CUBIT_FAILURE;
01202           }
01203         }
01204       }
01205       else if (areacoord.y() < GEOMETRY_RESABS) 
01206       {
01207         outside_facet = CUBIT_TRUE;
01208         if (areacoord.z() < GEOMETRY_RESABS) 
01209         {
01210           if (surfFacetEvalTool->eval_point( facet, 0, close_point ) 
01211             != CUBIT_SUCCESS) {
01212             return CUBIT_FAILURE;
01213           }
01214         }
01215         else 
01216         {
01217           if (surfFacetEvalTool->project_to_facetedge( facet, 2, 0, this_point, pt_on_plane, 
01218                          close_point, outside_facet ) !=CUBIT_SUCCESS) {
01219             return CUBIT_FAILURE;
01220           }
01221         }
01222       }
01223       else 
01224       {
01225         outside_facet = CUBIT_TRUE;
01226         if (surfFacetEvalTool->project_to_facetedge( facet, 0, 1, this_point, pt_on_plane, 
01227                        close_point, outside_facet ) !=CUBIT_SUCCESS) {
01228           return CUBIT_FAILURE;
01229         }
01230       }
01231       
01232       // keep track of the minimum distance
01233 
01234       double dist = sqrt(sqr(close_point.x() - this_point.x()) +
01235                          sqr(close_point.y() - this_point.y()) +
01236                          sqr(close_point.z() - this_point.z()));
01237       if (dist < mindist) {
01238         if ((best_outside_facet == CUBIT_FALSE && outside_facet == CUBIT_TRUE)) {
01239           //int x=1;
01240         }
01241         else {
01242           mindist = dist;
01243           best_point = close_point;
01244           best_edge = edge;
01245           best_facet = facet;
01246           best_areacoord = areacoord;
01247           best_outside_facet = outside_facet;
01248 
01249           if (dist < facet_tol) {
01250             done = CUBIT_TRUE;
01251           }
01252         }
01253       }
01254     }
01255 
01256     // We are done if we found at least one triangle.  Otherwise
01257     // increase the tolerance and try again
01258 
01259     nincr++;
01260     if (ncheck > 0) {
01261       if (best_outside_facet && nincr < 10) {
01262         tol *= 2.0;
01263         ntol++;
01264       }
01265       else {
01266         done = CUBIT_TRUE;
01267       }
01268     }
01269     else {
01270       tol *= 2.0e0;
01271       ntol++;
01272     }
01273   }
01274 
01275 
01276   //If area coords are still negative...we are still not on a "best_facet" 
01277   //Find closest point to "best_edge" and use this point for area coordinates
01278   if (best_areacoord.x() <= -GEOMETRY_RESABS || 
01279       best_areacoord.y() <= -GEOMETRY_RESABS || 
01280       best_areacoord.z() <= -GEOMETRY_RESABS) 
01281   {
01282     surfFacetEvalTool->facet_area_coordinate( best_facet, best_point, best_areacoord );
01283   }
01284 
01285 
01286   // if the closest point is outside of a facet, then evaluate the point
01287   // on the facet using its area coordinates (otherwise it would be 
01288   // trimmed to an edge or point)
01289   if ( !trim && best_outside_facet && interpOrder != 4) {
01290     if (surfFacetEvalTool->eval_facet( best_facet, this_point, best_areacoord, 
01291       best_point, best_outside_facet ) 
01292       != CUBIT_SUCCESS) {
01293       return CUBIT_FAILURE;
01294     }
01295     
01296     // see if its really outside (it could just be on an edge where the
01297     // curvature is convex)
01298 
01299     best_outside_facet = surfFacetEvalTool->is_outside( best_facet, best_areacoord );
01300   }
01301 
01302   // evaluate the tangent if required
01303 
01304   CubitVector tangent_vec;
01305   if (tangent_ptr || curvature_ptr) {
01306     CubitVector facet_tangent = best_edge->point(1)->coordinates() - 
01307                                 best_edge->point(0)->coordinates();
01308     if (curvSense == CUBIT_REVERSED)
01309       facet_tangent = -facet_tangent;
01310     facet_tangent.normalize();
01311     if (surfFacetEvalTool->interp_order() == 0)
01312     {
01313       tangent_vec = facet_tangent;
01314     }
01315     else
01316     {
01317       CubitVector normal;
01318       if (surfFacetEvalTool->eval_facet_normal( best_facet, best_areacoord, normal ) 
01319         != CUBIT_SUCCESS) {
01320         return CUBIT_FAILURE;
01321       }    
01322       tangent_vec = normal * (facet_tangent * normal);
01323     }
01324   }
01325 
01326   if( tangent_ptr )
01327     *tangent_ptr = tangent_vec;
01328 
01329   if (curvature_ptr) {
01330     //get adjacent facet edges to "best_edge"
01331     myEdgeList.move_to( best_edge );
01332     int index = myEdgeList.get_index();
01333 
01334     //"best_edge" could be last or first on curve 
01335     CubitFacetEdge* prev_edge = NULL; 
01336     myEdgeList.back();
01337     if( (index - 1) == myEdgeList.get_index() ) 
01338       prev_edge = myEdgeList.get();
01339 
01340     CubitFacetEdge* next_edge = NULL; 
01341     myEdgeList.step(2);
01342     if( (index + 1) == myEdgeList.get_index() ) 
01343       next_edge = myEdgeList.get();
01344 
01345     //now get 1 facet on each adj. edge
01346     CubitFacet *prev_facet = NULL;
01347     if( prev_edge )
01348     {
01349       prev_facet = prev_edge->adj_facet( 0 );
01350       if (!prev_facet)
01351         prev_facet = prev_edge->adj_facet( 1 );
01352     }
01353 
01354     CubitFacet *next_facet = NULL;
01355     if( next_edge )
01356     {
01357       next_facet = next_edge->adj_facet( 0 );
01358       if (!next_facet)
01359         next_facet = next_edge->adj_facet( 1 );
01360     }
01361 
01362     //get tangent at midpoint of prev_edge
01363     CubitVector prev_tangent_vec;
01364     if( prev_edge ) 
01365     {
01366       CubitVector facet_tangent = prev_edge->point(1)->coordinates() - 
01367                                   prev_edge->point(0)->coordinates();
01368       if (curvSense == CUBIT_REVERSED)
01369         facet_tangent = -facet_tangent;
01370       facet_tangent.normalize();
01371 
01372       if (surfFacetEvalTool->interp_order() == 0)
01373         prev_tangent_vec = facet_tangent;
01374       else
01375       {
01376         CubitVector prev_mid_point;
01377         prev_mid_point = (prev_edge->point(0)->coordinates() + 
01378                           prev_edge->point(1)->coordinates() ) / 2;
01379 
01380         CubitVector areacoord;
01381         surfFacetEvalTool->facet_area_coordinate( prev_facet, prev_mid_point, areacoord );
01382         CubitVector normal;
01383         if (surfFacetEvalTool->eval_facet_normal( prev_facet, areacoord, normal ) 
01384           != CUBIT_SUCCESS) 
01385         {
01386           return CUBIT_FAILURE;
01387         }    
01388         prev_tangent_vec = normal * (facet_tangent * normal);
01389       }
01390     }
01391 
01392     //get tangent at midpoint of next_edge
01393     CubitVector next_tangent_vec;
01394     if( next_edge ) 
01395     {
01396       CubitVector facet_tangent = next_edge->point(1)->coordinates() - 
01397                                   next_edge->point(0)->coordinates();
01398       if (curvSense == CUBIT_REVERSED)
01399         facet_tangent = -facet_tangent;
01400       facet_tangent.normalize();
01401 
01402       if (surfFacetEvalTool->interp_order() == 0)
01403         next_tangent_vec = facet_tangent;
01404       else
01405       {
01406         CubitVector next_mid_point; 
01407         next_mid_point = (next_edge->point(0)->coordinates() + 
01408                           next_edge->point(1)->coordinates() ) / 2;
01409 
01410         CubitVector areacoord;
01411         surfFacetEvalTool->facet_area_coordinate( next_facet, next_mid_point, areacoord );
01412         CubitVector normal;
01413         if (surfFacetEvalTool->eval_facet_normal( next_facet, areacoord, normal ) 
01414           != CUBIT_SUCCESS) 
01415         {
01416           return CUBIT_FAILURE;
01417         }    
01418         next_tangent_vec = normal * (facet_tangent * normal);
01419       }
01420     }
01421 
01422     //decide how to weight the tangents
01423     double prev_weight, next_weight; 
01424     if( !prev_edge ) 
01425     {
01426       prev_weight = 0;
01427       next_weight = 2;
01428     }
01429     else if( !next_edge )
01430     {
01431       prev_weight = 2;
01432       next_weight = 0;
01433     }
01434     else
01435     {
01436       double dist1 = best_edge->point(0)->coordinates().distance_between(
01437                      best_edge->point(1)->coordinates() );
01438       double dist2 = best_edge->point(0)->coordinates().distance_between(
01439                      best_point);
01440       next_weight = dist2/dist1;
01441       next_weight *= 2; 
01442       prev_weight = 2-next_weight; 
01443     }
01444 
01445     *curvature_ptr = (prev_weight*( tangent_vec - prev_tangent_vec ) + 
01446                      next_weight*( next_tangent_vec - tangent_vec ) );
01447   }
01448 
01449   closest_point = best_point;
01450  
01451   *outside = best_outside_facet;
01452 
01453   if (mydebug) {
01454     nncheck+= ncheck;
01455     calls++;
01456     if (calls%100==0){
01457       char message[100];
01458       sprintf(message,"calls = %d, ckecks = %d, ntol = %d\n",calls,nncheck,ntol);
01459       PRINT_INFO(message);
01460     }
01461   }
01462 
01463   // determine the parameter on the curve
01464 
01465   if (param)
01466   {
01467     *param = u_on_facet_edge( best_edge, closest_point );
01468   }
01469   
01470   return CUBIT_SUCCESS;
01471 }
01472 
01473 //===========================================================================
01474 //Function Name: project_to_edge_line
01475 //
01476 //Member Type:  PRIVATE
01477 //Description:  compute the area coordinate on the linear facet edge
01478 //===========================================================================
01479 CubitStatus CurveFacetEvalTool::project_to_edge_line( CubitFacetEdge *edge, 
01480                                                       CubitVector &this_point, 
01481                                                       CubitVector &pt_on_edge, 
01482                                                       double &dist_to_edge )
01483 {
01484   CubitVector p0 = edge->point(0)->coordinates();
01485   CubitVector p1 = edge->point(1)->coordinates();
01486   CubitVector v0 = p1 - p0;
01487   CubitVector v1 = this_point - p0;
01488   double h = v1.normalize();
01489   v0.normalize();
01490   double costheta = v0 % v1;
01491   double l = h * costheta;
01492   dist_to_edge = sqrt( fabs((h*h) - (l*l)) );
01493   pt_on_edge = p0 + l*v0;
01494   
01495   return CUBIT_SUCCESS;
01496 }
01497 
01498 //===========================================================================
01499 //Function Name: project_to_linear_facet_edge
01500 //
01501 //Member Type:  PRIVATE
01502 //Description:  project the point to the facets defining this curve.
01503 //              Note: this function assumes a piecewise linear representation
01504 //              of the curve.  Does not rely on an adjacent surface
01505 //              eval tool to project the point
01506 //===========================================================================
01507 CubitStatus CurveFacetEvalTool::project_to_linear_facet_edge(CubitVector &this_point,
01508                                                       CubitVector &closest_point,
01509                                                       CubitVector *tangent_ptr,
01510                                                       CubitVector *curvature_ptr,
01511                                                       double *param,
01512                                                       int *outside )
01513 {
01514   int trim = 0;
01515   int ncheck, ii, nincr=0;
01516   static int ntol=0;
01517   CubitBoolean outside_facet, best_outside_facet;
01518   CubitVector boxmin, boxmax, p0, p1;
01519   CubitVector close_point, best_point;
01520   CubitFacetEdge *best_edge, *edge;
01521 
01522   // so we don't evaluate an edge more than once - mark the edges
01523   // as we evaluate them.  Put the evaluated edges on a used_edge_list
01524   // so we clear the marks off when we are done.  Note: this assumes
01525   // theat marks are initially cleared.
01526   
01527   DLIList<CubitFacetEdge *>used_edge_list;
01528   for(ii=0; ii<myEdgeList.size(); ii++)
01529     myEdgeList.get_and_step()->set_flag(0);
01530   CubitBoolean eval_all = CUBIT_FALSE;
01531 
01532   double tol = facetLength * 1.0e-3;
01533   double facet_tol = facetLength * GEOMETRY_RESABS;
01534   double mindist = CUBIT_DBL_MAX;
01535   double dist = 0.0e0;
01536   CubitBoolean done = CUBIT_FALSE;
01537   while(!done) {
01538 
01539     // define a bounding box around the point
01540 
01541     CubitVector ptmin( this_point.x() - tol, 
01542                        this_point.y() - tol, 
01543                        this_point.z() - tol );
01544 
01545     CubitVector ptmax( this_point.x() + tol, 
01546                this_point.y() + tol, 
01547                this_point.z() + tol );
01548 
01549     ncheck = 0;
01550     best_outside_facet = CUBIT_TRUE;
01551     myEdgeList.reset();
01552     for ( ii = myEdgeList.size(); ii > 0 && !done; ii-- ) 
01553     {
01554       edge = myEdgeList.get_and_step();
01555       
01556 //      if( (edge->get_flag() == 1) ) 
01557 //        continue;
01558 
01559       p0 = edge->point( 0 )->coordinates();
01560       p1 = edge->point( 1 )->coordinates();
01561 
01562       // Try to trivially reject this facet with a bounding box test
01563 
01564       if (!eval_all)
01565       {
01566         boxmin.x( CUBIT_MIN( p0.x(), p1.x() ) );
01567         boxmax.x( CUBIT_MAX( p0.x(), p1.x() ) );
01568           if (ptmax.x() < boxmin.x() ||
01569                 ptmin.x() > boxmax.x()) {
01570           continue;
01571         }
01572         boxmin.y( CUBIT_MIN( p0.y(), p1.y() ) );
01573         boxmax.y( CUBIT_MAX( p0.y(), p1.y() ) );
01574         if (ptmax.y() < boxmin.y() ||
01575                 ptmin.y() > boxmax.y()) {
01576           continue;
01577         }
01578         boxmax.z( CUBIT_MAX( p0.z(), p1.z() ) );
01579         if (ptmax.z() < boxmin.z() ||
01580                 ptmin.z() > boxmax.z()) {
01581           continue;
01582         }
01583       }
01584 
01585       // Only edges that pass the bounding box test will get past here!
01586 
01587       // find distance to this edge
01588       dist = edge->dist_to_edge( this_point, close_point, outside_facet );
01589 
01590       if (dist <= mindist) {
01591         if ((best_outside_facet == CUBIT_FALSE && outside_facet == CUBIT_TRUE)) {
01592           //int x=1;
01593         }
01594         else {
01595           mindist = dist;
01596           best_point = close_point;
01597           best_edge = edge;
01598           best_outside_facet = outside_facet;
01599 
01600           if (dist < facet_tol) {
01601             done = CUBIT_TRUE;
01602           }
01603         }
01604       }
01605       ncheck++;
01606 //      edge->set_flag(1);
01607 //      used_edge_list.append(edge);
01608     }
01609 
01610     // We are done if we found at least one edge.  Otherwise
01611     // increase the tolerance and try again
01612 
01613     nincr++;
01614     if (ncheck > 0) {
01615       done = CUBIT_TRUE;
01616       if (best_outside_facet && nincr < 10) {
01617         done = CUBIT_FALSE;
01618       }
01619     }
01620 
01621     if (!done)
01622     {
01623       if (nincr < 10)
01624       {
01625         tol *= 2.0e0;
01626         ntol++;
01627       }
01628       else {
01629         eval_all = CUBIT_TRUE;
01630       }
01631     }
01632   }
01633 
01634   assert(best_edge != NULL);
01635 
01636   // if the closest point is outside of a facet, then evaluate the point
01637   // on the facet using its area coordinates (otherwise it would be 
01638   // trimmed to an edge or point)
01639 
01640 
01641   if ( !trim && best_outside_facet) {
01642 //    if (best_edge->proj_to_line( this_point, best_point )!= CUBIT_SUCCESS) {
01643     if (best_edge->closest_point( this_point, best_point )!= CUBIT_SUCCESS) {
01644       return CUBIT_FAILURE;
01645     }
01646   }
01647 
01648 
01649   // evaluate the tangent if required
01650  
01651   if (tangent_ptr) {
01652     //get 2 adjacent edges
01653     CubitVector tangent;
01654     if (best_edge->edge_tangent( best_point, tangent ) 
01655       != CUBIT_SUCCESS) {
01656       return CUBIT_FAILURE;
01657     }
01658     if (curvSense == CUBIT_REVERSED)
01659       tangent = -tangent;
01660     *tangent_ptr = tangent;
01661   }
01662 
01663   // evaluate the curvature if required
01664   if (curvature_ptr) {
01665     CubitVector curvature;
01666     myEdgeList.move_to( best_edge );
01667     int index = myEdgeList.get_index();
01668 
01669     //"best_edge" could be last or first on curve 
01670     CubitFacetEdge* prev_edge = NULL; 
01671     myEdgeList.back();
01672     if( (index - 1) == myEdgeList.get_index() ) 
01673       prev_edge = myEdgeList.get();
01674 
01675     CubitFacetEdge* next_edge = NULL; 
01676     myEdgeList.step(2);
01677     if( (index + 1) == myEdgeList.get_index() ) 
01678       next_edge = myEdgeList.get();
01679 
01680 
01681     CubitFacetEdge *closest_edge;
01682     //determine which adjacent edge is closest to "best_point"
01683     if( prev_edge && next_edge )
01684     {
01685       CubitVector tmp_vec;
01686       double prev_dist, next_dist;
01687       tmp_vec = (prev_edge->point(0)->coordinates() + 
01688                  prev_edge->point(1)->coordinates() ) / 2;
01689       prev_dist = best_point.distance_between( tmp_vec ); 
01690 
01691       tmp_vec = (next_edge->point(0)->coordinates() + 
01692                  next_edge->point(1)->coordinates() ) / 2;
01693       next_dist = best_point.distance_between( tmp_vec ); 
01694       
01695       if( prev_dist < next_dist )
01696         closest_edge = prev_edge;
01697       else
01698         closest_edge = next_edge;
01699     }
01700     else if( prev_edge )
01701       closest_edge = prev_edge;
01702     else
01703       closest_edge = next_edge;
01704 
01705     if (best_edge->edge_curvature( best_point, curvature, closest_edge ) != CUBIT_SUCCESS) {
01706       return CUBIT_FAILURE;
01707     }
01708     if (curvSense == CUBIT_REVERSED)
01709       curvature = -curvature;
01710     *curvature_ptr = curvature;
01711   }
01712 
01713   closest_point = best_point;
01714   *outside = best_outside_facet;
01715 
01716   if (param)
01717   {
01718     *param = u_on_facet_edge( best_edge, closest_point );
01719   }
01720 
01721   // clear the marks from the used edges
01722 
01723   for (ii=0; ii<used_edge_list.size(); ii++)
01724   {
01725     edge = used_edge_list.get_and_step();
01726     edge->set_flag( 0 );
01727   }
01728 
01729   
01730   return CUBIT_SUCCESS;
01731 }
01732 
01733 */
01734 //===========================================================================
01735 //Function Name: u_on_facet_edge
01736 //
01737 //Member Type:  PRIVATE
01738 //Description:  return the u param on the facet curve given a point on the
01739 //              curve and the facet edge it is on
01740 //===========================================================================
01741 double CurveFacetEvalTool::u_on_facet_edge( CubitFacetEdge *edge_at_pt, 
01742                                             CubitVector pt )
01743 {
01744   int ii;
01745   double cum_len = 0.0;
01746   CubitBoolean done = CUBIT_FALSE;
01747   myEdgeList.reset();
01748   for (ii=0; ii<myEdgeList.size() && !done; ii++) {
01749     CubitFacetEdge *edge = myEdgeList.get_and_step();
01750     if (edge != edge_at_pt)
01751     {
01752       cum_len += edge->length();
01753     }
01754     else
01755     {
01756       CubitVector pt0;
01757       if (curvSense == CUBIT_REVERSED)
01758       {
01759         pt0 = edge->point( 1 )->coordinates();
01760       }
01761       else
01762       {
01763         pt0 = edge->point( 0 )->coordinates();
01764       }
01765       cum_len += pt.distance_between( pt0 );
01766       done  = CUBIT_TRUE;
01767     }
01768   }
01769   if (!done)
01770   {
01771     PRINT_DEBUG_122( "Error in CurveFacetEvalTool::u_on_facet_edge" );
01772   }
01773   double u = cum_len / facetLength;
01774   return u;
01775 }
01776 
01777 //===========================================================================
01778 //Function Name: destroy_facets
01779 //
01780 //Member Type:  PRIVATE
01781 //Description:  Deletes the points and facets.
01782 //===========================================================================
01783 void CurveFacetEvalTool::destroy_facets()
01784 {
01785 
01786 }
01787   
01788 
01789 //===========================================================================
01790 //Function Name: draw_edges
01791 //
01792 //Member Type:  PRIVATE
01793 //Description:  draw the facet edges 
01794 //===========================================================================
01795 void CurveFacetEvalTool::draw_edges(int color)
01796 {
01797   int ii;
01798   if ( color == -1 )
01799     color = CUBIT_BLUE_INDEX;
01800   for ( ii = myEdgeList.size(); ii > 0; ii-- )
01801   {
01802     CubitFacetEdge *edge = myEdgeList.get_and_step();
01803     CubitPoint *begin_point = edge->point(0);
01804     CubitPoint *end_point = edge->point(1);
01805     GfxDebug::draw_line(begin_point->x(), 
01806                         begin_point->y(), 
01807                         begin_point->z(),
01808                         end_point->x(), 
01809                         end_point->y(), 
01810                         end_point->z(), 
01811                         color);
01812   }
01813   GfxDebug::flush();
01814 }
01815 
01816 //===========================================================================
01817 //Function Name: draw_edge
01818 //
01819 //Member Type:  PRIVATE
01820 //Description:  draw the facet edge 
01821 //===========================================================================
01822 void CurveFacetEvalTool::draw_edge(CubitFacetEdge *edge, int color)
01823 {
01824 
01825   CubitPoint *begin_point = edge->point(0);
01826   CubitPoint *end_point = edge->point(1);
01827   GfxDebug::draw_line(begin_point->x(), 
01828                       begin_point->y(), 
01829                       begin_point->z(),
01830                       end_point->x(), 
01831                       end_point->y(), 
01832                       end_point->z(), 
01833                       color);
01834 
01835   GfxDebug::flush();
01836 }
01837 
01838 //===========================================================================
01839 //Function Name: draw_line
01840 //
01841 //Member Type:  PRIVATE 
01842 //===========================================================================
01843 void CurveFacetEvalTool::draw_line(CubitVector &begin, CubitVector &end, int color)
01844 {
01845   GfxDebug::draw_line(begin.x(), begin.y(), begin.z(),
01846                       end.x(), end.y(), end.z(), color);
01847   GfxDebug::flush();
01848 }
01849 
01850 //===========================================================================
01851 //Function Name: draw_location
01852 //
01853 //Member Type:  PRIVATE 
01854 //===========================================================================
01855 void CurveFacetEvalTool::draw_location(CubitVector &loc, int color )
01856 {
01857   if ( color == -1 )
01858     color = CUBIT_YELLOW_INDEX;
01859   GfxDebug::draw_point(loc, color);
01860   GfxDebug::flush();
01861 }
01862 
01863 //===========================================================================
01864 //Function Name: set_length
01865 //
01866 //Member Type:  PRIVATE
01867 //Description:  compute the length of the facets in this curve
01868 // assumption:  facet edges have been set up
01869 //===========================================================================
01870 void CurveFacetEvalTool::set_length()
01871 {
01872   int ii;
01873   CubitFacetEdge *cf_edge;
01874 
01875   facetLength = 0.0e0;
01876 
01877   for (ii=0; ii<myEdgeList.size(); ii++)
01878   {
01879     cf_edge = myEdgeList.get_and_step();
01880     facetLength += cf_edge->length();
01881   }
01882 
01883 }
01884 
01885 //===========================================================================
01886 //Function Name: save
01887 //
01888 //Member Type:  PUBLIC
01889 //Description:  save the curve facet eval tool to a cubit file  
01890 // Assumption:  contained edge facets have been previuosly saved.  This function
01891 //              saves only the edge facet ids.
01892 //===========================================================================
01893 CubitStatus CurveFacetEvalTool::save( 
01894   FILE *fp )
01895 {
01896   NCubitFile::CIOWrapper cio(fp);
01897   typedef NCubitFile::UnsignedInt32 int32;
01898 
01899     // write out "interpOrder" 
01900   cio.Write(reinterpret_cast<int32*>(&interpOrder), 1);
01901 
01902    // write the associated facet eval tool id.  If there is none then write -1 
01903   int surf_tool_id = -1;
01904   if (surfFacetEvalTool != NULL)
01905     surf_tool_id = surfFacetEvalTool->get_output_id();
01906   cio.Write(reinterpret_cast<int32*>(&surf_tool_id), 1);
01907 
01908     // convert "curvSense" in an int
01909   int sense;
01910   if( curvSense == CUBIT_UNKNOWN )
01911     sense = -1;
01912   else 
01913     sense = (curvSense == CUBIT_REVERSED) ? 1 : 0; 
01914 
01915     // write "curveSense" and "goodCurveData"
01916   cio.Write(reinterpret_cast<int32*>(&sense), 1);
01917   int32 is_good = goodCurveData ? 1 : 0;
01918   cio.Write(&is_good, 1);
01919  
01920     // write "facetLength"
01921   cio.Write( &facetLength, 1 );
01922 
01923     // write ids of facet edges in "myEdgeList"
01924   int ii;
01925   CubitFacetEdge *edge_ptr;
01926   int nedges = myEdgeList.size();
01927   int32* edge_id = new int32 [nedges];
01928   myEdgeList.reset();
01929   for (ii=0; ii<nedges; ii++)
01930   {
01931     edge_ptr = myEdgeList.get_and_step();
01932     edge_id[ii] = edge_ptr->id();
01933   }
01934   cio.Write(reinterpret_cast<int32*>(&nedges), 1);
01935   if (nedges > 0)
01936   {
01937     cio.Write(edge_id, nedges);
01938   }
01939   delete [] edge_id;
01940 
01941     // write ids of points in "myPointList" 
01942   CubitPoint *point_ptr;
01943   int npoints = myPointList.size();
01944   int32* point_id = new int32 [npoints];
01945   myPointList.reset();
01946   for (ii=0; ii<npoints; ii++)
01947   {
01948     point_ptr = myPointList.get_and_step();
01949     point_id[ii] = point_ptr->id();
01950   }
01951   cio.Write(reinterpret_cast<int32*>(&npoints), 1);
01952   if (npoints > 0)
01953   {
01954     cio.Write(point_id, npoints);
01955   }
01956   delete [] point_id;
01957 
01958   return CUBIT_SUCCESS;
01959 }
01960 
01961 //===========================================================================
01962 //Function Name: restore
01963 //Member Type:  PUBLIC
01964 //Description:  restore curve eval tool from a CUB file  
01965 //author: sjowen
01966 //Date:1/28/2003
01967 //===========================================================================
01968 CubitStatus CurveFacetEvalTool::restore(FILE *fp,
01969                       unsigned int endian,
01970                       int num_edges, 
01971                       int num_points,
01972                       CubitFacetEdge **edges, 
01973                       CubitPoint **points,
01974                       int num_fets,
01975                       FacetEvalTool **fet_array)
01976 {
01977   NCubitFile::CIOWrapper cio(endian, fp);
01978   typedef NCubitFile::UnsignedInt32 int32;
01979 
01980     // read stuff about this eval tool
01981 
01982   int ii;
01983   int int_data[4];
01984   cio.Read(reinterpret_cast<int32*>(int_data), 4);
01985   interpOrder = int_data[0];
01986   int surf_tool_id = int_data[1]; 
01987 
01988   if (int_data[2] == -1 )  
01989     curvSense = CUBIT_UNKNOWN;
01990   else
01991     curvSense= int_data[2] ? CUBIT_REVERSED : CUBIT_FORWARD;
01992 
01993   goodCurveData = (int_data[3]==0) ? CUBIT_FALSE : CUBIT_TRUE;
01994 
01995   if( surf_tool_id != -1 )
01996     surfFacetEvalTool = fet_array[ surf_tool_id ]; 
01997   else
01998     surfFacetEvalTool = NULL; 
01999 
02000   cio.Read(&facetLength, 1);
02001 
02002     // read the edges
02003 
02004   int nedges; 
02005   cio.Read(reinterpret_cast<int32*>(&nedges), 1);
02006   if (nedges > 0)
02007   {
02008     int32* edge_id = new int32 [nedges];
02009     cio.Read(edge_id, nedges);
02010     int id;
02011     for (ii=0; ii<nedges; ii++)
02012     {
02013       id = edge_id[ii];
02014       if (id <0 || id >= num_edges)
02015       {
02016         delete [] edge_id;
02017         return CUBIT_FAILURE;
02018       }
02019       myEdgeList.append(edges[id]);
02020     }
02021     delete [] edge_id;
02022   }
02023   
02024     // read the points
02025 
02026   int npoints; 
02027   cio.Read(reinterpret_cast<int32*>(&npoints), 1);
02028   int id;
02029   if (npoints > 0)
02030   {
02031     int32* point_id = new int32 [npoints];
02032     cio.Read(point_id, npoints);
02033     for (ii=0; ii<npoints; ii++)
02034     {
02035       id = point_id[ii];
02036       if (id <0 || id >= num_points)
02037       {
02038         delete [] point_id;
02039         return CUBIT_FAILURE;
02040       }
02041       myPointList.append(points[id]);
02042     }
02043     delete [] point_id;
02044   }
02045 
02046   bounding_box();
02047 
02048   return CUBIT_SUCCESS;
02049 }
02050 
02051 CubitStatus CurveFacetEvalTool::fix_point_edge_order()
02052 {
02053   CubitFacetEdge* this_edge;
02054   CubitFacetEdge* next_edge;
02055   CubitPoint *this_pt1;
02056   CubitPoint *next_pt0, *next_pt1;
02057   
02058   if( myEdgeList.size() == 0 )
02059     return CUBIT_FAILURE;
02060 
02061   this_edge = myEdgeList.get_and_step();
02062   int ii;
02063   for( ii = myEdgeList.size() - 1; ii > 0; ii-- )
02064   {
02065     if( 0 != this_edge->num_adj_facets() )
02066        continue;
02067     
02068     next_edge = myEdgeList.get_and_step();
02069 
02070     this_pt1 = this_edge->point( 1 );
02071     next_pt0 = next_edge->point( 0 );
02072     next_pt1 = next_edge->point( 1 );
02073 
02074     if( this_pt1 != next_pt0 &&
02075         this_pt1 != next_pt1 )
02076     {
02077         //Swap direction of edge.  (mod. 3-7-06)  Now calling flip instead
02078         // of doing the flip manually.  The flip function also tracks
02079         // the orientation so that we can remember the original orientation
02080         // of the edge.
02081       this_edge->flip();
02082       
02083     }
02084     
02085     this_edge = next_edge;
02086   }
02087     //Handle last edge
02088   next_edge = myEdgeList.prev(2);
02089   if( 0 == this_edge->num_adj_facets() )
02090   {
02091     CubitPoint* this_pt0 = this_edge->point( 0 );
02092     next_pt0 = next_edge->point( 0 );
02093     next_pt1 = next_edge->point( 1 );
02094 
02095     if( this_pt0 != next_pt0 &&
02096         this_pt0 != next_pt1 )
02097     {
02098         //Swap direction of edge.(mod. 3-7-06)  Now calling flip instead
02099         // of doing the flip manually.  The flip function also tracks
02100         // the orientation so that we can remember the original orientation
02101         // of the edge.
02102       this_edge->flip();
02103       
02104     }
02105   }
02106 
02107   return CUBIT_SUCCESS;
02108 }
02109 //===========================================================================
02110 //Function Name: debug_draw_facet_edges
02111 //
02112 //Member Type:  PUBLIC
02113 //Descriptoin:  draw the facet edges for debug 
02114 //===========================================================================
02115 void CurveFacetEvalTool::debug_draw_facet_edges( int color )
02116 {
02117   draw_edges(color);
02118 }
02119 
02120 CubitBoolean CurveFacetEvalTool::replace_point( CubitPoint *del_pnt, CubitPoint *keep_pnt )
02121 {
02122   CubitPoint *point_ptr;
02123   int npoints = myPointList.size();
02124   myPointList.reset();
02125   CubitBoolean istat = CUBIT_FALSE;
02126   int i;
02127   for ( i = 0; i < npoints; i++ )
02128   {
02129     point_ptr = myPointList.get();
02130     
02131     if( point_ptr == del_pnt )
02132     {
02133       myPointList.remove();
02134       myPointList.insert( keep_pnt );
02135       istat = CUBIT_TRUE;
02136     }
02137     myPointList.step();
02138   }
02139   
02140   return istat;
02141 }
02142 
02143 
02144 CubitBoolean CurveFacetEvalTool::replace_facets( DLIList< CubitFacetEdge *> &curv_edges )
02145 {
02146 
02147   // replace edges 
02148   this->myEdgeList = curv_edges;
02149 
02150   // replace points
02151   DLIList<CubitPoint *> point_list;
02152   int i;
02153   // insert start point of every facet_edge
02154   curv_edges.reset();
02155   for( i = 0; i < curv_edges.size(); i++ )
02156   {
02157     point_list.append( CAST_TO( curv_edges.get_and_step(), CubitFacetEdge )->point(0) );
02158   }
02159   // insert end point of last facet_edge
02160   curv_edges.step( curv_edges.size() - 1 );
02161   point_list.append( CAST_TO( curv_edges.get(), CubitFacetEdge )->point(1) );
02162   this->myPointList = point_list;
02163 
02164   return CUBIT_TRUE;
02165 }
02166 
02167 
02168 void CurveFacetEvalTool::remove_facets( DLIList<CubitFacetEdge*> &facet_edges)
02169 {
02170   facet_edges = myEdgeList;
02171   myEdgeList.clean_out();
02172   myPointList.clean_out();
02173 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines