cgma
ImprintBoundaryTool.cpp
Go to the documentation of this file.
00001 //--------------------------------------------------------------------------
00002 //  Class: ImprintBoundaryTool
00003 //  Description:  Imprints the boundaries of two surfaces.  The boundaries
00004 //                are discritized or faceted, and the then intersected.
00005 //                Virtual geometry is used for the actual imprinting of the
00006 //                topology.
00007 //  Owner: David R. White
00008 //  Creation Date: 4/15/2002
00009 //--------------------------------------------------------------------------
00010 #include "ImprintBoundaryTool.hpp"
00011 #include "ImprintPointData.hpp"
00012 #include "ImprintLineSegment.hpp"
00013 #include "RefFace.hpp"
00014 #include "RefEdge.hpp"
00015 #include "RefVertex.hpp"
00016 #include "CoEdge.hpp"
00017 #include "Loop.hpp"
00018 #include "GeometryQueryEngine.hpp"
00019 #include "Curve.hpp"
00020 #include "DLIList.hpp"
00021 #include "CubitVector.hpp"
00022 #include "GMem.hpp"
00023 #include "GfxDebug.hpp"
00024 #include "CubitBox.hpp"
00025 #include "CastTo.hpp"
00026 #include "IntersectionTool.hpp"
00027 #include "PartitionTool.hpp"
00028 //#include "VirtualQueryEngine.hpp"
00029 #include "GeometryQueryTool.hpp"
00030 #include "MergeTool.hpp"
00031 #include "KDDTree.hpp"
00032 #include "AbstractTree.hpp"
00033 #include "FacetModifyEngine.hpp"
00034 #include "Point.hpp"
00035 #include "FacetCurve.hpp"
00036 #include "CubitPointData.hpp"
00037 #include "CubitFacetEdgeData.hpp"
00038 #include "CubitFacetEdge.hpp"
00039 #include "CurveFacetEvalTool.hpp"
00040 #include "AppUtil.hpp"
00041 #include "GeometryEvent.hpp"
00042 
00043 //-----------------------------------------------------
00044 // Constructor
00045 //-----------------------------------------------------
00046 ImprintBoundaryTool::ImprintBoundaryTool(RefFace *ref_face_1,
00047                                          RefFace *ref_face_2,
00048                                          double tol)
00049 {
00050   refFacePtr1 = ref_face_1;
00051   refFacePtr2 = ref_face_2;
00052   myTolerance = tol;
00053   modBound1 = CUBIT_FALSE;
00054   modBound2 = CUBIT_FALSE;
00055   allocatedPointData = new PointList;
00056   allocatedLineData =  new SegList;
00057   allocatedPointLoops =  new PointLoopList;
00058   allocatedLineLoops =  new SegLoopList;
00059   allocatedMatchData = new DLIList<ImprintMatchData*>;
00060   allocatedRefEdge = new DLIList<RefEdge*>;
00061 }
00062 //-----------------------------------------------------
00063 // Destructor
00064 //-----------------------------------------------------
00065 ImprintBoundaryTool::~ImprintBoundaryTool()
00066 {
00067   int ii;
00068   for ( ii = allocatedPointData->size(); ii > 0; ii-- )
00069     delete allocatedPointData->pop();
00070   delete allocatedPointData;
00071   for ( ii = allocatedLineData->size(); ii > 0; ii-- )
00072     delete allocatedLineData->pop();
00073   delete allocatedLineData;
00074   for ( ii = allocatedPointLoops->size(); ii > 0; ii-- )
00075     delete allocatedPointLoops->pop();
00076   delete allocatedPointLoops;
00077   for ( ii = allocatedLineLoops->size(); ii > 0; ii-- )
00078     delete allocatedLineLoops->pop();
00079   delete allocatedLineLoops;
00080   for ( ii = allocatedMatchData->size(); ii > 0; ii-- )
00081     delete allocatedMatchData->pop();
00082   delete allocatedMatchData;
00083   for ( ii = allocatedRefEdge->size(); ii > 0; ii-- )
00084   {
00085     RefEdge *tmp_edge_ptr = allocatedRefEdge->pop();
00086     if ( tmp_edge_ptr->num_ref_faces() == 0 )
00087     {
00088       RefEntity *tmp_ent = CAST_TO(tmp_edge_ptr, RefEntity);
00089       GeometryQueryTool::instance()->delete_RefEntity(tmp_ent);
00090     }
00091   }
00092 
00093 }
00094 //-----------------------------------------------------
00095 // Public Function: imprint
00096 // Description: Does the actual imprinting of the boundaries
00097 //              of the two surfaces passed in. This funcntion
00098 //              is the primary interface for the tool.
00099 //-----------------------------------------------------
00100 CubitStatus ImprintBoundaryTool::imprint(DLIList <RefFace*> &results,
00101                                          CubitBoolean merge)
00102 {
00103   CubitBox ref_box1 = refFacePtr1->bounding_box();
00104   CubitBox ref_box2 = refFacePtr2->bounding_box();
00105 
00106   if ( !ref_box1.overlap(myTolerance, ref_box2 ) )
00107     return CUBIT_SUCCESS;
00108   if ( refFacePtr1->num_loops() == 0 ||
00109       refFacePtr2->num_loops() == 0 )
00110   {
00111     PRINT_WARNING("Virtual imprinting currently can't imprint\n"
00112                   "surfaces that have no boundary curves (surfaces %d or %d\n"
00113                   "has no boundary curves.\n", refFacePtr1->id(), refFacePtr2->id());
00114     return CUBIT_SUCCESS;
00115   }
00116   if ( merge )
00117     PRINT_WARNING("Can't merge while virtual imprinting yet.\n");
00118   PRINT_DEBUG_129("Imprinting surfaces: %d and %d\n",
00119                   refFacePtr1->id(),
00120                   refFacePtr2->id() );
00121   int debug5 = 0;
00122   if ( debug5)
00123   {
00124     GfxDebug::clear();
00125     GfxDebug::draw_ref_face_edges(refFacePtr1, CUBIT_GREEN_INDEX);
00126     GfxDebug::draw_ref_face_edges(refFacePtr2, CUBIT_YELLOW_INDEX);
00127     GfxDebug::flush();
00128     GfxDebug::mouse_xforms();
00129     CubitMessage::instance()->debug_flag(129, CUBIT_TRUE);
00130   }
00131   int ii, jj;
00132   PointLoopList boundary_point_loops1;
00133   PointLoopList boundary_point_loops2;
00134   CubitStatus stat = get_boundary_points(refFacePtr1,
00135                                          boundary_point_loops1);
00136   if ( stat != CUBIT_SUCCESS )
00137     return stat;
00138 
00139   stat = get_boundary_points(refFacePtr2,
00140                              boundary_point_loops2);
00141   if ( stat != CUBIT_SUCCESS )
00142     return stat;
00143   boundary_point_loops1.reset();
00144   boundary_point_loops2.reset();
00145   if ( DEBUG_FLAG(129) )
00146   {
00147       //Drawing the boundary loops.
00148     GfxDebug::clear();
00149     GfxDebug::flush();
00150     PointList *point_list;
00151     for ( ii = boundary_point_loops1.size(); ii > 0; ii-- )
00152     {
00153       point_list = boundary_point_loops1.get_and_step();
00154       for ( jj = point_list->size(); jj > 0; jj-- )
00155       {
00156         ImprintPointData *point = point_list->get_and_step();
00157         //RefEntity *entity = point->owner();
00158         draw_point(point);
00159       }
00160     }
00161     if (debug5)
00162     {
00163       GfxDebug::mouse_xforms();
00164       GfxDebug::clear();    
00165       GfxDebug::draw_ref_face_edges(refFacePtr2);
00166       GfxDebug::flush();
00167     }
00168     for ( ii = boundary_point_loops2.size(); ii > 0; ii-- )
00169     {
00170       point_list = boundary_point_loops2.get_and_step();
00171       for ( jj = point_list->size(); jj > 0; jj-- )
00172       {
00173         ImprintPointData *point = point_list->get_and_step();
00174         //RefEntity *entity = point->owner();
00175         draw_point(point);
00176       }
00177     }
00178     if (debug5)
00179     {
00180       GfxDebug::mouse_xforms();
00181     }
00182   }
00183     //Now intersect the two boundary loops.  Either mark the nodes
00184     //that are intersecting, or insert new nodes into the boundary loops,
00185     //that intersect the boundaries.
00186   stat = imprint_boundaries( boundary_point_loops1,
00187                              boundary_point_loops2,
00188                              refFacePtr1, refFacePtr2,
00189                              results);
00190   if ( results.size() == 0 )
00191   {
00192     if ( modBound1 )
00193       results.append(refFacePtr1);
00194     if ( modBound2 )
00195       results.append(refFacePtr2);
00196   }
00197   if ( stat != CUBIT_SUCCESS )
00198   {
00199     PRINT_ERROR("Imprinting Surface %d and %d failed\n",
00200                 refFacePtr1->id(), refFacePtr2->id() );
00201     return CUBIT_FAILURE;
00202   }
00203   return CUBIT_SUCCESS;
00204 }
00205 CubitStatus ImprintBoundaryTool::get_boundary_points( RefFace *ref_face,
00206                                                       PointLoopList &boundary_point_loops )
00207 {
00208   DLIList<DLIList<CoEdge*> > co_edge_loops;
00209   ref_face->co_edge_loops(co_edge_loops);
00210   int ii, jj;
00211   PointList *new_point_loop_ptr, tmp_point_list;
00212   RefEdge *ref_edge_ptr;
00213   CoEdge *co_edge_ptr;
00214   CubitStatus stat;
00215   CubitSense sense;
00216   RefEntity *temp_ref;
00217   RefVertex *temp_vert;
00218   
00219   for ( ii = co_edge_loops.size(); ii > 0; ii-- )
00220   {
00221     DLIList <CoEdge*> &co_edge_list_ptr = co_edge_loops.get_and_step();
00222     new_point_loop_ptr = new PointList;
00223     allocatedPointLoops->append(new_point_loop_ptr);
00224     for ( jj = co_edge_list_ptr.size(); jj > 0; jj-- )
00225     {
00226       co_edge_ptr = co_edge_list_ptr.get_and_step();
00227       ref_edge_ptr = co_edge_ptr->get_ref_edge_ptr();
00228       tmp_point_list.clean_out();
00229       stat = get_curve_facets( ref_edge_ptr, tmp_point_list );
00230       PRINT_DEBUG_129("curve %d has %d points\n",
00231                       ref_edge_ptr->id(),
00232                       tmp_point_list.size());
00233       if ( stat != CUBIT_SUCCESS ) {
00234         return CUBIT_FAILURE;
00235       }
00236       tmp_point_list.reset();
00237         //the points are in order from start vertex to end vertex.
00238         //append them now according to the loop.
00239 
00240         //Assign the points to be part owned by the vertex, rather than the
00241         //curve.
00242       if ( ref_edge_ptr->start_vertex() !=
00243            ref_edge_ptr->end_vertex() )
00244       {
00245         ImprintPointData *temp_point = tmp_point_list.get();
00246         CubitVector v1 = temp_point->coordinates();
00247         CubitVector v2 = ref_edge_ptr->start_vertex()->coordinates();
00248         if ( !v1.within_tolerance(v2, myTolerance) )
00249         {
00250           PRINT_ERROR("Problem with surface geometry\n"
00251                       "Check surface %d and %d, especially curve %d\n",
00252                       refFacePtr1->id(), refFacePtr2->id(), ref_edge_ptr->id());
00253         }
00254         temp_vert = ref_edge_ptr->start_vertex();
00255         temp_ref = CAST_TO(temp_vert, RefEntity);
00256         temp_point->owner(temp_ref);
00257         temp_point = tmp_point_list.prev();
00258         v1 = temp_point->coordinates();
00259         v2 = ref_edge_ptr->end_vertex()->coordinates();
00260         if (!v1.within_tolerance(v2, myTolerance))
00261         {
00262           PRINT_ERROR("Problem with surface geometry\n"
00263                       "Check surface %d and %d, especially curve %d\n",
00264                       refFacePtr1->id(), refFacePtr2->id(), ref_edge_ptr->id());
00265           return CUBIT_FAILURE;
00266         }
00267         temp_vert = ref_edge_ptr->end_vertex();
00268         temp_ref = CAST_TO(temp_vert, RefEntity);
00269         temp_point->owner(temp_ref);
00270       }
00271       else
00272       {
00273         ImprintPointData *temp_point = tmp_point_list.get();
00274         CubitVector v1 = temp_point->coordinates();
00275         CubitVector v2 = ref_edge_ptr->start_vertex()->coordinates();
00276         if ( !v1.about_equal(v2) )
00277         {
00278           temp_point = tmp_point_list.prev();
00279           v1 = temp_point->coordinates();
00280           v2 = ref_edge_ptr->start_vertex()->coordinates();
00281           assert(v1.about_equal(v2));
00282         }
00283         temp_vert = ref_edge_ptr->end_vertex();
00284         temp_ref = CAST_TO( temp_vert, RefEntity );
00285         temp_point->owner(temp_ref);
00286       }
00287       tmp_point_list.reset();
00288       sense = co_edge_ptr->get_sense();
00289       if ( CUBIT_FORWARD != sense )
00290         tmp_point_list.reverse();
00291         //Now take off the last point as it is a duplicate with the
00292         //other list...
00293       tmp_point_list.reset();
00294       if ( co_edge_list_ptr.size() != 1 )
00295         tmp_point_list.pop();
00296       (*new_point_loop_ptr) += tmp_point_list;
00297 
00298       if ( num_coedges_on_face(ref_edge_ptr, ref_face) > 1 )
00299       {
00300         PRINT_ERROR("Surface %d has a sipe or hard line.\n"
00301                     "Virtual imprinting does not support that type\n"
00302                     "of surface.\n", ref_face->id());
00303         return CUBIT_FAILURE;
00304       }
00305     }
00306     CubitVector curr, prev;
00307     for ( jj = new_point_loop_ptr->size(); jj > 0; jj-- )
00308     {
00309       prev = new_point_loop_ptr->prev()->coordinates();
00310       curr = new_point_loop_ptr->get_and_step()->coordinates();
00311       if ( prev.about_equal(curr) )
00312       {
00313         PRINT_DEBUG_129("Points within tolerance in boundaryloop.\n");
00314         int debug = 0;
00315         if ( debug )
00316         {
00317           GfxDebug::draw_point(new_point_loop_ptr->prev(3)->coordinates(), CUBIT_RED_INDEX);
00318           GfxDebug::draw_point(new_point_loop_ptr->prev(2)->coordinates(), CUBIT_YELLOW_INDEX);
00319           GfxDebug::draw_point(new_point_loop_ptr->prev()->coordinates(), CUBIT_BLUE_INDEX);
00320           GfxDebug::draw_point(new_point_loop_ptr->get()->coordinates(), CUBIT_GREEN_INDEX);
00321         }
00322         new_point_loop_ptr->back();
00323         new_point_loop_ptr->remove();
00324       }
00325     }
00326     boundary_point_loops.append(new_point_loop_ptr);
00327   }
00328   CubitVector curr1, curr2;
00329   int kk, ll;
00330   PointList *check_list;
00331   double min_dist = CUBIT_DBL_MAX;
00332   PointLoopList boundary_point_loops2 = boundary_point_loops;
00333   for ( ii = boundary_point_loops.size(); ii > 0; ii-- )
00334   {
00335     new_point_loop_ptr = boundary_point_loops.get_and_step();
00336     for ( kk = boundary_point_loops.size(); kk > 0; kk-- )
00337     {
00338       check_list = boundary_point_loops2.get_and_step();
00339       if ( new_point_loop_ptr == check_list )
00340         continue;
00341       for ( jj = new_point_loop_ptr->size(); jj > 0; jj-- )
00342       {
00343         curr1 = new_point_loop_ptr->get_and_step()->coordinates();
00344         for ( ll = check_list->size(); ll > 0; ll-- )
00345         {
00346           curr2 = check_list->get_and_step()->coordinates();
00347           if (curr1.about_equal(curr2, myTolerance) )
00348           {
00349             double dist = (curr1-curr2).length();
00350             if ( dist < min_dist )
00351               min_dist = dist;
00352           }
00353         }
00354       }
00355     }
00356   }
00357   if ( min_dist < CUBIT_DBL_MAX && min_dist < myTolerance  )
00358   {
00359     PRINT_INFO("Two loops on Surface %d are within tolerance of each other!\n",
00360                ref_face->id());
00361             
00362     PRINT_INFO("Changing the tolerance to less than %f\n"
00363                "(the smallest distance between the two loops.)\n",
00364                min_dist);
00365 
00366     myTolerance = min_dist/4;
00367     PRINT_INFO("For surface %d and %d tolerance changed to %f\n",
00368                refFacePtr1->id(), refFacePtr2->id(), myTolerance);
00369       //return CUBIT_FAILURE;
00370   }
00371   
00372   return CUBIT_SUCCESS;
00373 }
00374 
00375 CubitStatus ImprintBoundaryTool::get_curve_facets( RefEdge* curve, PointList &segments ) 
00376 {
00377 //  const double COS_ANGLE_TOL =  0.965925826289068312213715; // cos(15)
00378 //  const double COS_ANGLE_TOL =  0.984807753012208020315654; // cos(10)
00379   //const double COS_ANGLE_TOL =  0.996194698091745545198705; // cos(5)
00380   GMem curve_graphics;
00381     //make this tol bigger than myTolerance, to
00382     //make sure the segments are larger than the tolerance.
00383   const double dist_tol = 2*myTolerance + .5*myTolerance;// + .05*myTolerance;
00384   //const double dist_tol_sqr = dist_tol*dist_tol;
00385   Curve* curve_ptr = curve->get_curve_ptr();
00386   curve_ptr->get_geometry_query_engine()->get_graphics( curve_ptr, &curve_graphics );
00387   
00388   GPoint* gp = curve_graphics.point_list();
00389   ImprintPointData* last = new ImprintPointData( gp[0].x, gp[0].y, gp[0].z );
00390   allocatedPointData->append(last);
00391   last->owner(dynamic_cast<RefEntity*>(curve));
00392   CubitVector lastv = last->coordinates();
00393   int num_points = curve_graphics.pointListCount;
00394   segments.append( last );
00395   int ii;
00396   CubitBoolean remove_second_to_end = CUBIT_FALSE;
00397   for ( ii = 1; ii < num_points; ii++ )
00398   {
00399     CubitVector pos(  gp[ii].x, gp[ii].y, gp[ii].z );
00400     CubitVector step1 = (pos - lastv);
00401     double len1 = step1.length();
00402     if( len1 < dist_tol && ii != num_points - 1) 
00403       continue;
00404     else if ( len1 < dist_tol && ii == num_points-1 )
00405     {
00406       remove_second_to_end = CUBIT_TRUE;
00407     }
00408     last = new ImprintPointData( pos );
00409     if ( DEBUG_FLAG(129) )
00410       draw_point(last);
00411     allocatedPointData->append(last);
00412     last->owner(dynamic_cast<RefEntity*>(curve));
00413     segments.append( last );
00414     lastv = last->coordinates();
00415   }
00416     // Now check if the segment list is reversed wrt the curve direction.
00417   segments.reset();
00418   if ( remove_second_to_end )
00419   {
00420     if ( segments.size() == 2 )
00421     {
00422       PRINT_DEBUG_129("Tolerance size is small for imprinting\n" 
00423                       "(curve %d is small)\n",
00424                       curve->id());
00425       double leng = curve->measure();
00426       if ( leng < myTolerance )
00427       {
00428         PRINT_ERROR("Tolerance for surfaces %d and %d is too small.\n"
00429                     "Curve %d is of size %f.  Try making the tolerance\n"
00430                     "1/4 of that value or (%f).\n", refFacePtr1->id(),
00431                     refFacePtr2->id(), curve->id(), leng, leng/4.0);
00432         return CUBIT_FAILURE;
00433       }
00434     }
00435     else
00436     {
00437         //Remove the second to last one.  To do
00438         //this efficiently (don't do remove), pop
00439         //the last one, then save that and
00440         //re-add it after poping the second one.
00441       ImprintPointData *temp = segments.pop();
00442       segments.pop();
00443       segments.append(temp);
00444     }
00445   }
00446   segments.reset();
00447   if( curve->start_vertex() != curve->end_vertex() )
00448   {
00449     CubitVector start_vec, end_vec;
00450     start_vec = curve->start_vertex()->coordinates();
00451     end_vec = curve->end_vertex()->coordinates();
00452     CubitVector start_seg = segments.get()->coordinates();
00453     double dist_1 = (start_seg - start_vec).length_squared();
00454     double dist_2 = (start_seg - end_vec).length_squared();
00455     if ( dist_1 > dist_2 )
00456       segments.reverse();
00457       //Now make sure that the start and end vertices are "right-on" with
00458       //the facet representations...
00459     segments.reset();
00460     start_seg = segments.get()->coordinates();
00461     CubitVector end_seg = segments.prev()->coordinates();
00462       //make sure the start and end positions match up "exactly"
00463       //with the vertex coordinates of the curves.  The facets sometimes
00464       //aren't really "right-on"
00465     segments.get()->set(start_vec);
00466     segments.prev()->set(end_seg);
00467   }
00468   else
00469   {
00470     double u1, u2;
00471     u1 = curve->u_from_position( (segments.next(1)->coordinates()) );
00472     u2 = curve->u_from_position( (segments.next(2)->coordinates()) );    
00473     if( (u2 < u1) && (curve->start_param() <= curve->end_param()) )
00474       segments.reverse();
00475   }
00476     //clean up the periodic curve case (last seg may be too small.)
00477   if ( curve->start_vertex() == curve->end_vertex() )
00478   {
00479     segments.reset();
00480     CubitVector start_v = segments.get()->coordinates();
00481     CubitVector last_v = segments.prev()->coordinates();
00482     double dist = (start_v - last_v).length();
00483     if ( dist < dist_tol )
00484     {
00485         //remove the last one.
00486       segments.pop();
00487     }
00488       //now make sure the one vertex matches up "exactly" with the
00489       //first segement.
00490     segments.reset();
00491     CubitVector start_vec = curve->start_vertex()->coordinates();
00492       //replace start_seg with start_vec.
00493     segments.get()->set(start_vec);
00494   }
00495     
00496     //Make sure we don't have duplicate points.
00497   int jj;
00498   CubitVector curr, prev;
00499   for ( jj = segments.size(); jj > 0; jj-- )
00500   {
00501     prev = segments.prev()->coordinates();
00502     curr = segments.get_and_step()->coordinates();
00503     if ( prev.about_equal(curr) )
00504     {
00505       PRINT_DEBUG_129("Points on curve %d within tolerance...\n", curve->id());
00506       segments.back();
00507       segments.remove();
00508     }
00509   }
00510   if ( segments.size() < 2 )
00511   {
00512     PRINT_ERROR("Tolerance size is too small for imprinting\n"
00513                 "(curve %d is small)\n",
00514                 curve->id());
00515     return CUBIT_FAILURE;
00516   }
00517   return CUBIT_SUCCESS;
00518 }
00519 //CubitStatus ImprintBoundaryTool::find_intersections(PointLoopList &boundary_line_loops_1,
00520 //                                                    PointLoopList &boundary_line_loops_2,
00521 //--------------------------------------------------------
00522 // Public Function: imprint_boundaries
00523 // Description: Given the two lists of boundary loops, where
00524 //              the nodes in the loops are assumed to be from either
00525 //              a refedge or a refvertex, intersect them with the other
00526 //              loops.
00527 //--------------------------------------------------------
00528 CubitStatus ImprintBoundaryTool::imprint_boundaries(PointLoopList &boundary_loops_1,
00529                                                     PointLoopList &boundary_loops_2,
00530                                                     RefFace *ref_face_1,
00531                                                     RefFace *ref_face_2,
00532                                                     DLIList <RefFace*> &results)
00533 {
00534   int ii, jj;
00535   SegLoopList boundary_line_loops_1, boundary_line_loops_2;
00536   
00537     //Now convert the point lists to line segments.
00538     //REMEMBER, delete all the data from boundary_line_loops, the lists and the data...
00539   CubitStatus st = convert_to_lines( boundary_loops_1, boundary_line_loops_1, ref_face_1, CUBIT_TRUE);
00540   if ( st != CUBIT_SUCCESS )
00541   {
00542     return CUBIT_FAILURE;
00543   }
00544   st = convert_to_lines( boundary_loops_2, boundary_line_loops_2, ref_face_2, CUBIT_FALSE);
00545   if ( st != CUBIT_SUCCESS )
00546   {
00547     return CUBIT_FAILURE;
00548   }
00549   if ( boundary_line_loops_1.size() == 0 || boundary_line_loops_2.size() == 0 )
00550     return CUBIT_FAILURE;    
00551   //Do the actual intersecting and imprinting.  Basically splits segments and
00552     //matches the points on the two boundaries.  Also classifies the connections.
00553   CubitStatus stat = imprint_segments( boundary_line_loops_1,
00554                                        boundary_line_loops_2,
00555                                        boundary_loops_1,
00556                                        boundary_loops_2);
00557 
00558   if (stat != CUBIT_SUCCESS )
00559     return CUBIT_FAILURE;
00560     //Note that the boundary_line_loops are outof date at this point and shouldn't be used. 
00561     //These lists are also stored in the allocatedLineLoops list and the memory will be
00562     //cleaned up in the destructor.  Just clean them out to avoid useing the data.
00563   boundary_line_loops_1.clean_out();
00564   boundary_line_loops_2.clean_out();
00565   
00566     //Mark each node as to which loop its in and its position
00567     //for efficient searching.
00568   PointList *point_loop;
00569   for ( ii = 0; ii < boundary_loops_1.size(); ii++ )
00570   {
00571     point_loop = boundary_loops_1.get_and_step();
00572     int loop_size = point_loop->size();
00573     for ( jj = 0; jj < loop_size; jj++ )
00574       point_loop->get_and_step()->set_loop_pos(ii,jj, loop_size);
00575   }
00576   for ( ii = 0; ii < boundary_loops_2.size(); ii++ )
00577   {
00578     point_loop = boundary_loops_2.get_and_step();
00579     int loop_size = point_loop->size();
00580     for ( jj = 0; jj < loop_size; jj++ )
00581       point_loop->get_and_step()->set_loop_pos(ii,jj, loop_size);
00582   }
00583 
00584     //Now go through and find the curves that need to be created, and vertices
00585     //that need to be imprinted for each surface.
00586   PointLoopList part_segs_1, part_segs_2;
00587   PointList partition_points_1, partition_points_2;
00588   
00589   stat = find_graph_for_surf( boundary_loops_1,
00590                               boundary_loops_2,
00591                               ref_face_1,
00592                               part_segs_1,
00593                               partition_points_1,
00594                               CUBIT_TRUE);
00595   if ( stat != CUBIT_SUCCESS )
00596     return CUBIT_FAILURE;
00597   stat = find_graph_for_surf( boundary_loops_2,
00598                               boundary_loops_1,
00599                               ref_face_2,
00600                               part_segs_2,
00601                               partition_points_2,
00602                               CUBIT_FALSE);
00603   if ( stat != CUBIT_SUCCESS )
00604     return CUBIT_FAILURE;
00605   
00606     //Okay now go through and partition the boundaries.
00607   CubitBoolean mod_bound1, mod_bound2;
00608   stat = imprint_boundary_vertices( partition_points_1,
00609                                     mod_bound1);
00610   if ( stat != CUBIT_SUCCESS )
00611     return CUBIT_FAILURE;
00612   stat = imprint_boundary_vertices( partition_points_2,
00613                                     mod_bound2);
00614   if ( stat != CUBIT_SUCCESS )
00615     return CUBIT_FAILURE;
00616     //Now go through and paritition the surfaces.
00617   DLIList<RefFace*> results_1, results_2;
00618   stat = imprint_surface(ref_face_1, part_segs_1, results_1);
00619   if ( stat != CUBIT_SUCCESS )
00620     return CUBIT_FAILURE;
00621   stat = imprint_surface(ref_face_2, part_segs_2, results_2);
00622   if ( stat != CUBIT_SUCCESS )
00623     return CUBIT_FAILURE;
00624   if ( mod_bound1 || results_1.size() )
00625     modBound1 = CUBIT_TRUE;
00626   if ( mod_bound2 || results_2.size() )
00627     modBound2 = CUBIT_TRUE;
00628   results += results_1;
00629   results += results_2;
00630   return CUBIT_SUCCESS;
00631 }
00632 
00633 CubitStatus ImprintBoundaryTool::intersect_segments( ImprintLineSegment *seg_1,
00634                                                      ImprintLineSegment *seg_2,
00635                                                      IntersectResult &int_result,
00636                                                      ImprintLineSegment **new_segments)
00637 {
00638   int ii;
00639     //initialize the results first.
00640   for ( ii = 0; ii < 4; ii++)
00641     new_segments[ii] = NULL;
00642   ImprintPointData* imp_point_0 = seg_1->get_start();
00643   ImprintPointData* imp_point_1 = seg_1->get_end();
00644   ImprintPointData* imp_point_2 = seg_2->get_start();
00645   ImprintPointData* imp_point_3 = seg_2->get_end();
00646   int debug4 = 0;
00647   if ( debug4 )
00648   {
00649     draw_point(imp_point_0);
00650     draw_point(imp_point_1);
00651     draw_point(imp_point_2);
00652     draw_point(imp_point_3);
00653   }
00654   int debug = 0;
00655     //First go through and test the end points.
00656     //This will test for cases L_INTERSECT, and SEGS_EQUAL, and OVERLAP_JOIN.
00657   MatchType type_0, type_1, type_2, type_3;
00658   CubitStatus stat1 = match_points(seg_1, seg_2,type_0,
00659                                    type_1, type_2, type_3);
00660     //First handle the basic stuff;
00661   if ( type_0 == MATCH_0_2 && type_1 == MATCH_1_3 &&
00662        type_2 == MATCH_0_2 && type_3 == MATCH_1_3 )
00663   {
00664     imp_point_0->set_matching_point(imp_point_2);
00665     imp_point_2->set_matching_point(imp_point_0);
00666     imp_point_1->set_matching_point(imp_point_3);
00667     imp_point_3->set_matching_point(imp_point_1);
00668     
00669       //These segments are equal.
00670     set_type_for_equal(imp_point_0, imp_point_2,
00671                        imp_point_1, imp_point_3);
00672     int_result = SEGS_EQUAL_0_2;
00673     PRINT_DEBUG_129("Found SEGS_EQUAL_0_2\n");
00674     return CUBIT_SUCCESS;
00675   }
00676   else if ( type_0 == MATCH_0_3 && type_1 == MATCH_1_2 &&
00677             type_3 == MATCH_0_3 && type_2 == MATCH_1_2 )
00678   {
00679     imp_point_0->set_matching_point(imp_point_3);
00680     imp_point_3->set_matching_point(imp_point_0);
00681     imp_point_1->set_matching_point(imp_point_2);
00682     imp_point_2->set_matching_point(imp_point_1);
00683     
00684       //These segments are equal.
00685     set_type_for_equal(imp_point_0, imp_point_3,
00686                        imp_point_1, imp_point_2);
00687     int_result = SEGS_EQUAL_0_3;
00688     PRINT_DEBUG_129("Found SEGS_EQUAL_0_3\n");
00689     return CUBIT_SUCCESS;
00690   }
00691   else if ( type_0 == MATCH_0_2 && type_2 == MATCH_0_2 &&
00692             (type_1 == NO_MATCH || type_1 == MATCH_1_6 ||
00693              type_1 == MATCH_1_7) &&
00694             (type_3 == NO_MATCH || type_3 == MATCH_3_4 ||
00695              type_3 == MATCH_3_5) )
00696   {
00697     imp_point_0->set_matching_point(imp_point_2);
00698     imp_point_2->set_matching_point(imp_point_0);
00699     return case_0_2_equal(seg_1, seg_2,
00700                           imp_point_0, imp_point_1,
00701                           imp_point_2, imp_point_3,
00702                           type_1, type_3,
00703                           int_result, new_segments);
00704   }
00705   else if ( type_0 == MATCH_0_3 && type_3 == MATCH_0_3 &&
00706             (type_1 == NO_MATCH || type_1 == MATCH_1_6 ||
00707              type_1 == MATCH_1_7) &&
00708             (type_2 == NO_MATCH || type_2 == MATCH_2_4 ||
00709              type_2 == MATCH_2_5) )
00710   {
00711     
00712     imp_point_0->set_matching_point(imp_point_3);
00713     imp_point_3->set_matching_point(imp_point_0);
00714     return case_0_3_equal(seg_1, seg_2,
00715                           imp_point_0, imp_point_1,
00716                           imp_point_2, imp_point_3,
00717                           type_1, type_2,
00718                           int_result, new_segments);
00719   }
00720   else if ( type_1 == MATCH_1_2 && type_2 == MATCH_1_2 &&
00721             (type_0 == NO_MATCH || type_0 == MATCH_0_6 ||
00722              type_0 == MATCH_0_7) &&
00723             (type_3 == NO_MATCH || type_3 == MATCH_3_4 ||
00724              type_3 == MATCH_3_5) )
00725   {
00726     
00727     imp_point_1->set_matching_point(imp_point_2);
00728     imp_point_2->set_matching_point(imp_point_1);
00729     return case_1_2_equal(seg_1, seg_2,
00730                           imp_point_0, imp_point_1,
00731                           imp_point_2, imp_point_3,
00732                           type_0, type_3,
00733                           int_result, new_segments);
00734   }
00735   else if ( type_1 == MATCH_1_3 && type_3 == MATCH_1_3 &&
00736             (type_0 == NO_MATCH || type_0 == MATCH_0_6 ||
00737              type_0 == MATCH_0_7) &&
00738             (type_2 == NO_MATCH || type_2 == MATCH_2_4 ||
00739              type_2 == MATCH_2_5) )
00740   {
00741     
00742     imp_point_1->set_matching_point(imp_point_3);
00743     imp_point_3->set_matching_point(imp_point_1);
00744     return case_1_3_equal(seg_1, seg_2,
00745                           imp_point_0, imp_point_1,
00746                           imp_point_2, imp_point_3,
00747                           type_0, type_2,
00748                           int_result, new_segments);
00749   }
00750   else if ( type_0 != NO_MATCH || type_1 != NO_MATCH ||
00751             type_2 != NO_MATCH || type_3 != NO_MATCH )
00752   {
00753     if ( type_0 == MATCH_0_2 || type_0 == MATCH_0_3 ||
00754          type_1 == MATCH_1_2 || type_1 == MATCH_1_3 ||
00755          type_2 == MATCH_1_2 || type_2 == MATCH_0_2 ||
00756          type_3 == MATCH_0_3 || type_3 == MATCH_1_3 )
00757     {
00758       if (debug )
00759       {
00760         draw_point(imp_point_0);
00761         draw_point(imp_point_1);
00762         draw_point(imp_point_2);
00763         draw_point(imp_point_3);
00764         draw_point(seg_1->get_prev()->get_start());
00765         draw_point(seg_1->get_next()->get_end());
00766         draw_point(seg_2->get_prev()->get_start());
00767         draw_point(seg_2->get_next()->get_end());
00768         GfxDebug::mouse_xforms();
00769       }
00770       if ( type_1 == MATCH_1_2 && type_2 == MATCH_1_2 &&
00771            imp_point_1->get_matching_point() == imp_point_2 )
00772       {
00773         if ( type_0 == MATCH_0_3 && type_3 == MATCH_3_5 )
00774         {
00775           int_result = NO_INTERSECT;
00776           return CUBIT_SUCCESS;
00777         }
00778         else if ( type_3 == MATCH_0_3 && type_0 == MATCH_0_7 )
00779         {
00780           int_result = NO_INTERSECT;
00781           return CUBIT_SUCCESS;
00782         }
00783         else
00784         {
00785           if (( type_0 == MATCH_0_2 ||  type_3 == MATCH_1_3 ) ||
00786               ( type_0 == MATCH_0_3 && type_3 == MATCH_3_4 )  ||
00787               ( type_0 == MATCH_0_7 && type_3 == MATCH_0_3 )  ||
00788               ( type_0 == MATCH_0_6 && type_3 == MATCH_0_3 )  ||
00789               ( type_0 == MATCH_0_3 && type_3 == MATCH_3_5 ) )
00790           {
00791               //This means that 0 and 2 are within tolerance
00792               //but 1 and 2 are closer.  For now just ignore this...
00793               //or...
00794               //This means that 1 and 3 are within tolerance
00795               //but 1 and 2 are closer.  For now just ignore this...
00796             imp_point_1->set_matching_point(imp_point_2);
00797             imp_point_2->set_matching_point(imp_point_1);
00798             return case_1_2_equal(seg_1, seg_2,
00799                                   imp_point_0, imp_point_1,
00800                                   imp_point_2, imp_point_3,
00801                                   type_0, type_3,
00802                                   int_result, new_segments);
00803 
00804           }
00805           else
00806           {
00807             PRINT_ERROR("Problems with tolerance. (Need special match code.)\n");
00808             return CUBIT_FAILURE;
00809           }
00810         }
00811       }
00812       else if ( type_0 == MATCH_0_3 && type_3 == MATCH_0_3 &&
00813                 imp_point_0->get_matching_point() == imp_point_3 )
00814       {
00815         if ( type_1 == MATCH_1_2 && type_2 == MATCH_2_4 )
00816         {
00817           int_result = NO_INTERSECT;
00818           return CUBIT_SUCCESS;
00819         }
00820         else if ( type_2 == MATCH_1_2 && type_1 == MATCH_1_7 )
00821         {
00822           int_result = NO_INTERSECT;
00823           return CUBIT_SUCCESS;
00824         }
00825         else
00826         {
00827           if (( type_1 == MATCH_1_3 ||  type_2 == MATCH_0_2 ) ||
00828               ( type_1 == MATCH_1_2 && type_2 == MATCH_2_5 ) ||
00829               ( type_1 == MATCH_1_2 && type_2 == MATCH_2_4 ) ||
00830               ( type_1 == MATCH_1_6 && type_2 == MATCH_1_2 ) ||
00831               ( type_1 == MATCH_1_7 && type_2 == MATCH_1_2 ) )
00832 
00833           {
00834               //This means that 1 and 3 are within tolerance
00835               //but 0 and 3 are closer.  For now just ignore this...
00836               //or...
00837               //This means that 0 and 2 are within tolerance
00838               //but 0 and 3 are closer.  For now just ignore this...
00839             imp_point_0->set_matching_point(imp_point_3);
00840             imp_point_3->set_matching_point(imp_point_0);
00841             return case_0_3_equal(seg_1, seg_2,
00842                                   imp_point_0, imp_point_1,
00843                                   imp_point_2, imp_point_3,
00844                                   type_1, type_2,
00845                                   int_result, new_segments);
00846             
00847           }
00848           else
00849           {
00850             PRINT_ERROR("Problems with tolerance. (Need special match code.)\n");
00851             return CUBIT_FAILURE;
00852           }
00853         }
00854       }
00855       else if ( type_1 == MATCH_1_3 && type_3 == MATCH_1_3 &&
00856                 imp_point_1->get_matching_point() == imp_point_3 )
00857       {
00858         if ( type_0 == MATCH_0_2 && type_2 == MATCH_2_5 )
00859         {
00860           int_result = NO_INTERSECT;
00861           return CUBIT_SUCCESS;
00862         }
00863         else if ( type_2 == MATCH_0_2 && type_0 == MATCH_0_7 )
00864         {
00865           int_result = NO_INTERSECT;
00866           return CUBIT_SUCCESS;
00867         }
00868         else
00869         {
00870           if (( type_0 == MATCH_0_3 ||  type_2 == MATCH_1_2 ) ||
00871               ( type_0 == MATCH_0_2 &&  type_2 == MATCH_2_4 ) ||
00872               ( type_0 == MATCH_0_2 &&  type_2 == MATCH_2_5 ) ||
00873               ( type_0 == MATCH_0_6 && type_2 == MATCH_0_2 )  ||
00874               ( type_0 == MATCH_0_7 && type_2 == MATCH_0_2 ) )
00875 
00876           {
00877               //This means that 0 and 3 are within tolerance
00878               //but 1 and 3 are closer.  For now just ignore this...
00879               //or...
00880               //This means that 1 and 2 are within tolerance
00881               //but 1 and 3 are closer.  For now just ignore this...
00882             imp_point_1->set_matching_point(imp_point_3);
00883             imp_point_3->set_matching_point(imp_point_1);
00884             return case_1_3_equal(seg_1, seg_2,
00885                                   imp_point_0, imp_point_1,
00886                                   imp_point_2, imp_point_3,
00887                                   type_0, type_2,
00888                                   int_result, new_segments);
00889             
00890           }
00891           else
00892           {
00893             PRINT_ERROR("Problems with tolerance. (Need special match code.)\n");
00894             return CUBIT_FAILURE;
00895           }
00896         }
00897       }
00898       else if ( type_0 == MATCH_0_2 && type_2 == MATCH_0_2 &&
00899                 imp_point_0->get_matching_point() == imp_point_2 )
00900       {
00901         if ( type_1 == MATCH_1_3 && type_3 == MATCH_3_4 )
00902         {
00903           int_result = NO_INTERSECT;
00904           return CUBIT_SUCCESS;
00905         }
00906         else if ( type_3 == MATCH_1_3 && type_1 == MATCH_1_6 )
00907         {
00908           int_result = NO_INTERSECT;
00909           return CUBIT_SUCCESS;
00910         }
00911         else
00912         {
00913           if (( type_1 == MATCH_1_2 ||  type_3 == MATCH_0_3 ) ||
00914               ( type_1 == MATCH_1_3 && type_3 == MATCH_3_5) ||
00915               ( type_1 == MATCH_1_3 && type_3 == MATCH_3_4) ||
00916               ( type_1 == MATCH_1_6 && type_3 == MATCH_1_3) ||
00917               ( type_1 == MATCH_1_7 && type_3 == MATCH_1_3) )
00918 
00919           {
00920               //This means that 0 and 3 are within tolerance
00921               //but 0 and 2 are closer.  For now just ignore this...
00922               //or...
00923               //This means that 1 and 2 are within tolerance
00924               //but 0 and 2 are closer.  For now just ignore this...
00925             imp_point_0->set_matching_point(imp_point_2);
00926             imp_point_2->set_matching_point(imp_point_0);
00927             return case_0_2_equal(seg_1, seg_2,
00928                                   imp_point_0, imp_point_1,
00929                                   imp_point_2, imp_point_3,
00930                                   type_1, type_3,
00931                                   int_result, new_segments);
00932             
00933           }
00934           else
00935           {
00936             PRINT_ERROR("Problems with tolerance. (Need special match code.)\n");
00937             return CUBIT_FAILURE;
00938           }
00939         }
00940       }
00941       else if ( type_0 == MATCH_0_2 || ( type_0 == MATCH_0_3 &&
00942                 (type_2 != MATCH_0_2 && type_3 != MATCH_0_3 ) ) )
00943       {
00944         if ( type_2 != MATCH_1_2 && type_3 != MATCH_1_3 &&
00945              type_1 != MATCH_1_2 && type_1 != MATCH_1_3 )
00946         {
00947           int_result = NO_INTERSECT;
00948           return CUBIT_SUCCESS;
00949         }
00950         else
00951         {
00952           PRINT_ERROR("Problems with tolerance. (Need special match code.)\n");
00953           return CUBIT_FAILURE;
00954         }
00955       }
00956       else if ( type_1 == MATCH_1_2 || ( type_1 == MATCH_1_3 &&
00957                 (type_2 != MATCH_1_2 && type_3 != MATCH_1_3 ) ) )
00958       {
00959         if ( type_2 != MATCH_0_2 && type_3 != MATCH_0_3 &&
00960              type_0 != MATCH_0_2 && type_1 != MATCH_0_3 )
00961         {
00962           int_result = NO_INTERSECT;
00963           return CUBIT_SUCCESS;
00964         }
00965         else
00966         {
00967           PRINT_ERROR("Problems with tolerance. (Need special match code.)\n");
00968           return CUBIT_FAILURE;
00969         }
00970       }
00971       else if ( type_2 == MATCH_0_2 || ( type_2 == MATCH_1_2 &&
00972                 (type_0 != MATCH_0_2 && type_1 != MATCH_1_2) ) )
00973       {
00974         if ( type_0 != MATCH_0_2 && type_1 != MATCH_1_2 &&
00975              type_3 != MATCH_0_3 && type_3 != MATCH_1_3 )
00976         {
00977           int_result = NO_INTERSECT;
00978           return CUBIT_SUCCESS;
00979         }
00980         else
00981         {
00982           PRINT_ERROR("Problems with tolerance. (Need special match code.)\n");
00983           return CUBIT_FAILURE;
00984         }
00985       }
00986       else if ( type_3 == MATCH_0_3 || ( type_3 == MATCH_1_3 &&
00987                 (type_0 != MATCH_0_3 && type_1 != MATCH_1_3) ) )
00988       {
00989         if ( type_0 != MATCH_0_3 && type_1 != MATCH_1_3 &&
00990              type_2 != MATCH_0_2 && type_2 != MATCH_1_2 )
00991         {
00992           int_result = NO_INTERSECT;
00993           return CUBIT_SUCCESS;
00994         }
00995         else
00996         {
00997           PRINT_ERROR("Problems with tolerance. (Need special match code.)\n");
00998           return CUBIT_FAILURE;
00999         }
01000       }
01001       else
01002       {
01003         PRINT_ERROR("Problems with tolerance. (Need special match code.)\n");
01004         return CUBIT_FAILURE;
01005       }
01006     }
01007   }
01008   
01009     //At this point we know that none of the end points of the
01010     //line segements are within tolerance.  The remaining possibilities
01011     //Are: T_INTERSECT, OVERLAP_PART, OVERLAP_ALL, or CROSS_INTERSECT.
01012   
01013   CubitBoolean point_0_on_seg_2 = CUBIT_FALSE;
01014   CubitBoolean point_1_on_seg_2 = CUBIT_FALSE;
01015   CubitBoolean point_2_on_seg_1 = CUBIT_FALSE;
01016   CubitBoolean point_3_on_seg_1 = CUBIT_FALSE;
01017     //Test to get the correct values for these flags.  From the above
01018     //flags we can figure out everything except for CROSS_INTERSECT.
01019   stat1 = determine_on_boundary( seg_1, seg_2, type_0, type_1,
01020                                  type_2, type_3 );
01021   if ( stat1 != CUBIT_SUCCESS )
01022     return stat1;
01023       
01024   if ( type_0 == ON_SEG_2 )
01025     point_0_on_seg_2 = CUBIT_TRUE;
01026   if ( type_1 == ON_SEG_2 )
01027     point_1_on_seg_2 = CUBIT_TRUE;
01028   if ( type_2 == ON_SEG_1 )
01029     point_2_on_seg_1 = CUBIT_TRUE;
01030   if ( type_3 == ON_SEG_1 )
01031     point_3_on_seg_1 = CUBIT_TRUE;
01032     //Okay, test for T_INTERSECT.
01033   if ( point_0_on_seg_2 && !point_1_on_seg_2 &&
01034        !point_2_on_seg_1 && !point_3_on_seg_1 )
01035   {
01036     PRINT_DEBUG_129("Found T_INTERSECT_0\n");
01037     int_result = T_INTERSECT_0;
01038       //split seg_2
01039     ImprintLineSegment *new_seg_2_0, *new_seg_0_3;
01040       //copy imp_point_0 to use it in list 2.
01041     CubitVector closest_point;
01042     closest_point_seg( imp_point_0, seg_2, closest_point);
01043     ImprintPointData *new_point_0 = new ImprintPointData(imp_point_0, closest_point);
01044     new_point_0->owner(seg_2->owner());
01045     allocatedPointData->append(new_point_0);
01046       //set the point type to be so we create a vertex here.
01047     new_point_0->set_point_type(CREATE_NEW_VERTEX);
01048     if ( imp_point_0->is_owner_vertex() &&
01049          imp_point_0->get_point_type() != CREATE_NEW_VERTEX )
01050       imp_point_0->set_point_type(VERTEX_ON_BOTH_BOUNDARIES);
01051     else
01052       imp_point_0->set_point_type(CREATE_NEW_VERTEX);
01053       
01054     new_seg_2_0 = new ImprintLineSegment(imp_point_2, new_point_0, seg_2->owner());
01055     new_seg_0_3 = new ImprintLineSegment(new_point_0, imp_point_3, seg_2->owner());
01056     allocatedLineData->append(new_seg_2_0);
01057     allocatedLineData->append(new_seg_0_3);
01058     new_segments[2] = new_seg_2_0;
01059     new_segments[3] = new_seg_0_3;
01060       //update the linked list.
01061     update_list(new_segments, seg_1, seg_2, CUBIT_FALSE);
01062     seg_2->set_inactive(CUBIT_TRUE);
01063     return CUBIT_SUCCESS;
01064   }
01065   else if ( point_1_on_seg_2 && !point_0_on_seg_2 &&
01066             !point_2_on_seg_1 && !point_3_on_seg_1 )
01067   {
01068       //split seg_2
01069     PRINT_DEBUG_129("Found T_INTERSECT_1\n");
01070     int_result = T_INTERSECT_1;
01071     ImprintLineSegment *new_seg_2_1, *new_seg_1_3;
01072       //copy imp_point_1 to use it in list 2.
01073     CubitVector closest_point;
01074     closest_point_seg( imp_point_1, seg_2, closest_point);
01075     ImprintPointData *new_point_1 = new ImprintPointData(imp_point_1, closest_point);
01076     new_point_1->owner(seg_2->owner());
01077     allocatedPointData->append(new_point_1);
01078       //set the point type to be so we create a vertex here.
01079     new_point_1->set_point_type(CREATE_NEW_VERTEX);
01080     if ( imp_point_1->is_owner_vertex() &&
01081          imp_point_1->get_point_type() != CREATE_NEW_VERTEX )
01082       imp_point_1->set_point_type(VERTEX_ON_BOTH_BOUNDARIES);
01083     else
01084       imp_point_1->set_point_type(CREATE_NEW_VERTEX);
01085     new_seg_2_1 = new ImprintLineSegment(imp_point_2,
01086                                          new_point_1, seg_2->owner());
01087     new_seg_1_3 = new ImprintLineSegment(new_point_1,
01088                                          imp_point_3, seg_2->owner());
01089     allocatedLineData->append(new_seg_2_1);
01090     allocatedLineData->append(new_seg_1_3);
01091     new_segments[2] = new_seg_2_1;
01092     new_segments[3] = new_seg_1_3;
01093       //update the linked list
01094     update_list(new_segments, seg_1, seg_2, CUBIT_FALSE);
01095     seg_2->set_inactive(CUBIT_TRUE);
01096     return CUBIT_SUCCESS;
01097   }
01098   else if ( point_2_on_seg_1 && !point_0_on_seg_2 &&
01099             !point_1_on_seg_2 && !point_3_on_seg_1 )
01100   {
01101     PRINT_DEBUG_129("Found T_INTERSECT_2\n");
01102     int_result = T_INTERSECT_2;
01103       //split seg_1
01104     ImprintLineSegment *new_seg_0_2, *new_seg_2_1;
01105       //copy imp_point_2 to use it in list 1.
01106     CubitVector closest_point;
01107     closest_point_seg( imp_point_2, seg_1, closest_point);
01108     ImprintPointData *new_point_2 = new ImprintPointData(imp_point_2, closest_point);
01109     new_point_2->owner(seg_1->owner());
01110     allocatedPointData->append(new_point_2);
01111       //set the point type to be so we create a vertex here.
01112     new_point_2->set_point_type(CREATE_NEW_VERTEX);
01113     if ( imp_point_2->is_owner_vertex() &&
01114          imp_point_2->get_point_type() != CREATE_NEW_VERTEX )
01115       imp_point_2->set_point_type(VERTEX_ON_BOTH_BOUNDARIES);
01116     else
01117       imp_point_2->set_point_type(CREATE_NEW_VERTEX);
01118     new_seg_0_2 = new ImprintLineSegment(imp_point_0, new_point_2,
01119                                          seg_1->owner());
01120     new_seg_2_1 = new ImprintLineSegment(new_point_2, imp_point_1,
01121                                          seg_1->owner());
01122     allocatedLineData->append(new_seg_0_2);
01123     allocatedLineData->append(new_seg_2_1);
01124     new_segments[0] = new_seg_0_2;
01125     new_segments[1] = new_seg_2_1;
01126       //update the linked list
01127     update_list(new_segments, seg_1, seg_2, CUBIT_TRUE);
01128     seg_1->set_inactive(CUBIT_TRUE);
01129     return CUBIT_SUCCESS;
01130   }
01131   else if ( point_3_on_seg_1 && !point_0_on_seg_2 &&
01132             !point_1_on_seg_2 && !point_2_on_seg_1 )
01133   {
01134     PRINT_DEBUG_129("Found T_INTERSECT_3\n");
01135     int_result = T_INTERSECT_3;
01136       //split seg_1
01137       //copy imp_point_3 to use it in list 1.
01138     CubitVector closest_point;
01139     closest_point_seg( imp_point_3, seg_1, closest_point);
01140     ImprintPointData *new_point_3 = new ImprintPointData(imp_point_3, closest_point);
01141     new_point_3->owner(seg_1->owner());
01142     allocatedPointData->append(new_point_3);
01143       //set the point type to be so we create a vertex here.
01144     new_point_3->set_point_type(CREATE_NEW_VERTEX);
01145     if ( imp_point_3->is_owner_vertex() &&
01146          imp_point_3->get_point_type() != CREATE_NEW_VERTEX )
01147       imp_point_3->set_point_type(VERTEX_ON_BOTH_BOUNDARIES);
01148     else
01149       imp_point_3->set_point_type(CREATE_NEW_VERTEX);
01150 
01151     ImprintLineSegment *new_seg_0_3, *new_seg_3_1;
01152     new_seg_0_3 = new ImprintLineSegment(imp_point_0, new_point_3,
01153                                          seg_1->owner());
01154     new_seg_3_1 = new ImprintLineSegment(new_point_3, imp_point_1,
01155                                          seg_1->owner());
01156     allocatedLineData->append(new_seg_0_3);
01157     allocatedLineData->append(new_seg_3_1);
01158     new_segments[0] = new_seg_0_3;
01159     new_segments[1] = new_seg_3_1;
01160       //update the linked list
01161     update_list(new_segments, seg_1, seg_2, CUBIT_TRUE);
01162     seg_1->set_inactive(CUBIT_TRUE);
01163     return CUBIT_SUCCESS;
01164   }
01165     //Okay, we are done with T intersections, it now must be one
01166     //of the remaining overlaps (part or all.) or the cross intersection.
01167 
01168     //First test for the part overlaps.
01169   if ( point_1_on_seg_2 && point_2_on_seg_1 &&
01170        !point_0_on_seg_2 && !point_3_on_seg_1 )
01171   {
01172     PRINT_DEBUG_129("Found OVEVERLAP_PART_0_3\n");
01173     int_result = OVERLAP_PART_0_3;
01174     ImprintLineSegment *new_seg_0_2, *new_seg_2_1;
01175     ImprintLineSegment *new_seg_2_1_v2, *new_seg_1_3;
01176       //Copy point 2 to use on seg_1
01177     CubitVector closest_point;
01178     closest_point_seg( imp_point_2, seg_1, closest_point);
01179     ImprintPointData *new_point_2 = new ImprintPointData(imp_point_2, closest_point);
01180     new_point_2->owner(seg_1->owner());
01181     allocatedPointData->append(new_point_2);
01182     if ( imp_point_2->is_owner_vertex() )
01183     {
01184       new_point_2->set_point_type(CREATE_NEW_VERTEX);
01185       if ( imp_point_2->get_point_type() != CREATE_NEW_VERTEX )
01186         imp_point_2->set_point_type(VERTEX_ON_BOTH_BOUNDARIES);
01187     }
01188     else
01189     {
01190       new_point_2->set_point_type(ON_BOTH_BOUNDARIES);
01191       imp_point_2->set_point_type(ON_BOTH_BOUNDARIES);
01192     }
01193       //split both segs 1 and 2.
01194     new_seg_0_2 = new ImprintLineSegment(imp_point_0, new_point_2,
01195                                          seg_1->owner());
01196     new_seg_2_1 = new ImprintLineSegment(new_point_2, imp_point_1,
01197                                          seg_1->owner());
01198     allocatedLineData->append(new_seg_0_2);
01199     allocatedLineData->append(new_seg_2_1);
01200       //Copy point 1 to use on seg_2
01201     closest_point_seg( imp_point_1, seg_2, closest_point);
01202     ImprintPointData *new_point_1 = new ImprintPointData(imp_point_1, closest_point);
01203     new_point_1->owner(seg_2->owner());
01204     allocatedPointData->append(new_point_1);
01205     if ( imp_point_1->is_owner_vertex() )
01206     {
01207       new_point_1->set_point_type(CREATE_NEW_VERTEX);
01208       if ( imp_point_1->get_point_type() != CREATE_NEW_VERTEX )
01209         imp_point_1->set_point_type(VERTEX_ON_BOTH_BOUNDARIES);
01210     }
01211     else
01212       new_point_1->set_point_type(ON_BOTH_BOUNDARIES);
01213     
01214     new_seg_2_1_v2 = new ImprintLineSegment(imp_point_2, new_point_1,
01215                                             seg_2->owner());
01216     new_seg_1_3 = new ImprintLineSegment(new_point_1, imp_point_3,
01217                                          seg_2->owner());
01218     allocatedLineData->append(new_seg_2_1_v2);
01219     allocatedLineData->append(new_seg_1_3);
01220     new_segments[0] = new_seg_0_2;
01221     new_segments[1] = new_seg_2_1;
01222     new_segments[2] = new_seg_2_1_v2;
01223     new_segments[3] = new_seg_1_3;
01224       //now update both linked lists.
01225     update_list(new_segments, seg_1, seg_2, CUBIT_TRUE);
01226     update_list(new_segments, seg_1, seg_2, CUBIT_FALSE);
01227     seg_1->set_inactive(CUBIT_TRUE);
01228     seg_2->set_inactive(CUBIT_TRUE);
01229     return CUBIT_SUCCESS;
01230   }
01231   else if ( point_1_on_seg_2 && !point_2_on_seg_1 &&
01232             !point_0_on_seg_2 && point_3_on_seg_1 )
01233   {
01234     PRINT_DEBUG_129("Found OVEVERLAP_PART_0_2\n");
01235     int_result = OVERLAP_PART_0_2;
01236     ImprintLineSegment *new_seg_0_3, *new_seg_3_1;
01237     ImprintLineSegment *new_seg_2_1, *new_seg_1_3;
01238       //Copy point 2 to use on seg_1
01239     CubitVector closest_point;
01240     closest_point_seg( imp_point_3, seg_1, closest_point);
01241     ImprintPointData *new_point_3 = new ImprintPointData(imp_point_3, closest_point);
01242     new_point_3->owner(seg_1->owner());
01243     allocatedPointData->append(new_point_3);
01244     int debug1 = 0;
01245     if ( debug1 )
01246     {
01247       GfxDebug::clear();
01248       draw_seg(seg_1);
01249       draw_seg(seg_2);
01250       draw_point(imp_point_0);
01251       draw_point(imp_point_1);
01252       draw_point(imp_point_2);
01253       draw_point(imp_point_3);
01254       GfxDebug::mouse_xforms();
01255     }
01256     if ( imp_point_3->is_owner_vertex() )
01257     {
01258       new_point_3->set_point_type(CREATE_NEW_VERTEX);
01259       if ( imp_point_3->get_point_type() != CREATE_NEW_VERTEX )
01260         imp_point_3->set_point_type(VERTEX_ON_BOTH_BOUNDARIES);
01261     }
01262     else
01263     {
01264       new_point_3->set_point_type(ON_BOTH_BOUNDARIES);
01265       imp_point_3->set_point_type(ON_BOTH_BOUNDARIES);
01266     }
01267       //split both segs 1 and 2.
01268     new_seg_0_3 = new ImprintLineSegment(imp_point_0, new_point_3,
01269                                          seg_1->owner());
01270     new_seg_3_1 = new ImprintLineSegment(new_point_3, imp_point_1,
01271                                          seg_1->owner());
01272     allocatedLineData->append(new_seg_0_3);
01273     allocatedLineData->append(new_seg_3_1);
01274       //Copy point 1 to use on seg_2
01275     closest_point_seg( imp_point_1, seg_2, closest_point);
01276     ImprintPointData *new_point_1 = new ImprintPointData(imp_point_1, closest_point);
01277     new_point_1->owner(seg_2->owner());
01278     allocatedPointData->append(new_point_1);
01279     if ( imp_point_1->is_owner_vertex() )
01280     {
01281       new_point_1->set_point_type(CREATE_NEW_VERTEX);
01282       if ( imp_point_1->get_point_type() != CREATE_NEW_VERTEX )
01283         imp_point_1->set_point_type(VERTEX_ON_BOTH_BOUNDARIES);
01284     }
01285     else
01286       new_point_1->set_point_type(ON_BOTH_BOUNDARIES);
01287     
01288     new_seg_2_1 = new ImprintLineSegment(imp_point_2, new_point_1,
01289                                          seg_2->owner());
01290     new_seg_1_3 = new ImprintLineSegment(new_point_1, imp_point_3,
01291                                          seg_2->owner());
01292     allocatedLineData->append(new_seg_2_1);
01293     allocatedLineData->append(new_seg_1_3);
01294     new_segments[0] = new_seg_0_3;
01295     new_segments[1] = new_seg_3_1;
01296     new_segments[2] = new_seg_2_1;
01297     new_segments[3] = new_seg_1_3;
01298       //now update both linked lists.
01299     update_list(new_segments, seg_1, seg_2, CUBIT_TRUE);
01300     update_list(new_segments, seg_1, seg_2, CUBIT_FALSE);
01301     seg_1->set_inactive(CUBIT_TRUE);
01302     seg_2->set_inactive(CUBIT_TRUE);
01303     return CUBIT_SUCCESS;
01304   }
01305   else if ( !point_1_on_seg_2 && !point_2_on_seg_1 &&
01306             point_0_on_seg_2 && point_3_on_seg_1 )
01307   {
01308     PRINT_DEBUG_129("Found OVERLAP_PART_1_2\n");
01309     int_result = OVERLAP_PART_1_2;
01310     ImprintLineSegment *new_seg_0_3, *new_seg_3_1;
01311     ImprintLineSegment *new_seg_2_0, *new_seg_0_3_v2;
01312       //Copy point_3 to use on seg 1.
01313     CubitVector closest_point;
01314     closest_point_seg( imp_point_3, seg_1, closest_point);
01315     ImprintPointData *new_point_3 = new ImprintPointData(imp_point_3, closest_point);
01316     new_point_3->owner(seg_1->owner());
01317     allocatedPointData->append(new_point_3);
01318     if ( imp_point_3->is_owner_vertex() )
01319     {
01320       new_point_3->set_point_type(CREATE_NEW_VERTEX);
01321       if ( imp_point_3->get_point_type() != CREATE_NEW_VERTEX )
01322         imp_point_3->set_point_type(VERTEX_ON_BOTH_BOUNDARIES);
01323     }
01324     else
01325     {
01326       new_point_3->set_point_type(ON_BOTH_BOUNDARIES);
01327       imp_point_3->set_point_type(ON_BOTH_BOUNDARIES);
01328     }
01329       //split both segs 1 and 2.
01330     new_seg_0_3 = new ImprintLineSegment(imp_point_0, new_point_3,
01331                                          seg_1->owner());
01332     new_seg_3_1 = new ImprintLineSegment(new_point_3, imp_point_1,
01333                                          seg_1->owner());
01334     allocatedLineData->append(new_seg_0_3);
01335     allocatedLineData->append(new_seg_3_1);
01336       //Copy point_0 to use on seg 2.
01337     closest_point_seg( imp_point_0, seg_2, closest_point);
01338     ImprintPointData *new_point_0 = new ImprintPointData(imp_point_0, closest_point);
01339     new_point_0->owner(seg_2->owner());
01340     allocatedPointData->append(new_point_0);
01341     if ( imp_point_0->is_owner_vertex() )
01342     {
01343       new_point_0->set_point_type(CREATE_NEW_VERTEX);
01344       if ( imp_point_0->get_point_type() != CREATE_NEW_VERTEX )
01345         imp_point_0->set_point_type(VERTEX_ON_BOTH_BOUNDARIES);
01346     }
01347     else
01348     {
01349       new_point_0->set_point_type(ON_BOTH_BOUNDARIES);
01350       imp_point_0->set_point_type(ON_BOTH_BOUNDARIES);
01351     }
01352     new_seg_2_0 = new ImprintLineSegment(imp_point_2, new_point_0,
01353                                          seg_2->owner());
01354     new_seg_0_3_v2 = new ImprintLineSegment(new_point_0, imp_point_3,
01355                                             seg_2->owner());
01356     allocatedLineData->append(new_seg_2_0);
01357     allocatedLineData->append(new_seg_0_3_v2);
01358 
01359     new_segments[0] = new_seg_0_3;
01360     new_segments[1] = new_seg_3_1;
01361     new_segments[2] = new_seg_2_0;
01362     new_segments[3] = new_seg_0_3_v2;
01363       //update both lists.
01364     update_list(new_segments, seg_1, seg_2, CUBIT_TRUE);
01365     update_list(new_segments, seg_1, seg_2, CUBIT_FALSE);
01366     seg_1->set_inactive(CUBIT_TRUE);
01367     seg_2->set_inactive(CUBIT_TRUE);
01368     return CUBIT_SUCCESS;
01369   }
01370   else if ( !point_1_on_seg_2 && point_2_on_seg_1 &&
01371             point_0_on_seg_2 && !point_3_on_seg_1 )
01372   {
01373     PRINT_DEBUG_129("Found OVERLAP_PART_1_3\n");
01374     int_result = OVERLAP_PART_1_3;
01375     ImprintLineSegment *new_seg_0_2, *new_seg_2_1;
01376     ImprintLineSegment *new_seg_2_0, *new_seg_0_3;
01377       //Copy point_3 to use on seg 1.
01378     CubitVector closest_point;
01379     closest_point_seg( imp_point_2, seg_1, closest_point);
01380     ImprintPointData *new_point_2 = new ImprintPointData(imp_point_2, closest_point);
01381     new_point_2->owner(seg_1->owner());
01382     allocatedPointData->append(new_point_2);
01383     if ( imp_point_2->is_owner_vertex() )
01384     {
01385       new_point_2->set_point_type(CREATE_NEW_VERTEX);
01386       if ( imp_point_2->get_point_type() != CREATE_NEW_VERTEX )
01387         imp_point_2->set_point_type(VERTEX_ON_BOTH_BOUNDARIES);
01388     }
01389     else
01390     {
01391       new_point_2->set_point_type(ON_BOTH_BOUNDARIES);
01392       imp_point_2->set_point_type(ON_BOTH_BOUNDARIES);
01393     }
01394       //split both segs 1 and 2.
01395     new_seg_0_2 = new ImprintLineSegment(imp_point_0, new_point_2,
01396                                          seg_1->owner());
01397     new_seg_2_1 = new ImprintLineSegment(new_point_2, imp_point_1,
01398                                          seg_1->owner());
01399     allocatedLineData->append(new_seg_0_2);
01400     allocatedLineData->append(new_seg_2_1);
01401       //Copy point_0 to use on seg 2.
01402     closest_point_seg( imp_point_0, seg_2, closest_point);
01403     ImprintPointData *new_point_0 = new ImprintPointData(imp_point_0, closest_point);
01404     new_point_0->owner(seg_2->owner());
01405     allocatedPointData->append(new_point_0);
01406     if ( imp_point_0->is_owner_vertex() )
01407     {
01408       new_point_0->set_point_type(CREATE_NEW_VERTEX);
01409       if ( imp_point_0->get_point_type() != CREATE_NEW_VERTEX )
01410         imp_point_0->set_point_type(VERTEX_ON_BOTH_BOUNDARIES);
01411     }
01412     else
01413     {
01414       new_point_0->set_point_type(ON_BOTH_BOUNDARIES);
01415       imp_point_0->set_point_type(ON_BOTH_BOUNDARIES);
01416     }
01417     new_seg_2_0 = new ImprintLineSegment(imp_point_2, new_point_0,
01418                                          seg_2->owner());
01419     new_seg_0_3 = new ImprintLineSegment(new_point_0, imp_point_3,
01420                                          seg_2->owner());
01421     allocatedLineData->append(new_seg_2_0);
01422     allocatedLineData->append(new_seg_0_3);
01423 
01424     new_segments[0] = new_seg_0_2;
01425     new_segments[1] = new_seg_2_1;
01426     new_segments[2] = new_seg_2_0;
01427     new_segments[3] = new_seg_0_3;
01428       //update both lists.
01429     update_list(new_segments, seg_1, seg_2, CUBIT_TRUE);
01430     update_list(new_segments, seg_1, seg_2, CUBIT_FALSE);
01431     seg_1->set_inactive(CUBIT_TRUE);
01432     seg_2->set_inactive(CUBIT_TRUE);
01433     return CUBIT_SUCCESS;
01434   }
01435 
01436     //Now test for the overlap all conditions.
01437   else if ( !point_0_on_seg_2 && !point_1_on_seg_2 &&
01438             point_2_on_seg_1 && point_3_on_seg_1 )
01439   {
01440       //First we know that for either of the next cases, we
01441       //have to copy points 2 and 3, do that first then
01442       //decide the particular intersection case.
01443       //copy points 2 and 3 to use on segment 1.
01444     CubitVector closest_point;
01445     closest_point_seg( imp_point_2, seg_1, closest_point);
01446     ImprintPointData *new_point_2 = new ImprintPointData(imp_point_2, closest_point);
01447     new_point_2->owner(seg_1->owner());
01448     allocatedPointData->append(new_point_2);
01449     if ( imp_point_2->is_owner_vertex() )
01450     {
01451       new_point_2->set_point_type(CREATE_NEW_VERTEX);
01452       if ( imp_point_2->get_point_type() != CREATE_NEW_VERTEX )
01453         imp_point_2->set_point_type(VERTEX_ON_BOTH_BOUNDARIES);
01454     }
01455     else
01456     {
01457       new_point_2->set_point_type(ON_BOTH_BOUNDARIES);
01458       imp_point_2->set_point_type(ON_BOTH_BOUNDARIES);
01459     }
01460     closest_point_seg( imp_point_3, seg_1, closest_point);
01461     ImprintPointData *new_point_3 = new ImprintPointData(imp_point_3, closest_point);
01462     new_point_3->owner(seg_1->owner());
01463     allocatedPointData->append(new_point_3);
01464     if ( imp_point_3->is_owner_vertex() )
01465     {
01466       new_point_3->set_point_type(CREATE_NEW_VERTEX);
01467       if ( imp_point_3->get_point_type() != CREATE_NEW_VERTEX )
01468         imp_point_3->set_point_type(VERTEX_ON_BOTH_BOUNDARIES);
01469       imp_point_3->set_point_type(VERTEX_ON_BOTH_BOUNDARIES);
01470     }
01471     else
01472     {
01473       new_point_3->set_point_type(ON_BOTH_BOUNDARIES);
01474       imp_point_3->set_point_type(ON_BOTH_BOUNDARIES);
01475     }
01476       //IMPORTANT: Now breaking up the line segments is special for the
01477       //overlap all case.  This is the one situation where
01478       //the one exterior segment gets broken into *3* new segments.
01479       //Every other instance in this function only breaks each segment
01480       //into two...
01481       //To distinguish between OVERLAP_ALL_0_2_3_1 and OVERLAP_ALL_0_3_2_1,
01482       //test to see which value is closer to point_0 (2 or 3).
01483     CubitVector point_0 = imp_point_0->coordinates();
01484     CubitVector point_2 = imp_point_2->coordinates();
01485     CubitVector point_3 = imp_point_3->coordinates();
01486     double dist_1_sq = (point_0 - point_2).length_squared();
01487     double dist_2_sq = (point_0 - point_3).length_squared();
01488     if ( dist_1_sq < dist_2_sq )
01489     {
01490       PRINT_DEBUG_129("Found OVERLAP_ALL_0_2_3_1\n");
01491       int_result = OVERLAP_ALL_0_2_3_1;
01492       ImprintLineSegment *new_seg_0_2, *new_seg_2_3, *new_seg_3_1;
01493         //split seg_1
01494       new_seg_0_2 = new ImprintLineSegment(imp_point_0, new_point_2,
01495                                            seg_1->owner());
01496         //Yes this is really just a copy of seg_2, but do it this
01497         //way to make the data separate.
01498       new_seg_2_3 = new ImprintLineSegment(new_point_2, new_point_3,
01499                                            seg_1->owner());
01500       new_seg_3_1 = new ImprintLineSegment(new_point_3, imp_point_1,
01501                                            seg_1->owner());
01502       allocatedLineData->append(new_seg_0_2);
01503       allocatedLineData->append(new_seg_2_3);
01504       allocatedLineData->append(new_seg_3_1);
01505       new_segments[0] = new_seg_0_2;
01506       new_segments[1] = new_seg_2_3;
01507       new_segments[2] = new_seg_3_1;
01508         //Don't use the update_list function here
01509         //since this is our special case...
01510 
01511         //update list 1.
01512         //prev
01513       new_seg_0_2->set_prev(seg_1->get_prev());
01514       seg_1->get_prev()->set_next(new_seg_0_2);
01515         //next
01516       new_seg_0_2->set_next(new_seg_2_3);
01517       new_seg_2_3->set_prev(new_seg_0_2);
01518       new_seg_2_3->set_next(new_seg_3_1);
01519       new_seg_3_1->set_prev(new_seg_2_3);
01520       new_seg_3_1->set_next(seg_1->get_next());
01521       seg_1->get_next()->set_prev(new_seg_3_1);
01522         //seg_1 will no longer be used
01523       seg_1->set_inactive(CUBIT_TRUE);
01524       return CUBIT_SUCCESS;
01525     }
01526     else
01527     {
01528       PRINT_DEBUG_129("Found OVERLAP_ALL_0_3_2_1\n");
01529       int_result = OVERLAP_ALL_0_3_2_1;
01530       ImprintLineSegment *new_seg_0_3, *new_seg_3_2, *new_seg_2_1;
01531 
01532       new_seg_0_3 = new ImprintLineSegment(imp_point_0, new_point_3,
01533                                            seg_1->owner());
01534       new_seg_3_2 = new ImprintLineSegment(new_point_3, new_point_2,
01535                                            seg_1->owner());
01536       new_seg_2_1 = new ImprintLineSegment(new_point_2, imp_point_1,
01537                                            seg_1->owner());
01538       allocatedLineData->append(new_seg_0_3);
01539       allocatedLineData->append(new_seg_3_2);
01540       allocatedLineData->append(new_seg_2_1);
01541       new_segments[0] = new_seg_0_3;
01542       new_segments[1] = new_seg_3_2;
01543       new_segments[2] = new_seg_2_1;
01544         //don't use special function since this is special case.
01545         //update list 1
01546         //prev
01547       new_seg_0_3->set_prev(seg_1->get_prev());
01548       seg_1->get_prev()->set_next(new_seg_0_3);
01549         //next
01550       new_seg_0_3->set_next(new_seg_3_2);
01551       new_seg_3_2->set_prev(new_seg_0_3);
01552       new_seg_3_2->set_next(new_seg_2_1);
01553       new_seg_2_1->set_prev(new_seg_3_2);
01554       new_seg_2_1->set_next(seg_1->get_next());
01555       seg_1->get_next()->set_prev(new_seg_2_1);
01556         //seg_1 will no longer be used
01557       seg_1->set_inactive(CUBIT_TRUE);
01558       return CUBIT_SUCCESS;
01559     }
01560   }
01561   else if ( point_0_on_seg_2 && point_1_on_seg_2 &&
01562             !point_2_on_seg_1 && !point_3_on_seg_1 )
01563   {
01564       //First we know that for either of the next cases, we
01565       //have to copy points 0 and 1, do that first then
01566       //decide the particular intersection case.
01567       //copy points 0 and 1 to use on segment 2.
01568     CubitVector closest_point;
01569     closest_point_seg( imp_point_0, seg_2, closest_point);
01570     ImprintPointData *new_point_0 = new ImprintPointData(imp_point_0, closest_point);
01571     new_point_0->owner(seg_2->owner());
01572     allocatedPointData->append(new_point_0);
01573     if ( imp_point_0->is_owner_vertex() )
01574     {
01575       new_point_0->set_point_type(CREATE_NEW_VERTEX);
01576       if ( imp_point_0->get_point_type() != CREATE_NEW_VERTEX )
01577         imp_point_0->set_point_type(VERTEX_ON_BOTH_BOUNDARIES);
01578     }
01579     else
01580     {
01581       new_point_0->set_point_type(ON_BOTH_BOUNDARIES);
01582       imp_point_0->set_point_type(ON_BOTH_BOUNDARIES);
01583     }
01584     closest_point_seg( imp_point_1, seg_2, closest_point);
01585     ImprintPointData *new_point_1 = new ImprintPointData(imp_point_1, closest_point);
01586     new_point_1->owner(seg_2->owner());
01587     allocatedPointData->append(new_point_1);
01588     if ( imp_point_1->is_owner_vertex() )
01589     {
01590       new_point_1->set_point_type(CREATE_NEW_VERTEX);
01591       if ( imp_point_1->get_point_type() != CREATE_NEW_VERTEX )
01592         imp_point_1->set_point_type(VERTEX_ON_BOTH_BOUNDARIES);
01593     }
01594     else
01595     {
01596       new_point_1->set_point_type(ON_BOTH_BOUNDARIES);
01597       imp_point_1->set_point_type(ON_BOTH_BOUNDARIES);
01598     }
01599       //IMPORTANT: Now breaking up the line segments is special for the
01600       //overlap all case.  This is the one situation where
01601       //the one exterior segment gets broken into *3* new segments.
01602       //Every other instance in this function only breaks each segment
01603       //into two...
01604       //To distinguish between OVERLAP_ALL_2_0_1_3 and OVERLAP_ALL_2_1_0_3,
01605       //test to see which value is closer to point_2 (0 or 1).
01606     CubitVector point_0 = imp_point_0->coordinates();
01607     CubitVector point_1 = imp_point_1->coordinates();
01608     CubitVector point_2 = imp_point_2->coordinates();
01609     double dist_1_sq = (point_2 - point_0).length_squared();
01610     double dist_2_sq = (point_2 - point_1).length_squared();
01611     if ( dist_1_sq < dist_2_sq )
01612     {
01613       PRINT_DEBUG_129("Found OVERLAP_ALL_2_0_1_3\n");
01614       int_result = OVERLAP_ALL_2_0_1_3;
01615       ImprintLineSegment *new_seg_2_0, *new_seg_0_1, *new_seg_1_3;
01616 
01617       new_seg_2_0 = new ImprintLineSegment(imp_point_2, new_point_0,
01618                                            seg_2->owner());
01619         //Yes this is really just a copy of seg_2, but do it this
01620         //way to make the data separate.
01621       new_seg_0_1 = new ImprintLineSegment(new_point_0, new_point_1,
01622                                            seg_2->owner());
01623       new_seg_1_3 = new ImprintLineSegment(new_point_1, imp_point_3,
01624                                            seg_2->owner());
01625       allocatedLineData->append(new_seg_2_0);
01626       allocatedLineData->append(new_seg_0_1);
01627       allocatedLineData->append(new_seg_1_3);
01628       new_segments[1] = new_seg_2_0;
01629       new_segments[2] = new_seg_0_1;
01630       new_segments[3] = new_seg_1_3;
01631         //Don't use update list function since this is special case.
01632         //update list 2.
01633         //prev
01634       new_seg_2_0->set_prev(seg_2->get_prev());
01635       seg_2->get_prev()->set_next(new_seg_2_0);
01636         //next
01637       new_seg_2_0->set_next(new_seg_0_1);
01638       new_seg_0_1->set_prev(new_seg_2_0);
01639       new_seg_0_1->set_next(new_seg_1_3);
01640       new_seg_1_3->set_prev(new_seg_0_1);
01641       new_seg_1_3->set_next(seg_2->get_next());
01642       seg_2->get_next()->set_prev(new_seg_1_3);
01643         //seg_2 will no longer be used
01644       seg_2->set_inactive(CUBIT_TRUE);
01645       return CUBIT_SUCCESS;
01646     }
01647     else
01648     {
01649       PRINT_DEBUG_129("Found OVERLAP_ALL_2_1_0_3\n");
01650       int_result = OVERLAP_ALL_2_1_0_3;
01651       ImprintLineSegment *new_seg_2_1, *new_seg_1_0, *new_seg_0_3;
01652 
01653       new_seg_2_1 = new ImprintLineSegment(imp_point_2, new_point_1,
01654                                            seg_2->owner());
01655       new_seg_1_0 = new ImprintLineSegment(new_point_1, new_point_0,
01656                                            seg_2->owner());
01657       new_seg_0_3 = new ImprintLineSegment(new_point_0, imp_point_3,
01658                                            seg_2->owner());
01659       allocatedLineData->append(new_seg_2_1);
01660       allocatedLineData->append(new_seg_1_0);
01661       allocatedLineData->append(new_seg_0_3);
01662       new_segments[1] = new_seg_2_1;
01663       new_segments[2] = new_seg_1_0;
01664       new_segments[3] = new_seg_0_3;
01665         //Don't use update_list function since this is special case.
01666         //update list 2.
01667         //prev
01668       new_seg_2_1->set_prev(seg_2->get_prev());
01669       seg_2->get_prev()->set_next(new_seg_2_1);
01670         //next
01671       new_seg_2_1->set_next(new_seg_1_0);
01672       new_seg_1_0->set_prev(new_seg_2_1);
01673       new_seg_1_0->set_next(new_seg_0_3);
01674       new_seg_0_3->set_prev(new_seg_1_0);
01675       new_seg_0_3->set_next(seg_2->get_next());
01676       seg_2->get_next()->set_prev(new_seg_0_3);
01677         //seg_2 will no longer be used
01678       seg_2->set_inactive(CUBIT_TRUE);
01679       return CUBIT_SUCCESS;
01680     }
01681   }
01682   if ( point_0_on_seg_2 || point_1_on_seg_2 ||
01683        point_2_on_seg_1 || point_3_on_seg_1 )
01684   {
01685     PRINT_ERROR("Intersection problem, case not handled.\n");
01686     return CUBIT_FAILURE;
01687   }
01688     //Okay, finally test for the cross intersection.  If this isnt'
01689     //within tolerance, then these two segments couldn't
01690     //posibly intersect!
01691   IntersectionTool int_tool(GEOMETRY_RESABS); //use GEOMETRY_RESABS
01692     //rather than myTolerance for calculations...
01693   CubitVector point_0 = imp_point_0->coordinates();
01694   CubitVector point_1 = imp_point_1->coordinates();
01695   CubitVector point_2 = imp_point_2->coordinates();
01696   CubitVector point_3 = imp_point_3->coordinates();
01697   CubitVector closest_point_seg_1, closest_point_seg_2;
01698   double sc, tc;
01699   CubitStatus stat = int_tool.closest_points_on_segments(point_0, point_1,
01700                                                          point_2, point_3,
01701                                                          closest_point_seg_1,
01702                                                          closest_point_seg_2,
01703                                                          sc, tc);
01704   if (stat != CUBIT_SUCCESS )
01705   {
01706     PRINT_ERROR("Problems calculation closest points on "
01707                 "segments for boundary imprinting.\n");
01708     return CUBIT_FAILURE;
01709   }
01710     //Make sure the closest points aren't the end points.  If they are
01711     //and we are within tolerance, it may be that the tolerance is too big
01712     //cause we shouldn't be at a cross if the closest point is an end point...
01713   if ( sc > 0. && sc < 1. && tc > 0. && tc < 1. &&
01714        closest_point_seg_1.within_tolerance(closest_point_seg_2,myTolerance) )
01715   {
01716       //okay, these guys actually do intersect!
01717     PRINT_DEBUG_129("Found CROSS_INTERSECT\n");
01718     int_result = CROSS_INTERSECT;
01719     ImprintPointData *new_point_seg_1, *new_point_seg_2;
01720     new_point_seg_1 = new ImprintPointData(closest_point_seg_1.x(),
01721                                            closest_point_seg_1.y(),
01722                                            closest_point_seg_1.z());
01723     allocatedPointData->append(new_point_seg_1);
01724     new_point_seg_1->owner(seg_1->owner());
01725     new_point_seg_1->set_point_type(CREATE_NEW_VERTEX);
01726     new_point_seg_2 = new ImprintPointData(closest_point_seg_2.x(),
01727                                            closest_point_seg_2.y(),
01728                                            closest_point_seg_2.z());
01729     allocatedPointData->append(new_point_seg_2);
01730     new_point_seg_2->owner(seg_2->owner());
01731     new_point_seg_2->set_point_type(CREATE_NEW_VERTEX);
01732 
01733     new_point_seg_2->set_matching_point(new_point_seg_1);
01734     new_point_seg_1->set_matching_point(new_point_seg_2);
01735     
01736     new_segments[0] = new ImprintLineSegment(imp_point_0, new_point_seg_1,
01737                                              seg_1->owner());
01738     new_segments[1] = new ImprintLineSegment(new_point_seg_1, imp_point_1,
01739                                              seg_1->owner());
01740     new_segments[2] = new ImprintLineSegment(imp_point_2, new_point_seg_2,
01741                                              seg_2->owner());
01742     new_segments[3] = new ImprintLineSegment(new_point_seg_2, imp_point_3,
01743                                              seg_2->owner());
01744     allocatedLineData->append(new_segments[0]);
01745     allocatedLineData->append(new_segments[1]);
01746     allocatedLineData->append(new_segments[2]);
01747     allocatedLineData->append(new_segments[3]);
01748       //now update the lists.
01749       //update list 1.
01750     update_list(new_segments, seg_1, seg_2, CUBIT_TRUE);
01751       //update list 2.
01752     update_list(new_segments, seg_1, seg_2, CUBIT_FALSE);
01753       //seg_1 and seg_2 will no longer be used
01754     seg_1->set_inactive(CUBIT_TRUE);
01755     seg_2->set_inactive(CUBIT_TRUE);
01756     return CUBIT_SUCCESS;
01757   }
01758   else
01759   {
01760       //All that for nothing!  Some how I need to find this out
01761       //earlier to avoid all the comparisions...  Will have
01762       //to check at least for the intersection though..
01763     PRINT_DEBUG_129("Found NO_INTERSECT\n");
01764     int_result = NO_INTERSECT;
01765     return CUBIT_SUCCESS;
01766   }
01767 }
01768 
01769 void ImprintBoundaryTool::update_list(ImprintLineSegment **new_segments,
01770                                       ImprintLineSegment *seg_1,
01771                                       ImprintLineSegment *seg_2,
01772                                       const CubitBoolean list_1 )
01773 {
01774   if (list_1)
01775   {
01776     new_segments[0]->set_prev(seg_1->get_prev());
01777     seg_1->get_prev()->set_next(new_segments[0]);
01778     new_segments[0]->set_next(new_segments[1]);
01779     new_segments[1]->set_prev(new_segments[0]);
01780     new_segments[1]->set_next(seg_1->get_next());
01781     seg_1->get_next()->set_prev(new_segments[1]);
01782   }
01783   else
01784   {
01785     new_segments[2]->set_prev(seg_2->get_prev());
01786     seg_2->get_prev()->set_next(new_segments[2]);
01787     new_segments[2]->set_next(new_segments[3]);
01788     new_segments[3]->set_prev(new_segments[2]);
01789     new_segments[3]->set_next(seg_2->get_next());
01790     seg_2->get_next()->set_prev(new_segments[3]);
01791   }
01792 }
01793 CubitStatus ImprintBoundaryTool::case_0_2_equal( ImprintLineSegment *seg_1,
01794                                                  ImprintLineSegment *seg_2,
01795                                                  ImprintPointData* imp_point_0,
01796                                                  ImprintPointData* imp_point_1,
01797                                                  ImprintPointData* imp_point_2,
01798                                                  ImprintPointData* imp_point_3,
01799                                                  MatchType type_1, MatchType type_3,
01800                                                  IntersectResult &int_result,
01801                                                  ImprintLineSegment **new_segments)
01802 {
01803     //Okay at this point we know that point_0 and point_2 are
01804     //equal, and we know that point_1 doesn't match an end_point.
01805     //We know then that this is either an L or a overlap-join.
01806     //Test to see if point_1 is on seg_2 or point_3 is on seg_1.
01807     //If neither then we have an L, other wise an overlap-join.
01808   CubitBoolean point_1_on_seg_2 =CUBIT_FALSE;
01809   CubitBoolean point_3_on_seg_1 =CUBIT_FALSE;
01810   if ( on_interior_segment(imp_point_1, seg_2) )
01811     point_1_on_seg_2 = CUBIT_TRUE;
01812   if ( on_interior_segment(imp_point_3, seg_1) )
01813     point_3_on_seg_1 = CUBIT_TRUE;
01814   
01815   if ( !point_1_on_seg_2 && !point_3_on_seg_1 )
01816   {
01817     PRINT_DEBUG_129("Found L_INTERSECT_0_2\n");
01818     int_result = L_INTERSECT_0_2;
01819     set_type_for_L(imp_point_0, imp_point_2);
01820     return CUBIT_SUCCESS;
01821   }
01822   else if (point_1_on_seg_2 )
01823   {
01824     if (type_1 == MATCH_1_6 )
01825     {
01826       double dist_1 = (imp_point_1->coordinates() -
01827                        seg_2->get_prev()->get_start()->coordinates()).length_squared();
01828       CubitVector point_on_seg_2;
01829       closest_point_interior_seg(imp_point_1, seg_2, point_on_seg_2);
01830       double dist_2 = (imp_point_1->coordinates() - point_on_seg_2).length_squared();
01831       if ( dist_1 < dist_2 )
01832       {
01833         PRINT_DEBUG_129("Found L_INTERSECT_0_2\n");
01834         int_result = L_INTERSECT_0_2;
01835         set_type_for_L(imp_point_0, imp_point_2);
01836         return CUBIT_SUCCESS;
01837       }
01838     }
01839     else if (type_1 == MATCH_1_7 )
01840     {
01841       double dist_1 = (imp_point_1->coordinates() -
01842                        seg_2->get_next()->get_end()->coordinates()).length_squared();
01843       CubitVector point_on_seg_2;
01844       closest_point_interior_seg(imp_point_1, seg_2, point_on_seg_2);
01845       double dist_2 = (imp_point_1->coordinates() - point_on_seg_2).length_squared();
01846       if ( dist_1 < dist_2 )
01847       {
01848         PRINT_DEBUG_129("Found L_INTERSECT_0_2\n");
01849         int_result = L_INTERSECT_0_2;
01850         set_type_for_L(imp_point_0, imp_point_2);
01851         return CUBIT_SUCCESS;
01852       }
01853     }
01854   }
01855   else if (point_3_on_seg_1 )
01856   {
01857     if (type_3 == MATCH_3_4 )
01858     {
01859       double dist_1 = (imp_point_3->coordinates() -
01860                        seg_1->get_prev()->get_start()->coordinates()).length_squared();
01861       CubitVector point_on_seg_1;
01862       closest_point_interior_seg(imp_point_3, seg_1, point_on_seg_1);
01863       double dist_2 = (imp_point_3->coordinates() - point_on_seg_1).length_squared();
01864       if ( dist_1 < dist_2 )
01865       {
01866         PRINT_DEBUG_129("Found L_INTERSECT_0_2\n");
01867         int_result = L_INTERSECT_0_2;
01868         set_type_for_L(imp_point_0, imp_point_2);
01869         return CUBIT_SUCCESS;
01870       }
01871     }
01872     else if (type_3 == MATCH_3_5 )
01873     {
01874       double dist_1 = (imp_point_3->coordinates() -
01875                        seg_1->get_next()->get_end()->coordinates()).length_squared();
01876       CubitVector point_on_seg_1;
01877       closest_point_interior_seg(imp_point_3, seg_1, point_on_seg_1);
01878       double dist_2 = (imp_point_3->coordinates() - point_on_seg_1).length_squared();
01879       if ( dist_1 < dist_2 )
01880       {
01881         PRINT_DEBUG_129("Found L_INTERSECT_0_2\n");
01882         int_result = L_INTERSECT_0_2;
01883         set_type_for_L(imp_point_0, imp_point_2);
01884         return CUBIT_SUCCESS;
01885       }
01886     }
01887   }
01888   if ( point_1_on_seg_2 )
01889   {
01890       //This is an overlap_join.
01891     PRINT_DEBUG_129("Found OVERALP_JOIN_02_1_3\n");
01892     int_result = OVERLAP_JOIN_02_1_3;
01893       //Create the new segments, the first segment remains the same so
01894       //leave positions 0 and 1 empty.
01895     ImprintLineSegment *new_seg_2_1, *new_seg_1_3;
01896       //copy point 1 to use on segment 2
01897     CubitVector closest_point;
01898     closest_point_seg( imp_point_1, seg_2, closest_point);
01899     ImprintPointData *new_point_1 = new ImprintPointData(imp_point_1, closest_point);
01900     new_point_1->owner(seg_2->owner());
01901     allocatedPointData->append(new_point_1);
01902     if ( imp_point_1->is_owner_vertex() )
01903     {
01904       new_point_1->set_point_type(CREATE_NEW_VERTEX);
01905       if ( imp_point_1->get_point_type() != CREATE_NEW_VERTEX )
01906         imp_point_1->set_point_type(VERTEX_ON_BOTH_BOUNDARIES);
01907     }
01908     else
01909     {
01910       new_point_1->set_point_type(ON_BOTH_BOUNDARIES);
01911       imp_point_1->set_point_type(ON_BOTH_BOUNDARIES);
01912     }
01913     new_seg_2_1 = new ImprintLineSegment(imp_point_2, new_point_1,
01914                                          seg_2->owner());
01915     new_seg_1_3 = new ImprintLineSegment(new_point_1, imp_point_3,
01916                                          seg_2->owner());
01917     new_segments[2] = new_seg_2_1;
01918     new_segments[3] = new_seg_1_3;
01919     allocatedLineData->append(new_segments[2]);
01920     allocatedLineData->append(new_segments[3]);
01921       //update the lists.
01922     update_list(new_segments, seg_1, seg_2, CUBIT_FALSE);
01923     seg_2->set_inactive(CUBIT_TRUE);
01924     return CUBIT_SUCCESS;
01925   }
01926   else if ( point_3_on_seg_1 )
01927   {
01928       //This is an overlap_join.
01929     PRINT_DEBUG_129("Found OVERALP_JOIN_02_3_1\n");
01930     int_result = OVERLAP_JOIN_02_3_1;
01931       //Create the new segments, the first segment remains the same so
01932       //leave positions 0 and 1 empty.
01933     ImprintLineSegment *new_seg_0_3, *new_seg_3_1;
01934       //copy point 3 to use on segment 1
01935     CubitVector closest_point;
01936     closest_point_seg( imp_point_3, seg_1, closest_point);
01937     ImprintPointData *new_point_3 = new ImprintPointData(imp_point_3, closest_point);
01938     new_point_3->owner(seg_1->owner());
01939     allocatedPointData->append(new_point_3);
01940     if ( imp_point_3->is_owner_vertex() )
01941     {
01942       new_point_3->set_point_type(CREATE_NEW_VERTEX);
01943       if ( imp_point_3->get_point_type() != CREATE_NEW_VERTEX )
01944         imp_point_3->set_point_type(VERTEX_ON_BOTH_BOUNDARIES);
01945     }
01946     else
01947     {
01948       new_point_3->set_point_type(ON_BOTH_BOUNDARIES);
01949       imp_point_3->set_point_type(ON_BOTH_BOUNDARIES);
01950     }
01951 
01952     new_seg_0_3 = new ImprintLineSegment(imp_point_0, new_point_3,
01953                                          seg_1->owner());
01954     new_seg_3_1 = new ImprintLineSegment(new_point_3, imp_point_1,
01955                                          seg_1->owner());
01956     new_segments[0] = new_seg_0_3;
01957     new_segments[1] = new_seg_3_1;
01958     allocatedLineData->append(new_segments[0]);
01959     allocatedLineData->append(new_segments[1]);
01960       //update the lists
01961     update_list(new_segments, seg_1, seg_2, CUBIT_TRUE);
01962     seg_1->set_inactive(CUBIT_TRUE);
01963     return CUBIT_SUCCESS;
01964   }
01965   else
01966   {
01967       //For this case we must have an L condition.
01968     set_type_for_L(imp_point_0, imp_point_2);
01969     PRINT_DEBUG_129("Found L_INTERSECT_0_2\n");
01970     int_result = L_INTERSECT_0_2;
01971     return CUBIT_SUCCESS;
01972   }
01973 }
01974 CubitStatus ImprintBoundaryTool::case_0_3_equal( ImprintLineSegment *seg_1,
01975                                                  ImprintLineSegment *seg_2,
01976                                                  ImprintPointData* imp_point_0,
01977                                                  ImprintPointData* imp_point_1,
01978                                                  ImprintPointData* imp_point_2,
01979                                                  ImprintPointData* imp_point_3,
01980                                                  MatchType type_1, MatchType type_2,
01981                                                  IntersectResult &int_result,
01982                                                  ImprintLineSegment **new_segments)
01983 {
01984     //Okay at this point we know that point_0 and point_3 are
01985     //equal, and we know that point_1 doesn't match an end_point.
01986     //We know then that this is either an L or a overlap-join.
01987     //Test to see if point_1 is on seg_2 or point_2 is on seg_1.
01988     //If neither then we have an L, other wise an overlap-join.
01989   CubitBoolean point_1_on_seg_2 =CUBIT_FALSE;
01990   CubitBoolean point_2_on_seg_1 =CUBIT_FALSE;
01991   if ( on_interior_segment(imp_point_1, seg_2) )
01992     point_1_on_seg_2 = CUBIT_TRUE;
01993   if ( on_interior_segment(imp_point_2, seg_1) )
01994     point_2_on_seg_1 = CUBIT_TRUE;
01995   
01996   if ( !point_1_on_seg_2 && !point_2_on_seg_1 )
01997   {
01998     PRINT_DEBUG_129("Found L_INTERSECT_0_3\n");
01999     int_result = L_INTERSECT_0_3;
02000     set_type_for_L(imp_point_0, imp_point_3);
02001     return CUBIT_SUCCESS;
02002   }
02003   else if (point_1_on_seg_2 )
02004   {
02005     if (type_1 == MATCH_1_6 )
02006     {
02007       double dist_1 = (imp_point_1->coordinates() -
02008                        seg_2->get_prev()->get_start()->coordinates()).length_squared();
02009       CubitVector point_on_seg_2;
02010       closest_point_interior_seg(imp_point_1, seg_2, point_on_seg_2);
02011       double dist_2 = (imp_point_1->coordinates() - point_on_seg_2).length_squared();
02012       if ( dist_1 < dist_2 )
02013       {
02014         PRINT_DEBUG_129("Found L_INTERSECT_0_3\n");
02015         int_result = L_INTERSECT_0_3;
02016         set_type_for_L(imp_point_0, imp_point_3);
02017         return CUBIT_SUCCESS;
02018       }
02019     }
02020     else if (type_1 == MATCH_1_7 )
02021     {
02022       double dist_1 = (imp_point_1->coordinates() -
02023                        seg_2->get_next()->get_end()->coordinates()).length_squared();
02024       CubitVector point_on_seg_2;
02025       closest_point_interior_seg(imp_point_1, seg_2, point_on_seg_2);
02026       double dist_2 = (imp_point_1->coordinates() - point_on_seg_2).length_squared();
02027       if ( dist_1 < dist_2 )
02028       {
02029         PRINT_DEBUG_129("Found L_INTERSECT_0_3\n");
02030         int_result = L_INTERSECT_0_3;
02031         set_type_for_L(imp_point_0, imp_point_3);
02032         return CUBIT_SUCCESS;
02033       }
02034     }
02035   }
02036   else if (point_2_on_seg_1 )
02037   {
02038     if (type_2 == MATCH_2_4 )
02039     {
02040       double dist_1 = (imp_point_2->coordinates() -
02041                        seg_1->get_prev()->get_start()->coordinates()).length_squared();
02042       CubitVector point_on_seg_1;
02043       closest_point_interior_seg(imp_point_2, seg_1, point_on_seg_1);
02044       double dist_2 = (imp_point_2->coordinates() - point_on_seg_1).length_squared();
02045       if ( dist_1 < dist_2 )
02046       {
02047         PRINT_DEBUG_129("Found L_INTERSECT_0_3\n");
02048         int_result = L_INTERSECT_0_3;
02049         set_type_for_L(imp_point_0, imp_point_3);
02050         return CUBIT_SUCCESS;
02051       }
02052     }
02053     else if (type_2 == MATCH_2_5 )
02054     {
02055       double dist_1 = (imp_point_2->coordinates() -
02056                        seg_1->get_next()->get_end()->coordinates()).length_squared();
02057       CubitVector point_on_seg_1;
02058       closest_point_interior_seg(imp_point_2, seg_1, point_on_seg_1);
02059       double dist_2 = (imp_point_2->coordinates() - point_on_seg_1).length_squared();
02060       if ( dist_1 < dist_2 )
02061       {
02062         PRINT_DEBUG_129("Found L_INTERSECT_0_3\n");
02063         int_result = L_INTERSECT_0_3;
02064         set_type_for_L(imp_point_0, imp_point_3);
02065         return CUBIT_SUCCESS;
02066       }
02067     }
02068   }
02069 
02070   if ( point_1_on_seg_2 )
02071   {
02072       //This is an overlap_join.
02073     PRINT_DEBUG_129("Found OVERALP_JOIN_03_1_2\n");
02074     //double dist = (imp_point_1->coordinates() - imp_point_2->coordinates()).length();
02075     int_result = OVERLAP_JOIN_03_1_2;
02076       //Create the new segments, the first segment remains the same so
02077       //leave positions 0 and 1 empty.
02078     ImprintLineSegment *new_seg_2_1, *new_seg_1_3;
02079       //copy point 1 to use on segment 2
02080     CubitVector closest_point;
02081     closest_point_seg( imp_point_1, seg_2, closest_point);
02082     ImprintPointData *new_point_1 = new ImprintPointData(imp_point_1, closest_point);
02083     new_point_1->owner(seg_2->owner());
02084     allocatedPointData->append(new_point_1);
02085     if ( imp_point_1->is_owner_vertex() )
02086     {
02087       new_point_1->set_point_type(CREATE_NEW_VERTEX);
02088       if ( imp_point_1->get_point_type() != CREATE_NEW_VERTEX )
02089         imp_point_1->set_point_type(VERTEX_ON_BOTH_BOUNDARIES);
02090     }
02091     else
02092     {
02093       new_point_1->set_point_type(ON_BOTH_BOUNDARIES);
02094       imp_point_1->set_point_type(ON_BOTH_BOUNDARIES);
02095     }
02096 
02097     new_seg_2_1 = new ImprintLineSegment(imp_point_2, new_point_1,
02098                                          seg_2->owner());
02099     new_seg_1_3 = new ImprintLineSegment(new_point_1, imp_point_3,
02100                                          seg_2->owner());
02101     new_segments[2] = new_seg_2_1;
02102     new_segments[3] = new_seg_1_3;
02103     allocatedLineData->append(new_segments[2]);
02104     allocatedLineData->append(new_segments[3]);
02105       //update the list.
02106     update_list(new_segments, seg_1, seg_2, CUBIT_FALSE);
02107     seg_2->set_inactive(CUBIT_TRUE);
02108     return CUBIT_SUCCESS;
02109   }
02110   else if ( point_2_on_seg_1 )
02111   {
02112       //This is an overlap_join.
02113     PRINT_DEBUG_129("Found OVERALP_JOIN_03_2_1\n");
02114     int_result = OVERLAP_JOIN_03_2_1;
02115       //Create the new segments, the first segment remains the same so
02116       //leave positions 0 and 1 empty.
02117     ImprintLineSegment *new_seg_0_2, *new_seg_2_1;
02118       //copy point 1 to use on segment 2
02119     CubitVector closest_point;
02120     closest_point_seg( imp_point_2, seg_1, closest_point);
02121     ImprintPointData *new_point_2 = new ImprintPointData(imp_point_2, closest_point);
02122     new_point_2->owner(seg_1->owner());
02123     allocatedPointData->append(new_point_2);
02124     if ( imp_point_2->is_owner_vertex() )
02125     {
02126       new_point_2->set_point_type(CREATE_NEW_VERTEX);
02127       if ( imp_point_2->get_point_type() != CREATE_NEW_VERTEX )
02128         imp_point_2->set_point_type(VERTEX_ON_BOTH_BOUNDARIES);
02129     }
02130     else
02131     {
02132       new_point_2->set_point_type(ON_BOTH_BOUNDARIES);
02133       imp_point_2->set_point_type(ON_BOTH_BOUNDARIES);
02134     }
02135 
02136     new_seg_0_2 = new ImprintLineSegment(imp_point_0, new_point_2,
02137                                          seg_1->owner());
02138     new_seg_2_1 = new ImprintLineSegment(new_point_2, imp_point_1,
02139                                          seg_1->owner());
02140     new_segments[0] = new_seg_0_2;
02141     new_segments[1] = new_seg_2_1;
02142     allocatedLineData->append(new_segments[0]);
02143     allocatedLineData->append(new_segments[1]);
02144       //update the list.
02145     update_list(new_segments, seg_1, seg_2, CUBIT_TRUE);
02146     seg_1->set_inactive(CUBIT_TRUE);
02147     return CUBIT_SUCCESS;
02148   }
02149   else
02150   {
02151       //For this case we must have an L condition.
02152     set_type_for_L(imp_point_0, imp_point_3);
02153     PRINT_DEBUG_129("Found L_INTERSECT_0_3\n");
02154     int_result = L_INTERSECT_0_3;
02155     return CUBIT_SUCCESS;
02156   }
02157 }
02158 CubitStatus ImprintBoundaryTool::case_1_2_equal( ImprintLineSegment *seg_1,
02159                                                  ImprintLineSegment *seg_2,
02160                                                  ImprintPointData* imp_point_0,
02161                                                  ImprintPointData* imp_point_1,
02162                                                  ImprintPointData* imp_point_2,
02163                                                  ImprintPointData* imp_point_3,
02164                                                  MatchType type_0, MatchType type_3,
02165                                                  IntersectResult &int_result,
02166                                                  ImprintLineSegment **new_segments)
02167 {
02168     //Okay at this point we know that point_1 and point_2 are
02169     //equal, and we know that point_0 doesn't match an end_point.
02170     //We know then that this is either an L or a overlap-join.
02171     //Test to see if point_0 is on seg_2 or point_3 is on seg_1.
02172     //If neither then we have an L, other wise an overlap-join.
02173   CubitBoolean point_0_on_seg_2 =CUBIT_FALSE;
02174   CubitBoolean point_3_on_seg_1 =CUBIT_FALSE;
02175   if ( on_interior_segment(imp_point_0, seg_2) )
02176     point_0_on_seg_2 = CUBIT_TRUE;
02177   if ( on_interior_segment(imp_point_3, seg_1) )
02178     point_3_on_seg_1 = CUBIT_TRUE;
02179   
02180   if ( !point_0_on_seg_2 && !point_3_on_seg_1 )
02181   {
02182     PRINT_DEBUG_129("Found L_INTERSECT_1_2\n");
02183     int_result = L_INTERSECT_1_2;
02184     set_type_for_L(imp_point_1, imp_point_2);
02185     return CUBIT_SUCCESS;
02186   }
02187   else if (point_0_on_seg_2 )
02188   {
02189     if (type_0 == MATCH_0_6 )
02190     {
02191       double dist_1 = (imp_point_0->coordinates() -
02192                        seg_2->get_prev()->get_start()->coordinates()).length_squared();
02193       CubitVector point_on_seg_2;
02194       closest_point_interior_seg(imp_point_0, seg_2, point_on_seg_2);
02195       double dist_2 = (imp_point_0->coordinates() - point_on_seg_2).length_squared();
02196       if ( dist_1 < dist_2 )
02197       {
02198         PRINT_DEBUG_129("Found L_INTERSECT_1_2\n");
02199         int_result = L_INTERSECT_1_2;
02200         set_type_for_L(imp_point_1, imp_point_2);
02201         return CUBIT_SUCCESS;
02202       }
02203     }
02204     else if (type_0 == MATCH_0_7 )
02205     {
02206       double dist_1 = (imp_point_0->coordinates() -
02207                        seg_2->get_next()->get_end()->coordinates()).length_squared();
02208       CubitVector point_on_seg_2;
02209       closest_point_interior_seg(imp_point_0, seg_2, point_on_seg_2);
02210       double dist_2 = (imp_point_0->coordinates() - point_on_seg_2).length_squared();
02211       if ( dist_1 < dist_2 )
02212       {
02213         PRINT_DEBUG_129("Found L_INTERSECT_1_2\n");
02214         int_result = L_INTERSECT_1_2;
02215         set_type_for_L(imp_point_1, imp_point_2);
02216         return CUBIT_SUCCESS;
02217       }
02218     }
02219   }
02220   else if (point_3_on_seg_1 )
02221   {
02222     if (type_3 == MATCH_3_4 )
02223     {
02224       double dist_1 = (imp_point_3->coordinates() -
02225                        seg_1->get_prev()->get_start()->coordinates()).length_squared();
02226       CubitVector point_on_seg_1;
02227       closest_point_interior_seg(imp_point_3, seg_1, point_on_seg_1);
02228       double dist_2 = (imp_point_3->coordinates() - point_on_seg_1).length_squared();
02229       if ( dist_1 < dist_2 )
02230       {
02231         PRINT_DEBUG_129("Found L_INTERSECT_1_2\n");
02232         int_result = L_INTERSECT_1_2;
02233         set_type_for_L(imp_point_1, imp_point_2);
02234         return CUBIT_SUCCESS;
02235       }
02236     }
02237     else if (type_3 == MATCH_3_5 )
02238     {
02239       double dist_1 = (imp_point_3->coordinates() -
02240                        seg_1->get_next()->get_end()->coordinates()).length_squared();
02241       CubitVector point_on_seg_1;
02242       closest_point_interior_seg(imp_point_3, seg_1, point_on_seg_1);
02243       double dist_2 = (imp_point_3->coordinates() - point_on_seg_1).length_squared();
02244       if ( dist_1 < dist_2 )
02245       {
02246         PRINT_DEBUG_129("Found L_INTERSECT_1_2\n");
02247         int_result = L_INTERSECT_1_2;
02248         set_type_for_L(imp_point_1, imp_point_2);
02249         return CUBIT_SUCCESS;
02250       }
02251     }
02252   }
02253   if ( point_0_on_seg_2 )
02254   {
02255       //This is an overlap_join.
02256     PRINT_DEBUG_129("Found OVERALP_JOIN_12_0_3\n");
02257     int_result = OVERLAP_JOIN_12_0_3;
02258       //Create the new segments, the first segment remains the same so
02259       //leave positions 0 and 1 empty.
02260     ImprintLineSegment *new_seg_2_0, *new_seg_0_3;
02261       //copy point 1 to use on segment 2
02262     CubitVector closest_point;
02263     closest_point_seg( imp_point_0, seg_2, closest_point);
02264     ImprintPointData *new_point_0 = new ImprintPointData(imp_point_0, closest_point);
02265     new_point_0->owner(seg_2->owner());
02266     allocatedPointData->append(new_point_0);
02267     if ( imp_point_0->is_owner_vertex() )
02268     {
02269       new_point_0->set_point_type(CREATE_NEW_VERTEX);
02270       if ( imp_point_0->get_point_type() != CREATE_NEW_VERTEX )
02271         imp_point_0->set_point_type(VERTEX_ON_BOTH_BOUNDARIES);
02272     }
02273     else
02274     {
02275       new_point_0->set_point_type(ON_BOTH_BOUNDARIES);
02276       imp_point_0->set_point_type(ON_BOTH_BOUNDARIES);
02277     }
02278 
02279     new_seg_2_0 = new ImprintLineSegment(imp_point_2, new_point_0,
02280                                          seg_2->owner());
02281     new_seg_0_3 = new ImprintLineSegment(new_point_0, imp_point_3,
02282                                          seg_2->owner());
02283     new_segments[2] = new_seg_2_0;
02284     new_segments[3] = new_seg_0_3;
02285     allocatedLineData->append(new_segments[2]);
02286     allocatedLineData->append(new_segments[3]);
02287       //update the list.
02288     update_list(new_segments, seg_1, seg_2, CUBIT_FALSE);
02289     seg_2->set_inactive(CUBIT_TRUE);
02290     return CUBIT_SUCCESS;
02291   }
02292   else if ( point_3_on_seg_1 )
02293   {
02294       //This is an overlap_join.
02295     PRINT_DEBUG_129("Found OVERALP_JOIN_12_3_0\n");
02296     int_result = OVERLAP_JOIN_12_3_0;
02297       //Create the new segments, the first segment remains the same so
02298       //leave positions 0 and 1 empty.
02299     ImprintLineSegment *new_seg_3_1, *new_seg_0_3;
02300       //copy point 3 to use on segment 1
02301     CubitVector closest_point;
02302     closest_point_seg( imp_point_3, seg_1, closest_point);
02303     ImprintPointData *new_point_3 = new ImprintPointData(imp_point_3, closest_point);
02304     new_point_3->owner(seg_1->owner());
02305     allocatedPointData->append(new_point_3);
02306     if ( imp_point_3->is_owner_vertex() )
02307     {
02308       new_point_3->set_point_type(CREATE_NEW_VERTEX);
02309       if ( imp_point_3->get_point_type() != CREATE_NEW_VERTEX )
02310         imp_point_3->set_point_type(VERTEX_ON_BOTH_BOUNDARIES);
02311     }
02312     else
02313     {
02314       new_point_3->set_point_type(ON_BOTH_BOUNDARIES);
02315       imp_point_3->set_point_type(ON_BOTH_BOUNDARIES);
02316     }
02317     new_seg_0_3 = new ImprintLineSegment(imp_point_0, new_point_3,
02318                                          seg_1->owner());
02319     new_seg_3_1 = new ImprintLineSegment(new_point_3, imp_point_1,
02320                                          seg_1->owner());
02321     new_segments[0] = new_seg_0_3;
02322     new_segments[1] = new_seg_3_1;
02323     allocatedLineData->append(new_segments[0]);
02324     allocatedLineData->append(new_segments[1]);
02325       //update the list.
02326     update_list(new_segments, seg_1, seg_2, CUBIT_TRUE);
02327     seg_1->set_inactive(CUBIT_TRUE);
02328     return CUBIT_SUCCESS;
02329   }
02330   else
02331   {
02332       //For this case we must have an L condition.
02333     set_type_for_L(imp_point_1, imp_point_2);
02334     PRINT_DEBUG_129("Found L_INTERSECT_1_2\n");
02335     int_result = L_INTERSECT_1_2;
02336     return CUBIT_SUCCESS;
02337   }
02338 }
02339 CubitStatus ImprintBoundaryTool::determine_on_boundary( ImprintLineSegment *seg_1,
02340                                                         ImprintLineSegment *seg_2,
02341                                                         MatchType &type_0, MatchType &type_1,
02342                                                         MatchType &type_2, MatchType &type_3 )
02343 {
02344     //Find out if the points are on the boundary.  Also use the matching informatin
02345     //previously calculated, since some of the nodes may match more closely with
02346     //other nodes on the boundary.  For instance, if the boundary does a quick
02347     //reversal, a point may match an existing point better than here.
02348     //If the points should be on the segment, set the matchtype flags accordingly.
02349   ImprintPointData* imp_point_0,*imp_point_1,*imp_point_2,*imp_point_3;
02350   imp_point_0 = seg_1->get_start();
02351   imp_point_1 = seg_1->get_end();
02352   imp_point_2 = seg_2->get_start();
02353   imp_point_3 = seg_2->get_end();
02354 
02355   CubitBoolean point_0_on_seg_2 =CUBIT_FALSE;
02356   CubitBoolean point_1_on_seg_2 =CUBIT_FALSE;
02357   CubitBoolean point_2_on_seg_1 =CUBIT_FALSE;
02358   CubitBoolean point_3_on_seg_1 =CUBIT_FALSE;
02359 
02360   if ( on_interior_segment(imp_point_0, seg_2) )
02361     point_0_on_seg_2 = CUBIT_TRUE;
02362   if ( on_interior_segment(imp_point_1, seg_2) )
02363     point_1_on_seg_2 = CUBIT_TRUE;
02364   if ( on_interior_segment(imp_point_2, seg_1) )
02365     point_2_on_seg_1 = CUBIT_TRUE;
02366   if ( on_interior_segment(imp_point_3, seg_1) )
02367     point_3_on_seg_1 = CUBIT_TRUE;
02368 
02369   if ( point_0_on_seg_2 )
02370   {
02371     if ( type_0 == MATCH_0_6 )
02372     {
02373       double dist_1 = (imp_point_0->coordinates() -
02374                        seg_2->get_prev()->get_start()->coordinates()).length_squared();
02375       CubitVector point_on_seg_2;
02376       closest_point_interior_seg(imp_point_0, seg_2, point_on_seg_2);
02377       double dist_2 = (imp_point_0->coordinates() - point_on_seg_2).length_squared();
02378       if ( dist_1 < dist_2 )
02379         type_0 = NO_MATCH;
02380       else
02381         type_0 = ON_SEG_2;
02382     }
02383     else if (type_0 == MATCH_0_7 )
02384     {
02385       double dist_1 = (imp_point_0->coordinates() -
02386                        seg_2->get_next()->get_end()->coordinates()).length_squared();
02387       CubitVector point_on_seg_2;
02388       closest_point_interior_seg(imp_point_0, seg_2, point_on_seg_2);
02389       double dist_2 = (imp_point_0->coordinates() - point_on_seg_2).length_squared();
02390       if ( dist_1 < dist_2 )
02391         type_0 = NO_MATCH;
02392       else
02393         type_0 = ON_SEG_2;
02394     }
02395     else 
02396       type_0 = ON_SEG_2;
02397   }
02398     
02399   if ( point_1_on_seg_2 )
02400   {
02401     if ( type_1 == MATCH_1_6 )
02402     {
02403       double dist_1 = (imp_point_1->coordinates() -
02404                        seg_2->get_prev()->get_start()->coordinates()).length_squared();
02405       CubitVector point_on_seg_2;
02406       closest_point_interior_seg(imp_point_1, seg_2, point_on_seg_2);
02407       double dist_2 = (imp_point_1->coordinates() - point_on_seg_2).length_squared();
02408       if ( dist_1 < dist_2 )
02409         type_1 = NO_MATCH;
02410       else
02411         type_1 = ON_SEG_2;
02412     }
02413     else if (type_1 == MATCH_1_7 )
02414     {
02415       double dist_1 = (imp_point_1->coordinates() -
02416                        seg_2->get_next()->get_end()->coordinates()).length_squared();
02417       CubitVector point_on_seg_2;
02418       closest_point_interior_seg(imp_point_1, seg_2, point_on_seg_2);
02419       double dist_2 = (imp_point_1->coordinates() - point_on_seg_2).length_squared();
02420       if ( dist_1 < dist_2 )
02421         type_1 = NO_MATCH;
02422       else
02423         type_1 = ON_SEG_2;
02424     }
02425     else 
02426       type_1 = ON_SEG_2;
02427   }
02428   if ( point_2_on_seg_1 )
02429   {
02430     if ( type_2 == MATCH_2_4 )
02431     {
02432       double dist_1 = (imp_point_2->coordinates() -
02433                        seg_1->get_prev()->get_start()->coordinates()).length_squared();
02434       CubitVector point_on_seg_1;
02435       closest_point_interior_seg(imp_point_2, seg_1, point_on_seg_1);
02436       double dist_2 = (imp_point_2->coordinates() - point_on_seg_1).length_squared();
02437       if ( dist_1 < dist_2 )
02438         type_2 = NO_MATCH;
02439       else
02440         type_2 = ON_SEG_1;
02441     }
02442     else if (type_2 == MATCH_2_5 )
02443     {
02444       double dist_1 = (imp_point_2->coordinates() -
02445                        seg_1->get_next()->get_end()->coordinates()).length_squared();
02446       CubitVector point_on_seg_1;
02447       closest_point_interior_seg(imp_point_2, seg_1, point_on_seg_1);
02448       double dist_2 = (imp_point_2->coordinates() - point_on_seg_1).length_squared();
02449       if ( dist_1 < dist_2 )
02450         type_2 = NO_MATCH;
02451       else
02452         type_2 = ON_SEG_1;
02453     }
02454     else 
02455       type_2 = ON_SEG_1;
02456   }
02457   if ( point_3_on_seg_1 )
02458   {
02459     if ( type_3 == MATCH_3_4 )
02460     {
02461       double dist_1 = (imp_point_3->coordinates() -
02462                        seg_1->get_prev()->get_start()->coordinates()).length_squared();
02463       CubitVector point_on_seg_1;
02464       closest_point_interior_seg(imp_point_3, seg_1, point_on_seg_1);
02465       double dist_2 = (imp_point_3->coordinates() - point_on_seg_1).length_squared();
02466       if ( dist_1 < dist_2 )
02467         type_3 = NO_MATCH;
02468       else
02469         type_3 = ON_SEG_1;
02470     }
02471     else if (type_3 == MATCH_3_5 )
02472     {
02473       double dist_1 = (imp_point_3->coordinates() -
02474                        seg_1->get_next()->get_end()->coordinates()).length_squared();
02475       CubitVector point_on_seg_1;
02476       closest_point_interior_seg(imp_point_3, seg_1, point_on_seg_1);
02477       double dist_2 = (imp_point_3->coordinates() - point_on_seg_1).length_squared();
02478       if ( dist_1 < dist_2 )
02479         type_3 = NO_MATCH;
02480       else
02481         type_3 = ON_SEG_1;
02482     }
02483     else 
02484       type_3 = ON_SEG_1;
02485   }
02486   return CUBIT_SUCCESS;
02487 }
02488 
02489 CubitStatus ImprintBoundaryTool::case_1_3_equal( ImprintLineSegment *seg_1,
02490                                                  ImprintLineSegment *seg_2,
02491                                                  ImprintPointData* imp_point_0,
02492                                                  ImprintPointData* imp_point_1,
02493                                                  ImprintPointData* imp_point_2,
02494                                                  ImprintPointData* imp_point_3,
02495                                                  MatchType type_0, MatchType type_2,
02496                                                  IntersectResult &int_result,
02497                                                  ImprintLineSegment **new_segments)
02498 {
02499     //Okay at this point we know that point_1 and point_3 are
02500     //equal, and we know that point_0 doesn't match an end_point.
02501     //We know then that this is either an L or a overlap-join.
02502     //Test to see if point_0 is on seg_2 or point_2 is on seg_1.
02503     //If neither then we have an L, other wise an overlap-join.
02504 
02505     //First test to see if they are are on the segments.
02506   CubitBoolean point_0_on_seg_2 =CUBIT_FALSE;
02507   CubitBoolean point_2_on_seg_1 =CUBIT_FALSE;
02508   if ( on_interior_segment(imp_point_0, seg_2) )
02509     point_0_on_seg_2 = CUBIT_TRUE;
02510   if ( on_interior_segment(imp_point_2, seg_1) )
02511     point_2_on_seg_1 = CUBIT_TRUE;
02512   
02513   if ( !point_0_on_seg_2 && !point_2_on_seg_1 )
02514   {
02515     PRINT_DEBUG_129("Found L_INTERSECT_1_3\n");
02516     int_result = L_INTERSECT_1_3;
02517     set_type_for_L(imp_point_1, imp_point_3);
02518     return CUBIT_SUCCESS;
02519   }
02520     //Now resolve if there is a closer match to one of the other
02521     //points.
02522   else if (point_0_on_seg_2 )
02523   {
02524     if (type_0 == MATCH_0_6 )
02525     {
02526       double dist_1 = (imp_point_0->coordinates() -
02527                        seg_2->get_prev()->get_start()->coordinates()).length_squared();
02528       CubitVector point_on_seg_2;
02529       closest_point_interior_seg(imp_point_0, seg_2, point_on_seg_2);
02530       double dist_2 = (imp_point_0->coordinates() - point_on_seg_2).length_squared();
02531       if ( dist_1 < dist_2 )
02532       {
02533         PRINT_DEBUG_129("Found L_INTERSECT_1_3\n");
02534         int_result = L_INTERSECT_1_3;
02535         set_type_for_L(imp_point_1, imp_point_3);
02536         return CUBIT_SUCCESS;
02537       }
02538     }
02539     else if (type_0 == MATCH_0_7 )
02540     {
02541       double dist_1 = (imp_point_0->coordinates() -
02542                        seg_2->get_next()->get_end()->coordinates()).length_squared();
02543       CubitVector point_on_seg_2;
02544       closest_point_interior_seg(imp_point_0, seg_2, point_on_seg_2);
02545       double dist_2 = (imp_point_0->coordinates() - point_on_seg_2).length_squared();
02546       if ( dist_1 < dist_2 )
02547       {
02548         PRINT_DEBUG_129("Found L_INTERSECT_1_3\n");
02549         int_result = L_INTERSECT_1_3;
02550         set_type_for_L(imp_point_1, imp_point_3);
02551         return CUBIT_SUCCESS;
02552       }
02553     }
02554   }
02555   else if (point_2_on_seg_1 )
02556   {
02557     if (type_2 == MATCH_2_4 )
02558     {
02559       double dist_1 = (imp_point_2->coordinates() -
02560                        seg_1->get_prev()->get_start()->coordinates()).length_squared();
02561       CubitVector point_on_seg_1;
02562       closest_point_interior_seg(imp_point_2, seg_1, point_on_seg_1);
02563       double dist_2 = (imp_point_2->coordinates() - point_on_seg_1).length_squared();
02564       if ( dist_1 < dist_2 )
02565       {
02566         PRINT_DEBUG_129("Found L_INTERSECT_1_3\n");
02567         int_result = L_INTERSECT_1_3;
02568         set_type_for_L(imp_point_1, imp_point_3);
02569         return CUBIT_SUCCESS;
02570       }
02571     }
02572     else if (type_2 == MATCH_2_5 )
02573     {
02574       double dist_1 = (imp_point_2->coordinates() -
02575                        seg_1->get_next()->get_end()->coordinates()).length_squared();
02576       CubitVector point_on_seg_1;
02577       closest_point_interior_seg(imp_point_2, seg_1, point_on_seg_1);
02578       double dist_2 = (imp_point_2->coordinates() - point_on_seg_1).length_squared();
02579       if ( dist_1 < dist_2 )
02580       {
02581         PRINT_DEBUG_129("Found L_INTERSECT_1_3\n");
02582         int_result = L_INTERSECT_1_3;
02583         set_type_for_L(imp_point_1, imp_point_3);
02584         return CUBIT_SUCCESS;
02585       }
02586     }
02587   }
02588 
02589   if ( point_0_on_seg_2 )
02590   {
02591       //This is an overlap_join.
02592     PRINT_DEBUG_129("Found OVERLAP_JOIN_13_0_2\n");
02593     int_result = OVERLAP_JOIN_13_0_2;
02594       //Create the new segments, the first segment remains the same so
02595       //leave positions 0 and 1 empty.
02596     ImprintLineSegment *new_seg_2_0, *new_seg_0_3;
02597       //copy point 0 to use on segment 2
02598     CubitVector closest_point;
02599     closest_point_seg( imp_point_0, seg_2, closest_point);
02600     ImprintPointData *new_point_0 = new ImprintPointData(imp_point_0, closest_point);
02601     new_point_0->owner(seg_2->owner());
02602     allocatedPointData->append(new_point_0);
02603     if ( imp_point_0->is_owner_vertex() )
02604     {
02605       new_point_0->set_point_type(CREATE_NEW_VERTEX);
02606       if ( imp_point_0->get_point_type() != CREATE_NEW_VERTEX )
02607         imp_point_0->set_point_type(VERTEX_ON_BOTH_BOUNDARIES);
02608     }
02609     else
02610     {
02611       new_point_0->set_point_type(ON_BOTH_BOUNDARIES);
02612       imp_point_0->set_point_type(ON_BOTH_BOUNDARIES);
02613     }
02614     new_seg_2_0 = new ImprintLineSegment(imp_point_2, new_point_0,
02615                                          seg_2->owner());
02616     new_seg_0_3 = new ImprintLineSegment(new_point_0, imp_point_3,
02617                                          seg_2->owner());
02618     new_segments[2] = new_seg_2_0;
02619     new_segments[3] = new_seg_0_3;
02620     allocatedLineData->append(new_segments[2]);
02621     allocatedLineData->append(new_segments[3]);
02622       //update the list.
02623     update_list(new_segments, seg_1, seg_2, CUBIT_FALSE);
02624     seg_2->set_inactive(CUBIT_TRUE);
02625     return CUBIT_SUCCESS;
02626   }
02627   else if ( point_2_on_seg_1 )
02628   {
02629       //This is an overlap_join.
02630     PRINT_DEBUG_129("Found OVERLAP_JOIN_13_2_0\n");
02631     int_result = OVERLAP_JOIN_13_2_0;
02632       //Create the new segments, the first segment remains the same so
02633       //leave positions 0 and 1 empty.
02634     ImprintLineSegment *new_seg_0_2, *new_seg_2_1;
02635       //copy point 2 to use on segment 1
02636     CubitVector closest_point;
02637     closest_point_seg( imp_point_2, seg_1, closest_point);
02638     ImprintPointData *new_point_2 = new ImprintPointData(imp_point_2, closest_point);
02639     new_point_2->owner(seg_1->owner());
02640     allocatedPointData->append(new_point_2);
02641     if ( imp_point_2->is_owner_vertex() )
02642     {
02643       new_point_2->set_point_type(CREATE_NEW_VERTEX);
02644       if ( imp_point_2->get_point_type() != CREATE_NEW_VERTEX )
02645         imp_point_2->set_point_type(VERTEX_ON_BOTH_BOUNDARIES);
02646     }
02647     else
02648     {
02649       new_point_2->set_point_type(ON_BOTH_BOUNDARIES);
02650       imp_point_2->set_point_type(ON_BOTH_BOUNDARIES);
02651     }
02652     new_seg_0_2 = new ImprintLineSegment(imp_point_0, new_point_2,
02653                                          seg_1->owner());
02654     new_seg_2_1 = new ImprintLineSegment(new_point_2, imp_point_1,
02655                                          seg_1->owner());
02656     new_segments[0] = new_seg_0_2;
02657     new_segments[1] = new_seg_2_1;
02658     allocatedLineData->append(new_segments[0]);
02659     allocatedLineData->append(new_segments[1]);
02660       //update the list.
02661     update_list(new_segments, seg_1, seg_2, CUBIT_TRUE);
02662     seg_1->set_inactive(CUBIT_TRUE);
02663     return CUBIT_SUCCESS;
02664   }
02665   else
02666   {
02667       //For this case we must have an L condition.
02668     set_type_for_L(imp_point_1, imp_point_3);
02669     PRINT_DEBUG_129("Found L_INTERSECT_1_3\n");
02670     int_result = L_INTERSECT_1_3;
02671     return CUBIT_SUCCESS;
02672   }
02673 }
02674 CubitStatus ImprintBoundaryTool::set_type_for_equal(ImprintPointData *pair_1_1,
02675                                                     ImprintPointData *pair_1_2,
02676                                                     ImprintPointData *pair_2_1,
02677                                                     ImprintPointData *pair_2_2)
02678 {
02679     //These segments are equal.
02680     //Set the point types accoridingly.
02681   if ( pair_1_1->is_owner_vertex() &&
02682        !pair_1_2->is_owner_vertex() )
02683   {
02684     pair_1_2->set_point_type(CREATE_NEW_VERTEX);
02685     if ( pair_1_1->get_point_type() != CREATE_NEW_VERTEX )
02686       pair_1_1->set_point_type(VERTEX_ON_BOTH_BOUNDARIES);
02687   }
02688   else if (!pair_1_1->is_owner_vertex() &&
02689            pair_1_2->is_owner_vertex() )
02690   {
02691     pair_1_1->set_point_type(CREATE_NEW_VERTEX);
02692     if ( pair_1_2->get_point_type() != CREATE_NEW_VERTEX )
02693       pair_1_2->set_point_type(VERTEX_ON_BOTH_BOUNDARIES);
02694   }
02695   else if ( pair_1_1->is_owner_vertex() &&
02696             pair_1_2->is_owner_vertex() )
02697   {
02698     if ( pair_1_1->get_point_type() != CREATE_NEW_VERTEX )
02699       pair_1_1->set_point_type(VERTEX_ON_BOTH_BOUNDARIES);
02700     if (pair_1_2->get_point_type() != CREATE_NEW_VERTEX )
02701       pair_1_2->set_point_type(VERTEX_ON_BOTH_BOUNDARIES);
02702   }
02703   else
02704   {
02705     pair_1_1->set_point_type(ON_BOTH_BOUNDARIES);
02706     pair_1_2->set_point_type(ON_BOTH_BOUNDARIES);
02707   }
02708   if ( pair_2_1->is_owner_vertex() &&
02709        !pair_2_2->is_owner_vertex() )
02710   {
02711     pair_2_2->set_point_type(CREATE_NEW_VERTEX);
02712     if ( pair_2_1->get_point_type() != CREATE_NEW_VERTEX )
02713       pair_2_1->set_point_type(VERTEX_ON_BOTH_BOUNDARIES);
02714   }
02715   else if (!pair_2_1->is_owner_vertex() &&
02716            pair_2_2->is_owner_vertex() )
02717   {
02718     pair_2_1->set_point_type(CREATE_NEW_VERTEX);
02719     if ( pair_2_2->get_point_type() != CREATE_NEW_VERTEX )
02720       pair_2_2->set_point_type(VERTEX_ON_BOTH_BOUNDARIES);
02721   }
02722   else if ( pair_2_1->is_owner_vertex() &&
02723             pair_2_2->is_owner_vertex() )
02724   {
02725     if ( pair_2_1->get_point_type() != CREATE_NEW_VERTEX )
02726       pair_2_1->set_point_type(VERTEX_ON_BOTH_BOUNDARIES);
02727     if ( pair_2_2->get_point_type() != CREATE_NEW_VERTEX )
02728       pair_2_2->set_point_type(VERTEX_ON_BOTH_BOUNDARIES);
02729   }
02730   else
02731   {
02732     pair_2_1->set_point_type(ON_BOTH_BOUNDARIES);
02733     pair_2_2->set_point_type(ON_BOTH_BOUNDARIES);
02734   }
02735   return CUBIT_SUCCESS;
02736 }
02737 CubitStatus ImprintBoundaryTool::set_type_for_L( ImprintPointData *imp_point_1,
02738                                                  ImprintPointData *imp_point_2)
02739 {
02740   CubitBoolean owner_vert_1 = imp_point_1->is_owner_vertex();
02741   CubitBoolean owner_vert_2 = imp_point_2->is_owner_vertex();
02742   if ( owner_vert_1 && !owner_vert_2 )
02743   {
02744     imp_point_2->set_point_type(CREATE_NEW_VERTEX);
02745     if (imp_point_1->get_point_type() != CREATE_NEW_VERTEX )
02746       imp_point_1->set_point_type(VERTEX_ON_BOTH_BOUNDARIES);
02747   }
02748   else if (!owner_vert_1 && owner_vert_2 )
02749   {
02750     imp_point_1->set_point_type(CREATE_NEW_VERTEX);
02751     if (imp_point_2->get_point_type() != CREATE_NEW_VERTEX )
02752       imp_point_2->set_point_type(VERTEX_ON_BOTH_BOUNDARIES);
02753   }
02754   else if ( owner_vert_1 && owner_vert_2 )
02755   {
02756       //Only make them verts on both boundaries if
02757       //they aready all vertices.  Their owner could
02758       //have been set previously by some other intersection
02759       //like a cross or a T.  It is important that points
02760       //that need vertices on them end up being marked
02761       //as a vertex on the other boundary...
02762     if(imp_point_1->get_point_type() != CREATE_NEW_VERTEX )
02763       imp_point_1->set_point_type(VERTEX_ON_BOTH_BOUNDARIES);
02764     if(imp_point_2->get_point_type() != CREATE_NEW_VERTEX )
02765       imp_point_2->set_point_type(VERTEX_ON_BOTH_BOUNDARIES);
02766   }
02767   else
02768   {
02769     imp_point_1->set_point_type(ON_BOTH_BOUNDARIES);
02770     imp_point_2->set_point_type(ON_BOTH_BOUNDARIES);
02771   }
02772   return CUBIT_SUCCESS;
02773 }
02774 CubitBoolean ImprintBoundaryTool::on_interior_segment(ImprintPointData *point,
02775                                                       ImprintLineSegment *line )
02776 {
02777     //Find the closest point on the line segement.
02778   CubitVector closest_point;
02779   CubitBoolean on_interior = closest_point_interior_seg( point, line, closest_point);
02780   if (!on_interior )
02781     return CUBIT_FALSE;
02782   CubitVector my_point = point->coordinates();
02783   if ( my_point.within_tolerance( closest_point, myTolerance ) )
02784     return CUBIT_TRUE;
02785   else
02786     return CUBIT_FALSE;
02787 }
02788 
02789 CubitBoolean ImprintBoundaryTool::closest_point_interior_seg( ImprintPointData *point,
02790                                                               ImprintLineSegment *line,
02791                                                               CubitVector &closest_point )
02792 {
02793     //Find the closest point between this line and the point.
02794   double node[3];
02795   double point_0[3], point_1[3];
02796   CubitVector point_v = point->coordinates();
02797   node[0] = point_v.x();
02798   node[1] = point_v.y();
02799   node[2] = point_v.z();
02800   CubitVector start_v = line->get_start()->coordinates();
02801   CubitVector end_v = line->get_end()->coordinates();
02802   point_0[0] = start_v.x();
02803   point_0[1] = start_v.y();
02804   point_0[2] = start_v.z();
02805   point_1[0] = end_v.x();
02806   point_1[1] = end_v.y();
02807   point_1[2] = end_v.z();
02808     //use geometry_resabs rather than tolerance to get more accuracy.
02809   IntersectionTool new_tool(GEOMETRY_RESABS);
02810   double t;
02811   double dist = new_tool.distance_point_line(node, point_0,
02812                                              point_1, t);
02813   if ( dist < 0.0 )
02814   {
02815     return CUBIT_FALSE;
02816   }
02817   else
02818   {
02819     CubitVector p_0_1 = end_v - start_v;
02820     closest_point = start_v + t*p_0_1;
02821   }
02822   return CUBIT_TRUE;
02823 }
02824 CubitStatus ImprintBoundaryTool::closest_point_seg( ImprintPointData *point,
02825                                                     ImprintLineSegment *line,
02826                                                     CubitVector &closest_point )
02827 {
02828     //Find the closest point between this line and the point.
02829   double node[3];
02830   double point_0[3], point_1[3];
02831   CubitVector point_v = point->coordinates();
02832   node[0] = point_v.x();
02833   node[1] = point_v.y();
02834   node[2] = point_v.z();
02835   CubitVector start_v = line->get_start()->coordinates();
02836   CubitVector end_v = line->get_end()->coordinates();
02837   point_0[0] = start_v.x();
02838   point_0[1] = start_v.y();
02839   point_0[2] = start_v.z();
02840   point_1[0] = end_v.x();
02841   point_1[1] = end_v.y();
02842   point_1[2] = end_v.z();
02843     //use geometry_resabs rather than tolerance to get more accuracy.
02844   IntersectionTool new_tool(GEOMETRY_RESABS);
02845   double t;
02846   double dist = new_tool.distance_point_line(node, point_0,
02847                                              point_1, t);
02848   if ( dist < 0.0 )
02849   {
02850       //This happens if the point is beyond the line segment, in which
02851       //case we just want the closer end point.
02852     if ( t < 0.0 )
02853     {
02854       closest_point = start_v;
02855     }
02856     else
02857     {
02858       closest_point = end_v;
02859     }
02860   }
02861   else
02862   {
02863     CubitVector p_0_1 = end_v - start_v;
02864     closest_point = start_v + t*p_0_1;
02865   }
02866   return CUBIT_SUCCESS;
02867 }
02868 CubitStatus ImprintBoundaryTool::closest_point_seg( CubitVector &point_v,
02869                                                     ImprintLineSegment *line,
02870                                                     CubitVector &closest_point )
02871 {
02872     //Find the closest point between this line and the point.
02873   double node[3];
02874   double point_0[3], point_1[3];
02875   node[0] = point_v.x();
02876   node[1] = point_v.y();
02877   node[2] = point_v.z();
02878   CubitVector start_v = line->get_start()->coordinates();
02879   CubitVector end_v = line->get_end()->coordinates();
02880   point_0[0] = start_v.x();
02881   point_0[1] = start_v.y();
02882   point_0[2] = start_v.z();
02883   point_1[0] = end_v.x();
02884   point_1[1] = end_v.y();
02885   point_1[2] = end_v.z();
02886     //use geometry_resabs rather than tolerance to get more accuracy.
02887   IntersectionTool new_tool(GEOMETRY_RESABS);
02888   double t;
02889   double dist = new_tool.distance_point_line(node, point_0,
02890                                              point_1, t);
02891   if ( dist < 0.0 )
02892   {
02893       //This happens if the point is beyond the line segment, in which
02894       //case we just want the closer end point.
02895     if ( t < 0.0 )
02896     {
02897       closest_point = start_v;
02898     }
02899     else
02900     {
02901       closest_point = end_v;
02902     }
02903   }
02904   else
02905   {
02906     CubitVector p_0_1 = end_v - start_v;
02907     closest_point = start_v + t*p_0_1;
02908   }
02909   return CUBIT_SUCCESS;
02910 }
02911                                                     
02912 CubitStatus ImprintBoundaryTool::convert_to_lines( PointLoopList &boundary_point_loops,
02913                                                    SegLoopList &boundary_line_loops,
02914                                                    RefFace *ref_face,
02915                                                    const CubitBoolean boundary_1 )
02916 {
02917     //This does more than just converts the boundary points to line segments.  It also
02918     //Sets up a doubily linked list through the ImprintLineSegment data structure.
02919     //Calling codes need to make sure all this data is deleted.
02920     //This function also sets the PointType for each of the boundary points.  This
02921     //will depend also on the boundary_1 flag.  If we are doing boundary_1 then,
02922     //the flag will be true, otherwise it will be false.
02923   int ii, jj;
02924   PointList *point_list;
02925   SegList *segment_list;
02926   ImprintLineSegment *new_line, *prev = NULL;
02927   RefEntity *entity_start, *entity_end, *seg_owner;
02928   boundary_point_loops.reset();
02929   PointType vertex_on_boundary, on_boundary;
02930   if ( boundary_1 )
02931   {
02932     vertex_on_boundary = VERTEX_ON_BOUNDARY_1;
02933     on_boundary = ON_BOUNDARY_1;
02934   }
02935   else
02936   {
02937     vertex_on_boundary = VERTEX_ON_BOUNDARY_2;
02938     on_boundary = ON_BOUNDARY_2;
02939   }
02940   for ( ii = boundary_point_loops.size(); ii > 0; ii-- )
02941   {
02942     point_list = boundary_point_loops.get_and_step();
02943     segment_list = new SegList;
02944     prev = NULL;
02945     new_line = NULL;
02946     seg_owner = NULL;
02947     for ( jj = point_list->size(); jj > 0; jj-- )
02948     {
02949       entity_start = point_list->get()->owner();
02950       entity_end = point_list->next()->owner();
02951       seg_owner =  CAST_TO(entity_start, RefEdge);
02952       if ( seg_owner == NULL )
02953       {
02954         seg_owner = CAST_TO(entity_end, RefEdge);
02955         if ( seg_owner == NULL )
02956         {
02957           RefVertex *ref_vert_end = CAST_TO(entity_end, RefVertex);
02958           RefVertex *ref_vert_start = CAST_TO(entity_start, RefVertex);
02959           DLIList <RefEdge*> common_edges;
02960           ref_vert_start->common_ref_edges(ref_vert_end,
02961                                            common_edges,
02962                                            ref_face);
02963           if ( common_edges.size() == 0  )
02964           {
02965             PRINT_ERROR("ImprintBoundaryTool::convert_to_lines having problem finding owner of boundary\n"
02966                         "segment.\n");
02967             return CUBIT_FAILURE;
02968           }
02969           if ( common_edges.size() == 1 )
02970             seg_owner = common_edges.get();
02971           else
02972           {
02973               //Now we have to decide which of these edges is the one.
02974               //Lets take a mid point on this segment and check the distances.
02975               //First find the mid_point of the line segment.
02976             CubitVector start = point_list->get()->coordinates();
02977             CubitVector end = point_list->next()->coordinates();
02978             CubitVector mid = (start+end)/2.0;
02979             CubitVector closest_point;
02980             
02981               //Now test the edges to see which is closest.
02982             RefEdge *closest_edge = NULL, *curr_ref_edge;
02983             double min_dist = CUBIT_DBL_MAX, dist;
02984             int kk;
02985             for ( kk = common_edges.size(); kk > 0; kk-- )
02986             {
02987               curr_ref_edge = common_edges.get_and_step();
02988               curr_ref_edge->closest_point(mid, closest_point);
02989               dist = (mid - closest_point).length_squared();
02990               if ( dist < min_dist )
02991               {
02992                 min_dist = dist;
02993                 closest_edge = curr_ref_edge;
02994               }
02995             }
02996             if ( closest_edge == NULL )
02997             {
02998               PRINT_ERROR("Problems determining segment ownwership.\n"
02999                           "Internal problem with virtual imprinting.\n");
03000               boundary_line_loops.clean_out();
03001               return CUBIT_FAILURE;
03002             }
03003             seg_owner = closest_edge;
03004           }
03005         }
03006       }
03007       new_line = new ImprintLineSegment( point_list->get(), point_list->next(), seg_owner);
03008       allocatedLineData->append(new_line);
03009         //Now for use later on, set the point type.  This will be useful
03010         //when we get to the intersection parts.
03011       if ( CAST_TO(entity_start, RefEdge) != NULL )
03012       {
03013         new_line->get_start()->set_point_type(on_boundary);
03014       }
03015       else {
03016         assert( CAST_TO(entity_start, RefVertex) != NULL );
03017         new_line->get_start()->set_point_type(vertex_on_boundary);
03018       }
03019       if ( CAST_TO(entity_end, RefEdge) != NULL )
03020       {
03021         new_line->get_end()->set_point_type(on_boundary);
03022       }
03023       else {
03024         assert( CAST_TO(entity_end, RefVertex) != NULL );
03025         new_line->get_end()->set_point_type(vertex_on_boundary);
03026       }
03027       point_list->step();
03028       segment_list->append(new_line);
03029       if ( prev != NULL )
03030       {
03031         prev->set_next(new_line);
03032         new_line->set_prev(prev);
03033       }
03034       prev = new_line;
03035     }
03036     if ( prev != NULL )
03037     {
03038       segment_list->reset();
03039       assert(prev == segment_list->prev());
03040       segment_list->prev()->set_next(segment_list->get());
03041       segment_list->get()->set_prev(segment_list->prev());
03042       assert(segment_list->get()->get_next() != NULL );
03043     }
03044     if ( segment_list->size() )
03045     {
03046       boundary_line_loops.append(segment_list);
03047       allocatedLineLoops->append(segment_list);
03048     }
03049     else
03050       delete segment_list;
03051   }
03052   return CUBIT_SUCCESS;
03053 }
03054 //--------------------------------------------------------------
03055 // Private Function: find_graph_for_surf
03056 // Description:  Given the boundary_line_loops for a surface
03057 //               that have already been intersected against another
03058 //               surface, and the boundary_line_loops for that surface,
03059 //               determine the line segments that are needed
03060 //               to perform the actual imprint.  Also find points
03061 //               That are need to partition or imprint the existing boundaries.
03062 //               These points will also include the points of the segments
03063 //               that touch against the boundary, if necessary.  The
03064 //               RefFace is pretty important as it is used to determine
03065 //               if the points are inside or outside the surface.
03066 //---------------------------------------------------------------
03067 CubitStatus ImprintBoundaryTool::find_graph_for_surf(PointLoopList &boundary_loops_1,
03068                                                      PointLoopList &boundary_loops_2,
03069                                                      RefFace *ref_face,
03070                                                      PointLoopList &part_segs,
03071                                                      PointList &partition_points,
03072                                                      CubitBoolean surf_1)
03073                                                      
03074 {
03075     //Traverse the boundary_line_loops_2.
03076     //First search for intersections. If an intersection is found,
03077     //traverse from there until another intersection is found.
03078     //If no intersection is found for a loop, test to see if the
03079     //nodes lie inside the surface.  If they do, then the intire loop
03080     //should be used for partitioning.
03081   int ii, jj;
03082     //ASSUME my boundary is loop_2.
03083   CubitBoolean start_recording = CUBIT_FALSE;
03084   CubitBoolean found_start = CUBIT_FALSE;
03085   
03086   PointList *loop_1_ptr, *loop_2_ptr, *new_part_line;
03087   ImprintPointData *curr_point, *next_point;
03088   for ( ii = boundary_loops_2.size(); ii > 0; ii-- )
03089   {
03090     loop_2_ptr = boundary_loops_2.get_and_step();
03091     start_recording = CUBIT_FALSE;
03092     new_part_line = NULL;
03093     found_start = CUBIT_FALSE;
03094       //find a good place to start.  It messes things
03095       //up if we start the loop at a non-meeting spot.
03096     for ( jj = loop_2_ptr->size(); jj > 0; jj-- )
03097     {
03098       curr_point = loop_2_ptr->get_and_step();
03099       if ( curr_point->get_point_type() == CREATE_NEW_VERTEX ||
03100            curr_point->get_point_type() == VERTEX_ON_BOTH_BOUNDARIES )
03101       {
03102         loop_2_ptr->back();
03103         found_start = CUBIT_TRUE;
03104         break;
03105       }
03106     }
03107     if ( found_start )
03108     {
03109       for ( jj = loop_2_ptr->size(); jj > 0; jj-- )
03110       {
03111         curr_point = loop_2_ptr->get_and_step();
03112         next_point = loop_2_ptr->get();
03113         if ( DEBUG_FLAG(129) )
03114           draw_point(curr_point);
03115         if ( curr_point->get_point_type() == CREATE_NEW_VERTEX ||
03116              curr_point->get_point_type() == VERTEX_ON_BOTH_BOUNDARIES )
03117         {
03118           CubitStatus stat;
03119             //This section of the code just got too big.  So it may change
03120             //the loop_2_ptr position, the loop counter jj and other things.
03121           stat = point_intersects_case( curr_point, next_point,
03122                                         ref_face,
03123                                         part_segs,  new_part_line,
03124                                         start_recording, surf_1 );
03125           if (CUBIT_SUCCESS != stat) {
03126             PRINT_ERROR("ImprintBoundaryTool::point_intersects_case failed.\n");
03127             return stat;
03128           }
03129         }
03130         else
03131         {
03132           if (start_recording)
03133           {
03134             if ( !new_part_line )
03135             {
03136               PRINT_ERROR("Bad Logic ImprintBoundaryTool::find_graph_for_surf.\n");
03137               assert(new_part_line != NULL);
03138               return CUBIT_FAILURE;
03139             }
03140             CubitBox surf_box = ref_face->bounding_box();
03141             CubitBox curr_box(curr_point->coordinates());
03142             if( surf_box.overlap(myTolerance, curr_box ) &&
03143                 on_surface(curr_point, ref_face) )
03144             {
03145               new_part_line->append(curr_point);
03146               if ( jj == 1 && 
03147                    (next_point->get_point_type() == CREATE_NEW_VERTEX ||
03148                     next_point->get_point_type() == VERTEX_ON_BOTH_BOUNDARIES) )
03149               {
03150                   //Do the last node since that is where we have to go to inorder
03151                   //to stop the partitioning.
03152                 jj++;
03153               }
03154             }
03155             else
03156             {
03157                 //remove new_part_line from the part_segs list and
03158                 //break out of this loop.
03159               part_segs.pop();
03160               start_recording = CUBIT_FALSE;
03161               break;
03162             }
03163           }
03164         }
03165       }
03166       if ( start_recording )
03167       {
03168           //This is bad news.  We never should finish the loop and still
03169           //be recording...
03170         PRINT_ERROR("Bad Logic ImprintBoundaryTool::find_graph_for_surf.\n");
03171         assert(!start_recording);
03172         return CUBIT_FAILURE;
03173       }
03174     }
03175     else
03176     {
03177         //Okay this is an interior hole to the ref_face.  Just add the
03178         //entire loop.
03179       int mm;
03180       CubitBox surf_box = ref_face->bounding_box();     
03181       int debug = 0;
03182       if ( debug )
03183       {
03184         GfxDebug::clear();
03185         GfxDebug::draw_box(surf_box, CUBIT_RED_INDEX);
03186         GfxDebug::flush();
03187       }
03188       CubitBox curr_box;
03189         //Getting the first point is important.  Make
03190         //sure it is a vertex.
03191       CubitBoolean start = CUBIT_FALSE;
03192       for ( mm = loop_2_ptr->size(); mm > 0; mm-- )
03193       {
03194         curr_point = loop_2_ptr->get_and_step();
03195         curr_box.reset(curr_point->coordinates());
03196         if ( debug )
03197         {
03198           draw_point(curr_point);
03199         }
03200         if ( surf_box.overlap(myTolerance,curr_box) )
03201         {
03202           if ( on_surface(curr_point, ref_face) &&
03203                curr_point->is_owner_vertex() )
03204           {
03205             loop_2_ptr->back();
03206             start = CUBIT_TRUE;
03207             break;
03208           }
03209         }
03210       }
03211       if ( !start )
03212       {
03213           //this loop has no affect on the surface. (no points
03214           //are on the boundary and are vertices...)
03215         continue;
03216       }
03217       else
03218       {
03219         new_part_line = new PointList;
03220         allocatedPointLoops->append(new_part_line);
03221           //Test one the nodes to see if they are interior to the surface.
03222         loop_2_ptr->get()->set_start_partition();
03223         loop_2_ptr->get()->set_end_partition();
03224         part_segs.append(new_part_line);
03225         CubitBoolean valid_loop = CUBIT_TRUE;
03226         for ( mm = loop_2_ptr->size(); mm > 0; mm-- )
03227         {
03228           curr_point = loop_2_ptr->get_and_step();
03229           curr_box.reset(curr_point->coordinates());
03230           if ( surf_box.overlap(myTolerance, curr_box) )
03231           {
03232             if ( on_surface(curr_point, ref_face) )
03233             {
03234               new_part_line->append(curr_point);
03235             }
03236             else
03237               valid_loop = CUBIT_FALSE;
03238           }
03239           else
03240             valid_loop = CUBIT_FALSE;
03241         }
03242         if ( !valid_loop )
03243         {
03244             //remove the part_line.  The
03245             //entire loop must go into the surface.
03246           part_segs.pop();
03247         }
03248       }
03249         //Otherwise just ignore this loop it has no affect on the ref_face.
03250     }
03251   }
03252     //Okay now go through and find the points that are needed to create as imprints on the boundary.
03253   for ( ii = boundary_loops_1.size(); ii > 0; ii-- )
03254   {
03255     loop_1_ptr = boundary_loops_1.get_and_step();
03256     for ( jj = loop_1_ptr->size(); jj > 0; jj-- )
03257     {
03258       curr_point = loop_1_ptr->get_and_step();
03259       if ( curr_point->get_point_type() == CREATE_NEW_VERTEX )
03260         partition_points.append(curr_point);
03261     }
03262   }
03263     //Okay, we should be set now!
03264   return CUBIT_SUCCESS;
03265 }
03266 //--------------------------------------------------------------
03267 // Private Function: point_intersects_case
03268 // Description:  Given the fact that curr_point's PointType shows
03269 //               that it is a vertex on both boundaries or a new vertex,
03270 //               Resolve how the partition curves are extraced from the
03271 //               boundary loop 2 on surface 1.
03272 //--------------------------------------------------------------
03273 CubitStatus ImprintBoundaryTool::point_intersects_case( ImprintPointData *curr_point,
03274                                                         ImprintPointData *next_point,
03275                                                         RefFace *ref_face,
03276                                                         PointLoopList &part_segs,
03277                                                         PointList *&new_part_line,
03278                                                         CubitBoolean &start_recording,
03279                                                         CubitBoolean surf_1 )
03280 {
03281   PointType vertex_my_boundary = surf_1 ? VERTEX_ON_BOUNDARY_2 : VERTEX_ON_BOUNDARY_1;
03282   PointType edge_my_boundary = surf_1 ? ON_BOUNDARY_2 : ON_BOUNDARY_1;
03283   CubitBoolean do_nothing = CUBIT_FALSE;
03284   ImprintPointData *match_point_cur, *match_point_nex;
03285   if ( !start_recording )
03286   {
03287       //Okay.  This is an intersection.  The possible outcomes are:
03288       //1) This is the end of a paritition :-> do nothing.
03289       //2) This is the begining of a short partition (one segment)
03290       //3) This is the begining of a parition :-> start recording it.
03291       //4) This is a vertex imprint from our surface. :-> do nothing.
03292     
03293       //For case 1 resolution, we need to test to see if the next node is either:
03294       // a) on the boundary of both surf 1 and surf 2.
03295       // b) outside surf 1 and not intersecting surf_1's boundary.
03296       // If case a, then we need to find out if its matching point
03297       // and the matching point of the next point are on the same
03298       // segment.
03299     
03300       //For case 2, we need to test the underlying refentities to
03301       //see if we really are splitting a surface or on a the boundary.
03302     
03303       //For case 3, we need to test the next node to see if it is
03304       //only on loop 2's boundary and INTERIOR to the ref_face.
03305     
03306       //For case 4, that will be the counter examples of case 3 or
03307       //rather when their interior or refentity traversals fail.
03308       //Also if the next node is on both boundaries but not as
03309       //a vertex.  This is a simple overlap.
03310     
03311       //Both points are vertices.  Need to find out if this is a
03312       //single segment split or on the boundary.
03313     
03314     if ( next_point->get_point_type() == CREATE_NEW_VERTEX ||
03315          next_point->get_point_type() == VERTEX_ON_BOTH_BOUNDARIES )
03316     {
03317         //To decifer, determine this from the topology of the points
03318         //these match with on boundary 1.
03319       match_point_cur = curr_point->get_matching_point();
03320       match_point_nex = next_point->get_matching_point();
03321       int list_id_1 = match_point_cur->get_loop_pos();
03322       int list_id_2 = match_point_nex->get_loop_pos();
03323       if ( list_id_1 == 0 )
03324       {
03325         if (list_id_2 == match_point_nex->get_loop_size() - 1 )
03326         {
03327             //okay force this to work, we just went around the loop.
03328           list_id_2 = 1;
03329         }
03330       }
03331       if ( list_id_2 == 0 )
03332       {
03333         if (list_id_1 == match_point_nex->get_loop_size() - 1 )
03334         {
03335             //okay force this to work, we just went around the loop.
03336           list_id_1 = 1;
03337         }
03338       }
03339       int diff;
03340       if ( list_id_1 > list_id_2 )
03341         diff = list_id_1 - list_id_2;
03342       else
03343         diff = list_id_2 - list_id_1;
03344       if ( (match_point_cur->get_list_loop_pos() ==
03345             match_point_nex->get_list_loop_pos()) &&
03346            diff == 1 )
03347       {
03348           //CASE 1
03349           //This is the case that curr_point and next_point are
03350           //both create vertices or matched with vertices.
03351           //If the points that they match with, are also right
03352           //next to each other, then don't partition them since
03353           //they all match prefectly.
03354         do_nothing = CUBIT_TRUE;
03355       }
03356       else
03357       {
03358           //Also, this may be a case where the one boundary is
03359           //curved and the segment croses the curve portion.
03360           //We'll have to do a surface check mid-way through
03361           //the segment.
03362         CubitVector p0 = curr_point->coordinates();
03363         CubitVector p1 = next_point->coordinates();
03364         CubitVector point_q = p0 + (p1-p0)*.5;
03365         if ( on_surface(point_q, ref_face) )
03366         {
03367             //CASE 2
03368             //So they aren't connected.  This means that
03369             //we need to have a single segment where we
03370             //partition with just these two points.
03371           new_part_line = new PointList;
03372           allocatedPointLoops->append(new_part_line);
03373           new_part_line->append(curr_point);
03374           new_part_line->append(next_point);
03375           curr_point->set_start_partition();
03376           next_point->set_end_partition();
03377           part_segs.append(new_part_line);
03378           new_part_line = NULL;
03379           do_nothing = CUBIT_TRUE;
03380         }
03381         else
03382           do_nothing = CUBIT_TRUE;
03383       }
03384     }
03385     else if ( next_point->get_point_type() == ON_BOTH_BOUNDARIES )
03386     {
03387         //CASE 4.
03388         //hmmm.  This has got to be a simple imprint so do nothing here.
03389       do_nothing = CUBIT_TRUE;
03390     }
03391     else if ( next_point->get_point_type() == edge_my_boundary ||
03392               next_point->get_point_type() == vertex_my_boundary )
03393     {
03394         //We need to test to see if this point is on the ref_face or not.
03395         //If it is, then we need to start recording.  If it
03396         //isn't then we can do nothing.
03397       if ( on_surface(next_point, ref_face) )
03398           //CASE 3
03399         start_recording = CUBIT_TRUE;
03400       else
03401           //CASE 4
03402         do_nothing = CUBIT_TRUE;
03403     }
03404     else
03405     {
03406       PRINT_ERROR("Bad Logic ImprintBoundaryTool::find_graph_for_surf.\n");
03407       assert(0);
03408       return CUBIT_FAILURE;
03409     }
03410     if ( do_nothing )
03411       return CUBIT_SUCCESS;
03412 
03413     assert(start_recording);
03414       //Okay start recording.  Create a new list.  Put the curr_point
03415       //into that list and continue.
03416     curr_point->set_start_partition();
03417     new_part_line = new PointList;
03418     allocatedPointLoops->append(new_part_line);
03419     new_part_line->append(curr_point);
03420     part_segs.append(new_part_line);
03421   }
03422   else {
03423       //Now we need to terminate the recording.
03424     curr_point->set_end_partition();
03425     if ( !curr_point->get_start_partition() )
03426     {
03427       new_part_line->append(curr_point);
03428     }
03429     else{
03430         //case where circle loop imprints an edge at just one point.
03431         //do nothing.
03432     }
03433     new_part_line = NULL;
03434     start_recording = CUBIT_FALSE;
03435   }
03436   return CUBIT_SUCCESS;
03437 }
03438 //-------------------------------------------------------
03439 // Private Function: on_surface
03440 // Description:  Determines through the find_closest_point_trimmed
03441 //               function if a point is inside or outside a surface.
03442 //               This is not a very efficient method but since the
03443 //               surface can be non-planar, we can't do a simple test.
03444 //-------------------------------------------------------
03445 CubitBoolean ImprintBoundaryTool::on_surface( ImprintPointData *point,
03446                                               RefFace *ref_face )
03447 {
03448     //Determine if the vertex is on the curve within the feature size...
03449   CubitVector vert_point = point->coordinates();
03450   CubitVector point_on = vert_point;
03451     //Move the point to the curve and check the distance.
03452   ref_face->find_closest_point_trimmed(vert_point, point_on);
03453   if ( vert_point.within_tolerance(point_on, myTolerance) )
03454     return CUBIT_TRUE;
03455   else
03456     return CUBIT_FALSE;
03457 }
03458 CubitBoolean ImprintBoundaryTool::on_surface( CubitVector &vert_point,
03459                                               RefFace *ref_face )
03460 {
03461     //Determine if the vertex is on the curve within the feature size...
03462   CubitVector point_on = vert_point;
03463     //Move the point to the curve and check the distance.
03464   ref_face->find_closest_point_trimmed(vert_point, point_on);
03465   if ( vert_point.within_tolerance(point_on, myTolerance) )
03466     return CUBIT_TRUE;
03467   else
03468     return CUBIT_FALSE;
03469 }
03470 CubitBoolean ImprintBoundaryTool::on_curve( ImprintPointData *point,
03471                                             RefEdge *ref_edge )
03472 {
03473   CubitBoolean on_boundary = CUBIT_FALSE;
03474     //Determine if the vertex is on the curve within the feature size...
03475   CubitVector vert_point = point->coordinates();
03476   CubitVector point_on = point->coordinates();
03477     //Move the point to the curve and check the distance.
03478   ref_edge->closest_point_trimmed(vert_point, point_on);
03479   CubitVector distance = vert_point - point_on;
03480   double leng = distance.length();
03481   if ( leng < myTolerance )
03482   {
03483     on_boundary = CUBIT_TRUE;
03484   }
03485   return on_boundary;
03486 }
03487 //-------------------------------------------------------
03488 // Private Function:are_connected
03489 // Description:  Determines through topology traversals
03490 //               if the two refentities are directly
03491 //               connected.  The function assumes
03492 //               that the RefEntities are either RefVerticies or
03493 //               RefEdges.  The entites must be connected within
03494 //               one entity for vertices or the same for
03495 //               curves...
03496 //-------------------------------------------------------
03497 CubitBoolean ImprintBoundaryTool::are_connected( RefEntity *ent_1,
03498                                                  RefEntity *ent_2,
03499                                                  RefFace *ref_face )
03500 {
03501   RefEdge *curve_cur, *curve_nex;
03502   RefVertex *vert_cur, *vert_nex;
03503   curve_cur = CAST_TO(ent_1, RefEdge);
03504   curve_nex = CAST_TO(ent_2, RefEdge);
03505   vert_cur = CAST_TO(ent_1, RefVertex);
03506   vert_nex = CAST_TO(ent_2, RefVertex);
03507     //just do some sanity checking first.  Really shouldn't happen...
03508   if ( !curve_cur && !vert_cur )
03509   {
03510     assert(curve_cur || vert_cur);
03511     PRINT_ERROR("messed up logic!!!! in ImprintBoundaryTool::are_connected\n");
03512     return CUBIT_FALSE;
03513   }
03514   if ( !curve_nex && !vert_nex )
03515   {
03516     assert(curve_nex || vert_nex);
03517     PRINT_ERROR("messed up logic!!!! in ImprintBoundaryTool::are_connected\n");
03518     return CUBIT_FALSE;
03519   }
03520   if ( curve_cur )
03521   {
03522     if ( curve_cur == curve_nex )
03523       return CUBIT_TRUE;
03524     if ( !vert_nex && curve_nex )
03525       return CUBIT_FALSE;
03526     if ( vert_nex && !curve_nex )
03527     {
03528       if ( curve_cur->start_vertex() == vert_nex ||
03529            curve_cur->end_vertex() == vert_nex )
03530         return CUBIT_TRUE;
03531       else
03532         return CUBIT_FALSE;
03533     }
03534   }
03535   else if ( vert_cur )
03536   {
03537     if ( vert_nex == vert_cur )
03538       return CUBIT_TRUE;
03539     if ( !curve_nex && vert_nex )
03540     {
03541       if ( vert_nex == vert_cur )
03542       {
03543         assert(0);
03544         PRINT_ERROR("Next and cur have same vertex in\n"
03545                     "ImprintBoundaryTool::are_connected.\n");
03546         return CUBIT_TRUE;
03547       }
03548       else if ( vert_cur->common_ref_edge(vert_nex, ref_face) )
03549         return CUBIT_TRUE;
03550       else
03551         return CUBIT_FALSE;
03552     }
03553     if ( !vert_nex && curve_nex )
03554     {
03555       if ( curve_nex->start_vertex() == vert_cur ||
03556            curve_nex->end_vertex() == vert_cur )
03557         return CUBIT_TRUE;
03558       else
03559         return CUBIT_FALSE;
03560     }
03561   }
03562   assert(0);
03563   PRINT_ERROR("ImprintBoundaryTool::are_connected failed\n");
03564   return CUBIT_FALSE;
03565 }
03566 CubitStatus ImprintBoundaryTool::imprint_boundary_vertices( PointList &partition_points,
03567                                                             CubitBoolean &modified_boundary )
03568 {
03569   ImprintPointData *curr_point;
03570   RefEntity *ref_ent;
03571   int ii;
03572   RefEdge *ref_edge, *edge1, *edge2;  
03573   modified_boundary = CUBIT_FALSE;
03574   while( partition_points.size() > 0 )
03575   {
03576     curr_point = partition_points.pop();
03577     ref_ent = curr_point->owner();
03578     ref_edge = CAST_TO(ref_ent, RefEdge);
03579     if ( ref_edge == NULL )
03580     {
03581       PRINT_ERROR("Bad logic in point owners for ImprintBoundaryTool.\n");
03582       assert(ref_edge != NULL);
03583       return CUBIT_FAILURE;
03584     }
03585     CubitVector part_vec = curr_point->coordinates();
03586     CubitVector closest_point;
03587     ref_edge->closest_point(part_vec, closest_point);
03588     double dist = (part_vec - closest_point).length_squared();
03589     if ( dist > myTolerance*myTolerance )
03590     {
03591       PRINT_ERROR("Curve %d may have bad geometry.\n"
03592                   "While try to partition the curve the move_to operation\n"
03593                   "returned a move distance larger than the tolerance.\n"
03594                   "Please try healing or using mesh based geometry for curve %d.\n",
03595                   ref_edge->id(), ref_edge->id());
03596       return CUBIT_FAILURE;
03597     }
03598     PRINT_DEBUG_129("Partitioning curve %d\n",
03599                     ref_edge->id());
03600     RefVertex *vtx_ptr= PartitionTool::instance()->partition(ref_edge,
03601                                                              part_vec,
03602                                                              edge1, edge2);
03603     if ( vtx_ptr == NULL )
03604     {
03605       PRINT_ERROR("Partitioning curve failed.\n");
03606       return CUBIT_FAILURE;
03607     }
03608     if ( edge1->measure() < myTolerance ||
03609          edge2->measure() < myTolerance )
03610     {
03611       PRINT_WARNING("Virtual imprinting created an edge smaller than\n"
03612                     " the tolerance value.  This could be an error.\n"
03613                     " Check curve %d or %d, imprinting surfs %d and %d.\n",
03614                     edge1->id(), edge2->id(), refFacePtr1->id(),
03615                     refFacePtr2->id());
03616     }
03617     modified_boundary = CUBIT_TRUE;
03618     curr_point->owner(vtx_ptr);
03619       //Now readjust owners cause they can change if we partition more
03620       //than one curve.
03621     for ( ii = partition_points.size(); ii > 0; ii-- )
03622     {
03623       curr_point = partition_points.get_and_step();
03624       if( curr_point->owner() == ref_ent )
03625       {
03626         if ( on_curve(curr_point, edge1) )
03627           curr_point->owner(dynamic_cast<RefEntity*>(edge1));
03628         else
03629           curr_point->owner(dynamic_cast<RefEntity*>(edge2));
03630       }
03631     }    
03632   }
03633   return CUBIT_SUCCESS;
03634 }
03635 CubitStatus ImprintBoundaryTool::imprint_surface(RefFace *ref_face,
03636                                                  PointLoopList &part_segs,
03637                                                  DLIList <RefFace*> &results)
03638 {
03639     //Now go through and create refedges for partitioning.
03640   int ii, jj, counter;
03641   DLIList<RefFace*> tmp_results;
03642   DLIList<RefEdge*> ref_edges;
03643   ImprintPointData *start_imp, *end_imp, *curr_imp, *matching_start, *matching_end;
03644   PointList *loop_ptr;
03645   DLIList<CubitVector*> curve_vectors;
03646   CubitBoolean first_on_loop;
03647   RefVertex *prev_end;
03648   RefVertex *first_v_on_loop = NULL;
03649   
03650   for ( ii = part_segs.size(); ii > 0; ii-- )
03651   {
03652     loop_ptr = part_segs.get_and_step();
03653     loop_ptr->reset();
03654     first_on_loop = CUBIT_TRUE;  
03655     prev_end = NULL;
03656     first_v_on_loop = NULL;
03657     for ( jj = loop_ptr->size(); jj > 0; jj-- )
03658     {
03659       start_imp = loop_ptr->get_and_step();
03660       if ( !start_imp->is_owner_vertex() )
03661       {
03662         PRINT_ERROR("Bad logic in imprint_surface for ImprintBoundaryTool\n");
03663         assert( start_imp->is_owner_vertex() );
03664         return CUBIT_FAILURE;
03665       }
03666       end_imp = NULL;
03667       curve_vectors.clean_out();
03668       counter = 0;
03669         //For the last point, only create another edge if the
03670         //the start is also an end...
03671       if ( jj == 1 && loop_ptr->get()->get_end_partition() != CUBIT_TRUE )
03672         continue;
03673         //Loop until we get to the end of the partition or
03674         //till we have to create a new ref_edge.
03675       while( loop_ptr->get()->get_end_partition() != CUBIT_TRUE )
03676       {
03677         counter++;
03678         curr_imp = loop_ptr->get_and_step();
03679         if (curr_imp->is_owner_vertex())
03680         {
03681           end_imp = curr_imp;
03682           counter--;
03683           loop_ptr->back();
03684           break;
03685         }
03686         else
03687         {
03688           CubitVector *temp = new CubitVector(curr_imp->coordinates());
03689           curve_vectors.append(temp);
03690         }
03691       }
03692       jj -= counter;
03693       CubitBoolean verts_same = CUBIT_FALSE;
03694       if ( end_imp == NULL )
03695       {
03696         if ( loop_ptr->get()->get_end_partition() == CUBIT_TRUE )
03697         {
03698             //Do this last segment.  This means that we have a complete loop
03699             //for partitioning.
03700           end_imp = loop_ptr->get();
03701           if ( curve_vectors.size() == loop_ptr->size() - 1)
03702             verts_same = CUBIT_TRUE;
03703         }
03704         else {
03705             //Either we have a screw-up or we have
03706             //a periodic boundary.
03707             //Lets say end_imp is the last in the loop.
03708           loop_ptr->reset();
03709           end_imp = loop_ptr->prev();
03710             //Now make sure that end_imp and start_imp are connected.
03711           RefEntity *ent_1 = start_imp->owner();
03712           RefEntity *ent_2 = end_imp->owner();
03713           if ( are_connected( ent_1, ent_2, ref_face ) )
03714           {
03715             verts_same = CUBIT_TRUE;
03716             end_imp = start_imp;
03717           }
03718           else {
03719             PRINT_ERROR("Problems extracting parition edge in ImprintBoundaryTool.\n");
03720             return CUBIT_FAILURE;
03721           }
03722         }
03723       }
03724         //Create vertices from the first and last vectors.
03725       CubitVector tmp_vec = start_imp->coordinates();
03726       matching_start = start_imp->get_matching_point();
03727       if ( matching_start != NULL )
03728       {
03729           //use this location instead.  This should be on 
03730           //the other boundary and will insure that the point
03731           // intersects it...
03732         tmp_vec = matching_start->coordinates();
03733       }
03734 
03735       RefVertex *first_ref = create_virtual_vertex(tmp_vec);
03736         //It is tempting to update the start_imp's owner at this point,
03737         //but DON'T.  These vertices belong to this surfaces boundary.  The
03738         //start_imp really belongs to the other boundary that is intersecting
03739         //with this boundary.  If you change the owner, you'll end up merging
03740         //vertices accross boundaries.  Don't do that...
03741       RefVertex *last_ref=NULL;
03742       if ( verts_same )
03743       {
03744         last_ref = first_ref;
03745         prev_end = last_ref;
03746       }
03747       else
03748       {
03749         tmp_vec = end_imp->coordinates();
03750         matching_end = end_imp->get_matching_point();
03751         if ( matching_end != NULL )
03752         {
03753             //use this location instead.  This should be on 
03754             //the other boundary and will insure that the point
03755             // intersects it...
03756           tmp_vec = matching_end->coordinates();
03757         }
03758         last_ref = create_virtual_vertex(tmp_vec);
03759           //again don't update the end_imp owner either., see above comment.
03760       }
03761       assert( first_ref && last_ref );
03762       RefEdge *ref_edge = NULL;
03763         //if curve_vectors is empty, this is just a straight line
03764         //curve.
03765       ref_edge = create_virtual_edge(first_ref, last_ref, curve_vectors);
03766       allocatedRefEdge->append(ref_edge);
03767      
03768       int tt;
03769       for ( tt = curve_vectors.size(); tt > 0; tt-- )
03770         delete curve_vectors.pop();
03771       if ( ref_edge == NULL )
03772       {
03773         PRINT_ERROR("Problem creating virtual edge in imprinting.\n");
03774         return CUBIT_FAILURE;
03775       }
03776       ref_edges.append(ref_edge);
03777       if ( first_on_loop )
03778       {
03779         first_on_loop = CUBIT_FALSE;
03780           //merge the start_imp's vertex with it's matching vertex.
03781         matching_start = start_imp->get_matching_point();
03782         if ( matching_start != NULL )
03783         {
03784           RefEntity *other_ent = matching_start->owner();
03785           RefVertex *matching_vert = CAST_TO(other_ent, RefVertex);
03786           if ( matching_vert == NULL )
03787           {
03788             PRINT_ERROR("Problems mergeing partition to boundary on imprint.\n");
03789             assert(matching_vert != NULL);
03790             return CUBIT_FAILURE;
03791           }
03792           CubitBoolean kept_1 = CUBIT_TRUE;
03793           CubitStatus temp_stat = merge_vertices(matching_vert, first_ref, kept_1);
03794           if ( temp_stat != CUBIT_SUCCESS )
03795             return CUBIT_FAILURE;
03796           RefVertex *owner_v = kept_1 ? matching_vert : first_ref;
03797             //Update the matching_start cause the matching imprint point data IS on
03798             //this boundary. (which is why we had to merge with it!).
03799           matching_start->owner(owner_v);
03800           if ( start_imp->get_start_partition() &&
03801                start_imp->get_end_partition() )
03802             first_v_on_loop = owner_v;
03803         }
03804         else
03805           first_v_on_loop = first_ref;
03806       }
03807       else if ( prev_end && last_ref != first_ref)
03808       {
03809           //merge the prev_end vert and first_ref verts.
03810         CubitBoolean kept_1 = CUBIT_TRUE;
03811         CubitStatus temp_stat = merge_vertices(prev_end, first_ref, kept_1);
03812         if ( temp_stat != CUBIT_SUCCESS )
03813           return CUBIT_FAILURE;
03814         prev_end = kept_1 ? prev_end : first_ref;
03815           //Don't update any imprint point data owners, nothing changed for this
03816           //boundary.
03817       }
03818 
03819       if ( last_ref != first_ref )
03820         prev_end = last_ref;
03821     }
03822       //Merge the end vertex to the boundary.
03823     loop_ptr->reset();
03824     end_imp = loop_ptr->prev();
03825     if ( end_imp->is_owner_vertex() &&
03826          (end_imp->get_point_type() == CREATE_NEW_VERTEX ||
03827           end_imp->get_point_type() == VERTEX_ON_BOTH_BOUNDARIES )
03828          && end_imp->get_matching_point() )
03829     {
03830       matching_end = end_imp->get_matching_point();
03831       RefEntity *other_ent = matching_end->owner();
03832       RefVertex *matching_vert = CAST_TO(other_ent, RefVertex);
03833         //use prev_end, hope its still valid!!!
03834       assert(prev_end != NULL);
03835       RefVertex *end_vertex = prev_end;
03836       if ( matching_vert == NULL || end_vertex == NULL )
03837       {
03838         PRINT_ERROR("Problems mergeing partition to boundary on imprint.\n");
03839         assert(matching_vert != NULL);
03840         assert(end_vertex != NULL);
03841         return CUBIT_FAILURE;
03842       }
03843       CubitBoolean kept_1 = CUBIT_TRUE;
03844       CubitStatus temp_stat = merge_vertices(matching_vert, end_vertex, kept_1);
03845       if ( temp_stat != CUBIT_SUCCESS )
03846         return CUBIT_FAILURE;
03847       RefVertex *owner_v = kept_1 ? matching_vert : end_vertex;
03848         //Again just update the matching_end since it is on this boundary.
03849       matching_end->owner(owner_v);
03850     }
03851     else if ( loop_ptr->get()->get_start_partition() &&
03852               loop_ptr->get()->get_end_partition() )
03853     {
03854       assert(first_v_on_loop != NULL);
03855         //Merge the prev_end and this vertex.
03856       CubitBoolean kept_1;
03857       CubitStatus temp_stat = merge_vertices(first_v_on_loop, prev_end, kept_1);
03858       if ( temp_stat != CUBIT_SUCCESS )
03859         return CUBIT_FAILURE;
03860     }
03861   }
03862   CubitStatus stat;
03863     //Okay, these should all be merged properly and ready to partition!
03864   if ( ref_edges.size() > 0 )
03865   {
03866       //Make sure that either the ref_edge_list touches the boundary at least
03867       //twice or is a complete loop...
03868     if ( valid_partition( ref_edges, ref_face ) )
03869     {
03870       PRINT_DEBUG_129("Partitioning surface %d\n",
03871                       ref_face->id());
03872       int tmp_debug = 0;
03873       if (tmp_debug)
03874       {
03875         GfxDebug::clear();
03876         GfxDebug::draw_ref_face(ref_face);
03877         int oo;
03878         for (oo=0; oo < ref_edges.size(); oo++ )
03879           GfxDebug::draw_ref_edge(ref_edges.next(oo), CUBIT_RED_INDEX);
03880         GfxDebug::flush();
03881         GfxDebug::mouse_xforms();
03882       }
03883       stat = PartitionTool::instance()->partition(ref_face, ref_edges,
03884                                                   tmp_results, CUBIT_FALSE, NULL, CUBIT_TRUE);
03885       if ( stat != CUBIT_SUCCESS )
03886       {
03887         PRINT_ERROR("Partitioning surface %d failed\n", ref_face->id());
03888         return stat;
03889       }
03890       else 
03891       {
03892         results += tmp_results;
03893       }
03894     }
03895   }
03896   return CUBIT_SUCCESS;
03897 }
03898 CubitBoolean ImprintBoundaryTool::valid_partition(DLIList <RefEdge*> &ref_edges,
03899                                                   RefFace *ref_face )
03900 {
03901     //Test to make sure the vertices of the ref_edges hit at least twice
03902     //on the boundary of the ref_face_ptr.
03903   DLIList <RefVertex*> boundary_verts;
03904   RefEdge *curr_edge;
03905   RefVertex *ref_vert1, *ref_vert2;
03906   int ii;
03907   //int vert_boundary_count = 0;
03908   
03909   for ( ii = ref_edges.size(); ii > 0; ii-- )
03910   {
03911     curr_edge = ref_edges.get_and_step();
03912     ref_vert1 = curr_edge->start_vertex();
03913     ref_vert2 = curr_edge->end_vertex();
03914     if ( ref_vert1 == ref_vert2 )
03915       continue;
03916     if ( ref_vert1->num_ref_edges() < 2 )
03917       return CUBIT_FALSE;
03918     if ( ref_vert1->num_ref_faces() > 0)
03919       boundary_verts.append(ref_vert1);
03920     if ( ref_vert2->num_ref_edges() < 2 )
03921       return CUBIT_FALSE;
03922     if ( ref_vert2->num_ref_faces() > 0 )
03923       boundary_verts.append(ref_vert2);
03924   }
03925   if ( ref_face->num_loops() > 1 )
03926   {
03927       //Walk on the surface.  Determine if this partition is
03928       //creating a sipeish partition.  We can't handle that right
03929       //now.
03930       //Start with a boundary_vert.  Determine the loop that it is
03931       //on.  Go on it accross the imprint.  Find its imprint.
03932     DLIList <Loop*> loop_list;
03933     DLIList <RefEdge*> ref_edge_list;
03934     Loop *start_loop = NULL;
03935     while (boundary_verts.size())
03936     {
03937       ref_vert1 = boundary_verts.pop();
03938       loop_list.clean_out();
03939       ref_vert1->loops(loop_list);
03940       for ( ii = loop_list.size(); ii > 0; ii-- )
03941       {
03942         if ( loop_list.get()->get_ref_face_ptr() == ref_face )
03943           break;
03944         else
03945           loop_list.step();
03946       }
03947       if ( loop_list.get()->get_ref_face_ptr() != ref_face )
03948       {
03949         PRINT_ERROR("Problems in valid partition logic...");
03950         return CUBIT_FALSE;
03951       }
03952       start_loop = loop_list.get();
03953       do {
03954         loop_list.clean_out();
03955         ref_edge_list.clean_out();
03956         ref_vert1->ref_edges(ref_edge_list);
03957           //Find the ref_edge that has no surfaces.
03958         for ( ii = ref_edge_list.size(); ii > 0; ii--)
03959         {
03960           if ( ref_edge_list.get()->num_ref_faces() == 0 )
03961             break;
03962           else
03963             ref_edge_list.step();
03964         }
03965         if ( ref_edge_list.get()->num_ref_faces() != 0 )
03966         {
03967           PRINT_ERROR("Problems in valid partition logic...");
03968           return CUBIT_FALSE;
03969         }
03970         curr_edge = ref_edge_list.get();
03971         if ( curr_edge->start_vertex() ==
03972              curr_edge->end_vertex() )
03973           continue;
03974         if ( curr_edge->start_vertex() == ref_vert1 )
03975           ref_vert2 = curr_edge->end_vertex();
03976         else
03977           ref_vert2 = curr_edge->start_vertex();
03978         if ( ref_vert2->num_ref_faces() > 0 )
03979         {
03980             //This is a boundary vert.  Remove it...
03981           if ( !boundary_verts.move_to(ref_vert2) )
03982           {
03983               //If this has already been removed,
03984               //then we have a bad partition.
03985             return CUBIT_FALSE;
03986           }
03987           boundary_verts.remove(ref_vert2);
03988           loop_list.clean_out();
03989           ref_vert2->loops(loop_list);
03990           for ( ii = loop_list.size(); ii > 0; ii-- )
03991           {
03992             if ( loop_list.get()->get_ref_face_ptr() == ref_face )
03993               break;
03994             else
03995               loop_list.step();
03996           }
03997           if ( loop_list.get()->get_ref_face_ptr() != ref_face )
03998           {
03999             PRINT_ERROR("Problems in valid partition logic...");
04000             return CUBIT_FALSE;
04001           }
04002           if ( loop_list.get() == start_loop )
04003           {
04004               //This isn't a bad partition.  Break out to the outer loop.
04005               //The partition splits its own loop which is fine...
04006             break;
04007           }
04008           else if ( loop_list.get() != start_loop &&
04009                     boundary_verts.size() == 0 )
04010           {
04011             return CUBIT_FALSE;
04012           }
04013             //Okay, find a vertex on this loop that is a partition vertex.
04014           DLIList <RefVertex*> ref_vertices;
04015           loop_list.get()->ref_vertices(ref_vertices);
04016           for ( ii = ref_vertices.size(); ii > 0; ii-- )
04017           {
04018             ref_vert1 = ref_vertices.get_and_step();
04019             if ( ref_vert1 != ref_vert2 &&
04020                  boundary_verts.move_to(ref_vert1) )
04021             {
04022               break;
04023             }
04024           }
04025           if ( ref_vert1 == ref_vert2 ||
04026                !boundary_verts.move_to(ref_vert1) )
04027           {
04028               //if the vert had been removed or we have a loop
04029               //this is a bad partition.
04030             return CUBIT_FALSE;
04031           }
04032             //ref_vert1 is now set to continue on...
04033           boundary_verts.remove(ref_vert1);
04034         }
04035         else
04036           ref_vert1 = ref_vert2;
04037       } while (ref_vert1 != NULL );
04038       
04039     }
04040   }
04041   return CUBIT_TRUE;
04042 } 
04043 
04044 CubitStatus ImprintBoundaryTool::merge_vertices(DLIList <RefVertex*> &ref_verts)
04045 {
04046     //This is simply a function to reduce code bloat...
04047   double tol_factor = myTolerance / GEOMETRY_RESABS;
04048   double old_geometry_factor = GeometryQueryTool::get_geometry_factor();
04049   GeometryQueryTool::set_geometry_factor( tol_factor );
04050     //merge the vertices to get a connected intersection graph.
04051   CubitStatus stat = MergeTool::instance()->merge_refvertices( ref_verts );
04052   GeometryQueryTool::set_geometry_factor( old_geometry_factor );
04053   if ( stat != CUBIT_SUCCESS )
04054     return stat;
04055   return CUBIT_SUCCESS;
04056 }
04057 CubitStatus ImprintBoundaryTool::merge_vertices(RefVertex *ref_vertex1,
04058                                                 RefVertex *ref_vertex2,
04059                                                 CubitBoolean &kept_1)
04060 {
04061 
04062     //force merge the vertices
04063   RefVertex* result =  MergeTool::instance()->
04064                           force_merge( ref_vertex1, ref_vertex2 );
04065   if (result == ref_vertex1)
04066     kept_1 = CUBIT_TRUE;
04067   else if(result == ref_vertex2)
04068     kept_1 = CUBIT_FALSE;
04069   else
04070     return CUBIT_FAILURE;
04071 
04072   return CUBIT_SUCCESS;
04073 }
04074 void ImprintBoundaryTool::draw_seg(ImprintLineSegment *seg, int color)
04075 {
04076   CubitVector start_point = seg->get_start()->coordinates();
04077   CubitVector end_point = seg->get_end()->coordinates();
04078   if ( color == -1 )
04079     color = CUBIT_GREEN_INDEX;
04080   GfxDebug::draw_line( start_point.x(),start_point.y(),start_point.z(),
04081                           end_point.x(),end_point.y(),end_point.z(),
04082                           color);
04083   GfxDebug::flush();
04084 }
04085 void ImprintBoundaryTool::draw_loops(PointLoopList &boundary_loops)
04086 {
04087   int ii, jj;
04088   PointList *point_list;
04089   ImprintPointData *imp_point;
04090   for (ii = 0; ii < boundary_loops.size(); ii++ )
04091   {
04092     point_list = boundary_loops.get_and_step();
04093     for ( jj = 0; jj < point_list->size(); jj++ )
04094     {
04095       imp_point = point_list->get_and_step();
04096       draw_point(imp_point);
04097     }
04098   }
04099 }
04100 
04101 void ImprintBoundaryTool::draw_point(ImprintPointData *imp_point, int color)
04102 {
04103   CubitPoint *point = (CubitPoint*) imp_point;
04104   PointType p_type = imp_point->get_point_type();
04105   if (color == -1 )
04106   {
04107     switch ( p_type )
04108     {
04109       case VERTEX_ON_BOUNDARY_1:
04110         color = CUBIT_RED_INDEX;
04111         break;
04112       case VERTEX_ON_BOUNDARY_2:
04113         color = CUBIT_ORANGE_INDEX;
04114         break;
04115       case VERTEX_ON_BOTH_BOUNDARIES:
04116         color = CUBIT_MAGENTA_INDEX;
04117         break;
04118       case CREATE_NEW_VERTEX:
04119         color = CUBIT_CYAN_INDEX;
04120         break;
04121       case ON_BOUNDARY_1:
04122         color = CUBIT_GREEN_INDEX;
04123         break;
04124       case ON_BOUNDARY_2:
04125         color = CUBIT_YELLOW_INDEX;
04126         break;
04127       case ON_BOTH_BOUNDARIES:
04128         color = CUBIT_BLUE_INDEX;
04129         break;
04130       default:
04131         color = CUBIT_BROWN_INDEX;
04132     }
04133   }
04134 //  point->draw(color);
04135   int id_val = point->id();
04136   GfxDebug::draw_label(id_val, point->x(), point->y(), point->z(), color);
04137   GfxDebug::flush();
04138 }
04139 void ImprintBoundaryTool::draw_end(ImprintLineSegment *seg)
04140 {
04141   ImprintPointData *end = seg->get_end();
04142   CubitPoint *point = (CubitPoint*) end;
04143   PointType p_type = end->get_point_type();
04144   int color;
04145   switch ( p_type )
04146   {
04147     case VERTEX_ON_BOUNDARY_1:
04148       color = CUBIT_RED_INDEX;
04149       break;
04150     case VERTEX_ON_BOUNDARY_2:
04151       color = CUBIT_ORANGE_INDEX;
04152       break;
04153     case VERTEX_ON_BOTH_BOUNDARIES:
04154       color = CUBIT_MAGENTA_INDEX;
04155       break;
04156     case CREATE_NEW_VERTEX:
04157       color = CUBIT_CYAN_INDEX;
04158       break;
04159     case ON_BOUNDARY_1:
04160       color = CUBIT_GREEN_INDEX;
04161       break;
04162     case ON_BOUNDARY_2:
04163       color = CUBIT_YELLOW_INDEX;
04164       break;
04165     case ON_BOTH_BOUNDARIES:
04166       color = CUBIT_BLUE_INDEX;
04167       break;
04168     default:
04169       color = CUBIT_BROWN_INDEX;
04170   }
04171   int id_val = point->id();
04172   GfxDebug::draw_label(id_val, point->x(), point->y(), point->z(), color);
04173   GfxDebug::flush();
04174 }
04175 CubitStatus ImprintBoundaryTool::resolve_on_boundaries( PointLoopList &boundary_loops_1,
04176                                                         PointLoopList &boundary_loops_2)
04177 {
04178   int ii, jj;
04179   PointList *loop_ptr;
04180   ImprintPointData *curr_point, *next_point, *prev_point, *matching_point;
04181   
04182     //loop around the boundaries, if the point goes from on both boundaries to just on boundary,
04183     //then we know we need to create a vertex there.
04184   for ( ii = boundary_loops_1.size(); ii > 0; ii-- )
04185   {
04186     loop_ptr = boundary_loops_1.get_and_step();
04187     for ( jj = loop_ptr->size(); jj > 0; jj-- )
04188     {
04189       curr_point = loop_ptr->get_and_step();
04190       if ( curr_point->get_point_type() == ON_BOTH_BOUNDARIES )
04191       {
04192         next_point = loop_ptr->get();
04193         prev_point = loop_ptr->prev(2);
04194 
04195         if ( (next_point->get_point_type() == ON_BOUNDARY_1 ||
04196               next_point->get_point_type() == VERTEX_ON_BOUNDARY_1) ||
04197              (prev_point->get_point_type() == ON_BOUNDARY_1 ||
04198               prev_point->get_point_type() == VERTEX_ON_BOUNDARY_1 ) )
04199           
04200         {
04201           curr_point->set_point_type(CREATE_NEW_VERTEX);
04202             //If curr_point is on both boundaries, then the
04203             //matching point cant be a vertex either so
04204             //create a new vertex there too.
04205           matching_point =curr_point->get_matching_point();
04206           matching_point->set_point_type(CREATE_NEW_VERTEX);
04207         }
04208       }
04209     }
04210   }
04211   for ( ii = boundary_loops_2.size(); ii > 0; ii-- )
04212   {
04213     loop_ptr = boundary_loops_2.get_and_step();
04214     for ( jj = loop_ptr->size(); jj > 0; jj-- )
04215     {
04216       curr_point = loop_ptr->get_and_step();
04217       if ( curr_point->get_point_type() == ON_BOTH_BOUNDARIES )
04218       {
04219         next_point = loop_ptr->get();
04220         prev_point = loop_ptr->prev(2);
04221         if ( (next_point->get_point_type() == ON_BOUNDARY_2 ||
04222               next_point->get_point_type() == VERTEX_ON_BOUNDARY_2) ||
04223              (prev_point->get_point_type() == ON_BOUNDARY_2 ||
04224               prev_point->get_point_type() == VERTEX_ON_BOUNDARY_2 ) )
04225         {
04226           curr_point->set_point_type(CREATE_NEW_VERTEX);
04227             //If curr_point is on both boundaries, then the
04228             //matching point cant be a vertex either so
04229             //create a new vertex there too.
04230           matching_point =curr_point->get_matching_point();
04231           matching_point->set_point_type(CREATE_NEW_VERTEX);
04232         }
04233       }
04234     }
04235   }
04236     
04237   return CUBIT_SUCCESS;
04238 }
04239 CubitBoolean ImprintBoundaryTool::resolve_match_conflict_other(ImprintPointData *this_point,
04240                                                                ImprintPointData *other,
04241                                                                CubitBoolean this_is_1 )
04242 {
04243   CubitVector other_v = other->coordinates();
04244   CubitVector coords = this_point->coordinates();
04245   ImprintPointData *conflict_match = other->get_matching_point();
04246   CubitVector c_match_vec = conflict_match->coordinates();
04247   double dist_1 = (other_v - c_match_vec).length_squared();
04248   double dist_2 = (other_v - coords).length_squared();
04249   if ( dist_1 < dist_2 ) //this says leave it alone, and don't match these two.
04250   {
04251       //The conflict match and other should be left matching.  Don't
04252       //match this_point and other...
04253     return CUBIT_FALSE;
04254   }
04255   else
04256   {
04257       //Okay we need to clean this up.
04258       //It used to be that conflict_match and other were paired
04259       //up.  But now we need to undo that and match other and this_point.
04260       //To do that find out what the correct PointType setting should be
04261       //for conflict_match.  Try setting it back to its original.
04262     RefEntity* owner_conflict = conflict_match->owner();
04263       //Use the this_is_1 flag.  Assume conflict_match and
04264       //this_point are on the same boundary.
04265     if( CAST_TO(owner_conflict, RefEdge) )
04266     {
04267       if ( this_is_1 )
04268         conflict_match->set_point_type(ON_BOUNDARY_1);
04269       else
04270         conflict_match->set_point_type(ON_BOUNDARY_2);
04271     }
04272     else if ( CAST_TO(owner_conflict, RefVertex) )
04273     {
04274       if ( this_is_1 )
04275         conflict_match->set_point_type(VERTEX_ON_BOUNDARY_1);
04276       else
04277         conflict_match->set_point_type(VERTEX_ON_BOUNDARY_2);
04278     }
04279     else
04280     {
04281       PRINT_ERROR("Problems resolving matching point type.\n");
04282       return CUBIT_FALSE;
04283     }
04284       //Now do the same thing for other.  Clean it back to its
04285       //preset types. (except use the opposite of this_is_1 flag
04286       //since it is on the other boundary of this_point.)
04287     RefEntity* owner_other = other->owner();
04288     if( CAST_TO(owner_other,RefEdge) )
04289     {
04290       if ( this_is_1 )
04291         other->set_point_type(ON_BOUNDARY_2);
04292       else
04293         other->set_point_type(ON_BOUNDARY_1);
04294     }
04295     else if ( CAST_TO(owner_other,RefVertex))
04296     {
04297       if ( this_is_1 )
04298         other->set_point_type(VERTEX_ON_BOUNDARY_2);
04299       else
04300         other->set_point_type(VERTEX_ON_BOUNDARY_1);
04301     }
04302     else
04303     {
04304       PRINT_ERROR("Problems resolving matching point type.\n");
04305       return CUBIT_FALSE;
04306     }
04307     return CUBIT_TRUE;
04308   }
04309 }
04310   
04311 CubitBoolean ImprintBoundaryTool::resolve_match_conflict_this(ImprintPointData *this_point,
04312                                                               ImprintPointData *other,
04313                                                               CubitBoolean this_is_1 )
04314 {
04315   ImprintPointData *conflict_match = this_point->get_matching_point();
04316   CubitVector other_v = other->coordinates();
04317   CubitVector coords = this_point->coordinates();
04318   CubitVector c_match_vec = conflict_match->coordinates();
04319   double dist_1 = (coords - c_match_vec).length_squared();
04320   double dist_2 = (coords - other_v).length_squared();
04321   if ( dist_1 < dist_2 ) //this says leave it alone, and don't match these two.
04322   {
04323       //The conflict match and this_point should be left matching.  Don't
04324       //match this_point and other...
04325     return CUBIT_FALSE;
04326   }
04327   else
04328   {
04329       //Okay we need to clean this up.
04330       //It used to be that conflict_match and this_point were paired
04331       //up.  But now we need to undo that and match other and this_point.
04332       //To do that find out what the correct PointType setting should be
04333       //for conflict_match.  Try setting it back to its original.
04334     RefEntity* owner_conflict = conflict_match->owner();
04335       //Use the this_is_1 flag.  Assume conflict_match and
04336       //other are on the same boundary.
04337     if( CAST_TO(owner_conflict,RefEdge) )
04338     {
04339       if ( this_is_1 )
04340         conflict_match->set_point_type(ON_BOUNDARY_2);
04341       else
04342         conflict_match->set_point_type(ON_BOUNDARY_1);
04343     }
04344     else if ( CAST_TO(owner_conflict,RefVertex) )
04345     {
04346       if ( this_is_1 )
04347         conflict_match->set_point_type(VERTEX_ON_BOUNDARY_2);
04348       else
04349         conflict_match->set_point_type(VERTEX_ON_BOUNDARY_1);
04350     }
04351     else
04352     {
04353       PRINT_ERROR("Problems resolving matching point type.\n");
04354       return CUBIT_FALSE;
04355     }
04356       //Now do the same thing for this_point.  Clean it back to its
04357       //preset types. (except use the opposite of this_is_1 flag
04358       //since it is on the other boundary of this_point.)
04359     RefEntity* owner_this = this_point->owner();
04360     if( CAST_TO(owner_this,RefEdge))
04361     {
04362       if ( this_is_1 )
04363         this_point->set_point_type(ON_BOUNDARY_1);
04364       else
04365         this_point->set_point_type(ON_BOUNDARY_2);
04366     }
04367     else if (CAST_TO(owner_this,RefVertex) )
04368     {
04369       if ( this_is_1 )
04370         this_point->set_point_type(VERTEX_ON_BOUNDARY_1);
04371       else
04372         this_point->set_point_type(VERTEX_ON_BOUNDARY_2);
04373     }
04374     else
04375     {
04376       PRINT_ERROR("Problems resolving matching point type.\n");
04377       return CUBIT_FALSE;
04378     }
04379     return CUBIT_TRUE;
04380   }
04381 }
04382 CubitStatus ImprintBoundaryTool::match_points( ImprintLineSegment *seg_1,
04383                                                ImprintLineSegment *seg_2,
04384                                                MatchType &type_0,
04385                                                MatchType &type_1,
04386                                                MatchType &type_2,
04387                                                MatchType &type_3)
04388 {
04389   ImprintPointData *imp_point_0, *imp_point_1, *imp_point_2, *imp_point_3;
04390   ImprintPointData *imp_point_4, *imp_point_5, *imp_point_6, *imp_point_7;
04391   ImprintLineSegment *prev_seg_1 = seg_1->get_prev();
04392   ImprintLineSegment *next_seg_1 = seg_1->get_next();
04393   ImprintLineSegment *prev_seg_2 = seg_2->get_prev();
04394   ImprintLineSegment *next_seg_2 = seg_2->get_next();
04395   imp_point_0 = seg_1->get_start();
04396   imp_point_1 = seg_1->get_end();
04397   imp_point_4 = prev_seg_1->get_start();
04398   imp_point_5 = next_seg_1->get_end();
04399   imp_point_2 = seg_2->get_start();
04400   imp_point_3 = seg_2->get_end();
04401   imp_point_6 = prev_seg_2->get_start();
04402   imp_point_7 = next_seg_2->get_end();
04403   
04404   CubitVector point_0, point_1, point_2, point_3;
04405   CubitVector point_4, point_5, point_6, point_7;
04406   point_0 = imp_point_0->coordinates();
04407   point_1 = imp_point_1->coordinates();
04408   point_2 = imp_point_2->coordinates();
04409   point_3 = imp_point_3->coordinates();
04410   point_4 = imp_point_4->coordinates();
04411   point_5 = imp_point_5->coordinates();
04412   point_6 = imp_point_6->coordinates();
04413   point_7 = imp_point_7->coordinates();
04414 
04415     //There are four possible matches for each of the points (0,1,2,and3).
04416     //Find out which ones match.
04417   CubitBoolean match_02=CUBIT_FALSE, match_03=CUBIT_FALSE,
04418     match_06=CUBIT_FALSE, match_07=CUBIT_FALSE;
04419   CubitBoolean match_12=CUBIT_FALSE, match_13=CUBIT_FALSE,
04420     match_16=CUBIT_FALSE, match_17=CUBIT_FALSE;
04421   CubitBoolean match_24=CUBIT_FALSE, match_25=CUBIT_FALSE;
04422   CubitBoolean match_34=CUBIT_FALSE, match_35=CUBIT_FALSE;
04423     //compute the matching.
04424   if (point_0.within_tolerance(point_2, myTolerance) )
04425     match_02=CUBIT_TRUE;
04426   if (point_0.within_tolerance(point_3, myTolerance) )
04427     match_03=CUBIT_TRUE;
04428   if (point_0.within_tolerance(point_6, myTolerance) )
04429     match_06=CUBIT_TRUE;
04430   if (point_0.within_tolerance(point_7, myTolerance) )
04431     match_07=CUBIT_TRUE;
04432 
04433   if (point_1.within_tolerance(point_2, myTolerance) )
04434     match_12=CUBIT_TRUE;
04435   if (point_1.within_tolerance(point_3, myTolerance) )
04436     match_13=CUBIT_TRUE;
04437   if (point_1.within_tolerance(point_6, myTolerance) )
04438     match_16=CUBIT_TRUE;
04439   if (point_1.within_tolerance(point_7, myTolerance) )
04440     match_17=CUBIT_TRUE;
04441 
04442   if (point_2.within_tolerance(point_4, myTolerance) )
04443     match_24=CUBIT_TRUE;
04444   if (point_2.within_tolerance(point_5, myTolerance) )
04445     match_25=CUBIT_TRUE;
04446   if (point_3.within_tolerance(point_4, myTolerance) )
04447     match_34=CUBIT_TRUE;
04448   if (point_3.within_tolerance(point_5, myTolerance) )
04449     match_35=CUBIT_TRUE;
04450     //Now for those that match, compute the distances.
04451   double dist_02 = 0.0, dist_03 = 0.0, dist_06 = 0.0, dist_07 = 0.0;
04452   double dist_12 = 0.0, dist_13 = 0.0, dist_16 = 0.0, dist_17 = 0.0;
04453   double dist_24 = 0.0, dist_25 = 0.0;
04454   double dist_34 = 0.0, dist_35 = 0.0;
04455   if ( match_02 )
04456     dist_02 = (point_0-point_2).length_squared();
04457   if ( match_03 )
04458     dist_03 = (point_0-point_3).length_squared();
04459   if ( match_06 )
04460     dist_06 = (point_0-point_6).length_squared();
04461   if ( match_07 )
04462     dist_07 = (point_0-point_7).length_squared();
04463 
04464   if ( match_12 )
04465     dist_12 = (point_1-point_2).length_squared();
04466   if ( match_13 )
04467     dist_13 = (point_1-point_3).length_squared();
04468   if ( match_16 )
04469     dist_16 = (point_1-point_6).length_squared();
04470   if ( match_17 )
04471     dist_17 = (point_1-point_7).length_squared();
04472 
04473   if ( match_24 )
04474     dist_24 = (point_2-point_4).length_squared();
04475   if ( match_25 )
04476     dist_25 = (point_2-point_5).length_squared();
04477 
04478   if ( match_34 )
04479     dist_34 = (point_3-point_4).length_squared();
04480   if ( match_35 )
04481     dist_35 = (point_3-point_5).length_squared();
04482 
04483     //Okay, determine the solution by finding the closest
04484     //points, and then determining the final four results;
04485 
04486     //point 0
04487   double min_dist = CUBIT_DBL_MAX;
04488   type_0 = NO_MATCH;
04489   type_1 = NO_MATCH;
04490   type_2 = NO_MATCH;
04491   type_3 = NO_MATCH;
04492   if ( match_02 && dist_02 < min_dist )
04493   {
04494     min_dist = dist_02;
04495     type_0 = MATCH_0_2;
04496   }
04497   if ( match_03 && dist_03 < min_dist )
04498   {
04499     min_dist = dist_03;
04500     type_0 = MATCH_0_3;
04501   }
04502   if ( match_06 && dist_06 < min_dist )
04503   {
04504     min_dist = dist_06;
04505     type_0 = MATCH_0_6;
04506   }
04507   if ( match_07 && dist_07 < min_dist )
04508   {
04509     min_dist = dist_07;
04510     type_0 = MATCH_0_7;
04511   }
04512     //point 1
04513   min_dist = CUBIT_DBL_MAX;
04514   type_1 = NO_MATCH;
04515   if ( match_12 && dist_12 < min_dist )
04516   {
04517     min_dist = dist_12;
04518     type_1 = MATCH_1_2;
04519   }
04520   if ( match_13 && dist_13 < min_dist )
04521   {
04522     min_dist = dist_13;
04523     type_1 = MATCH_1_3;
04524   }
04525   if ( match_16 && dist_16 < min_dist )
04526   {
04527     min_dist = dist_16;
04528     type_1 = MATCH_1_6;
04529   }
04530   if ( match_17 && dist_17 < min_dist )
04531   {
04532     min_dist = dist_17;
04533     type_1 = MATCH_1_7;
04534   }
04535     //point 2
04536   min_dist = CUBIT_DBL_MAX;
04537   type_2 = NO_MATCH;
04538   if ( match_02 && dist_02 < min_dist )
04539   {
04540     min_dist = dist_02;
04541     type_2 = MATCH_0_2;
04542   }
04543   if ( match_12 && dist_12 < min_dist )
04544   {
04545     min_dist = dist_12;
04546     type_2 = MATCH_1_2;
04547   }
04548   if ( match_24 && dist_24 < min_dist )
04549   {
04550     min_dist = dist_24;
04551     type_2 = MATCH_2_4;
04552   }
04553   if ( match_25 && dist_25 < min_dist )
04554   {
04555     min_dist = dist_25;
04556     type_2 = MATCH_2_5;
04557   }
04558     //point 3
04559   min_dist = CUBIT_DBL_MAX;
04560   type_3 = NO_MATCH;
04561   if ( match_03 && dist_03 < min_dist )
04562   {
04563     min_dist = dist_03;
04564     type_3 = MATCH_0_3;
04565   }
04566   if ( match_13 && dist_13 < min_dist )
04567   {
04568     min_dist = dist_13;
04569     type_3 = MATCH_1_3;
04570   }
04571   if ( match_34 && dist_34 < min_dist )
04572   {
04573     min_dist = dist_34;
04574     type_3 = MATCH_3_4;
04575   }
04576   if ( match_35 && dist_35 < min_dist )
04577   {
04578     min_dist = dist_35;
04579     type_3 = MATCH_3_5;
04580   }
04581   return CUBIT_SUCCESS;
04582 }
04583 
04584   
04585   
04586   
04587 int ImprintBoundaryTool::num_coedges_on_face(RefEdge *edge_ptr,
04588                                              RefFace *ref_face)
04589 {
04590   DLIList <CoEdge*> coedges;
04591   edge_ptr->co_edges(coedges);
04592   int ii;
04593   int count = 0;
04594   for ( ii = coedges.size(); ii > 0; ii-- )
04595   {
04596     if ( coedges.get_and_step()->get_ref_face() == ref_face )
04597       count++;
04598   }
04599   return count;
04600 }
04601 
04602 CubitStatus ImprintBoundaryTool::imprint_segments( SegLoopList &boundary_line_loops_1,
04603                                                    SegLoopList &boundary_line_loops_2,
04604                                                    PointLoopList &boundary_loops_1,
04605                                                    PointLoopList &boundary_loops_2)
04606 {
04607   int ii, jj;
04608   ImprintLineSegment **surf_1_loop_heads, **surf_2_loop_heads;
04609   surf_1_loop_heads = new ImprintLineSegment*[boundary_line_loops_1.size()];
04610   surf_2_loop_heads = new ImprintLineSegment*[boundary_line_loops_2.size()];
04611   SegList *line_loop_1, *line_loop_2;
04612   ImprintLineSegment *curr_seg;
04613   
04614   for ( ii = 0; ii < boundary_line_loops_1.size(); ii++ )
04615   {
04616     line_loop_1 = boundary_line_loops_1.get_and_step();
04617     surf_1_loop_heads[ii] = line_loop_1->get();
04618   }
04619   for ( ii = 0; ii < boundary_line_loops_2.size(); ii++ )
04620   {
04621     line_loop_2 = boundary_line_loops_2.get_and_step();
04622     surf_2_loop_heads[ii] = line_loop_2->get();
04623   }
04624   KDDTree <ImprintLineSegment*> atree_1(myTolerance, true);
04625   KDDTree <ImprintLineSegment*> atree_2(myTolerance, true);
04626     //Insert all of the segments on for the boundary line loops into
04627     //their respective R-Tree.
04628   for ( ii = 0; ii < boundary_line_loops_1.size(); ii++ )
04629   {
04630     line_loop_1 = boundary_line_loops_1.get_and_step();
04631     for ( jj = 0; jj < line_loop_1->size(); jj++ )
04632     {
04633       curr_seg = line_loop_1->get_and_step();
04634       atree_1.add(curr_seg);
04635     }
04636   }
04637   atree_1.balance();
04638   for ( ii = 0; ii < boundary_line_loops_2.size(); ii++ )
04639   {
04640     line_loop_2 = boundary_line_loops_2.get_and_step();
04641     for ( jj = 0; jj < line_loop_2->size(); jj++ )
04642     {
04643       curr_seg = line_loop_2->get_and_step();
04644       atree_2.add(curr_seg);
04645     }
04646   }
04647   atree_2.balance();
04648     //Now for each segment on boundary 1, find the closest segments on
04649     //boundary 2.  Determine for each point on boundary 1 the closest
04650     //point on boundary 2 if it is within tolerance.  Set this
04651     //data in the pointmatched data in ImprintPointData.
04652   CubitStatus stat = find_matching_points(boundary_line_loops_1,
04653                                           atree_2 );
04654   if ( stat != CUBIT_SUCCESS )
04655     return stat;
04656 
04657     //Now for each segment on boundary 2, find the closest segments on
04658     //boundary 1.  Determine for each point on boundary 2 the closest
04659     //point on boundary 1 if it is within tolerance.  Set this
04660     //data in the pointmatched data in ImprintPointData.
04661   stat = find_matching_points(boundary_line_loops_2,
04662                               atree_1 );
04663   if ( stat != CUBIT_SUCCESS )
04664     return stat;
04665 
04666     //Now we need to go over each node on the boundaries and resolve
04667     //descripensies.  Find nodes that match each other and set them
04668     //to match each other. Also at this time.  Nodes that have
04669     //closest points on the interior of a segment will get the
04670     //segment split.  Also as segments are modified, update the
04671     //atree.
04672   int num_loops_1 = boundary_line_loops_1.size();
04673   int num_loops_2 = boundary_line_loops_2.size();
04674   stat = final_match( surf_1_loop_heads, num_loops_1,
04675                       surf_2_loop_heads, num_loops_2,
04676                       atree_1, atree_2);
04677   if ( stat != CUBIT_SUCCESS )
04678     return stat;
04679 
04680     //Unfortunately, we are not done.  We now need to find
04681     //cross intersections.  These are where two segments of different
04682     //surfaces intersect.  They don't intersect at the points themselves,
04683     //so they weren't captured previously.  If I could do this in any other
04684     //part of the previous code, I would.  I just can't figure out
04685     //how to do it without sacrificing robustness.
04686     //Note that only atree_2 is passed in.  After this point,
04687     //atree_1 will be out of date.
04688   stat = find_crossings(surf_1_loop_heads, num_loops_1,
04689                         surf_2_loop_heads, num_loops_2,
04690                         atree_2);
04691   if ( stat != CUBIT_SUCCESS )
04692     return stat;
04693 
04694     //Recaputure the linked list into the DLIList structure.
04695   update_boundary_loops( boundary_loops_1, surf_1_loop_heads);
04696   update_boundary_loops( boundary_loops_2, surf_2_loop_heads);
04697 
04698   delete [] surf_1_loop_heads;
04699   delete [] surf_2_loop_heads;
04700 
04701   stat = resolve_on_boundaries( boundary_loops_1,
04702                                 boundary_loops_2);
04703   if ( stat != CUBIT_SUCCESS )
04704     return stat;
04705   if ( DEBUG_FLAG(129) )
04706   {
04707     GfxDebug::clear();
04708     draw_loops(boundary_loops_1);
04709     draw_loops(boundary_loops_2);
04710     GfxDebug::mouse_xforms();
04711   }
04712   
04713   return CUBIT_SUCCESS;
04714 }
04715 CubitStatus ImprintBoundaryTool::find_matching_points( SegLoopList &seg_loops,
04716                                                        AbstractTree <ImprintLineSegment*> &atree )
04717 {
04718     //Loop over seg_loops.  For each segment loop, find the closest matching point
04719     //from the segments in the atree.  
04720   int ii, jj, kk;
04721   SegList *loop_ptr;
04722   ImprintLineSegment *curr_seg, *test_seg;
04723   ImprintPointData *imp_point_0, *imp_point_1;
04724   SegList close_segments;
04725   CubitBox curr_box;
04726   CubitStatus stat;
04727   for ( ii = 0; ii < seg_loops.size(); ii++ )
04728   {
04729     loop_ptr = seg_loops.get_and_step();
04730     for ( jj = 0; jj < loop_ptr->size(); jj++ )
04731     {
04732       curr_seg = loop_ptr->get_and_step();
04733       close_segments.clean_out();
04734       curr_box = curr_seg->bounding_box();
04735       atree.find(curr_box, close_segments);
04736       if ( close_segments.size() == 0 )
04737           continue;
04738 
04739       for ( kk = 0; kk < close_segments.size(); kk++ )
04740       {
04741         test_seg = close_segments.get_and_step();
04742         stat = find_closest_points(curr_seg, test_seg);
04743         if (stat != CUBIT_SUCCESS )
04744           return stat;
04745       }
04746         //Now given those closest points,
04747         //find the match for point 0.
04748       imp_point_0 = curr_seg->get_start();
04749       if (!imp_point_0->is_matched() )
04750         set_closest_point(imp_point_0);
04751         //Now given those closest points,
04752         //find the match for point 1.
04753       imp_point_1 = curr_seg->get_end();
04754       if (!imp_point_1->is_matched() )
04755         set_closest_point(imp_point_1);
04756     }
04757   }
04758   return CUBIT_SUCCESS;
04759 }
04760 void ImprintBoundaryTool::set_closest_point(ImprintPointData *imp_point_0)
04761 {
04762   DLIList <ImprintMatchData*> closest_points;
04763   int kk;
04764   imp_point_0->get_match_list(closest_points);
04765   double min_dist = CUBIT_DBL_MAX;
04766   ImprintMatchData *closest_point = NULL, *close_point;
04767   for ( kk = 0; kk < closest_points.size(); kk++ )
04768   {
04769     close_point = closest_points.get_and_step();
04770     if ( close_point->get_closest_dist() < min_dist )
04771     {
04772       min_dist = close_point->get_closest_dist();
04773       closest_point = close_point;
04774     }
04775   }
04776   if ( closest_point )
04777   {
04778     imp_point_0->set_matched(closest_point);
04779   }
04780 }
04781 
04782 CubitStatus ImprintBoundaryTool::find_closest_points(ImprintLineSegment *curr_seg,
04783                                                      ImprintLineSegment *test_seg )
04784 {
04785     //Given the two
04786   ImprintPointData *curr_data_a, *curr_data_b;
04787   curr_data_a = curr_seg->get_start();
04788   curr_data_b = curr_seg->get_end();
04789   ImprintMatchData *point_a_match = NULL;
04790   ImprintMatchData *point_b_match = NULL;
04791   
04792   CubitStatus stat1 = match_seg_points(curr_seg, test_seg, point_a_match,
04793                                        point_b_match);
04794   if ( stat1 != CUBIT_SUCCESS )
04795     return stat1;
04796   if ( !curr_data_a->is_matched() && 
04797        point_a_match != NULL )
04798     curr_data_a->add_match_data(point_a_match);
04799   if ( !curr_data_b->is_matched() && 
04800        point_b_match != NULL )
04801     curr_data_b->add_match_data(point_b_match);
04802   return CUBIT_SUCCESS;
04803 }
04804 CubitStatus ImprintBoundaryTool::match_seg_points( ImprintLineSegment *seg_1,
04805                                                    ImprintLineSegment *seg_2,
04806                                                    ImprintMatchData *&point_0_match,
04807                                                    ImprintMatchData *&point_1_match )
04808 {
04809   ImprintPointData *imp_point_0, *imp_point_1, *imp_point_2, *imp_point_3;
04810   imp_point_0 = seg_1->get_start();
04811   imp_point_1 = seg_1->get_end();
04812   imp_point_2 = seg_2->get_start();
04813   imp_point_3 = seg_2->get_end();
04814 
04815   
04816   CubitVector point_0, point_1, point_2, point_3;
04817   point_0 = imp_point_0->coordinates();
04818   point_1 = imp_point_1->coordinates();
04819   point_2 = imp_point_2->coordinates();
04820   point_3 = imp_point_3->coordinates();
04821   CubitBoolean dont_test_0 = imp_point_0->is_matched();
04822   CubitBoolean dont_test_1 = imp_point_1->is_matched();
04823   point_0_match = NULL;
04824   point_1_match = NULL;
04825   if ( dont_test_0 && dont_test_1 )
04826     return CUBIT_SUCCESS;
04827   
04828   int debug = 0;
04829   if ( debug )
04830   {
04831     draw_seg(seg_1, CUBIT_GREEN_INDEX);
04832     draw_seg(seg_2, CUBIT_YELLOW_INDEX);
04833     draw_point(imp_point_0, CUBIT_GREEN_INDEX);
04834     draw_point(imp_point_1, CUBIT_GREEN_INDEX);
04835     draw_point(imp_point_2, CUBIT_YELLOW_INDEX);
04836     draw_point(imp_point_3, CUBIT_YELLOW_INDEX);
04837     GfxDebug::mouse_xforms();
04838   }
04839     //There are four possible matches for each of the points (0,1,2,and3).
04840     //Find out which ones match.
04841   CubitBoolean match_02=CUBIT_FALSE, match_03=CUBIT_FALSE;
04842   CubitBoolean match_12=CUBIT_FALSE, match_13=CUBIT_FALSE;
04843     //compute the matching.
04844   if ( !dont_test_0 )
04845   {
04846     if (point_0.within_tolerance(point_2, myTolerance) )
04847       match_02=CUBIT_TRUE;
04848     if (point_0.within_tolerance(point_3, myTolerance) )
04849       match_03=CUBIT_TRUE;
04850   }
04851   if ( !dont_test_1 )
04852   {
04853     if (point_1.within_tolerance(point_2, myTolerance) )
04854       match_12=CUBIT_TRUE;
04855     if (point_1.within_tolerance(point_3, myTolerance) )
04856       match_13=CUBIT_TRUE;
04857   }
04858     //Now for those that match, compute the distances.
04859   double dist_02 = 0.0, dist_03 = 0.0;
04860   double dist_12 = 0.0, dist_13 = 0.0;
04861   if ( match_02 )
04862     dist_02 = (point_0-point_2).length_squared();
04863   if ( match_03 )
04864     dist_03 = (point_0-point_3).length_squared();
04865   if ( match_12 )
04866     dist_12 = (point_1-point_2).length_squared();
04867   if ( match_13 )
04868     dist_13 = (point_1-point_3).length_squared();
04869 
04870   if ( match_02 && match_03 )
04871   {
04872     if ( dist_02 < dist_03 )
04873       match_03 = CUBIT_FALSE;
04874     else
04875       match_02 = CUBIT_FALSE;
04876   }
04877   if ( match_12 && match_13 )
04878   {
04879     if ( dist_12 < dist_13 )
04880       match_13 = CUBIT_FALSE;
04881     else
04882       match_12 = CUBIT_FALSE;
04883   }
04884 
04885     //Now find the closest points on the segment.
04886   CubitBoolean on_interior_0 = CUBIT_FALSE;
04887   CubitBoolean on_interior_1 = CUBIT_FALSE;
04888   CubitVector closest_point_0, closest_point_1;
04889   if ( !dont_test_0 && closest_point_interior_seg(imp_point_0,
04890                                                   seg_2,
04891                                                   closest_point_0 ) )
04892   {
04893     if ( point_0.within_tolerance(closest_point_0,
04894                                   myTolerance) )
04895     {
04896         //There is a close point on the interior.
04897       on_interior_0 = CUBIT_TRUE;
04898     }
04899   }
04900   if ( !dont_test_1 && closest_point_interior_seg(imp_point_1,
04901                                                   seg_2,
04902                                                   closest_point_1 ) )
04903   {
04904       //This means the closest_point is perpendicular
04905       //to the segment.  Now test if the point is within
04906       //tolerance.
04907     if ( point_1.within_tolerance(closest_point_1,
04908                                   myTolerance) )
04909     {
04910         //There is a close point on the interior.
04911       on_interior_1 = CUBIT_TRUE;
04912     }
04913   }
04914     //point 0
04915   //double min_dist = CUBIT_DBL_MAX;
04916   point_0_match = NULL;
04917   point_1_match = NULL;
04918   if ( match_02 )
04919   {
04920     point_0_match = new ImprintMatchData; 
04921     if ( on_interior_0 )
04922     {
04923         //set the distance to be equal to the
04924         //distance to the closest_point_0 and point_0 rather
04925         //than 2 and 0.  0 and 2 should snap together but
04926         //for finding the min distance, we want to make sure
04927         //we get the closest segment.
04928       dist_02 = (point_0 - closest_point_0).length_squared();
04929     }
04930 
04931     allocatedMatchData->append(point_0_match);
04932     point_0_match->set_closest_point(imp_point_2);
04933     point_0_match->set_closest_dist(dist_02);
04934     point_0_match->set_closest_seg(seg_2);
04935     seg_2->add_match_data(point_0_match);
04936   }
04937   else if ( match_03 )
04938   {
04939     point_0_match = new ImprintMatchData;
04940     if ( on_interior_0 )
04941     {
04942         //set the distance to be equal to the
04943         //distance to the closest_point_0 and point_0 rather
04944         //than 3 and 0.  0 and 3 should snap together but
04945         //for finding the min distance, we want to make sure
04946         //we get the closest segment.
04947       dist_03 = (point_0 - closest_point_0).length_squared();
04948     }
04949 
04950     allocatedMatchData->append(point_0_match);
04951     point_0_match->set_closest_point(imp_point_3);
04952     point_0_match->set_closest_dist(dist_03);
04953     point_0_match->set_closest_seg(seg_2);
04954     seg_2->add_match_data(point_0_match);
04955   }
04956   else if ( on_interior_0 && !match_02 && !match_03 )
04957   {
04958     double dist = (point_0 - closest_point_0).length_squared();
04959     point_0_match = new ImprintMatchData;
04960     allocatedMatchData->append(point_0_match);
04961     point_0_match->set_closest_seg(seg_2);
04962     seg_2->add_match_data(point_0_match);
04963     point_0_match->set_point_on(closest_point_0);
04964     point_0_match->set_closest_dist(dist);
04965   }
04966   if ( match_12 )
04967   {
04968     point_1_match = new ImprintMatchData;  
04969     if ( on_interior_1 )
04970     {
04971         //set the distance to be equal to the
04972         //distance to the closest_point_1 and point_1 rather
04973         //than 2 and 1.  1 and 2 should snap together but
04974         //for finding the min distance, we want to make sure
04975         //we get the closest segment.
04976       dist_12 = (point_1 - closest_point_1).length_squared();
04977     }
04978 
04979     allocatedMatchData->append(point_1_match);
04980     point_1_match->set_closest_point(imp_point_2);
04981     point_1_match->set_closest_dist(dist_12);
04982     point_1_match->set_closest_seg(seg_2);
04983     seg_2->add_match_data(point_1_match);
04984   }
04985   else if ( match_13 )
04986   {    
04987     point_1_match = new ImprintMatchData;
04988     if ( on_interior_1 )
04989     {
04990         //set the distance to be equal to the
04991         //distance to the closest_point_1 and point_1 rather
04992         //than 3 and 1.  1 and 3 should snap together but
04993         //for finding the min distance, we want to make sure
04994         //we get the closest segment.
04995       dist_13 = (point_1 - closest_point_1).length_squared();
04996     }
04997 
04998     allocatedMatchData->append(point_1_match);
04999     point_1_match->set_closest_point(imp_point_3);
05000     point_1_match->set_closest_dist(dist_13);
05001     point_1_match->set_closest_seg(seg_2);    
05002     seg_2->add_match_data(point_1_match);
05003   }
05004   else if ( on_interior_1 && !match_12 && !match_13 )
05005   {
05006     double dist = (point_1 - closest_point_1).length_squared();
05007     //double debug_dist = (point_0 - point_2).length();
05008     point_1_match = new ImprintMatchData;
05009     allocatedMatchData->append(point_1_match);
05010     point_1_match->set_closest_seg(seg_2);
05011     point_1_match->set_point_on(closest_point_1);
05012     point_1_match->set_closest_dist(dist);
05013     seg_2->add_match_data(point_1_match);
05014   }
05015   return CUBIT_SUCCESS;
05016 }
05017 CubitStatus ImprintBoundaryTool::final_match( ImprintLineSegment **surf_1_loop_heads,
05018                                               int num_loops_1,
05019                                               ImprintLineSegment **surf_2_loop_heads,
05020                                               int num_loops_2,
05021                                               AbstractTree <ImprintLineSegment*>& atree_1,
05022                                               AbstractTree <ImprintLineSegment*>& atree_2)
05023 {
05024   CubitStatus stat;
05025     //Match the points on surface 1 with the points on surface 2.
05026     //Resolve cases where more than 1 point match to another point.
05027     //Also resolve where a point on surface 1 matches with a segment
05028     //on surface 2.  This will possibly alter the loop_heads of surface 2,
05029     //and the atree of surface2.
05030   stat = final_match_loop( surf_1_loop_heads, num_loops_1,
05031                            surf_2_loop_heads, num_loops_2,
05032                            atree_1, atree_2);
05033   if (stat != CUBIT_SUCCESS )
05034     return stat;
05035     //Now match the points on surface 2 with surface 1.
05036     //This should go faster since hopefully they were done
05037     //at once.  But there will be points that match with segments
05038     //that are left...
05039     //This will possibly alter the loop_heads of surface 1 and
05040     //the atree of surface1.
05041   stat = final_match_loop( surf_2_loop_heads, num_loops_2,
05042                            surf_1_loop_heads, num_loops_1,
05043                            atree_2, atree_1);
05044   if (stat != CUBIT_SUCCESS )
05045     return stat;
05046   
05047   return CUBIT_SUCCESS;
05048 }
05049 CubitStatus ImprintBoundaryTool::final_match_loop( ImprintLineSegment **surf_1_loop_heads,
05050                                                    int num_loops_1,
05051                                                    ImprintLineSegment **surf_2_loop_heads,
05052                                                    int num_loops_2,
05053                                                    AbstractTree <ImprintLineSegment*>& atree_1,
05054                                                    AbstractTree <ImprintLineSegment*>& atree_2)
05055 
05056 {
05057   int ii;
05058   ImprintLineSegment *prev_seg, *curr_seg;
05059   CubitBoolean first = CUBIT_TRUE;
05060   ImprintPointData *start_point;
05061   DLIList<ImprintMatchData*> match_data_list;
05062   ImprintMatchData *start_match;
05063   CubitStatus stat;
05064   
05065   for(ii = 0; ii < num_loops_1; ii++ )
05066   {
05067     prev_seg = surf_1_loop_heads[ii]->get_prev();
05068     first = CUBIT_TRUE;
05069     while(prev_seg != surf_1_loop_heads[ii]->get_prev() || first )
05070     {
05071       first = CUBIT_FALSE;
05072       curr_seg = prev_seg->get_next();
05073       if ( DEBUG_FLAG(129) )
05074       {
05075         draw_seg(curr_seg, CUBIT_GREEN_INDEX);
05076       }
05077         //Setup the next itteration.
05078       prev_seg = curr_seg;
05079         //Now on to the algorithm
05080         //Just check the start point for each segment (so that
05081         //we don't do each point more than once!
05082       start_point = curr_seg->get_start();
05083       if ( start_point->get_matching_point() != NULL )
05084         continue;
05085         //Get the match data.
05086       match_data_list.clean_out();
05087       start_point->get_match_list(match_data_list);
05088       if ( match_data_list.size() == 0 )
05089         start_match = NULL;
05090       else if ( match_data_list.size() == 1 )
05091         start_match = match_data_list.get();
05092       else
05093       {
05094         PRINT_ERROR("Unresolved match data in final match section.  This\n"
05095                     "is a bug!. Please report it.\n");
05096         return CUBIT_FAILURE;
05097       }
05098       if ( start_match )
05099       {
05100         CubitBoolean ignore = CUBIT_FALSE;
05101         if ( ignore_match(start_point, start_match, atree_1, ignore)
05102              != CUBIT_SUCCESS )
05103           return CUBIT_FAILURE;
05104         if ( ignore )
05105           continue;
05106         if ( start_match->get_closest_point() != NULL )
05107         {
05108           stat = match_on_point(start_point, start_match,
05109                                 surf_2_loop_heads, num_loops_2,
05110                                 atree_2);
05111           if ( stat != CUBIT_SUCCESS )
05112             return CUBIT_FAILURE;
05113         }
05114         else if ( start_match->get_point_on() != NULL )
05115         {
05116             //split the segment with start point and update
05117             //the loops heads for surf_2 if it is changed.
05118           stat = match_on_segment(start_point, start_match,
05119                                   surf_2_loop_heads, num_loops_2,
05120                                   atree_2);
05121           if ( stat != CUBIT_SUCCESS )
05122             return stat;
05123         }
05124         else
05125         {
05126             //There really can't be anything else at this point.  Either
05127             //it matches with a node, or it matches on a segment.
05128           PRINT_ERROR("Problems with point matching logic in imprinting.\n");
05129           PRINT_ERROR("MatchData found without closest point or segment.\n");
05130           PRINT_ERROR("Internal Imprint Problem, Please Report.\n");
05131           return CUBIT_FAILURE;
05132         }
05133       }
05134     }
05135   }
05136   return CUBIT_SUCCESS;
05137 }
05138 CubitStatus ImprintBoundaryTool::match_on_point( ImprintPointData *start_point,
05139                                                  ImprintMatchData *start_match,
05140                                                  ImprintLineSegment **loop_heads,
05141                                                  int num_loops,
05142                                                  AbstractTree <ImprintLineSegment*>& atree_2)
05143 {
05144     //This point matches with a point on the other boundary.  Find
05145     //the other point, and make sure that the other point, also
05146     //matches with start_point.  If it doesn't, it is that the tolerance
05147     //is big for the features and that we have points that match up
05148     //improperly.
05149   ImprintMatchData *temp_match;
05150   ImprintPointData *closest_point;
05151   DLIList <ImprintMatchData*> match_data_list;
05152   closest_point = start_match->get_closest_point();
05153   closest_point->get_match_list(match_data_list);
05154   if ( match_data_list.size() == 1 )
05155   {
05156     temp_match = match_data_list.get();
05157     if ( temp_match->get_closest_point() == start_point )
05158     {
05159         //Great.  We have a solid match.  Setup the data
05160         //structure.
05161       just_match_two_points(start_point, closest_point);
05162     }
05163     else
05164     {
05165         // start_point is point D.
05166         //Basically there can be one of two conditions.
05167         //1) A--------------------------------------B
05168         // C----------D------------------------------E
05169         //This condition, D is within tolerance of A, but
05170         //A's closest point is C.  To resolve this, we need
05171         //to match D with the segment A-B.
05172         //
05173         //2)                     
05174         //                          D
05175         //                         /
05176         //                        /
05177         //                      E-----------C-------
05178         //                    B----------A--------------F
05179         //For this condition, D matches with A, but A matches
05180         //with the  C.  This case we want to ignore.
05181 
05182       ImprintLineSegment *line_seg = temp_match->get_closest_seg();
05183       if ( line_seg == NULL )
05184       {
05185         PRINT_ERROR("Bad logic in ImprintBoundaryTool::match_point, bug...\n");
05186         assert(line_seg != NULL);
05187         return CUBIT_FAILURE;
05188       }
05189       ImprintPointData *point_D = start_point;
05190       //ImprintPointData *point_A = closest_point;
05191       ImprintPointData *point_C = temp_match->get_closest_point();
05192         //Find if D and C are on the same segment.  If they
05193         //are assume we have condition 1, else assume condition 2.
05194       ImprintLineSegment *prev_seg = line_seg->get_prev();
05195       ImprintLineSegment *next_seg = line_seg->get_next();
05196       CubitBoolean ignore = CUBIT_TRUE;
05197       if ( (point_D == prev_seg->get_start() ||
05198             point_D == prev_seg->get_end() ) &&
05199            (point_C == prev_seg->get_start() ||
05200             point_C == prev_seg->get_end() ) )
05201       {
05202         ignore = CUBIT_FALSE;
05203       }
05204       else if ((point_D == line_seg->get_start() ||
05205                 point_D == line_seg->get_end() ) &&
05206                (point_C == line_seg->get_start() ||
05207                 point_C == line_seg->get_end() ) )
05208       {
05209         ignore = CUBIT_FALSE;
05210       }
05211       else if ((point_D == next_seg->get_start() ||
05212                 point_D == next_seg->get_end() ) &&
05213                (point_C == next_seg->get_start() ||
05214                 point_C == next_seg->get_end() ) )
05215       {
05216         ignore = CUBIT_FALSE;
05217       }
05218 //      if ( ignore )
05219 //        start_point->set_unmatched();
05220       if ( !ignore )
05221       {
05222         line_seg = start_match->get_closest_seg();
05223         ImprintLineSegment *other_seg;
05224         if ( closest_point == line_seg->get_start() )
05225           other_seg = line_seg->get_prev();
05226         else
05227           other_seg = line_seg->get_next();
05228           //Find out which segment start_point is closest to.
05229         CubitVector close_1, close_2, start_v = start_point->coordinates();
05230         CubitBoolean on_line_seg = CUBIT_FALSE;
05231         CubitBoolean on_other_seg = CUBIT_FALSE;
05232         if ( closest_point_interior_seg(start_point,
05233                                         line_seg, close_1 ) )
05234         {
05235           if ( start_v.within_tolerance(close_1, myTolerance) )
05236             on_line_seg = CUBIT_TRUE;
05237         }
05238         if ( closest_point_interior_seg(start_point,
05239                                         other_seg, close_2 ) )
05240         {
05241           if ( start_v.within_tolerance(close_2, myTolerance) )
05242             on_other_seg = CUBIT_TRUE;
05243         }
05244         ImprintLineSegment *the_seg = NULL;
05245         CubitVector the_point;
05246         if ( on_line_seg && !on_other_seg )
05247         {
05248           the_seg = line_seg;
05249           the_point = close_1;
05250         }
05251         else if ( !on_line_seg && on_other_seg )
05252         {
05253           the_seg = other_seg;
05254           the_point = close_2;
05255         }
05256         else if ( on_line_seg && on_other_seg )
05257         {
05258           double dist_1 = (start_v-close_1).length_squared();
05259           double dist_2 = (start_v-close_2).length_squared();
05260           if ( dist_1 < dist_2 )
05261           {
05262             the_seg = line_seg;
05263             the_point = close_1;
05264           }
05265           else
05266           {
05267             the_seg = other_seg;
05268             the_point = close_2;
05269           }
05270         }
05271         if ( the_point.within_tolerance(closest_point->coordinates(),
05272                                         GEOMETRY_RESABS*500 ) )
05273         {
05274           PRINT_ERROR("The tolerance is too large for virtual imprinting\n"
05275                       "Surface %d and %d\n", refFacePtr1->id(),
05276                       refFacePtr2->id());
05277           return CUBIT_FAILURE;
05278         }
05279         start_match->set_closest_point(NULL);
05280         start_match->set_closest_seg(the_seg);
05281         start_match->set_point_on(the_point);
05282         return match_on_segment(start_point, start_match,
05283                                 loop_heads, num_loops,
05284                                 atree_2);
05285       }
05286     }
05287   }
05288   else
05289   {
05290     if ( match_data_list.size() == 0 )
05291       return CUBIT_SUCCESS;
05292     else
05293     {
05294       PRINT_ERROR("More than one match in final match(%d).\n",match_data_list.size() );
05295       PRINT_ERROR("This is a bug in virtual imprinting, try reducing\n"
05296                   "the tolerance.\n");
05297       return CUBIT_FAILURE;
05298     }
05299   }
05300   return CUBIT_SUCCESS;
05301 }
05302 
05303 CubitStatus ImprintBoundaryTool::match_on_segment( ImprintPointData *start_point,
05304                                                    ImprintMatchData *start_match,
05305                                                    ImprintLineSegment **loop_heads,
05306                                                    int num_loops,
05307                                                    AbstractTree <ImprintLineSegment*>& atree_2)
05308 {
05309     //Closest point is on a segment on the other boundary.
05310     //Split that segment at the closest point.
05311     //Adjust the data...
05312   ImprintLineSegment *new_seg_1,*new_seg_2;
05313   
05314   ImprintLineSegment* closest_seg = start_match->get_closest_seg();
05315   CubitVector closest_vec(*(start_match->get_point_on()));
05316   ImprintPointData *new_point = new ImprintPointData(start_point,
05317                                                      closest_vec);
05318   allocatedPointData->append(new_point);
05319   new_point->owner(closest_seg->owner());
05320   if ( start_point->is_owner_vertex() )
05321   {
05322     new_point->set_point_type(CREATE_NEW_VERTEX);
05323     if ( start_point->get_point_type() != CREATE_NEW_VERTEX )
05324       start_point->set_point_type(VERTEX_ON_BOTH_BOUNDARIES);
05325   }
05326   else
05327   {
05328     new_point->set_point_type(ON_BOTH_BOUNDARIES);
05329     start_point->set_point_type(ON_BOTH_BOUNDARIES);
05330   }
05331 
05332   new_seg_1 = new ImprintLineSegment( closest_seg->get_start(),
05333                                       new_point,
05334                                       closest_seg->owner());
05335   new_seg_2 = new ImprintLineSegment( new_point,
05336                                       closest_seg->get_end(),
05337                                       closest_seg->owner());
05338   allocatedLineData->append(new_seg_1);
05339   allocatedLineData->append(new_seg_2);
05340     //update the linked list structure to leave out the closest_seg
05341     //but include the new segs instead.
05342   update_linked_list(closest_seg, new_seg_1, new_seg_2);
05343     //update the ImprintMatchData that reference the closest_seg
05344     //to reference new_seg_1 or new_seg_2.
05345   CubitStatus stat = update_seg_matches(closest_seg, new_seg_1, new_seg_2, start_match);
05346   if ( stat != CUBIT_SUCCESS )
05347     return stat;
05348   closest_seg->set_inactive(CUBIT_TRUE);
05349   int jj;
05350   for (jj = 0; jj < num_loops; jj++ )
05351   {
05352     if ( loop_heads[jj] == closest_seg )
05353       loop_heads[jj] = new_seg_1;
05354   }
05355     //update the atree.
05356   atree_2.remove(closest_seg);
05357   atree_2.add(new_seg_1);
05358   atree_2.add(new_seg_2);
05359   return CUBIT_SUCCESS;
05360 
05361 }
05362 
05363 CubitStatus ImprintBoundaryTool::update_seg_matches(ImprintLineSegment *old_seg,
05364                                                     ImprintLineSegment *new_seg_1,
05365                                                     ImprintLineSegment *new_seg_2,
05366                                                     ImprintMatchData *curr_match_data)
05367 {
05368   DLIList <ImprintMatchData*> seg_match_data;
05369   old_seg->get_match_data(seg_match_data);
05370   if ( seg_match_data.size() == 0 )
05371     return CUBIT_SUCCESS;
05372     //get the equation of the line.
05373   CubitVector split_coord = new_seg_1->get_end()->coordinates();
05374   CubitVector start_v = old_seg->get_start()->coordinates();
05375   CubitVector end_v = old_seg->get_end()->coordinates();
05376   CubitVector diff_end_start = end_v - start_v;
05377   double dot1 = diff_end_start%diff_end_start;
05378   if ( dot1 > -CUBIT_RESABS && dot1 < CUBIT_RESABS )
05379   {
05380       //This is bad.  It means that the start and end
05381       //vectors are really close together.
05382     PRINT_ERROR("Segment used for imprinting is corrupted.\n");
05383     PRINT_ERROR("Internal Imprint Problem, Please Report.\n");
05384     return CUBIT_FAILURE;
05385   }
05386   CubitVector diff_split_start = split_coord - start_v;
05387   double split_t = (diff_split_start%diff_end_start)/dot1;
05388   
05389   int ii;
05390   ImprintMatchData *match_data;
05391   CubitVector *closest_point, diff_curr_start, temp_v;
05392   double curr_t;
05393   for ( ii = seg_match_data.size(); ii > 0; ii-- )
05394   {
05395     match_data = seg_match_data.get_and_step();
05396     if ( match_data == curr_match_data )
05397       continue;
05398     closest_point = match_data->get_point_on();
05399     if (closest_point == NULL )
05400     {
05401       temp_v = match_data->get_closest_point()->coordinates();
05402       closest_point = &temp_v;
05403     }
05404       //Find the parametric position on the old_seg for this
05405       //point.
05406     diff_curr_start = (*closest_point) - start_v;
05407     curr_t = (diff_curr_start%diff_end_start)/dot1;
05408     if ( curr_t < split_t )
05409     {
05410       match_data->set_closest_seg(new_seg_1);
05411       new_seg_1->add_match_data(match_data);
05412     }
05413     else if (curr_t > split_t )
05414     {
05415       match_data->set_closest_seg(new_seg_2);
05416       new_seg_2->add_match_data(match_data);
05417     }
05418     else
05419     {
05420         //hmm two match datas at the same point.  That is
05421         //an error.
05422       PRINT_ERROR("Bad logic in match data.\n");
05423       PRINT_ERROR("Internal Imprint Problem, Please Report.\n");
05424       return CUBIT_FAILURE;
05425     }
05426   }
05427   return CUBIT_SUCCESS;
05428 }
05429   
05430 void ImprintBoundaryTool::update_linked_list(ImprintLineSegment *old_seg,
05431                                              ImprintLineSegment *new_seg_1,
05432                                              ImprintLineSegment *new_seg_2 )
05433 {
05434   new_seg_1->set_prev(old_seg->get_prev());
05435   old_seg->get_prev()->set_next(new_seg_1);
05436   new_seg_1->set_next(new_seg_2);
05437   new_seg_2->set_prev(new_seg_1);
05438   new_seg_2->set_next(old_seg->get_next());
05439   old_seg->get_next()->set_prev(new_seg_2);
05440 }
05441 
05442 void ImprintBoundaryTool::just_match_two_points(ImprintPointData *point_1,
05443                                                 ImprintPointData *point_2 )
05444 {
05445     //Okay, we need to match up point_2 and
05446     //point_1.          
05447     //Set the actual matching point for the imprinting
05448     //algorithm
05449   point_1->set_matching_point(point_2);
05450   point_2->set_matching_point(point_1);
05451     //Clear out the possible match lists.
05452   if ( point_1->id() == 681 ||
05453        point_1->id() == 150 )
05454   {
05455     int temp = 0;
05456     temp++;
05457   }
05458   if ( point_1->is_owner_vertex() &&
05459        !point_2->is_owner_vertex() )
05460   {
05461     point_1->set_point_type(VERTEX_ON_BOTH_BOUNDARIES);
05462     point_2->set_point_type(CREATE_NEW_VERTEX);
05463   }
05464   else if(!point_1->is_owner_vertex() &&
05465           point_2->is_owner_vertex() )
05466   {
05467     point_1->set_point_type(CREATE_NEW_VERTEX);
05468     point_2->set_point_type(VERTEX_ON_BOTH_BOUNDARIES);
05469   }
05470   else if ( point_1->is_owner_vertex() &&
05471             point_2->is_owner_vertex() )
05472   {
05473     point_1->set_point_type(VERTEX_ON_BOTH_BOUNDARIES);
05474     point_2->set_point_type(VERTEX_ON_BOTH_BOUNDARIES);
05475   }
05476   else // Both aren't vertices...
05477   {
05478     point_1->set_point_type(ON_BOTH_BOUNDARIES);
05479     point_2->set_point_type(ON_BOTH_BOUNDARIES);
05480   }
05481 }
05482 CubitStatus ImprintBoundaryTool::find_crossings( ImprintLineSegment **surf_1_loop_heads,
05483                                                  int num_loops_1,
05484                                                  ImprintLineSegment **surf_2_loop_heads,
05485                                                  int num_loops_2,
05486                                                  AbstractTree <ImprintLineSegment*>& atree )
05487 {
05488   int ii, jj;
05489   ImprintLineSegment *curr_seg, *prev_seg, *test_seg;
05490   DLIList <ImprintLineSegment*> close_segments;
05491   CubitBoolean first = CUBIT_TRUE;
05492   CubitBox curr_box;
05493   ImprintPointData *imp_point_0, *imp_point_1;
05494   ImprintPointData *imp_point_2, *imp_point_3;
05495   
05496   for(ii = 0; ii < num_loops_1; ii++ )
05497   {
05498     prev_seg = surf_1_loop_heads[ii]->get_prev();
05499     first = CUBIT_TRUE;
05500     while(prev_seg != surf_1_loop_heads[ii]->get_prev() || first )
05501     {
05502       first = CUBIT_FALSE;
05503       curr_seg = prev_seg->get_next();
05504       if ( DEBUG_FLAG(129) )
05505       {
05506         draw_seg(curr_seg, CUBIT_GREEN_INDEX);
05507       }
05508         //Setup the next itteration.
05509       prev_seg = curr_seg;
05510       curr_box = curr_seg->bounding_box();
05511       close_segments.clean_out();
05512       atree.find(curr_box, close_segments);
05513       imp_point_0 = curr_seg->get_start();
05514       imp_point_1 = curr_seg->get_end();
05515       for ( jj = 0; jj < close_segments.size(); jj++ )
05516       {
05517         test_seg = close_segments.pop();
05518         imp_point_2 = test_seg->get_start();
05519         imp_point_3 = test_seg->get_end();
05520           //don't test if these already match.
05521         if ( imp_point_0->get_matching_point() == imp_point_2 ||
05522              imp_point_0->get_matching_point() == imp_point_3 ||
05523              imp_point_1->get_matching_point() == imp_point_2 ||
05524              imp_point_1->get_matching_point() == imp_point_3 )
05525           continue;
05526         CubitBoolean modified = CUBIT_FALSE;
05527           //Test and resolve.  Note that only one of the atrees
05528           //is getting updated (this atree is for surface 2.  )
05529           //The loop heads are updated, and curr_seg will
05530           //get modified if the a crossing intersect occurs.
05531         CubitStatus stat = do_crossing( imp_point_0, imp_point_1,
05532                                         imp_point_2, imp_point_3,
05533                                         curr_seg, test_seg,
05534                                         surf_1_loop_heads, num_loops_1,
05535                                         surf_2_loop_heads, num_loops_2,
05536                                         atree, modified );
05537         if ( stat != CUBIT_SUCCESS )
05538           return CUBIT_FAILURE;
05539         if ( modified )
05540         {
05541             //curr_seg was modified in the do_crossing (the original
05542             //was split.).  Make sure we start again to check for
05543             //crossings with this item.  To do that, set prev seg
05544             //to it's previous segment.  The result is that the next
05545             //time through it will be curr_seg.
05546           prev_seg = curr_seg->get_prev();
05547         }
05548       }
05549     }
05550   }
05551   return CUBIT_SUCCESS;
05552 }
05553 CubitStatus ImprintBoundaryTool::do_crossing( ImprintPointData *imp_point_0,
05554                                               ImprintPointData *imp_point_1,
05555                                               ImprintPointData *imp_point_2,
05556                                               ImprintPointData *imp_point_3,
05557                                               ImprintLineSegment *&seg_1,
05558                                               ImprintLineSegment *seg_2,
05559                                               ImprintLineSegment **surf_1_loop_heads,
05560                                               int num_loops_1,
05561                                               ImprintLineSegment **surf_2_loop_heads,
05562                                               int num_loops_2,
05563                                               AbstractTree <ImprintLineSegment*>& atree,
05564                                               CubitBoolean &modified)
05565 {
05566                                               
05567     //Okay, Test for the cross intersection.  If this isnt'
05568     //within tolerance, then these two segments couldn't
05569     //posibly intersect!
05570   IntersectionTool int_tool(GEOMETRY_RESABS); //use GEOMETRY_RESABS
05571     //rather than myTolerance for calculations...
05572   CubitVector point_0 = imp_point_0->coordinates();
05573   CubitVector point_1 = imp_point_1->coordinates();
05574   CubitVector point_2 = imp_point_2->coordinates();
05575   CubitVector point_3 = imp_point_3->coordinates();
05576   CubitVector closest_point_seg_1, closest_point_seg_2;
05577   double sc, tc;
05578   CubitStatus stat = int_tool.closest_points_on_segments(point_0, point_1,
05579                                                          point_2, point_3,
05580                                                          closest_point_seg_1,
05581                                                          closest_point_seg_2,
05582                                                          sc, tc);
05583   if (stat != CUBIT_SUCCESS )
05584   {
05585     PRINT_ERROR("Problems calculation closest points on "
05586                 "segments for boundary imprinting.\n");
05587     return CUBIT_FAILURE;
05588   }
05589     //Make sure the closest points aren't the end points.  If they are
05590     //and we are within tolerance, it may be that the tolerance is too big
05591     //cause we shouldn't be at a cross if the closest point is an end point...
05592   if ( sc > 0. && sc < 1. && tc > 0. && tc < 1. &&
05593        closest_point_seg_1.within_tolerance(closest_point_seg_2,myTolerance) )
05594   {
05595     ImprintLineSegment *new_segments[4];
05596       //okay, these guys actually do intersect!
05597     PRINT_DEBUG_129("Found CROSS_INTERSECT\n");
05598     int debug = 0;
05599     if ( debug )
05600     {
05601       GfxDebug::clear();
05602       draw_point(imp_point_0);
05603       draw_point(imp_point_1);
05604       draw_point(imp_point_2);
05605       draw_point(imp_point_3);
05606       draw_seg(seg_1, CUBIT_RED_INDEX);
05607       draw_seg(seg_2, CUBIT_YELLOW_INDEX);
05608       GfxDebug::mouse_xforms();
05609     }
05610     ImprintPointData *new_point_seg_1, *new_point_seg_2;
05611     new_point_seg_1 = new ImprintPointData(closest_point_seg_1.x(),
05612                                            closest_point_seg_1.y(),
05613                                            closest_point_seg_1.z());
05614     allocatedPointData->append(new_point_seg_1);
05615     new_point_seg_1->owner(seg_1->owner());
05616     new_point_seg_1->set_point_type(CREATE_NEW_VERTEX);
05617     new_point_seg_2 = new ImprintPointData(closest_point_seg_2.x(),
05618                                            closest_point_seg_2.y(),
05619                                            closest_point_seg_2.z());
05620     allocatedPointData->append(new_point_seg_2);
05621     new_point_seg_2->owner(seg_2->owner());
05622     new_point_seg_2->set_point_type(CREATE_NEW_VERTEX);
05623 
05624     new_point_seg_2->set_matching_point(new_point_seg_1);
05625     new_point_seg_1->set_matching_point(new_point_seg_2);
05626     
05627     new_segments[0] = new ImprintLineSegment(imp_point_0, new_point_seg_1,
05628                                              seg_1->owner());
05629     new_segments[1] = new ImprintLineSegment(new_point_seg_1, imp_point_1,
05630                                              seg_1->owner());
05631     new_segments[2] = new ImprintLineSegment(imp_point_2, new_point_seg_2,
05632                                              seg_2->owner());
05633     new_segments[3] = new ImprintLineSegment(new_point_seg_2, imp_point_3,
05634                                              seg_2->owner());
05635     allocatedLineData->append(new_segments[0]);
05636     allocatedLineData->append(new_segments[1]);
05637     allocatedLineData->append(new_segments[2]);
05638     allocatedLineData->append(new_segments[3]);
05639       //now update the lists.
05640       //update list 1.
05641     update_list(new_segments, seg_1, seg_2, CUBIT_TRUE);
05642       //update list 2.
05643     update_list(new_segments, seg_1, seg_2, CUBIT_FALSE);
05644       //seg_1 and seg_2 will no longer be used
05645     seg_1->set_inactive(CUBIT_TRUE);
05646     seg_2->set_inactive(CUBIT_TRUE);
05647       //update the atree for the second surface.
05648     atree.remove(seg_2);
05649     atree.add(new_segments[2]);
05650     atree.add(new_segments[3]);
05651       //update the loop heads
05652     int jj;
05653     for (jj = 0; jj < num_loops_1;jj++ )
05654     {
05655       if ( surf_1_loop_heads[jj] == seg_1 )
05656         surf_1_loop_heads[jj] = new_segments[0];
05657     }
05658     for (jj = 0; jj < num_loops_2;jj++ )
05659     {
05660       if ( surf_2_loop_heads[jj] == seg_2 )
05661         surf_2_loop_heads[jj] = new_segments[2];
05662     }
05663       //now set seg_1 equal to new_segments[0]
05664       //so that we continue looping properly.
05665     seg_1 = new_segments[0];
05666     modified = CUBIT_TRUE;
05667   }
05668   
05669   return CUBIT_SUCCESS;
05670 }
05671 void ImprintBoundaryTool::update_boundary_loops( PointLoopList &boundary_loops,
05672                                                  ImprintLineSegment **surf_loop_heads)
05673 {
05674   int ii;
05675   PointList *point_loop;
05676   ImprintLineSegment *prev_seg, *seg;
05677   
05678   CubitBoolean first = CUBIT_TRUE;
05679   boundary_loops.reset();
05680   for ( ii = 0; ii < boundary_loops.size(); ii++ )
05681   {
05682     point_loop = boundary_loops.get_and_step();
05683     point_loop->clean_out();
05684       //now from the linked list get the line loop.
05685     prev_seg = surf_loop_heads[ii]->get_prev();
05686     first = CUBIT_TRUE;
05687     while( prev_seg != surf_loop_heads[ii]->get_prev() || first )
05688     {
05689       first = CUBIT_FALSE;
05690       seg = prev_seg->get_next();
05691       point_loop->append(seg->get_end());
05692       if ( DEBUG_FLAG(129) )
05693         draw_end(seg);
05694       prev_seg = seg;
05695     }
05696   }
05697 }
05698 
05699 CubitStatus ImprintBoundaryTool::ignore_match( ImprintPointData *start_point,
05700                                                ImprintMatchData *start_match,
05701                                                AbstractTree <ImprintLineSegment*>& atree_1,
05702                                                CubitBoolean &ignore)
05703 {
05704   ignore = CUBIT_TRUE;
05705     //assume that start_point is in atree_1 (here 1 and 2 don't neccesaryily mean
05706     //loopFacePtr1 and loopFacePtr2 because this is called for both faces.
05707 
05708     //First determine what type of match, point to point or point to segment.
05709   if ( start_match->get_closest_point() != NULL )
05710   {
05711      ImprintMatchData *temp_match;
05712      ImprintPointData *closest_point;
05713      DLIList <ImprintMatchData*> match_data_list;
05714      closest_point = start_match->get_closest_point();
05715      closest_point->get_match_list(match_data_list);
05716      if ( match_data_list.size() == 1 )
05717      {
05718        temp_match = match_data_list.get();
05719          //if they match don't ignore this.
05720        if ( temp_match->get_closest_point() == start_point )
05721        {
05722          ignore = CUBIT_FALSE;
05723          return CUBIT_SUCCESS;
05724        }
05725        else
05726        {
05727            //Now we have a conflict.  Start matches with closest_point,
05728            //but closest_point doesn't match with start.
05729 
05730            //Find out if there is a segment in atree_1 that is closer
05731            //to closest_point.  If there isn't, then we need to
05732            //match start with one of the two linesegments attached to closest
05733            //point.
05734            //If there is a closer line segment to closest_point, then don't
05735            //match.
05736 
05737            //First, define the search area as the area around the start_point.
05738          ImprintLineSegment *start_prev_seg = start_point->get_prev_seg();
05739          ImprintLineSegment *start_next_seg = start_point->get_next_seg();
05740          CubitBox curr_box = start_prev_seg->bounding_box();
05741          curr_box |= start_next_seg->bounding_box();
05742          DLIList<ImprintLineSegment*> closest_segments;
05743          atree_1.find(curr_box, closest_segments);
05744            //Find the segment that is closest to closest_point.
05745          ImprintLineSegment *closest_seg = NULL, *close_seg;
05746          double dist;
05747          double min_dist = CUBIT_DBL_MAX;
05748          int ii;
05749          CubitVector closest_vec, closest_point_vec = closest_point->coordinates();
05750          for ( ii = closest_segments.size(); ii > 0; ii-- )
05751          {
05752            close_seg = closest_segments.pop();
05753            if ( !closest_point_seg(closest_point, close_seg,
05754                                    closest_vec) )
05755              return CUBIT_FAILURE;
05756            dist = (closest_vec - closest_point_vec).length_squared();
05757            if ( dist < min_dist )
05758            {
05759              min_dist = dist;
05760              closest_seg = close_seg;
05761            }
05762          }
05763          if ( closest_seg == NULL )
05764          {
05765            PRINT_ERROR("Couldn't find a closest segment.(bug)\n");
05766            assert(closest_seg != NULL);
05767            return CUBIT_FAILURE;
05768          }
05769          if ( closest_seg != start_prev_seg ||
05770               closest_seg != start_next_seg )
05771          {
05772              //okay this we need to ignore.  Just say start point doesn't match with anything.
05773            start_point->set_unmatched();
05774            start_point->set_matching_point(NULL);
05775            ignore = CUBIT_TRUE;
05776            return CUBIT_SUCCESS;
05777          }
05778          else
05779          {
05780              //okay, now we actually want to match start point with one of the segments
05781              //attached to closest_point.
05782            ImprintLineSegment *next_close_seg, *prev_close_seg;
05783            next_close_seg = closest_point->get_next_seg();
05784            prev_close_seg = closest_point->get_prev_seg();
05785              //determine which is closer...
05786            CubitVector closest_next, closest_prev, start_vec = start_point->coordinates();
05787            if ( !closest_point_seg(start_point, next_close_seg,
05788                                    closest_next) )
05789              return CUBIT_FAILURE;
05790            if ( !closest_point_seg(start_point, prev_close_seg,
05791                                    closest_prev) )
05792              return CUBIT_FAILURE;
05793            double dist_prev, dist_next;
05794            CubitVector point_on;
05795            dist_next = (start_vec - closest_next).length_squared();
05796            dist_prev = (start_vec - closest_prev).length_squared();
05797            closest_seg = NULL;
05798            if ( dist_next < dist_prev )
05799            {
05800              closest_seg = next_close_seg;
05801              min_dist = dist_next;
05802              point_on = closest_next;
05803            }
05804            else
05805            {
05806              closest_seg = prev_close_seg;
05807              min_dist = dist_prev;
05808              point_on = closest_prev;
05809            }
05810 
05811             //make sure the point_on isn't the same location as the closest_point.
05812            CubitVector closest_point_vec = closest_point->coordinates();
05813            if ( closest_point_vec.within_tolerance(point_on, myTolerance/10.0) )
05814            {
05815              ignore = CUBIT_TRUE;
05816              start_point->set_unmatched();
05817              start_point->set_matching_point(NULL);
05818              return CUBIT_SUCCESS;
05819            }
05820              //make sure point_on and start point are within tolerances.
05821            dist = (point_on - start_vec).length_squared();
05822            if ( dist > myTolerance*myTolerance )
05823            {
05824              PRINT_ERROR("Bad logic in ignore_match in ImprintImprintTool.\n");
05825              assert(dist <= myTolerance*myTolerance);
05826              return CUBIT_FAILURE;
05827            }
05828            start_match->set_closest_point(NULL);
05829            start_point->set_matching_point(NULL);
05830            start_match->set_closest_dist(min_dist);
05831            start_match->set_point_on(point_on);
05832            start_match->set_closest_seg(closest_seg);
05833            ignore = CUBIT_FALSE;
05834            return CUBIT_SUCCESS;
05835          }
05836        }
05837      }
05838      else
05839      {
05840        if ( match_data_list.size() == 0 )
05841        {
05842          ignore = CUBIT_TRUE;
05843          return CUBIT_SUCCESS;
05844        }
05845        else
05846        {
05847          PRINT_ERROR("More than one match in final match(%d).\n",match_data_list.size() );
05848          PRINT_ERROR("This is a bug in loop imprinting, try reducing\n"
05849                      "the size for decomposition.\n");
05850          return CUBIT_FAILURE;
05851        }
05852      }
05853   }
05854   else if ( start_match->get_point_on() != NULL )
05855   {
05856     if ( start_point->get_matching_point() )
05857     {
05858       ImprintPointData *closest_point = start_point->get_matching_point();
05859       if ( closest_point->get_matching_point() == start_point )
05860       {
05861         ignore = CUBIT_TRUE;
05862         return CUBIT_SUCCESS;
05863       }
05864     }
05865       //this must mean we match on a segment.
05866 
05867       //Determine if there is a segment on 1, that is closer to this
05868       //point than start_point is.  If there is, ignore this match.
05869     CubitVector point_on;
05870     point_on.set(*(start_match->get_point_on()));
05871     ImprintLineSegment *start_prev_seg = start_point->get_prev_seg();
05872     ImprintLineSegment *start_next_seg = start_point->get_next_seg();
05873     CubitBox curr_box = start_prev_seg->bounding_box();
05874     curr_box |= start_next_seg->bounding_box();
05875     DLIList<ImprintLineSegment*> closest_segments;
05876     atree_1.find(curr_box, closest_segments);
05877       //Find the segment that is closest to closest_point.
05878     ImprintLineSegment *closest_seg = NULL, *close_seg;
05879     double dist;
05880     double min_dist = CUBIT_DBL_MAX;
05881     int ii;
05882     //dflush();
05883     CubitVector closest_vec;
05884     //CubitVector start_vec = start_point->coordinates();
05885    // dclear();
05886    // dseg(start_prev_seg);
05887    // dseg(start_next_seg);
05888     //dvec(point_on);
05889     //dmouse();
05890     for ( ii = closest_segments.size(); ii > 0; ii-- )
05891     {
05892       close_seg = closest_segments.pop();
05893       if ( !closest_point_seg(point_on, close_seg,
05894                               closest_vec) )
05895         return CUBIT_FAILURE;
05896       dist = (closest_vec - point_on).length_squared();
05897       if ( dist < min_dist )
05898       {
05899         min_dist = dist;
05900         closest_seg = close_seg;
05901       }
05902     }
05903     if ( closest_seg == NULL )
05904     {
05905       PRINT_ERROR("Couldn't find a closest segment.(bug)\n");
05906       assert(closest_seg != NULL);
05907       return CUBIT_FAILURE;
05908     }
05909     if ( closest_seg == start_prev_seg ||
05910          closest_seg == start_next_seg )
05911     {
05912       ignore = CUBIT_FALSE;
05913       return CUBIT_SUCCESS;
05914     }
05915     else
05916     {
05917       ignore = CUBIT_TRUE;
05918       start_point->set_unmatched();
05919       start_point->set_matching_point(NULL);
05920       return CUBIT_SUCCESS;
05921     }
05922     
05923   }
05924   
05925   return CUBIT_FAILURE;
05926 }
05927 
05928 //---------------------------------------------------------------------
05929 // Private Function: create_virtual_vertex
05930 // Creates a facet based vertex.
05931 //---------------------------------------------------------------------
05932 RefVertex* ImprintBoundaryTool::create_virtual_vertex(CubitVector &pos)
05933 {
05934     //Create a facet point first.
05935   TBPoint *new_point;
05936   if ( FacetModifyEngine::instance()->make_facet_point(pos, new_point)
05937        != CUBIT_SUCCESS )
05938   {
05939     PRINT_ERROR("Vertex creation failed.\n");
05940     return (RefVertex*)NULL;
05941   }
05942   
05943   return GeometryQueryTool::instance()->make_free_RefVertex(new_point);
05944 }
05945 //---------------------------------------------------------------------
05946 // Private Function: create_virtual_edge
05947 // Creates a facet based vertex.
05948 //---------------------------------------------------------------------
05949 RefEdge* ImprintBoundaryTool::create_virtual_edge(RefVertex *start,
05950                                                   RefVertex *end,
05951                                                   DLIList<CubitVector*> &interior_points)
05952 {
05953     //Create CubitPoints for all of these locations.
05954   DLIList<CubitPoint*> point_list;
05955   CubitPoint *start_p = (CubitPoint*) new CubitPointData(start->coordinates());
05956   CubitPoint *end_p = (CubitPoint*) new CubitPointData(end->coordinates());
05957   CubitPoint *new_point, *prev_point;
05958   int ii;
05959   CubitVector *curr_pos;
05960   interior_points.reset();
05961   CubitFacetEdge *new_edge;
05962   prev_point = start_p;
05963   DLIList<CubitFacetEdge*> edge_list;
05964   point_list.append(start_p);
05965   for ( ii = 0; ii < interior_points.size(); ii++ )
05966   {
05967     curr_pos = interior_points.get_and_step();
05968     new_point = (CubitPoint*) new CubitPointData(*curr_pos);
05969     point_list.append(new_point);
05970     new_edge = (CubitFacetEdge*) new CubitFacetEdgeData(prev_point,
05971                                                         new_point);
05972     edge_list.append(new_edge);
05973     prev_point = new_point;
05974   }
05975     //create the last edge.
05976   new_edge = (CubitFacetEdge*) new CubitFacetEdgeData(prev_point,
05977                                                       end_p);
05978   point_list.append(end_p);
05979   edge_list.append(new_edge);
05980   CurveFacetEvalTool *curve_facet_tool = new CurveFacetEvalTool;
05981   CubitStatus status = curve_facet_tool->initialize( edge_list, point_list );
05982   if ( status != CUBIT_SUCCESS )
05983   {
05984       PRINT_ERROR("Error in creating new facet curve.\n");
05985       return NULL;
05986   }
05987 
05988   bool start_vertex_is_free = true;
05989   if( start->num_parent_ref_entities() )
05990     start_vertex_is_free = false;
05991 
05992   bool end_vertex_is_free = true;
05993   if( end->num_parent_ref_entities() )
05994     end_vertex_is_free = false;
05995 
05996   DLIList<CoEdgeSM*> coedgesms;
05997   GeometryEntity *ge = start->get_geometry_entity_ptr();
05998   TBPoint *start_psm = CAST_TO(ge, TBPoint);
05999   ge = end->get_geometry_entity_ptr();
06000   TBPoint *end_psm = CAST_TO(ge, TBPoint);
06001   assert(start_psm && end_psm);
06002   FacetCurve *new_facet_curve = new FacetCurve(curve_facet_tool,
06003                                                start_psm,
06004                                                end_psm, coedgesms);
06005   if ( new_facet_curve == NULL )
06006   {
06007     PRINT_ERROR("Error in creating new facet curve.\n");
06008     assert(new_facet_curve != NULL);
06009     return (RefEdge*)NULL;
06010   }
06011   
06012   //if vertices are consumed....notify that they are gone.
06013   if( start_vertex_is_free )
06014     AppUtil::instance()->send_event(GeometryEvent(GeometryEvent::TOP_LEVEL_ENTITY_DESTRUCTED, start) );
06015   if( end_vertex_is_free )
06016     AppUtil::instance()->send_event(GeometryEvent(GeometryEvent::TOP_LEVEL_ENTITY_DESTRUCTED, end));
06017   
06018   Curve *new_curve_ptr = (Curve*) new_facet_curve;
06019   return GeometryQueryTool::instance()->make_RefEdge(new_curve_ptr);
06020 }
06021 
06022 
06023   
06024   
06025   
06026 
06027   
06028   
06029                                                        
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines