cgma
|
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