cgma
|
00001 //- Class: ChollaEngine 00002 //- Description: Creates the topology for a given geometry described by facets. 00003 //- Owner: Steven J. Owen 00004 //- Checked by: 00005 //- Version: 00006 //#include <list> 00007 #include <set> 00008 #include <map> 00009 #include <vector> 00010 #include "CubitDefines.h" 00011 #include "ChollaEngine.hpp" 00012 #include "DLIList.hpp" 00013 #include "TDGeomFacet.hpp" 00014 #include "CastTo.hpp" 00015 #include "ChollaSkinTool.hpp" 00016 #include "ChollaVolume.hpp" 00017 #include "ChollaSurface.hpp" 00018 #include "ChollaCurve.hpp" 00019 #include "ChollaPoint.hpp" 00020 #include "CubitFacet.hpp" 00021 #include "CubitFacetData.hpp" 00022 #include "CubitFacetEdge.hpp" 00023 #include "CubitFacetEdgeData.hpp" 00024 #include "CubitPoint.hpp" 00025 #include "CubitPointData.hpp" 00026 #include "FacetEntity.hpp" 00027 #include "FacetEvalTool.hpp" 00028 #include "FacetDataUtil.hpp" 00029 #include "ChollaDebug.hpp" 00030 #include "TDFacetBoundaryEdge.hpp" 00031 #include "TDFacetBoundaryPoint.hpp" 00032 #include "CurveFacetEvalTool.hpp" 00033 #include "Cholla.h" 00034 #include "GfxDebug.hpp" 00035 #include "TDFacetboolData.hpp" 00036 #include "GMem.hpp" 00037 00038 //============================================================================ 00039 //Function: ChollaEngine (PUBLIC) (constructor) 00040 //============================================================================ 00041 ChollaEngine::ChollaEngine() 00042 { 00043 hashCurveArray = NULL; 00044 hashCurveSize = 0; 00045 hashPointArray = NULL; 00046 hashPointSize = 0; 00047 } 00048 00049 //============================================================================ 00050 //Function: ChollaEngine (PUBLIC) (constructor) 00051 //============================================================================ 00052 ChollaEngine::ChollaEngine(DLIList<FacetEntity*> &face_list, 00053 DLIList<FacetEntity*> &edge_list, 00054 DLIList<FacetEntity*> &point_list ) 00055 { 00056 faceList = face_list; 00057 edgeList = edge_list; 00058 pointList = point_list; 00059 set_up_tool_datas(); 00060 hashCurveArray = NULL; 00061 hashCurveSize = 0; 00062 hashPointArray = NULL; 00063 hashPointSize = 0; 00064 doFlip = CUBIT_FALSE; 00065 } 00066 00067 //============================================================================ 00068 //Function: ChollaEngine (PUBLIC) (constructor) 00069 //============================================================================ 00070 ChollaEngine::ChollaEngine(DLIList<CubitFacet*> &facet_list, 00071 DLIList<CubitFacetEdge*> &edge_list, 00072 DLIList<CubitPoint*> &point_list ) 00073 { 00074 CAST_LIST(facet_list, faceList, FacetEntity); 00075 CAST_LIST(edge_list, edgeList, FacetEntity); 00076 CAST_LIST(point_list, pointList, FacetEntity); 00077 set_up_tool_datas(); 00078 hashCurveArray = NULL; 00079 hashCurveSize = 0; 00080 hashPointArray = NULL; 00081 hashPointSize = 0; 00082 doFlip = CUBIT_FALSE; 00083 } 00084 00085 //============================================================================ 00086 //Function: ChollaEngine (PUBLIC) (constructor) 00087 //Notes: This case is used only when the cholla entities have been generated 00088 // directly rather than using create_geometry 00089 // Does not use the TDGeomFacet Tooldatas 00090 //============================================================================ 00091 ChollaEngine::ChollaEngine(DLIList<CubitFacet*> &facet_list, 00092 DLIList<CubitFacetEdge*> &edge_list, 00093 DLIList<CubitPoint*> &point_list, 00094 DLIList<ChollaVolume *> &cholla_volumes, 00095 DLIList<ChollaSurface *> &cholla_surfaces, 00096 DLIList<ChollaCurve *> &cholla_curves, 00097 DLIList<ChollaPoint *> &cholla_points ) 00098 { 00099 CAST_LIST(facet_list, faceList, FacetEntity); 00100 CAST_LIST(edge_list, edgeList, FacetEntity); 00101 CAST_LIST(point_list, pointList, FacetEntity); 00102 //set_up_tool_datas(); TDGeomFacet tooldatas should have already been added 00103 00104 hashCurveArray = NULL; 00105 hashCurveSize = 0; 00106 hashPointArray = NULL; 00107 hashPointSize = 0; 00108 doFlip = CUBIT_FALSE; 00109 00110 chollaVolumeList = cholla_volumes; 00111 chollaSurfaceList = cholla_surfaces; 00112 chollaCurveList = cholla_curves; 00113 chollaPointList = cholla_points; 00114 } 00115 00116 00117 //============================================================================ 00118 //Function: set_up_tool_datas 00119 //============================================================================ 00120 void ChollaEngine::set_up_tool_datas( ) 00121 { 00122 int ii; 00123 FacetEntity *fe_ptr; 00124 for (ii=0; ii<faceList.size(); ii++) 00125 { 00126 fe_ptr = faceList.get_and_step(); 00127 TDGeomFacet::add_geom_facet( fe_ptr, -1 ); 00128 } 00129 for (ii=0; ii<pointList.size(); ii++) 00130 { 00131 fe_ptr = pointList.get_and_step(); 00132 TDGeomFacet::add_geom_facet( fe_ptr, -1 ); 00133 } 00134 } 00135 00136 CubitStatus ChollaEngine::build_eval_tools() 00137 { 00138 CubitBoolean use_feature_angle = CUBIT_FALSE; 00139 double min_dot = 0.0; 00140 int interp_order = 0; 00141 CubitBoolean smooth_non_manifold = CUBIT_FALSE; 00142 CubitBoolean split_surfaces = CUBIT_FALSE; 00143 00144 return build_eval_tools( chollaSurfaceList, 00145 chollaCurveList, 00146 interp_order, use_feature_angle, 00147 min_dot, smooth_non_manifold, 00148 split_surfaces ); 00149 } 00150 00151 //============================================================================ 00152 //Function: delete_tool_datas 00153 //============================================================================ 00154 void ChollaEngine::delete_tool_datas( ) 00155 { 00156 int ii; 00157 FacetEntity *fe_ptr; 00158 for (ii=0; ii<faceList.size(); ii++) 00159 { 00160 fe_ptr = faceList.get_and_step(); 00161 fe_ptr->delete_TD( &TDGeomFacet::is_geom_facet ); 00162 } 00163 for (ii=0; ii<edgeList.size(); ii++) 00164 { 00165 fe_ptr = edgeList.get_and_step(); 00166 fe_ptr->delete_TD( &TDGeomFacet::is_geom_facet ); 00167 } 00168 for (ii=0; ii<pointList.size(); ii++) 00169 { 00170 fe_ptr = pointList.get_and_step(); 00171 fe_ptr->delete_TD( &TDGeomFacet::is_geom_facet ); 00172 } 00173 } 00174 00175 //============================================================================ 00176 //Function: delete_eval_tools 00177 //============================================================================ 00178 void ChollaEngine::delete_eval_tools() 00179 { 00180 00181 delete_tool_datas(); 00182 int ii; 00183 ChollaSurface *cs_ptr = NULL; 00184 FacetEvalTool *fe_tool_ptr; 00185 for (ii = chollaSurfaceList.size(); ii > 0; ii-- ) 00186 { 00187 cs_ptr = chollaSurfaceList.get_and_step(); 00188 fe_tool_ptr = cs_ptr->get_eval_tool(); 00189 if (fe_tool_ptr) 00190 delete fe_tool_ptr; 00191 } 00192 ChollaCurve *cc_ptr = NULL; 00193 CurveFacetEvalTool *ce_tool_ptr; 00194 for (ii = chollaCurveList.size(); ii > 0; ii-- ) 00195 { 00196 cc_ptr = chollaCurveList.get_and_step(); 00197 ce_tool_ptr = cc_ptr->get_eval_tool(); 00198 if (ce_tool_ptr) 00199 delete ce_tool_ptr; 00200 } 00201 faceList.clean_out(); 00202 edgeList.clean_out(); 00203 pointList.clean_out(); 00204 } 00205 00206 //============================================================================ 00207 //Function: delete_eval_tools_but_not_facets 00208 //============================================================================ 00209 void ChollaEngine::delete_eval_tools_but_not_facets() 00210 { 00211 00212 delete_tool_datas(); 00213 int ii; 00214 ChollaSurface *cs_ptr = NULL; 00215 FacetEvalTool *fe_tool_ptr; 00216 for (ii = chollaSurfaceList.size(); ii > 0; ii-- ) 00217 { 00218 cs_ptr = chollaSurfaceList.get_and_step(); 00219 fe_tool_ptr = cs_ptr->get_eval_tool(); 00220 if (fe_tool_ptr) 00221 { 00222 DLIList<CubitFacet *>facets; 00223 fe_tool_ptr->remove_facets(facets); 00224 delete fe_tool_ptr; 00225 } 00226 } 00227 ChollaCurve *cc_ptr = NULL; 00228 CurveFacetEvalTool *ce_tool_ptr; 00229 for (ii = chollaCurveList.size(); ii > 0; ii-- ) 00230 { 00231 cc_ptr = chollaCurveList.get_and_step(); 00232 ce_tool_ptr = cc_ptr->get_eval_tool(); 00233 if (ce_tool_ptr) 00234 { 00235 delete ce_tool_ptr; 00236 } 00237 } 00238 faceList.clean_out(); 00239 edgeList.clean_out(); 00240 pointList.clean_out(); 00241 } 00242 00243 //============================================================================ 00244 //Function: ~ChollaEngine (PUBLIC) (destructor) 00245 //============================================================================ 00246 ChollaEngine::~ChollaEngine() 00247 { 00248 } 00249 00250 //============================================================================ 00251 //Function: delete (PUBLIC) 00252 //Description: removes all cholla entities stored with the cholla engine 00253 // usually called before destructor 00254 //============================================================================ 00255 void ChollaEngine::delete_me() 00256 { 00257 delete_tool_datas(); 00258 int ii; 00259 //clean up any data remaining. 00260 for (ii = chollaPointList.size(); ii > 0; ii-- ) 00261 delete chollaPointList.remove(); 00262 for (ii = chollaCurveList.size(); ii > 0; ii-- ) 00263 delete chollaCurveList.remove(); 00264 for (ii = chollaSurfaceList.size(); ii > 0; ii-- ) 00265 delete chollaSurfaceList.remove(); 00266 00267 } 00268 00269 //================================================================================== 00270 //Function: create_geometry (PUBLIC) 00271 //Description: Interface function to acutally create the topology 00272 // for the given mesh. 00273 //================================================================================== 00274 CubitStatus ChollaEngine::create_geometry( 00275 CubitBoolean use_feature_angle, // use an angle to define where to break surfaces 00276 double angle, // the feature angle 00277 int interp_order, // 0=linear, 4=b-spline patches 00278 CubitBoolean smooth_non_manifold, // check for continuity accross >2 valence edges 00279 CubitBoolean split_surfaces) // create new FacetEntities to split surfaces at 00280 // at features. Otherwise - don't mess with the 00281 // FacetEntities. (creates TDs instead) 00282 00283 { 00284 if (0) 00285 { 00286 dump("cyl.cholla", angle); 00287 } 00288 00289 //- convert feature angle to a dot product 00290 00291 double min_dot = 0.0; 00292 if (use_feature_angle) 00293 { 00294 if (angle > 180.0) angle = 180.0; 00295 if (angle < 0.0) angle = 0.0; 00296 double rad_angle = (180.0 - angle) * CUBIT_PI / 180.0; 00297 min_dot = cos( rad_angle ); 00298 } 00299 00300 //- create one facet surface to start with 00301 00302 ChollaSkinTool c_skin_tool; 00303 ChollaSurface *cholla_surface_ptr = NULL; 00304 CubitStatus stat = c_skin_tool.skin_2d(faceList, cholla_surface_ptr); 00305 if ( stat != CUBIT_SUCCESS ) 00306 return stat; 00307 if ( cholla_surface_ptr ) 00308 chollaSurfaceList.append(cholla_surface_ptr); 00309 00310 // before building the surfaces, orient the facets so they are consistent 00311 00312 DLIList<CubitFacet *>total_facet_list; 00313 CAST_LIST( faceList, total_facet_list, CubitFacet ); 00314 //stat = check_all_facet_orientations( total_facet_list, doFlip ); 00315 if (stat!=CUBIT_SUCCESS) 00316 return stat; 00317 00318 // generate the topology from the facets 00319 00320 stat = create_volume_boundaries( chollaSurfaceList, 00321 use_feature_angle, min_dot, 00322 split_surfaces ); 00323 if ( stat == CUBIT_FAILURE ) 00324 return stat; 00325 00326 stat = create_surface_boundaries( chollaSurfaceList, chollaCurveList, 00327 use_feature_angle, min_dot ); 00328 if ( stat == CUBIT_FAILURE ) 00329 return stat; 00330 00331 stat = create_curve_boundaries( chollaCurveList, chollaPointList ); 00332 if ( stat == CUBIT_FAILURE ) 00333 return stat; 00334 00335 // Okay. Now we are ready to actually build the geometry. 00336 int mydebug = 0; 00337 if (mydebug) 00338 print_me(); 00339 00340 stat = build_eval_tools( chollaSurfaceList, 00341 chollaCurveList, 00342 interp_order, use_feature_angle, 00343 min_dot, smooth_non_manifold, 00344 split_surfaces ); 00345 00346 return stat; 00347 } 00348 00349 //============================================================================= 00350 //Function: create_volume_boundaries (PRIVATE) 00351 //Description: creates the surfaces based on the sideset and element block 00352 // information 00353 //Author: sjowen 00354 //Date: 10/17/00 00355 //============================================================================= 00356 CubitStatus ChollaEngine::create_volume_boundaries( 00357 DLIList<ChollaSurface*> &cholla_surface_sheets, // output global list of surfaces 00358 CubitBoolean use_feature_angle, // define surfaces based on feature angle 00359 double min_dot, // minimum dot product between face normals 00360 CubitBoolean split_surfaces ) // create new FacetEntities to split surfaces at 00361 // at features. Otherwise - don't mess with the 00362 // FacetEntities. (creates TDs instead) 00363 { 00364 CubitStatus rv = CUBIT_SUCCESS; 00365 00366 // Split these surfaces so that there is only one set of continuous 00367 // faces per surface 00368 00369 int ii; 00370 int num_surfaces = cholla_surface_sheets.size(); 00371 cholla_surface_sheets.reset(); 00372 for ( ii = num_surfaces; ii > 0; ii-- ) 00373 { 00374 00375 ChollaSurface *chsurf_ptr = cholla_surface_sheets.get_and_step(); 00376 00377 DLIList<FacetEntity*> surf_facet_list; 00378 FacetEntity *sfacet; 00379 chsurf_ptr->get_facets(surf_facet_list); 00380 DLIList<CubitFacet*> facet_list; 00381 CubitFacet *facet; 00382 CubitFacetEdge *fedge; 00383 int kk, mm; 00384 int mydebug = 0; 00385 if(mydebug){ 00386 GfxDebug::clear(); 00387 } 00388 DLIList<CubitFacetEdge *> feature_edge_list; 00389 for ( kk = surf_facet_list.size(); kk > 0; kk-- ) { 00390 sfacet = surf_facet_list.get_and_step(); 00391 facet_list.clean_out(); 00392 sfacet->facets(facet_list); 00393 facet = facet_list.get(); 00394 TDFacetboolData* tdf = TDFacetboolData::get(facet); 00395 if ( tdf ) { 00396 int *cptr; 00397 cptr = tdf->get_edge_indices( (bool) facet->is_backwards()); 00398 for ( mm = 0; mm < 3; mm++ ) { 00399 if ( cptr[mm] != 0 ) { 00400 fedge = facet->edge((2+mm)%3); 00401 if(mydebug){ 00402 if(facet->is_backwards()){ 00403 facet->edge((1+mm)%3)->debug_draw(CUBIT_GREEN_INDEX); 00404 facet->edge((mm)%3)->debug_draw(CUBIT_RED_INDEX); 00405 00406 fedge->debug_draw(CUBIT_BLUE_INDEX); 00407 } 00408 else 00409 fedge->debug_draw(CUBIT_WHITE_INDEX); 00410 } 00411 00412 TDGeomFacet::add_geom_facet(fedge, -1); 00413 fedge->set_as_feature(); 00414 feature_edge_list.append( fedge ); 00415 } 00416 } 00417 } 00418 } 00419 if(mydebug){ 00420 GfxDebug::mouse_xforms(); 00421 } 00422 // make a list of feature edges 00423 00424 rv = chsurf_ptr->add_preexisting_feature_edges( feature_edge_list ); 00425 if (rv != CUBIT_SUCCESS) 00426 return rv; 00427 00428 if (use_feature_angle) 00429 { 00430 rv = chsurf_ptr->feature_angle( min_dot, feature_edge_list ); 00431 } 00432 else 00433 { 00434 rv = chsurf_ptr->non_manifold_edges( feature_edge_list ); 00435 } 00436 if (rv != CUBIT_SUCCESS) 00437 return rv; 00438 00439 // crack the surface at the feature edges. create new edges and 00440 // points so the facet representation is discontinuous. 00441 00442 rv = make_features( feature_edge_list, split_surfaces ); 00443 if (rv != CUBIT_SUCCESS) 00444 return rv; 00445 00446 // split up the surface 00447 00448 rv = chsurf_ptr->split_surface( cholla_surface_sheets ); 00449 if (rv != CUBIT_SUCCESS) 00450 return rv; 00451 } 00452 00453 // Clean up any edges that do not form complete loops as a result of 00454 // feature angle. For this implementation we will allow features to exist 00455 // within the surface without defining a complete loop. -- so the next 00456 // piece of code is never executed. 00457 00458 CubitBoolean use_complete_loops_only = CUBIT_FALSE; 00459 if (use_feature_angle && use_complete_loops_only) 00460 { 00461 for ( ii = cholla_surface_sheets.size(); ii > 0; ii-- ) 00462 { 00463 ChollaSurface *chsurf_ptr = cholla_surface_sheets.get_and_step(); 00464 chsurf_ptr->clean_features(); 00465 } 00466 } 00467 00468 // Now that we've broken everything into surfaces, update the surface IDs 00469 // on the boundary facet tool data 00470 00471 if (!split_surfaces) 00472 { 00473 for ( ii = cholla_surface_sheets.size(); ii > 0; ii-- ) 00474 { 00475 ChollaSurface *chsurf_ptr = cholla_surface_sheets.get_and_step(); 00476 chsurf_ptr->update_boundary_tool_data(); 00477 } 00478 } 00479 return rv; 00480 } 00481 00482 00483 //============================================================================= 00484 //Function: create_surface_boundaries (PRIVATE) 00485 //Description: creates the curves based on the facet surface information 00486 //Author: sjowen 00487 //Date: 12/3/00 00488 //============================================================================= 00489 CubitStatus ChollaEngine::create_surface_boundaries( 00490 DLIList<ChollaSurface*> &cholla_surface_list, // global list of surfaces 00491 DLIList<ChollaCurve*> &cholla_curve_list, // output global list of curves 00492 CubitBoolean use_feature_angle, 00493 double min_dot ) 00494 { 00495 CubitStatus stat = CUBIT_SUCCESS; 00496 00497 // determine the boundaries for each surface. One curve per surface 00498 00499 int ii; 00500 for ( ii = cholla_surface_list.size(); ii > 0; ii-- ) 00501 { 00502 ChollaSurface *chsurf_ptr = cholla_surface_list.get_and_step(); 00503 DLIList<ChollaCurve*> chcurve_list; 00504 chsurf_ptr->get_curves( chcurve_list ); 00505 if (chcurve_list.size() == 0) 00506 { 00507 DLIList<FacetEntity*> facet_list; 00508 chsurf_ptr->get_facets(facet_list); 00509 ChollaSkinTool c_skin_tool; 00510 stat = c_skin_tool.skin_2d(facet_list, chsurf_ptr); 00511 if ( stat != CUBIT_SUCCESS ) 00512 return stat; 00513 } 00514 } 00515 00516 // create a hash list of curves - to speed up classification 00517 00518 stat = init_hash_curves(); 00519 if (stat != CUBIT_SUCCESS) 00520 { 00521 delete_hash_curves(); 00522 return stat; 00523 } 00524 00525 // loop through each of the edges on the surfaces 00526 // Determine which curve it is a part of. 00527 // Create a new ChollaCurve for each curve 00528 // Curves are created wherever there is a unique set of associated 00529 // surfaces 00530 00531 int jj, kk; 00532 for ( ii = cholla_surface_list.size(); ii > 0; ii-- ) 00533 { 00534 00535 ChollaSurface *chsurf_ptr = cholla_surface_list.get_and_step(); 00536 DLIList<ChollaCurve*> chcurve_list; 00537 chsurf_ptr->get_curves( chcurve_list ); 00538 00539 // curently there should only be one curve list per surface 00540 00541 for (jj=chcurve_list.size(); jj>0; jj--) 00542 { 00543 ChollaCurve *chcurv_ptr = chcurve_list.get_and_step(); 00544 DLIList<FacetEntity*> facet_list = chcurv_ptr->get_facet_list(); 00545 FacetEntity *edge_ptr; 00546 for ( kk = 0; kk < facet_list.size(); kk++) 00547 { 00548 edge_ptr = facet_list.get_and_step(); 00549 stat = classify_edge( edge_ptr, cholla_curve_list, chsurf_ptr ); 00550 if (stat != CUBIT_SUCCESS) 00551 return stat; 00552 } 00553 00554 // delete this ChollaCurve - it should have been replaced by one 00555 // or more curves bounding this surface 00556 00557 chsurf_ptr->remove_curve( chcurv_ptr ); 00558 delete chcurv_ptr; 00559 } 00560 } 00561 delete_hash_curves(); 00562 00563 // Split these curves so that there is only one string of continuous 00564 // edges per curve (it will also order the edges and set the start 00565 // and end nodes for each curve) 00566 00567 int num_curves = cholla_curve_list.size(); 00568 00569 cholla_curve_list.reset(); 00570 for ( ii = num_curves; ii > 0 && stat == CUBIT_SUCCESS; ii-- ) 00571 { 00572 ChollaCurve *chcurv_ptr = cholla_curve_list.get(); 00573 00574 // if necessary mark nodes that will serve as feature breaks (vertices 00575 // will be generatedat them) 00576 00577 if (use_feature_angle) 00578 { 00579 stat = chcurv_ptr->feature_angle( min_dot ); 00580 if (stat != CUBIT_SUCCESS) 00581 return stat; 00582 } 00583 00584 // split the curve based on various criteria 00585 00586 stat = chcurv_ptr->split_curve( cholla_curve_list ); 00587 00588 // delete this curve (new curves were created in split_curve) 00589 00590 delete chcurv_ptr; 00591 cholla_curve_list.change_to(NULL); 00592 cholla_curve_list.step(); 00593 } 00594 cholla_curve_list.remove_all_with_value(NULL); 00595 00596 // update the point->curve associativity 00597 00598 for (ii=0; ii<cholla_curve_list.size(); ii++) 00599 { 00600 ChollaCurve *chcurv_ptr = cholla_curve_list.get_and_step(); 00601 CubitPoint *start_ptr, *end_ptr; 00602 chcurv_ptr->get_ends( start_ptr, end_ptr ); 00603 TDGeomFacet *td = TDGeomFacet::get_geom_facet( start_ptr ); 00604 td->add_cholla_curve( chcurv_ptr ); 00605 td = TDGeomFacet::get_geom_facet( end_ptr ); 00606 td->add_cholla_curve( chcurv_ptr ); 00607 } 00608 00609 return stat; 00610 } 00611 00612 //============================================================================= 00613 //Function: init_hash_curves (PRIVATE) 00614 //Description: create a hash array of all curves. They are hashed based on the 00615 // smallest id of any surface attached to the curve 00616 //Author: sjowen 00617 //Date: 3/7/01 00618 //============================================================================= 00619 CubitStatus ChollaEngine::init_hash_curves( ) 00620 { 00621 /* === find the next highest prime number */ 00622 00623 int num_surfs = chollaSurfaceList.size(); 00624 int i; 00625 hashCurveSize = num_surfs; 00626 if (num_surfs < 30) hashCurveSize = 31; 00627 else 00628 { 00629 i=2; 00630 while (i<hashCurveSize*0.5 + 1) { 00631 if (hashCurveSize % i == 0) { 00632 i=2; 00633 hashCurveSize++; 00634 } 00635 else { 00636 i++; 00637 } 00638 } 00639 } 00640 hashCurveArray = new DLIList<ChollaCurve*>[hashCurveSize]; 00641 00642 int key = 0; 00643 ChollaCurve *chcurv_ptr; 00644 DLIList<ChollaSurface*> *fsm_list_ptr; 00645 for (i=0; i<chollaCurveList.size(); i++) 00646 { 00647 chcurv_ptr = chollaCurveList.get_and_step(); 00648 fsm_list_ptr = chcurv_ptr->get_surface_list_ptr(); 00649 key = get_curve_hash_key( fsm_list_ptr ); 00650 hashCurveArray[key].append( chcurv_ptr ); 00651 } 00652 return CUBIT_SUCCESS; 00653 } 00654 00655 //============================================================================= 00656 //Function: delete_hash_curves (PRIVATE) 00657 //Description: delete the hash curve stuff 00658 //Author: sjowen 00659 //Date: 3/7/01 00660 //============================================================================= 00661 void ChollaEngine::delete_hash_curves( ) 00662 { 00663 if (hashCurveArray) 00664 delete [] hashCurveArray; 00665 hashCurveArray = NULL; 00666 hashCurveSize = 0; 00667 } 00668 00669 //============================================================================= 00670 //Function: get_curve_hash_key (PRIVATE) 00671 //Description: 00672 //Author: sjowen 00673 //Date: 3/7/01 00674 //============================================================================= 00675 int ChollaEngine::get_curve_hash_key( 00676 DLIList<ChollaSurface*> *fsm_list_ptr ) 00677 { 00678 int key, j; 00679 ChollaSurface *chsurf_ptr; 00680 if (fsm_list_ptr->size() == 0) 00681 { 00682 key = 0; 00683 } 00684 else 00685 { 00686 key = INT_MAX; 00687 for (j=0; j<fsm_list_ptr->size(); j++) 00688 { 00689 chsurf_ptr = fsm_list_ptr->get_and_step(); 00690 if (chsurf_ptr->get_id() < key) 00691 key = chsurf_ptr->get_id(); 00692 } 00693 } 00694 key = key % hashCurveSize; 00695 return key; 00696 } 00697 00698 00699 //============================================================================= 00700 //Function: classify_edge (PRIVATE) 00701 //Description: sorts a edge into its correct curve based on its associated 00702 // surfaces and sidesets/nodesets. Creates a new block curve if 00703 // necessary. 00704 //Author: sjowen 00705 //Date: 12/3/00 00706 //============================================================================= 00707 CubitStatus ChollaEngine::classify_edge( 00708 FacetEntity *edge_ptr, // the edge we are classifying 00709 DLIList<ChollaCurve*> &cholla_curve_list, // add to one of these 00710 ChollaSurface *cholla_surf_mesh_ptr ) // the current surface 00711 { 00712 CubitStatus rv = CUBIT_SUCCESS; 00713 00714 // see if we have already classified this edge (from another surface) 00715 00716 TDGeomFacet *td_gm_edge = TDGeomFacet::get_geom_facet(edge_ptr); 00717 if (td_gm_edge->get_hit_flag() != 0) 00718 return rv; 00719 td_gm_edge->set_hit_flag(1); 00720 00721 // get the surfaces adjacent to this edge 00722 00723 DLIList<ChollaSurface*> this_chsurf_list; 00724 td_gm_edge->get_cholla_surfs( this_chsurf_list ); 00725 int this_num_adj = this_chsurf_list.size(); 00726 00727 // see if the surfaces defined on this face match any 00728 // of the existing block curves 00729 00730 DLIList<ChollaSurface*> *chsurf_list_ptr; 00731 ChollaCurve *chcurv_ptr = NULL; 00732 int found = 0; 00733 int key = get_curve_hash_key( &this_chsurf_list ); 00734 int ii; 00735 for (ii=0; ii<hashCurveArray[key].size() && !found; ii++) 00736 { 00737 chcurv_ptr = hashCurveArray[key].get(); 00738 // the first one checked should be the same as the last one checked (don't 00739 // use get_and_step here) This should speed things up 00740 00741 // check if surfaces are the same 00742 00743 chsurf_list_ptr = chcurv_ptr->get_surface_list_ptr( ); 00744 int num_adj = chsurf_list_ptr->size(); 00745 if (num_adj == this_num_adj) 00746 { 00747 found = 1; 00748 int jj, kk; 00749 for (jj=chsurf_list_ptr->size(); jj>0 && found; jj--) 00750 { 00751 int same_surf = 0; 00752 ChollaSurface *chsurf_ptr = chsurf_list_ptr->get_and_step(); 00753 for(kk=this_chsurf_list.size(); kk>0 && !same_surf; kk--) 00754 { 00755 ChollaSurface *this_chsurf_ptr = this_chsurf_list.get_and_step(); 00756 if (this_chsurf_ptr == chsurf_ptr) 00757 { 00758 same_surf = 1; 00759 } 00760 } 00761 if (!same_surf) 00762 found = 0; 00763 } 00764 } 00765 if (!found) 00766 hashCurveArray[key].step(); 00767 } 00768 00769 // if the unique set of surfaces that this edge is associated 00770 // with was found to already exist for a facet curve -- add the 00771 // edge to the block curve 00772 00773 if (found) 00774 { 00775 00776 // add the edge to the block curve mesh (make sure it is only added once) 00777 00778 //int was_added = 00779 chcurv_ptr->add_facet_unique( edge_ptr ); 00780 00781 // add the curve to the surface (if needed) 00782 00783 cholla_surf_mesh_ptr->add_curve_unique( chcurv_ptr ); 00784 00785 // add the curve to the edge 00786 00787 td_gm_edge->add_cholla_curve( chcurv_ptr ); 00788 } 00789 00790 // if the unique set of surfaces that this edge is associated 00791 // with is not found, then create a new facet curve and add the edge to it 00792 00793 else 00794 { 00795 00796 // create it and update surface and nodeset info 00797 00798 int block_id = td_gm_edge->get_block_id(); 00799 ChollaCurve *new_chcurv_ptr = new ChollaCurve( block_id ); 00800 for (int mm=0; mm<this_num_adj; mm++) 00801 { 00802 new_chcurv_ptr->add_surface( this_chsurf_list.get_and_step() ); 00803 } 00804 00805 // add the edge 00806 00807 new_chcurv_ptr->add_facet( edge_ptr ); 00808 00809 // update the surface with this new curve 00810 00811 cholla_surf_mesh_ptr->add_curve( new_chcurv_ptr ); 00812 00813 // add the new curve to the global list 00814 00815 cholla_curve_list.append( new_chcurv_ptr ); 00816 00817 // add the curve to the edge 00818 00819 td_gm_edge->add_cholla_curve( new_chcurv_ptr ); 00820 00821 // add the new curve to the hash table 00822 00823 hashCurveArray[key].append( new_chcurv_ptr ); 00824 } 00825 return rv; 00826 } 00827 00828 //============================================================================= 00829 //Function: create_curve_boundaries (PRIVATE) 00830 //Description: creates the points based on the nodeset and curve information 00831 //Author: sjowen 00832 //Date: 12/6/00 00833 //============================================================================= 00834 CubitStatus ChollaEngine::create_curve_boundaries( 00835 DLIList<ChollaCurve*> &cholla_curve_list, // global list of curves 00836 DLIList<ChollaPoint*> &cholla_point_list ) // output global list of points 00837 { 00838 00839 CubitStatus stat = CUBIT_SUCCESS; 00840 00841 // hash the points for speed 00842 00843 stat = init_hash_points(); 00844 if (stat != CUBIT_SUCCESS) 00845 { 00846 delete_hash_points(); 00847 return stat; 00848 } 00849 00850 // loop through each of the end nodes on the curves 00851 // Determine which point it is a part of. 00852 // Create a new ChollaPoint for each point 00853 00854 //int mydebug = 0; 00855 int ii, kk; 00856 for ( ii = cholla_curve_list.size(); ii > 0; ii-- ) 00857 { 00858 ChollaCurve *chcurv_ptr = cholla_curve_list.get_and_step(); 00859 CubitPoint *point_ptr[2]; 00860 chcurv_ptr->get_ends( point_ptr[0], point_ptr[1] ); 00861 for ( kk = 0; kk < 2; kk++) 00862 { 00863 stat = classify_point( point_ptr[kk], cholla_point_list, chcurv_ptr ); 00864 if (stat != CUBIT_SUCCESS) 00865 { 00866 delete_hash_points(); 00867 return stat; 00868 } 00869 } 00870 } 00871 delete_hash_points(); 00872 return stat; 00873 } 00874 00875 //============================================================================= 00876 //Function: classify_point (PRIVATE) 00877 //Description: sorts a point into its correct point based on its associated 00878 // curve. Creates a new block point if necessary 00879 //Author: sjowen 00880 //Date: 12/6/00 00881 //============================================================================= 00882 CubitStatus ChollaEngine::classify_point( 00883 CubitPoint *point_ptr, // the node to classify 00884 DLIList<ChollaPoint*> &cholla_point_list, // global list of points 00885 ChollaCurve *chcurv_ptr ) // curve that the end point is on 00886 { 00887 int ii; 00888 int found = 0; 00889 TDGeomFacet *td_node = TDGeomFacet::get_geom_facet( point_ptr ); 00890 ChollaPoint *chpnt_ptr = NULL; 00891 DLIList<ChollaCurve*> fcm_list; 00892 td_node->get_cholla_curves(fcm_list); 00893 int key = get_point_hash_key( &fcm_list ); 00894 for (ii = 0; ii < hashPointArray[key].size() && !found; ii++) 00895 { 00896 chpnt_ptr = hashPointArray[key].get(); 00897 FacetEntity *this_point_ptr = chpnt_ptr->get_facets(); 00898 if (this_point_ptr == point_ptr) 00899 { 00900 found = 1; 00901 } 00902 else 00903 { 00904 hashPointArray[key].step(); 00905 } 00906 } 00907 00908 if (found) 00909 { 00910 chpnt_ptr->add_curve( chcurv_ptr ); 00911 chcurv_ptr->add_point( chpnt_ptr ); 00912 } 00913 else 00914 { 00915 ChollaPoint *new_chpnt_ptr = new ChollaPoint(); 00916 new_chpnt_ptr->add_facet( point_ptr ); 00917 new_chpnt_ptr->add_curve( chcurv_ptr ); 00918 chcurv_ptr->add_point( new_chpnt_ptr ); 00919 cholla_point_list.append( new_chpnt_ptr ); 00920 hashPointArray[key].append( new_chpnt_ptr ); 00921 } 00922 return CUBIT_SUCCESS; 00923 } 00924 00925 //============================================================================= 00926 //Function: init_hash_points (PRIVATE) 00927 //Description: create a hash array of all points. They are hashed based on the 00928 // smallest id of any curve attached to the curve 00929 //Author: sjowen 00930 //Date: 3/7/01 00931 //============================================================================= 00932 CubitStatus ChollaEngine::init_hash_points( ) 00933 { 00934 /* === find the next highest prime number */ 00935 00936 int num_curves = chollaCurveList.size(); 00937 int i; 00938 hashPointSize = num_curves; 00939 if (num_curves < 30) hashPointSize = 31; 00940 else 00941 { 00942 i=2; 00943 while (i<hashPointSize*0.5 + 1) { 00944 if (hashPointSize % i == 0) { 00945 i=2; 00946 hashPointSize++; 00947 } 00948 else { 00949 i++; 00950 } 00951 } 00952 } 00953 hashPointArray = new DLIList<ChollaPoint*>[hashPointSize]; 00954 00955 int key = 0; 00956 ChollaPoint *chpnt_ptr; 00957 DLIList<ChollaCurve*> *fcm_list_ptr; 00958 for (i=0; i<chollaPointList.size(); i++) 00959 { 00960 chpnt_ptr = chollaPointList.get_and_step(); 00961 fcm_list_ptr = chpnt_ptr->get_curve_list_ptr(); 00962 key = get_point_hash_key( fcm_list_ptr ); 00963 hashPointArray[key].append( chpnt_ptr ); 00964 } 00965 return CUBIT_SUCCESS; 00966 } 00967 00968 //============================================================================= 00969 //Function: delete_hash_points (PRIVATE) 00970 //Description: delete the hash point stuff 00971 //Author: sjowen 00972 //Date: 3/7/01 00973 //============================================================================= 00974 void ChollaEngine::delete_hash_points( ) 00975 { 00976 if (hashPointArray) 00977 delete [] hashPointArray; 00978 hashPointArray = NULL; 00979 hashPointSize = 0; 00980 } 00981 00982 //============================================================================= 00983 //Function: get_point_hash_key (PRIVATE) 00984 //Description: 00985 //Author: sjowen 00986 //Date: 3/7/01 00987 //============================================================================= 00988 int ChollaEngine::get_point_hash_key( 00989 DLIList<ChollaCurve*> *fcm_list_ptr ) 00990 { 00991 int key, j; 00992 ChollaCurve *chcurv_ptr; 00993 if (fcm_list_ptr->size() == 0) 00994 { 00995 key = 0; 00996 } 00997 else 00998 { 00999 key = INT_MAX; 01000 for (j=0; j<fcm_list_ptr->size(); j++) 01001 { 01002 chcurv_ptr = fcm_list_ptr->get_and_step(); 01003 if (chcurv_ptr->get_id() < key) 01004 key = chcurv_ptr->get_id(); 01005 } 01006 } 01007 key = key % hashPointSize; 01008 return key; 01009 } 01010 01011 //============================================================================= 01012 //Function: facet_dimension (PRIVATE) 01013 //Description: returns the dimension of a mesh entity. 01014 //============================================================================= 01015 int ChollaEngine::facet_dimension(FacetEntity *facet_ptr) 01016 { 01017 if (CAST_TO(facet_ptr, CubitFacet) != NULL) 01018 return 2; 01019 if (CAST_TO(facet_ptr, CubitFacetEdge) != NULL) 01020 return 1; 01021 if (CAST_TO(facet_ptr, CubitPoint) != NULL) 01022 return 0; 01023 return -1; 01024 } 01025 01026 01027 //=============================================================================== 01028 //Function: build_eval_tools (PRIVATE) 01029 //Description: build the CUBIT geometry based on the Facet entity class lists 01030 //=============================================================================== 01031 CubitStatus ChollaEngine::build_eval_tools( 01032 DLIList<ChollaSurface*> &cholla_surface_list, 01033 DLIList<ChollaCurve*> &cholla_curve_list, 01034 int interp_order, 01035 CubitBoolean use_feature_angle, 01036 double min_dot, 01037 CubitBoolean smooth_non_manifold, 01038 CubitBoolean split_surfaces ) 01039 { 01040 CubitStatus stat = CUBIT_SUCCESS; 01041 01042 if (stat == CUBIT_SUCCESS) 01043 stat = build_surface_and_curve_eval_tools( cholla_surface_list, 01044 interp_order, min_dot ); 01045 if (stat == CUBIT_SUCCESS) 01046 stat = build_curve_eval_tools( cholla_curve_list, interp_order ); 01047 01048 if (stat == CUBIT_SUCCESS) 01049 if (interp_order == 4) 01050 stat = clean_geometry( smooth_non_manifold, split_surfaces, 01051 use_feature_angle, min_dot, cholla_curve_list ); 01052 return stat; 01053 } 01054 01055 01056 //=============================================================================== 01057 //Function: build_curve_eval_tools (PRIVATE) 01058 //Description: From the cholla curve list, create CurveFacetEvalTools 01059 //=============================================================================== 01060 CubitStatus ChollaEngine::build_curve_eval_tools( 01061 DLIList<ChollaCurve*> &cholla_curve_list, 01062 int /* interp_order */) 01063 { 01064 CubitStatus stat = CUBIT_SUCCESS; 01065 int kk; 01066 for ( kk = cholla_curve_list.size(); kk > 0; kk-- ) 01067 { 01068 ChollaCurve *chcurv_ptr = cholla_curve_list.get_and_step(); 01069 CurveFacetEvalTool *curv_eval_tool_ptr = chcurv_ptr->get_eval_tool(); 01070 if (curv_eval_tool_ptr == NULL) 01071 { 01072 CubitPoint *start_point, *end_point; 01073 chcurv_ptr->get_ends( start_point, end_point ); 01074 01075 // if this is a curve without a parent surface then handle it 01076 // differently. (Curves with parents use the surface to evaluate to 01077 // With only a curve, it must evaluate to the curve) 01078 // Note the CurveFacetEvalTool for curves that have parent surfaces 01079 // are computed in build_surface_eval_tools 01080 01081 DLIList<ChollaSurface*> chsurf_list = chcurv_ptr->get_surfaces(); 01082 if (chsurf_list.size() == 0) 01083 { 01084 DLIList<FacetEntity*> facet_list; 01085 DLIList<CubitPoint*> point_list; // needs to be filled in 01086 facet_list = chcurv_ptr->get_facet_list(); 01087 DLIList<CubitFacetEdge*> edge_list; 01088 CAST_LIST( facet_list, edge_list, CubitFacetEdge ); 01089 if (stat != CUBIT_SUCCESS) 01090 return stat; 01091 01092 curv_eval_tool_ptr = new CurveFacetEvalTool; 01093 stat = curv_eval_tool_ptr->initialize( edge_list, point_list ); 01094 01095 if ( stat != CUBIT_SUCCESS ) 01096 { 01097 return stat; 01098 } 01099 chcurv_ptr->assign_eval_tool(curv_eval_tool_ptr); 01100 } 01101 else 01102 { 01103 //fix up the orientation of the Cholla curve 01104 stat = chcurv_ptr->order_edges(); 01105 if ( stat != CUBIT_SUCCESS ) 01106 { 01107 return stat; 01108 } 01109 01110 DLIList<FacetEntity*> facet_ents; 01111 facet_ents = chcurv_ptr->get_facet_list(); 01112 DLIList<CubitFacetEdge*> edge_facets; 01113 CAST_LIST(facet_ents, edge_facets, CubitFacetEdge ); 01114 DLIList<CubitPoint*> ordered_points; 01115 01116 for( int k=0; k<edge_facets.size(); k++ ) 01117 { 01118 CubitFacetEdge *tmp_edge = edge_facets.get_and_step(); 01119 if( k==0 ) 01120 { 01121 ordered_points.append( tmp_edge->point(0) ); 01122 ordered_points.append( tmp_edge->point(1) ); 01123 } 01124 else 01125 ordered_points.append( tmp_edge->point(1) ); 01126 } 01127 01128 FacetEvalTool *surf_eval_tool = chsurf_list.get()->get_eval_tool(); 01129 CurveFacetEvalTool *curv_eval_tool_ptr = new CurveFacetEvalTool; 01130 edge_facets.reset(); 01131 stat = curv_eval_tool_ptr->initialize( edge_facets, ordered_points, surf_eval_tool ); 01132 01133 if ( stat != CUBIT_SUCCESS ) 01134 { 01135 return stat; 01136 } 01137 chcurv_ptr->assign_eval_tool( curv_eval_tool_ptr ); 01138 } 01139 } 01140 } 01141 return stat; 01142 } 01143 01144 //=============================================================================== 01145 //Function: build_surface_eval_tools (PRIVATE) 01146 //Description: From the facet surface list, create the FacetEvalTools 01147 //=============================================================================== 01148 CubitStatus ChollaEngine::build_surface_and_curve_eval_tools( 01149 DLIList<ChollaSurface*> &cholla_surface_list, 01150 int interp_order, 01151 double min_dot) 01152 { 01153 CubitStatus stat = CUBIT_SUCCESS; 01154 int ii, kk; 01155 01156 // make sure the facet flags have been reset 01157 01158 for ( kk = cholla_surface_list.size(); kk > 0; kk-- ) 01159 { 01160 ChollaSurface *chsurf_ptr = cholla_surface_list.get_and_step(); 01161 chsurf_ptr->reset_facet_flags(); 01162 } 01163 01164 // now loop through surfaces and create them 01165 01166 for ( kk = cholla_surface_list.size(); kk > 0; kk-- ) 01167 { 01168 ChollaSurface *chsurf_ptr = cholla_surface_list.get_and_step(); 01169 DLIList<FacetEntity*> facet_entity_list; 01170 DLIList<CubitPoint*> point_list; 01171 chsurf_ptr->get_points(point_list); 01172 chsurf_ptr->get_facets(facet_entity_list); 01173 DLIList<CubitFacet*> facet_list; 01174 CAST_LIST( facet_entity_list, facet_list, CubitFacet ); 01175 01176 FacetEvalTool *eval_tool_ptr = new FacetEvalTool(); 01177 eval_tool_ptr->initialize(facet_list, point_list, interp_order, min_dot); 01178 01179 chsurf_ptr->assign_eval_tool(eval_tool_ptr); 01180 01181 // go through each of this surface's curves and create CurveFacetEvalTools 01182 01183 DLIList<ChollaCurve *> chcurv_list; 01184 chsurf_ptr->get_curves( chcurv_list ); 01185 for (ii=0; ii<chcurv_list.size(); ii++) 01186 { 01187 ChollaCurve *chcurv_ptr = chcurv_list.get_and_step(); 01188 01189 if (chcurv_ptr->get_eval_tool() == NULL) 01190 { 01191 //fix up the orientation of the Cholla curve 01192 stat = chcurv_ptr->order_edges(); 01193 if ( stat != CUBIT_SUCCESS ) 01194 { 01195 PRINT_ERROR("Problems ordering edges!!!!!\n"); 01196 return stat; 01197 } 01198 01199 DLIList<FacetEntity*> facet_ents; 01200 facet_ents = chcurv_ptr->get_facet_list(); 01201 DLIList<CubitFacetEdge*> edge_facets; 01202 CAST_LIST(facet_ents, edge_facets, CubitFacetEdge ); 01203 DLIList<CubitPoint*> ordered_points; 01204 01205 for( int k=0; k<edge_facets.size(); k++ ) 01206 { 01207 CubitFacetEdge *tmp_edge = edge_facets.get_and_step(); 01208 if( k==0 ) 01209 { 01210 ordered_points.append( tmp_edge->point(0) ); 01211 ordered_points.append( tmp_edge->point(1) ); 01212 } 01213 else 01214 ordered_points.append( tmp_edge->point(1) ); 01215 } 01216 01217 CurveFacetEvalTool *curv_eval_tool_ptr = new CurveFacetEvalTool; 01218 edge_facets.reset(); 01219 stat = curv_eval_tool_ptr->initialize( edge_facets, ordered_points, eval_tool_ptr ); 01220 01221 if ( stat != CUBIT_SUCCESS ) 01222 { 01223 return stat; 01224 } 01225 chcurv_ptr->assign_eval_tool( curv_eval_tool_ptr ); 01226 } 01227 } 01228 } 01229 return stat; 01230 } 01231 01232 CubitStatus ChollaEngine::rebuild_surface_and_curve_eval_tools( 01233 DLIList<ChollaSurface*> &cholla_surface_list, 01234 int interp_order, 01235 double min_dot ) 01236 { 01237 CubitStatus stat = CUBIT_SUCCESS; 01238 int ii, kk; 01239 01240 // make sure the facet flags have been reset 01241 for ( kk = cholla_surface_list.size(); kk > 0; kk-- ) 01242 { 01243 ChollaSurface *chsurf_ptr = cholla_surface_list.get_and_step(); 01244 chsurf_ptr->reset_facet_flags(); 01245 } 01246 01247 // get unique list of curves 01248 DLIList<ChollaCurve *> all_chcurves; 01249 for ( kk = cholla_surface_list.size(); kk > 0; kk-- ) 01250 { 01251 ChollaSurface *chsurf_ptr = cholla_surface_list.get_and_step(); 01252 DLIList<ChollaCurve *> chcurv_list; 01253 chsurf_ptr->get_curves( chcurv_list ); 01254 all_chcurves += chcurv_list; 01255 } 01256 all_chcurves.uniquify_ordered(); 01257 01258 // now loop through surfaces and create them 01259 01260 for ( kk = cholla_surface_list.size(); kk > 0; kk-- ) 01261 { 01262 ChollaSurface *chsurf_ptr = cholla_surface_list.get_and_step(); 01263 DLIList<FacetEntity*> facet_entity_list; 01264 DLIList<CubitPoint*> point_list; 01265 chsurf_ptr->get_points(point_list); 01266 chsurf_ptr->get_facets(facet_entity_list); 01267 DLIList<CubitFacet*> facet_list; 01268 CAST_LIST( facet_entity_list, facet_list, CubitFacet ); 01269 01270 FacetEvalTool *eval_tool_ptr = chsurf_ptr->get_eval_tool(); 01271 if (NULL != eval_tool_ptr) 01272 { 01273 DLIList<CubitFacet*> facets; 01274 eval_tool_ptr->remove_facets(facets); 01275 delete eval_tool_ptr; 01276 } 01277 01278 eval_tool_ptr = new FacetEvalTool(); 01279 if ( CUBIT_SUCCESS != eval_tool_ptr->initialize(facet_list, point_list, interp_order, min_dot) ) 01280 { 01281 return CUBIT_FAILURE; 01282 } 01283 01284 //eval_tool_ptr = new FacetEvalTool(); 01285 //eval_tool_ptr->replace_facets(facet_list); 01286 01287 chsurf_ptr->assign_eval_tool(eval_tool_ptr); 01288 } 01289 01290 // go through each of the curves and create CurveFacetEvalTools 01291 for (ii=0; ii<all_chcurves.size(); ii++) 01292 { 01293 ChollaCurve *chcurv_ptr = all_chcurves.get_and_step(); 01294 01295 CubitStatus rv = chcurv_ptr->order_edges(); 01296 if (CUBIT_SUCCESS != rv) { 01297 PRINT_ERROR("Failed to order edges.\n"); 01298 return rv; 01299 } 01300 01301 CurveFacetEvalTool* curve_eval = chcurv_ptr->get_eval_tool(); 01302 if (NULL != curve_eval) 01303 { 01304 DLIList<CubitFacetEdge*> eval_facets; 01305 curve_eval->remove_facets(eval_facets); 01306 delete curve_eval; 01307 } 01308 01309 DLIList<FacetEntity*> facet_ents; 01310 facet_ents = chcurv_ptr->get_facet_list(); 01311 DLIList<CubitFacetEdge*> edge_facets; 01312 CAST_LIST(facet_ents, edge_facets, CubitFacetEdge ); 01313 DLIList<CubitPoint*> ordered_points; 01314 01315 for( int k=0; k<edge_facets.size(); k++ ) 01316 { 01317 CubitFacetEdge *tmp_edge = edge_facets.get_and_step(); 01318 if( k==0 ) 01319 { 01320 ordered_points.append( tmp_edge->point(0) ); 01321 ordered_points.append( tmp_edge->point(1) ); 01322 } 01323 else 01324 ordered_points.append( tmp_edge->point(1) ); 01325 } 01326 01327 CurveFacetEvalTool *curv_eval_tool_ptr = new CurveFacetEvalTool; 01328 edge_facets.reset(); 01329 ordered_points.reset(); 01330 stat = curv_eval_tool_ptr->initialize( edge_facets, ordered_points); 01331 01332 if ( stat != CUBIT_SUCCESS ) 01333 { 01334 return stat; 01335 } 01336 chcurv_ptr->assign_eval_tool( curv_eval_tool_ptr ); 01337 } 01338 01339 return stat; 01340 } 01341 01342 //=============================================================================== 01343 //Function: determine_curve_orientation (static PUBLIC) 01344 //Description: Determine orientation of the curve with respect to the surface 01345 //=============================================================================== 01346 CubitStatus ChollaEngine::determine_curve_orientation( 01347 ChollaSurface *chsurf_ptr, 01348 ChollaCurve *chcurv_ptr, 01349 CubitSense & orientation ) 01350 { 01351 // get the first mesh edge on the curve. use it to determine the 01352 // orientation of the curve with respect to the surface 01353 01354 DLIList<FacetEntity*> facet_list = chcurv_ptr->get_facet_list(); 01355 facet_list.reset(); 01356 FacetEntity *facet_ptr = facet_list.get(); 01357 CubitFacetEdge *edge_ptr = CAST_TO( facet_ptr, CubitFacetEdge ); 01358 if (!edge_ptr) 01359 return CUBIT_FAILURE; // facet edges are not on the list - we shouldn't be here 01360 01361 // get the adjacent face on this surface 01362 01363 DLIList<FacetEntity*> adj_face_list; 01364 edge_ptr->get_parents( adj_face_list ); 01365 01366 DLIList<FacetEntity*> face_ptrs; 01367 int jj; 01368 for ( jj = 0; jj < adj_face_list.size(); jj++ ) 01369 { 01370 FacetEntity* face_ptr = adj_face_list.get_and_step(); 01371 TDGeomFacet *td_gm_face = TDGeomFacet::get_geom_facet(face_ptr); 01372 DLIList<ChollaSurface*> chsurf_list; 01373 if(td_gm_face) 01374 { 01375 td_gm_face->get_cholla_surfs( chsurf_list ); 01376 if (chsurf_list.size()) 01377 { 01378 ChollaSurface *face_chsurf_ptr = chsurf_list.get(); 01379 if(face_chsurf_ptr == chsurf_ptr) 01380 { 01381 face_ptrs.append(face_ptr); 01382 } 01383 } 01384 } 01385 } 01386 if(!face_ptrs.size()) 01387 return CUBIT_FAILURE; // didn't find an adj face on the surface ??? 01388 01389 01390 // if there are two, we'll just say the orientation is unknown 01391 // this happens when there is a non-manifold, callers are responsible for dealing with those 01392 if(face_ptrs.size() >= 2) 01393 { 01394 orientation = CUBIT_UNKNOWN; 01395 return CUBIT_SUCCESS; 01396 } 01397 01398 FacetEntity* face_ptr = face_ptrs[0]; 01399 01400 // determine orientation of nodes on this mesh face 01401 01402 CubitPoint *start_ptr, *end_ptr; 01403 chcurv_ptr->get_ends( start_ptr, end_ptr ); 01404 end_ptr = edge_ptr->other_point( start_ptr ); 01405 if (end_ptr == NULL) 01406 { 01407 return CUBIT_FAILURE; // the edge list may not be ordered correctly?? 01408 } 01409 CubitPoint *points[3]; 01410 CubitFacet *tri_ptr = CAST_TO( face_ptr, CubitFacet ); 01411 tri_ptr->points( points[0], points[1], points[2] ); 01412 01413 int found = 0; 01414 for ( jj = 0; jj < 3 && !found; jj++ ) 01415 { 01416 if (points[jj] == start_ptr) 01417 { 01418 int next_jj = (jj + 1)%3; 01419 int prev_jj = (jj + 2)%3; 01420 if(points[next_jj] == end_ptr) 01421 { 01422 found = 1; 01423 orientation = CUBIT_FORWARD; 01424 } 01425 else if(points[prev_jj] == end_ptr) 01426 { 01427 found = 1; 01428 orientation = CUBIT_REVERSED; 01429 } 01430 } 01431 } 01432 if (!found) 01433 return CUBIT_FAILURE; // couldn't determine the orientation 01434 01435 return CUBIT_SUCCESS; 01436 } 01437 01438 //=============================================================================== 01439 //Function: clean_geometry (PRIVATE) 01440 //Description: fix the edge control points and the normals so they are conforming 01441 // (or non-conforming) accross curves 01442 //=============================================================================== 01443 CubitStatus ChollaEngine::clean_geometry( 01444 CubitBoolean smooth_non_manifold, 01445 CubitBoolean split_surfaces, 01446 CubitBoolean use_feature_angle, 01447 double mindot, 01448 DLIList <ChollaCurve *> &cholla_curve_list ) 01449 { 01450 int iedge; 01451 ChollaCurve *chcurv_ptr; 01452 FacetEntity *fedge_ptr; 01453 CubitFacetEdge *edge_ptr; 01454 DLIList <FacetEntity *> facet_list; 01455 DLIList<CubitFacetEdge *> feature_edge_list; 01456 int icurve; 01457 for (icurve=0; icurve<cholla_curve_list.size(); icurve++) 01458 { 01459 chcurv_ptr = cholla_curve_list.get_and_step(); 01460 facet_list.clean_out(); 01461 facet_list = chcurv_ptr->get_facet_list( ); 01462 for (iedge=0; iedge<facet_list.size(); iedge++) 01463 { 01464 fedge_ptr = facet_list.get_and_step(); 01465 edge_ptr = CAST_TO( fedge_ptr, CubitFacetEdge ); 01466 feature_edge_list.append( edge_ptr ); 01467 } 01468 } 01469 01470 return fix_geometry( smooth_non_manifold,split_surfaces, 01471 use_feature_angle,mindot, feature_edge_list ); 01472 } 01473 01474 //============================================================================= 01475 //Function: check_all_facet_orientations (PUBLIC) 01476 //Description: check for consistent orientation of the facets and set the 01477 // isBackwards flag on the facets if necessary 01478 //Author: sjowen 01479 //Date: 8/14/01 01480 //============================================================================= 01481 CubitStatus ChollaEngine::check_all_facet_orientations( 01482 DLIList<CubitFacet*> &facet_list, 01483 CubitBoolean do_flip) 01484 { 01485 CubitStatus stat = CUBIT_SUCCESS; 01486 //return CUBIT_SUCCESS; 01487 // mark facets 01488 01489 int ii; 01490 for (ii=0; ii<facet_list.size(); ii++) 01491 facet_list.get_and_step()->marked(1); 01492 01493 int mydebug = 0; 01494 if (mydebug) 01495 { 01496 dcolor(CUBIT_YELLOW_INDEX); 01497 dfldraw(facet_list); 01498 dview(); 01499 } 01500 01501 // recursively loop through all facets making sure we are oriented the same 01502 int nfacets = 0; 01503 CubitFacet *facet_ptr; 01504 while ( nfacets < facet_list.size() ) 01505 { 01506 facet_ptr = facet_list.get_and_step(); 01507 if (facet_ptr->marked() == 1) 01508 { 01509 stat = check_facet_orientation( facet_ptr, do_flip, nfacets, mydebug ); 01510 if (stat!= CUBIT_SUCCESS) 01511 return stat; 01512 } 01513 } 01514 return stat; 01515 } 01516 01517 01518 //============================================================================= 01519 //Function: check_facet_orientation (PUBLIC) 01520 //Description: check for consistent orientation of the facets and change 01521 // orientation if necessary (is NOT recursive function) 01522 //Notes: If do_flip is CUBIT_TRUE, then the facet topology is actually 01523 // changed. Otherwise the is_backwards flag is set 01524 //Author: sjowen 01525 //Date: 6/3/01 01526 //============================================================================= 01527 CubitStatus ChollaEngine::check_facet_orientation( 01528 CubitFacet *start_facet, 01529 CubitBoolean do_flip, 01530 int &nfacets, int mydebug ) 01531 { 01532 01533 int jj; 01534 CubitFacet *adjfacet, *facet; 01535 CubitPoint *cpt0, *cpt1, *adjpt; 01536 DLIList<CubitFacet *>temp_flist; 01537 DLIList<CubitFacet *>adj_facet_list; 01538 temp_flist.append(start_facet); 01539 if (mydebug) 01540 { 01541 dcolor(CUBIT_RED_INDEX); 01542 dfdraw(start_facet); 01543 } 01544 nfacets++; 01545 start_facet->marked( 0 ); 01546 int adjidx; 01547 while(temp_flist.size()) 01548 { 01549 facet = temp_flist.pop(); 01550 if (facet->marked() == 0) 01551 { 01552 for (jj=0; jj<3; jj++) 01553 { 01554 cpt0 = facet->point(jj); 01555 cpt1 = facet->point((jj+1)%3); 01556 adj_facet_list.clean_out(); 01557 facet->shared_facets(cpt0, cpt1, adj_facet_list); 01558 if(adj_facet_list.size()==1) 01559 { 01560 adjfacet = adj_facet_list.get(); 01561 if (adjfacet->marked() == 1) 01562 { 01563 adjidx = adjfacet->point_index( cpt1 ); 01564 if (adjidx == -1) 01565 { 01566 return CUBIT_FAILURE; 01567 } 01568 adjpt = adjfacet->point((adjidx+1)%3); 01569 if (adjpt != cpt0) 01570 { 01571 // the orientation is not consistent -- flip the orientation of the 01572 // adjacent facet 01573 01574 // an assertion here means that the facets really don't share an 01575 // edge. Should not happen! 01576 01577 if (adjfacet->point((adjidx+2)%3) != cpt0) 01578 { 01579 return CUBIT_FAILURE; 01580 } 01581 01582 if (do_flip) 01583 { 01584 adjfacet->flip(); 01585 } 01586 else 01587 { 01588 if(adjfacet->is_backwards()) 01589 adjfacet->is_backwards( 0 ); 01590 else 01591 adjfacet->is_backwards( 1 ); 01592 } 01593 if(mydebug){ 01594 adjfacet->debug_draw(CUBIT_WHITE_INDEX); 01595 } 01596 } 01597 01598 // put its neighbor on the list to be processed later 01599 01600 if (adjfacet->marked() == 1) 01601 { 01602 temp_flist.append( adjfacet ); 01603 adjfacet->marked( 0 ); 01604 if(mydebug) 01605 { 01606 dfdraw(adjfacet); 01607 } 01608 nfacets++; 01609 } 01610 } 01611 } 01612 } 01613 } 01614 } 01615 if(mydebug) 01616 GfxDebug::mouse_xforms(); 01617 return CUBIT_SUCCESS; 01618 } 01619 01620 01621 #ifdef ALPHA_CABLE 01622 //============================================================================= 01623 //Function: split_surface_at_edges (PUBLIC) 01624 //Description: Given a list of edges that divides a surface into two, this 01625 // function splits the surface and modifies the engine to represent the 01626 // new geometry. 01627 //Author: mbrewer 01628 //Date: 4/22/2004 01629 //============================================================================= 01630 CubitStatus ChollaEngine::split_surface_at_edges( 01631 ChollaSurface* owning_surface, 01632 DLIList<CubitFacetEdge *> &feature_edge_list, 01633 DLIList<ChollaCurve*> &cholla_curves, 01634 DLIList<ChollaSurface*> &cholla_surfaces) 01635 { 01636 int i=0; 01637 DLIList<ChollaSurface*> original_surfaces = chollaSurfaceList; 01638 DLIList<ChollaCurve*> original_curves = chollaCurveList; 01639 //mark edges as feature 01640 CubitFacetEdge* edge_ptr=NULL; 01641 for(i=0;i<feature_edge_list.size();++i){ 01642 edge_ptr=feature_edge_list.get_and_step(); 01643 TDGeomFacet::add_geom_facet(edge_ptr, -1); 01644 TDGeomFacet* td_gm_edge = TDGeomFacet::get_geom_facet(edge_ptr); 01645 edge_ptr->set_as_feature(); 01646 } 01647 //Michael temp 01648 DLIList<FacetEntity*> *surf_facet_list=owning_surface->get_facet_list_ptr(); 01649 int surface_id = owning_surface->get_id(); 01650 for(i=0;i<surf_facet_list->size();++i){ 01651 FacetEntity* face_ptr = surf_facet_list->get_and_step(); 01652 TDGeomFacet *td_gm_face = TDGeomFacet::get_geom_facet(face_ptr); 01653 td_gm_face->set_hit_flag(surface_id); 01654 } 01655 01656 CubitStatus rv = make_features( feature_edge_list, CUBIT_FALSE ); 01657 if (rv != CUBIT_SUCCESS) 01658 return rv; 01659 01660 // split up the surface 01661 rv = owning_surface->split_surface( cholla_surfaces ); 01662 if (rv != CUBIT_SUCCESS) 01663 return rv; 01664 01665 for ( i = cholla_surfaces.size(); i > 0; i-- ) 01666 { 01667 ChollaSurface *chsurf_ptr = cholla_surfaces.get_and_step(); 01668 chsurf_ptr->update_boundary_tool_data(); 01669 if(chsurf_ptr != owning_surface){ 01670 chollaSurfaceList.append(chsurf_ptr); 01671 01672 } 01673 } 01674 rv = create_surface_boundaries( chollaSurfaceList, chollaCurveList, 01675 CUBIT_FALSE, 0.0); 01676 if ( !rv ) 01677 return rv; 01678 01679 rv = create_curve_boundaries( chollaCurveList, chollaPointList ); 01680 if ( !rv ) 01681 return rv; 01682 01683 rv = build_eval_tools( chollaSurfaceList, 01684 chollaCurveList, 01685 0, CUBIT_FALSE, 01686 0, CUBIT_FALSE, CUBIT_FALSE); 01687 01688 01689 cholla_surfaces = chollaSurfaceList; 01690 cholla_curves = chollaCurveList; 01691 01692 cholla_surfaces -= original_surfaces; 01693 cholla_curves -= original_curves; 01694 01695 return rv; 01696 } 01697 #endif//cable 01698 01699 //============================================================================= 01700 //Function: make_features (PRIVATE) 01701 //Description: add additional edges and points where feature angle requires 01702 // a break in the surface 01703 //Author: sjowen 01704 //Date: 4/31/01 01705 //============================================================================= 01706 CubitStatus ChollaEngine::make_features( 01707 DLIList<CubitFacetEdge *> &feature_edge_list, 01708 CubitBoolean split_surfaces ) 01709 { 01710 CubitStatus rv = CUBIT_SUCCESS; 01711 int ii, jj; 01712 CubitFacetEdge *edge_ptr; 01713 CubitPoint *point_ptr; 01714 int mydebug = 0; 01715 if(mydebug) 01716 GfxDebug::clear(); 01717 for (ii=0; ii<feature_edge_list.size(); ii++) 01718 { 01719 edge_ptr = feature_edge_list.get_and_step(); 01720 if(mydebug) 01721 edge_ptr->debug_draw(CUBIT_YELLOW_INDEX); 01722 for (jj=0; jj<2; jj++) 01723 { 01724 point_ptr = edge_ptr->point( jj ); 01725 point_ptr->marked( 0 ); 01726 } 01727 edge_ptr->set_flag( 1 ); // mark edges as being feature edges 01728 } 01729 01730 if (mydebug) 01731 { 01732 GfxDebug::mouse_xforms(); 01733 dcolor(CUBIT_WHITE_INDEX); 01734 deldraw(feature_edge_list); 01735 dview(); 01736 } 01737 01738 for (ii=0; ii<feature_edge_list.size(); ii++) 01739 { 01740 edge_ptr = feature_edge_list.get_and_step(); 01741 for (jj=0; jj<2; jj++) 01742 { 01743 point_ptr = edge_ptr->point( jj ); 01744 if (0 == point_ptr->marked()) 01745 { 01746 point_ptr->marked(1); 01747 if (split_surfaces) 01748 rv = crack_open_point( point_ptr, mydebug ); 01749 else 01750 rv = insert_discontinuity_at_point( point_ptr ); 01751 if (rv != CUBIT_SUCCESS) 01752 return rv; 01753 } 01754 } 01755 } 01756 01757 for (ii=0; ii<feature_edge_list.size(); ii++) 01758 { 01759 feature_edge_list.get_and_step()->set_flag( 0 ); 01760 } 01761 return rv; 01762 } 01763 01764 //============================================================================= 01765 //Function: crack_open_point (PRIVATE) 01766 //Description: split the surface facets at a point if required. Create 01767 // new points and edges as needed 01768 //Author: sjowen 01769 //Date: 4/31/01 01770 //============================================================================= 01771 CubitStatus ChollaEngine::crack_open_point( 01772 CubitPoint *point_ptr, 01773 int mydebug ) 01774 { 01775 CubitStatus rv = CUBIT_SUCCESS; 01776 01777 // get facets at this point and mark them all ready for recursion function 01778 // get_facets_at_point 01779 01780 int ii, jj; 01781 DLIList<CubitFacet *> facet_list; 01782 point_ptr->facets( facet_list ); 01783 CubitFacet *facet_ptr, *adj_facet_ptr; 01784 for (ii=0; ii<facet_list.size(); ii++) 01785 { 01786 facet_ptr = facet_list.get_and_step(); 01787 facet_ptr->marked( 0 ); 01788 } 01789 01790 // go through and find groups of adjacent facets that will form part of 01791 // new surfaces 01792 01793 int totfacets = facet_list.size(); 01794 int numfacets = 0; 01795 while(numfacets < totfacets) 01796 { 01797 facet_list.clean_out(); 01798 point_ptr->facets( facet_list ); 01799 facet_ptr = facet_list.get(); 01800 DLIList<CubitFacet *> adj_facet_list; 01801 DLIList<CubitFacetEdge *>feature_edge_list; 01802 01803 // make a list of all facets adjacet this point that are bounded 01804 // by feature edges. Start with facet_ptr and recurse until 01805 // we bump into feature edges at the point. 01806 01807 rv = get_facets_at_point( point_ptr, facet_ptr, adj_facet_list, 01808 feature_edge_list ); 01809 numfacets += adj_facet_list.size(); 01810 01811 // if the number of facets for this feature are the same as the number of 01812 // facets at this point, then we are done with this point. Otherwise 01813 // create new point and edges 01814 01815 if (numfacets < totfacets) 01816 { 01817 // create a new point and update the facets 01818 01819 CubitPoint *new_point_ptr = 01820 new CubitPointData( point_ptr->coordinates() ); 01821 TDGeomFacet::add_geom_facet( new_point_ptr , -1); 01822 for (ii=0; ii<adj_facet_list.size(); ii++) 01823 { 01824 adj_facet_ptr = adj_facet_list.get_and_step(); 01825 01826 // facet modifications can only occur with native CUBIT facet data 01827 // if we are using someone else's data (ie. Sierra) then fail. 01828 // (Should not be using split_surfaces = TRUE) 01829 01830 CubitFacetData *cfd_ptr = CAST_TO( adj_facet_ptr, CubitFacetData ); 01831 if (!cfd_ptr) 01832 return CUBIT_FAILURE; 01833 new_point_ptr->add_facet( adj_facet_ptr ); 01834 point_ptr->remove_facet( adj_facet_ptr ); 01835 int pidx = adj_facet_ptr->point_index( point_ptr ); 01836 cfd_ptr->set_point( new_point_ptr, pidx ); 01837 } 01838 01839 // The existing and the new points in some cases have to maintain 01840 // the same normal... so they need to keep track of 01841 // each other. They will likely wind up on different surfaces 01842 // and we don't want to go search for them later 01843 01844 TDGeomFacet *td_existing_point = TDGeomFacet::get_geom_facet( point_ptr ); 01845 TDGeomFacet *td_new_point = TDGeomFacet::get_geom_facet( new_point_ptr ); 01846 DLIList<CubitPoint *> partner_point_list; 01847 01848 // add the existing point's partner list to the new point 01849 01850 CubitPoint *partner_point_ptr; 01851 TDGeomFacet *td_partner; 01852 td_existing_point->get_partner_points( partner_point_list ); 01853 for (ii=0; ii<partner_point_list.size(); ii++) 01854 { 01855 partner_point_ptr = partner_point_list.get_and_step(); 01856 td_partner = TDGeomFacet::get_geom_facet( partner_point_ptr ); 01857 //added mbrewer: the check for a pointer here shouldn't 01858 // be necessary, but I have a case where it fails. I don't 01859 // see where the logic is wrong. 01860 if(!td_partner){ 01861 TDGeomFacet::add_geom_facet( partner_point_ptr , -1); 01862 td_partner = TDGeomFacet::get_geom_facet( partner_point_ptr ); 01863 } 01864 td_partner->add_partner_point( new_point_ptr ); 01865 td_new_point->add_partner_point( partner_point_ptr ); 01866 } 01867 01868 // Add each other as a partner 01869 01870 td_existing_point->add_partner_point( new_point_ptr ); 01871 td_new_point->add_partner_point( point_ptr ); 01872 01873 // create new edges at the point 01874 01875 CubitFacetEdgeData *cfed_ptr; 01876 for (ii=0; ii<feature_edge_list.size(); ii++) 01877 { 01878 CubitFacetEdge *edge_ptr = feature_edge_list.get_and_step(); 01879 cfed_ptr = CAST_TO( edge_ptr, CubitFacetEdgeData ); 01880 if (!cfed_ptr) 01881 return CUBIT_FAILURE; 01882 rv = CUBIT_FAILURE; 01883 for (jj=0; jj<adj_facet_list.size() && rv == CUBIT_FAILURE; jj++) 01884 { 01885 rv = cfed_ptr->remove_facet( adj_facet_list.get_and_step() ); 01886 } 01887 if (rv != CUBIT_SUCCESS) 01888 return rv; 01889 CubitPoint *p1 = edge_ptr->other_point( point_ptr ); 01890 01891 // create a new edge - the edge constructor will update 01892 // the facet and its edge use. 01893 01894 CubitFacetEdge *new_edge_ptr = 01895 new CubitFacetEdgeData( new_point_ptr, p1 ); 01896 TDGeomFacet::add_geom_facet( new_edge_ptr, -1 ); 01897 new_edge_ptr->set_as_feature(); 01898 if (mydebug) 01899 { 01900 dcolor(CUBIT_RED_INDEX); 01901 dedraw(new_edge_ptr); 01902 } 01903 01904 // The existing and the new edges have to maintain the same 01905 // control point locations, so they need to keep track of 01906 // each other. They will likely wind up on different surfaces 01907 // and we don't want to go search for them later 01908 01909 TDGeomFacet *td_existing_edge = TDGeomFacet::get_geom_facet( edge_ptr ); 01910 TDGeomFacet *td_new_edge = TDGeomFacet::get_geom_facet( new_edge_ptr ); 01911 DLIList<CubitFacetEdge *> partner_edge_list; 01912 01913 // add the existing edge's partner list to the new edge 01914 01915 CubitFacetEdge *partner_edge_ptr; 01916 td_existing_edge->get_partner_edges( partner_edge_list ); 01917 for (jj=0; jj<partner_edge_list.size(); jj++) 01918 { 01919 partner_edge_ptr = partner_edge_list.get_and_step(); 01920 td_partner = TDGeomFacet::get_geom_facet( partner_edge_ptr ); 01921 td_partner->add_partner_edge( new_edge_ptr ); 01922 td_new_edge->add_partner_edge( partner_edge_ptr ); 01923 } 01924 01925 // Add each other as a partner 01926 01927 td_existing_edge->add_partner_edge( new_edge_ptr ); 01928 td_new_edge->add_partner_edge( edge_ptr ); 01929 } 01930 01931 // update the other edges with the new point 01932 01933 for (ii=0; ii<adj_facet_list.size(); ii++) 01934 { 01935 adj_facet_ptr = adj_facet_list.get_and_step(); 01936 for (jj=0; jj<3; jj++) 01937 { 01938 CubitFacetEdge *edge_ptr = adj_facet_ptr->edge( jj ); 01939 cfed_ptr = CAST_TO( edge_ptr, CubitFacetEdgeData ); 01940 if (!cfed_ptr) 01941 return CUBIT_FAILURE; 01942 if (cfed_ptr->point( 0 ) == point_ptr) 01943 cfed_ptr->set_point( new_point_ptr, 0 ); 01944 if (cfed_ptr->point( 1 ) == point_ptr) 01945 cfed_ptr->set_point( new_point_ptr, 1 ); 01946 } 01947 } 01948 } 01949 } 01950 01951 return rv; 01952 } 01953 01954 //============================================================================= 01955 //Function: insert_discontinuity_at_point (PRIVATE) 01956 //Description: does the same as crack_open_point, but does not create new 01957 // facet entities at surface boundaries. Instead, it creates 01958 // facet boundary tooldatas to hold the additional control point 01959 // and normal data 01960 //Author: sjowen 01961 //Date: 4/31/01 01962 //============================================================================= 01963 CubitStatus ChollaEngine::insert_discontinuity_at_point( 01964 CubitPoint *point_ptr ) 01965 { 01966 CubitStatus rv = CUBIT_SUCCESS; 01967 01968 // get facets at this point and mark them all ready for recursion function 01969 // get_facets_at_point 01970 01971 int ii; 01972 DLIList<CubitFacet *> facet_list; 01973 point_ptr->facets( facet_list ); 01974 CubitFacet *facet_ptr = NULL; 01975 for (ii=0; ii<facet_list.size(); ii++) 01976 { 01977 facet_ptr = facet_list.get_and_step(); 01978 facet_ptr->marked( 0 ); 01979 } 01980 01981 int mydebug = 0; 01982 if (mydebug) { 01983 dfldraw(facet_list); 01984 dview(); 01985 } 01986 01987 // go through and find groups of adjacent facets that will form part of 01988 // new surfaces 01989 01990 TDFacetBoundaryPoint *td_fbp = 01991 TDFacetBoundaryPoint::get_facet_boundary_point( point_ptr ); 01992 int totfacets = facet_list.size(); 01993 int numfacets = 0; 01994 while(numfacets < totfacets) 01995 { 01996 ii = 0; 01997 int found = 0; 01998 while(!found && ii < totfacets ) 01999 { 02000 ii++; 02001 facet_ptr = facet_list.get_and_step(); 02002 if (facet_ptr != NULL) 02003 found = 1; 02004 } 02005 assert(found); 02006 DLIList<CubitFacet *> adj_facet_list; 02007 DLIList<CubitFacetEdge *>feature_edge_list; 02008 02009 // make a list of all facets adjacet this point that are bounded 02010 // by feature edges. Start with facet_ptr and recurse until 02011 // we bump into feature edges at the point. 02012 02013 rv = get_facets_at_point( point_ptr, facet_ptr, adj_facet_list, 02014 feature_edge_list ); 02015 02016 if (rv != CUBIT_SUCCESS) 02017 return rv; 02018 numfacets += adj_facet_list.size(); 02019 for (ii=0; ii<adj_facet_list.size(); ii++) 02020 { 02021 facet_list.move_to( adj_facet_list.get_and_step() ); 02022 facet_list.change_to( NULL ); 02023 } 02024 02025 // create a new boundary point tooldata if needed and add the facets 02026 // associated with this surface 02027 02028 if (td_fbp == NULL) 02029 { 02030 TDFacetBoundaryPoint::add_facet_boundary_point( point_ptr ); 02031 td_fbp = TDFacetBoundaryPoint::get_facet_boundary_point( point_ptr ); 02032 } 02033 td_fbp->add_surf_facets( adj_facet_list ); 02034 02035 // create new boundary edge tooldatas at the point 02036 for (ii=0; ii<feature_edge_list.size(); ii++) 02037 { 02038 CubitFacetEdge *edge_ptr = feature_edge_list.get_and_step(); 02039 02040 TDFacetBoundaryEdge *td_fbe = 02041 TDFacetBoundaryEdge::get_facet_boundary_edge( edge_ptr ); 02042 if (td_fbe == NULL) 02043 { 02044 TDFacetBoundaryEdge::add_facet_boundary_edge( edge_ptr ); 02045 td_fbe = TDFacetBoundaryEdge::get_facet_boundary_edge( edge_ptr ); 02046 } 02047 td_fbe->add_surf_facet( adj_facet_list ); 02048 } 02049 } 02050 02051 return rv; 02052 } 02053 02054 //============================================================================= 02055 //Function: get_facets_at_point (PRIVATE) 02056 //Description: make a list of all faces adjacent to a single point that are 02057 // bounded by feature edges - recursive function 02058 //Author: sjowen 02059 //Date: 5/2/01 02060 //============================================================================= 02061 CubitStatus ChollaEngine::get_facets_at_point( 02062 CubitPoint *point_ptr, 02063 CubitFacet *facet_ptr, 02064 DLIList<CubitFacet *> &facet_list, 02065 DLIList<CubitFacetEdge *> &feature_edge_list) 02066 { 02067 CubitStatus rv = CUBIT_SUCCESS; 02068 CubitFacetEdge *edge_ptr; 02069 CubitFacet *adj_facet; 02070 facet_list.append(facet_ptr); 02071 facet_ptr->marked( 1 ); 02072 02073 for (int ii=0; ii<3; ii++) 02074 { 02075 edge_ptr = facet_ptr->edge( ii ); 02076 if (edge_ptr->contains( point_ptr )) 02077 { 02078 if (!edge_ptr->is_feature()) 02079 { 02080 if (edge_ptr->num_adj_facets() >2) 02081 return CUBIT_FAILURE; 02082 adj_facet = edge_ptr->other_facet( facet_ptr ); 02083 if (adj_facet == NULL) 02084 return CUBIT_FAILURE; 02085 if (adj_facet->marked() == 0) 02086 { 02087 rv = get_facets_at_point( point_ptr, adj_facet, 02088 facet_list, feature_edge_list ); 02089 if (rv != CUBIT_SUCCESS) 02090 return rv; 02091 } 02092 } 02093 else 02094 { 02095 if (edge_ptr->num_adj_facets() > 1) 02096 { 02097 feature_edge_list.append_unique( edge_ptr ); 02098 } 02099 } 02100 } 02101 } 02102 return rv; 02103 } 02104 02105 //=============================================================================== 02106 //Function: fix_geometry (PUBLIC) 02107 //Description: fix the edge control points and the normals so they are conforming 02108 // (or non-conforming) accross curves 02109 //=============================================================================== 02110 CubitStatus ChollaEngine::fix_geometry( 02111 CubitBoolean smooth_non_manifold, 02112 CubitBoolean split_surfaces, 02113 CubitBoolean /* use_feature_angle */, 02114 double mindot, 02115 DLIList <CubitFacetEdge *> &feature_edge_list ) 02116 { 02117 CubitStatus stat = CUBIT_SUCCESS; 02118 02119 // unmark all the edges and points 02120 02121 CubitFacetEdge *edge_ptr; 02122 int iedge; 02123 int flag = (smooth_non_manifold) ? 0 : 1; 02124 for (iedge = 0; iedge < feature_edge_list.size(); iedge++) 02125 { 02126 edge_ptr = feature_edge_list.get_and_step(); 02127 edge_ptr->set_flag( flag ); 02128 edge_ptr->point( 0 )->marked( flag ); 02129 edge_ptr->point( 1 )->marked( flag ); 02130 } 02131 02132 // for non-manifold edges, find sets of adjacent facets that 02133 // we can smooth across. If adjacent facets do not satisfy the 02134 // feature angle criteria, then they should have C1 continuity 02135 // across the edge. To do this, the normals at the edge's 02136 // points on partner edges will need to be the same. This next 02137 // piece of code potentially alters the point normals. As a result 02138 // edge and facet control points will need to be updated. 02139 02140 DLIList<CubitFacet *>update_facet_list; 02141 if (smooth_non_manifold) 02142 { 02143 DLIList <CubitPoint *> changed_points; 02144 for (iedge = 0; iedge < feature_edge_list.size(); iedge++) 02145 { 02146 edge_ptr = feature_edge_list.get_and_step(); 02147 if (edge_ptr->get_flag() == 1) 02148 continue; 02149 edge_ptr->set_flag( 1 ); 02150 if (split_surfaces) 02151 stat = fix_split_non_manifold_edge( edge_ptr, mindot, 02152 changed_points ); 02153 else 02154 stat = fix_non_manifold_edge( edge_ptr, mindot, 02155 changed_points ); 02156 if (stat != CUBIT_SUCCESS) 02157 return stat; 02158 } 02159 if (changed_points.size() > 0) 02160 stat = update_edges_at_points( split_surfaces, 02161 changed_points, 02162 update_facet_list, 02163 mindot ); 02164 if (stat != CUBIT_SUCCESS) 02165 return stat; 02166 } 02167 02168 // For all cases we need to ensure that partner edges share the same 02169 // control, point locations. This piece of code goes through and 02170 // computes an average location for control points on partner edges 02171 // and sets them back on the edge 02172 02173 for (iedge = 0; iedge < feature_edge_list.size(); iedge++) 02174 { 02175 edge_ptr = feature_edge_list.get_and_step(); 02176 if (edge_ptr->get_flag() == 2) 02177 continue; 02178 edge_ptr->set_flag( 2 ); 02179 if (split_surfaces) 02180 stat = fix_split_edge( edge_ptr, update_facet_list ); 02181 else 02182 stat = fix_edge( edge_ptr, update_facet_list ); 02183 if (stat != CUBIT_SUCCESS) 02184 return stat; 02185 } 02186 02187 // since we have potentially modified the point normals and edge 02188 // control points, we need to fix the facet control points (interior 02189 // to the facet) The update_facet_list contains a non-unique list of 02190 // facets that will need to be recomputed. 02191 02192 int ii; 02193 CubitFacet *facet_ptr; 02194 for (ii=0; ii<update_facet_list.size(); ii++) 02195 update_facet_list.get_and_step()->marked( 0 ); 02196 02197 for (ii=0; ii<update_facet_list.size(); ii++) 02198 { 02199 facet_ptr = update_facet_list.get_and_step(); 02200 if (facet_ptr->marked() == 0) 02201 { 02202 facet_ptr->marked( 1 ); 02203 stat = FacetEvalTool::init_bezier_facet( facet_ptr ); 02204 if (stat != CUBIT_SUCCESS) 02205 return stat; 02206 } 02207 } 02208 02209 for (ii=0; ii<update_facet_list.size(); ii++) 02210 update_facet_list.get_and_step()->marked( 0 ); 02211 02212 return stat; 02213 } 02214 02215 //=============================================================================== 02216 //Function: update_edges_at_points (PRIVATE) 02217 //Description: recompute the edge control points at all facets sharing 02218 // points in the list 02219 //Date: 05/01 02220 //=============================================================================== 02221 CubitStatus ChollaEngine::update_edges_at_points( 02222 CubitBoolean /* split_surfaces */, // we are splitting facets to create geometry 02223 DLIList<CubitPoint *> &point_list, // points whose edges will be updated 02224 DLIList<CubitFacet *> &facet_update_list, // append facets adjacent edges that 02225 // will be updated later 02226 double mindot ) 02227 { 02228 CubitStatus stat = CUBIT_SUCCESS; 02229 CubitPoint *point_ptr; 02230 CubitFacetEdge *edge_ptr; 02231 DLIList <CubitFacetEdge *> edge_list; 02232 int ii; 02233 for (ii=0; ii<point_list.size(); ii++) 02234 { 02235 point_ptr = point_list.get_and_step(); 02236 point_ptr->edges( edge_list ); 02237 point_ptr->facets( facet_update_list ); 02238 } 02239 for (ii=0; ii<edge_list.size(); ii++) 02240 { 02241 edge_ptr = edge_list.get_and_step(); 02242 edge_ptr->set_flag( 0 ); 02243 } 02244 for (ii=0; ii<edge_list.size(); ii++) 02245 { 02246 edge_ptr = edge_list.get_and_step(); 02247 if (edge_ptr->get_flag() == 0) 02248 { 02249 edge_ptr->set_flag( 1 ); 02250 stat = FacetEvalTool::init_bezier_edge( edge_ptr, mindot ); 02251 } 02252 } 02253 return stat; 02254 } 02255 02256 //=============================================================================== 02257 //Function: fix_edge (PRIVATE) 02258 //Description: Enforce the condition where all partner edges to this edge 02259 // share the same control points. Compute the average of the 02260 // partner control points and set on the edge 02261 //Date: 05/01 02262 //=============================================================================== 02263 CubitStatus ChollaEngine::fix_edge( CubitFacetEdge *edge_ptr, 02264 DLIList<CubitFacet *> &update_facet_list) 02265 { 02266 if (edge_ptr->num_adj_facets() == 1) 02267 return CUBIT_SUCCESS; 02268 TDFacetBoundaryEdge *td_fbe = 02269 TDFacetBoundaryEdge::get_facet_boundary_edge( edge_ptr ); 02270 if (!td_fbe) 02271 return CUBIT_FAILURE; 02272 02273 edge_ptr->facets( update_facet_list ); 02274 CubitStatus stat = td_fbe->merge_control_points(); 02275 return stat; 02276 } 02277 02278 //=============================================================================== 02279 //Function: fix_split_edge (PRIVATE) 02280 //Description: Enforce the condition where all partner edges to this edge 02281 // share the same control points. Compute the average of the 02282 // partner control points and set on the edge 02283 //Date: 05/01 02284 //=============================================================================== 02285 CubitStatus ChollaEngine::fix_split_edge( CubitFacetEdge *edge_ptr, 02286 DLIList<CubitFacet *> &update_facet_list) 02287 { 02288 02289 // we only need to do this if the edge has any partners. Otherwise return 02290 02291 TDGeomFacet *td = TDGeomFacet::get_geom_facet( edge_ptr ); 02292 if (td->num_partner_edges() == 0) 02293 return CUBIT_SUCCESS; 02294 02295 // get the control points for this edge (oriented with 02296 // respect to point(0) on the edge)--- This means that 02297 // the rest of the partners to this edge must also 02298 // provide control points with respect to the same orientation 02299 02300 CubitVector control_points[3]; 02301 CubitPoint *start_ptr = edge_ptr->point(0); 02302 edge_ptr->get_control_points( start_ptr, control_points ); 02303 02304 // get all this edge's partners 02305 02306 int ii; 02307 CubitVector partner_control_points[3]; 02308 CubitFacetEdge *partner_edge_ptr; 02309 CubitPoint *partner_start_ptr; 02310 DLIList <CubitFacetEdge *> partner_edge_list; 02311 td->get_partner_edges( partner_edge_list ); 02312 for (ii=0; ii<partner_edge_list.size(); ii++) 02313 { 02314 partner_edge_ptr = partner_edge_list.get_and_step(); 02315 partner_edge_ptr->set_flag( 2 ); 02316 02317 // determine the same orientation as the first edge 02318 02319 partner_start_ptr = partner_edge_ptr->point(0); 02320 TDGeomFacet *td_point = TDGeomFacet::get_geom_facet( partner_start_ptr ); 02321 if (!td_point->is_partner( start_ptr )) 02322 { 02323 partner_start_ptr = partner_edge_ptr->point(1); 02324 td_point = TDGeomFacet::get_geom_facet( partner_start_ptr ); 02325 if (!td_point->is_partner( start_ptr )) 02326 { 02327 PRINT_ERROR("Topology error generating facet geometry\n"); 02328 return CUBIT_FAILURE; 02329 } 02330 } 02331 02332 // get the partner's control points and add to the current 02333 // totals 02334 02335 partner_edge_ptr->get_control_points( partner_start_ptr, 02336 partner_control_points ); 02337 control_points[0] += partner_control_points[0]; 02338 control_points[1] += partner_control_points[1]; 02339 control_points[2] += partner_control_points[2]; 02340 02341 // add this edge's adjacent facets to the update facet list 02342 02343 partner_edge_ptr->facets( update_facet_list ); 02344 } 02345 edge_ptr->facets( update_facet_list ); 02346 02347 // average the control point locations 02348 02349 int nedges = partner_edge_list.size() + 1; 02350 control_points[0] /= (double)nedges; 02351 control_points[1] /= (double)nedges; 02352 control_points[2] /= (double)nedges; 02353 02354 // set the new control points back on the edges 02355 02356 edge_ptr->set_control_points( start_ptr, control_points ); 02357 02358 TDGeomFacet *td_point; 02359 for (ii=0; ii<partner_edge_list.size(); ii++) 02360 { 02361 partner_edge_ptr = partner_edge_list.get_and_step(); 02362 02363 // determine the same orientation as the first edge 02364 02365 partner_start_ptr = partner_edge_ptr->point(0); 02366 td_point = TDGeomFacet::get_geom_facet( partner_start_ptr ); 02367 if (!td_point->is_partner( start_ptr )) 02368 { 02369 partner_start_ptr = partner_edge_ptr->point(1); 02370 td_point = TDGeomFacet::get_geom_facet( partner_start_ptr ); 02371 if (!td_point->is_partner( start_ptr )) 02372 { 02373 PRINT_ERROR("Topology error generating facet geometry\n"); 02374 return CUBIT_FAILURE; 02375 } 02376 } 02377 partner_edge_ptr->set_control_points( partner_start_ptr, 02378 control_points ); 02379 } 02380 return CUBIT_SUCCESS; 02381 } 02382 02383 //=============================================================================== 02384 //Function: fix_non_split_manifold_edge (PRIVATE) 02385 //Description: Enforce the condition where partner edges on non-manifold edges 02386 // with >2 adjacent facets that do not satisfy feature criteria 02387 // will have the same normal accross the edge 02388 //Date: 05/01 02389 //=============================================================================== 02390 CubitStatus ChollaEngine::fix_split_non_manifold_edge( 02391 CubitFacetEdge *edge_ptr, 02392 double min_dot, 02393 DLIList <CubitPoint *> &changed_points ) 02394 { 02395 // first check if this edge has 3 or more adjacent facets. Return now if not 02396 02397 CubitStatus stat = CUBIT_SUCCESS; 02398 TDGeomFacet *td = TDGeomFacet::get_geom_facet( edge_ptr ); 02399 int nedges = td->num_partner_edges() + 1; 02400 if (nedges < 3) 02401 return stat; 02402 02403 // make an array of partner edges 02404 02405 std::vector<int> partner0(nedges); 02406 std::vector<int> partner1(nedges); 02407 std::vector<double> partner_dot(nedges); 02408 int num_partners = 0; 02409 std::vector<CubitFacetEdge*> edges(nedges); 02410 02411 edges[0] = edge_ptr; 02412 DLIList<CubitFacetEdge *> partner_list; 02413 td->get_partner_edges( partner_list ); 02414 int ii; 02415 for (ii=0; ii< partner_list.size(); ii++) 02416 { 02417 edges[ii+1] = partner_list.get_and_step(); 02418 edges[ii+1]->set_flag( 1 ); 02419 } 02420 02421 02422 // check each facet against every other facet at this edge to 02423 // see if we need to enforce continuity. There may be several 02424 // cases where the feature angle criteria is (not) met. Find 02425 // the pair that has the greatest dot product between them. 02426 // If more than 1 pair has the same dot product and meets criteria 02427 // then it arbitrarily uses the first one. 02428 02429 int jj, kk; 02430 for (ii=0; ii<nedges-1; ii++) 02431 { 02432 CubitFacet *facet_ptr = edges[ii]->adj_facet( 0 ); 02433 CubitVector normal = facet_ptr->normal(); 02434 normal.normalize(); 02435 double best_dot = -1.0; 02436 for (jj=ii+1; jj<nedges; jj++) 02437 { 02438 CubitFacet *afacet_ptr = edges[jj]->adj_facet( 0 ); 02439 CubitVector anormal = afacet_ptr->normal(); 02440 anormal.normalize(); 02441 double dot = fabs(normal % anormal); 02442 if (dot > min_dot && dot > best_dot) 02443 { 02444 02445 // check to see if this partner pair has not already 02446 // been used in another partnership. If so, then check 02447 // to see if this match is better. Otherwise, ignore 02448 // this match. 02449 02450 int found = 0; 02451 for (kk=0; kk<num_partners; kk++) 02452 { 02453 if (partner0[kk] == ii || partner0[kk] == jj || 02454 partner1[kk] == ii || partner1[kk] == jj) 02455 { 02456 found = 1; 02457 if (dot > partner_dot[kk]) 02458 { 02459 partner_dot[kk] = dot; 02460 partner0[kk] = ii; 02461 partner1[kk] = jj; 02462 } 02463 } 02464 } 02465 if (!found) 02466 { 02467 partner_dot[num_partners] = dot; 02468 partner0[num_partners] = ii; 02469 partner1[num_partners] = jj; 02470 num_partners++; 02471 } 02472 best_dot = dot; 02473 } 02474 } 02475 } 02476 02477 // we found a partner facet(s) that needs to have C1 continuity 02478 // across this facet. Merge the normals on the edge so they 02479 // are the same 02480 02481 for (ii=0; ii<num_partners; ii++) 02482 { 02483 CubitFacetEdge *edge0 = edges[partner0[ii]]; 02484 CubitFacetEdge *edge1 = edges[partner1[ii]]; 02485 for (jj=0; jj<2; jj++) 02486 { 02487 CubitPoint *pt0 = edge0->point(jj); 02488 02489 // find its point partner on the partner edge 02490 02491 CubitPoint *pt1 = edge1->point( 0 ); 02492 td = TDGeomFacet::get_geom_facet( pt0 ); 02493 if (!td->is_partner( pt1 )) 02494 { 02495 pt1 = edge1->point( 1 ); 02496 if (!td->is_partner( pt1 )) 02497 { 02498 PRINT_ERROR("Internal error defining continuity across non-manifold edges\n"); 02499 return CUBIT_FAILURE; 02500 } 02501 } 02502 if (pt0->marked() == 0 || pt1->marked() == 0) 02503 { 02504 pt0->marked( 1 ); 02505 pt1->marked( 1 ); 02506 changed_points.append( pt0 ); 02507 changed_points.append( pt1 ); 02508 stat = merge_normals( pt0, pt1 ); 02509 if (stat != CUBIT_SUCCESS) 02510 return stat; 02511 } 02512 } 02513 } 02514 02515 return stat; 02516 } 02517 02518 //=============================================================================== 02519 //Function: fix_non_manifold_edge (PRIVATE) 02520 //Description: Enforce the condition where partner edges on non-manifold edges 02521 // with >2 adjacent facets that do not satisfy feature criteria 02522 // will have the same normal accross the edge 02523 //Date: 05/01 02524 //=============================================================================== 02525 CubitStatus ChollaEngine::fix_non_manifold_edge( 02526 CubitFacetEdge *edge_ptr, 02527 double min_dot, 02528 DLIList <CubitPoint *> &changed_points ) 02529 { 02530 // first check if this edge has 3 or more adjacent facets. Return now if not 02531 02532 CubitStatus stat = CUBIT_SUCCESS; 02533 int nfacets = edge_ptr->num_adj_facets(); 02534 if (nfacets < 3) 02535 return stat; 02536 02537 TDFacetBoundaryEdge *td_fbe = 02538 TDFacetBoundaryEdge::get_facet_boundary_edge( edge_ptr ); 02539 if (td_fbe == NULL) 02540 { 02541 return CUBIT_FAILURE; // there is supposed to be a tool data here! 02542 } 02543 02544 // make an array of partner edges 02545 02546 int *partner0 = new int [nfacets]; 02547 int *partner1 = new int [nfacets]; 02548 double *partner_dot = new double [nfacets]; 02549 int num_partners = 0; 02550 CubitFacet **facets = new CubitFacet * [nfacets]; 02551 if (!facets || !partner0 || !partner1 || !partner_dot) 02552 return CUBIT_FAILURE; 02553 DLIList <CubitFacet *>adj_facets; 02554 edge_ptr->facets( adj_facets ); 02555 int ii; 02556 for (ii=0; ii< adj_facets.size(); ii++) 02557 { 02558 facets[ii] = adj_facets.get_and_step(); 02559 facets[ii]->marked( 1 ); 02560 } 02561 02562 02563 // check each facet against every other facet at this edge to 02564 // see if we need to enforce continuity. There may be several 02565 // cases where the feature angle criteria is (not) met. Find 02566 // the pair that has the greatest dot product between them. 02567 // If more than 1 pair has the same dot product and meets criteria 02568 // then it arbitrarily uses the first one. 02569 02570 int jj, kk; 02571 for (ii=0; ii<nfacets-1; ii++) 02572 { 02573 CubitFacet *facet_ptr = facets[ii]; 02574 CubitVector normal = facet_ptr->normal(); 02575 normal.normalize(); 02576 double best_dot = -1.0; 02577 for (jj=ii+1; jj<nfacets; jj++) 02578 { 02579 CubitFacet *afacet_ptr = facets[jj]; 02580 CubitVector anormal = afacet_ptr->normal(); 02581 anormal.normalize(); 02582 double dot = fabs(normal % anormal); 02583 if (dot > min_dot && dot > best_dot) 02584 { 02585 02586 // check to see if this partner pair has not already 02587 // been used in another partnership. If so, then check 02588 // to see if this match is better. Otherwise, ignore 02589 // this match. 02590 02591 int found = 0; 02592 for (kk=0; kk<num_partners; kk++) 02593 { 02594 if (partner0[kk] == ii || partner0[kk] == jj || 02595 partner1[kk] == ii || partner1[kk] == jj) 02596 { 02597 found = 1; 02598 if (dot > partner_dot[kk]) 02599 { 02600 partner_dot[kk] = dot; 02601 partner0[kk] = ii; 02602 partner1[kk] = jj; 02603 } 02604 } 02605 } 02606 if (!found) 02607 { 02608 partner_dot[num_partners] = dot; 02609 partner0[num_partners] = ii; 02610 partner1[num_partners] = jj; 02611 num_partners++; 02612 } 02613 best_dot = dot; 02614 } 02615 } 02616 } 02617 02618 // we found a partner facet(s) that needs to have C1 continuity 02619 // across this facet. Merge the normals on the edge so they 02620 // are the same 02621 02622 if (num_partners > 0) 02623 { 02624 CubitPoint *pt0 = edge_ptr->point(0); 02625 CubitPoint *pt1 = edge_ptr->point(1); 02626 TDFacetBoundaryPoint *td_fbp0 = 02627 TDFacetBoundaryPoint::get_facet_boundary_point( pt0 ); 02628 TDFacetBoundaryPoint *td_fbp1 = 02629 TDFacetBoundaryPoint::get_facet_boundary_point( pt1 ); 02630 if (!td_fbp0 || !td_fbp1) { 02631 delete [] facets; 02632 delete [] partner0; 02633 delete [] partner1; 02634 delete [] partner_dot; 02635 return CUBIT_FAILURE; 02636 } 02637 02638 for (ii=0; ii<num_partners; ii++) 02639 { 02640 td_fbp0->merge_normals( facets[partner0[ii]], facets[partner1[ii]] ); 02641 td_fbp1->merge_normals( facets[partner0[ii]], facets[partner1[ii]] ); 02642 } 02643 pt0->marked( 1 ); 02644 pt1->marked( 1 ); 02645 changed_points.append( pt0 ); 02646 changed_points.append( pt1 ); 02647 } 02648 02649 delete [] facets; 02650 delete [] partner0; 02651 delete [] partner1; 02652 delete [] partner_dot; 02653 02654 return stat; 02655 } 02656 02657 //=============================================================================== 02658 //Function: merge_normals (PRIVATE) 02659 //Description: Enforce continuity across facets by merging the normals at two 02660 // points. Assumes the points are coincident. 02661 //Date: 05/01 02662 //=============================================================================== 02663 CubitStatus ChollaEngine::merge_normals( 02664 CubitPoint *pt0, 02665 CubitPoint *pt1) 02666 { 02667 02668 DLIList<CubitFacet*> adj_facet_list0; 02669 pt0->facets(adj_facet_list0); 02670 if (adj_facet_list0.size() == 0) 02671 return CUBIT_FAILURE; 02672 02673 CubitVector avg_normal(0.0e0, 0.0e0, 0.0e0); 02674 double totangle = 0.0e0; 02675 double angle; 02676 CubitFacet *facet; 02677 int j; 02678 02679 // weight the normal by the spanning angle at the point 02680 02681 for (j = 0; j < adj_facet_list0.size(); j++) 02682 { 02683 facet = adj_facet_list0.get_and_step(); 02684 angle = facet->angle( pt0 ); 02685 facet->weight( angle ); 02686 totangle += angle; 02687 } 02688 DLIList<CubitFacet*> adj_facet_list1; 02689 pt1->facets(adj_facet_list1); 02690 if (adj_facet_list1.size() == 0) 02691 return CUBIT_FAILURE; 02692 for (j = 0; j < adj_facet_list1.size(); j++) 02693 { 02694 facet = adj_facet_list1.get_and_step(); 02695 angle = facet->angle( pt1 ); 02696 facet->weight( angle ); 02697 totangle += angle; 02698 } 02699 02700 // computed weighted normal 02701 02702 CubitVector normal; 02703 for (j = 0; j < adj_facet_list0.size(); j++) 02704 { 02705 facet = adj_facet_list0.get_and_step(); 02706 normal = facet->normal(); 02707 normal.normalize(); 02708 avg_normal += (facet->weight() / totangle) * normal; 02709 } 02710 02711 // orientation of facets may be opposite on opposing surfaces. 02712 // Check for this case and correct of necessary 02713 02714 CubitVector norm0, norm1; 02715 norm0 = pt0->normal(); 02716 norm0.normalize(); 02717 norm1 = pt1->normal(); 02718 norm1.normalize(); 02719 double dot = norm0 % norm1; 02720 double sign = 1.0; 02721 if (dot < 0.0) 02722 sign = -1.0; 02723 02724 for (j = 0; j < adj_facet_list1.size(); j++) 02725 { 02726 facet = adj_facet_list1.get_and_step(); 02727 normal = sign * facet->normal(); 02728 normal.normalize(); 02729 avg_normal += (facet->weight() / totangle) * normal; 02730 } 02731 02732 // set the new normal on both points 02733 02734 avg_normal.normalize(); 02735 pt0->normal(avg_normal); 02736 CubitVector temp_vector = sign * avg_normal; 02737 pt1->normal(temp_vector); 02738 double coefd = -(pt0->coordinates()%avg_normal); 02739 pt0->d_coef( coefd ); 02740 pt1->d_coef( sign * coefd ); 02741 02742 return CUBIT_SUCCESS; 02743 } 02744 02745 //=============================================================================== 02746 //Function: print_me (PRIVATE) 02747 //Description: debug 02748 //=============================================================================== 02749 void ChollaEngine::print_me() 02750 { 02751 FILE *fp = fopen( "fbg.out", "w" ); 02752 int ii, jj, kk; 02753 for (ii=0; ii<chollaSurfaceList.size(); ii++) 02754 { 02755 ChollaSurface *chsurf_ptr = chollaSurfaceList.get_and_step(); 02756 fprintf( fp, "*********** Surface %d ***************\n", chsurf_ptr->get_id()); 02757 DLIList<ChollaCurve *> fcm_list; 02758 chsurf_ptr->get_curves( fcm_list ); 02759 for (jj=0; jj<fcm_list.size(); jj++) 02760 { 02761 ChollaCurve *chcurv_ptr = fcm_list.get_and_step(); 02762 fprintf(fp, " Curve %d\n", chcurv_ptr->get_id() ); 02763 //CubitVector start, end; 02764 DLIList<ChollaPoint *> fpm_list = chcurv_ptr->get_points(); 02765 for (kk=0; kk<fpm_list.size(); kk++) 02766 { 02767 ChollaPoint *chpnt_ptr = fpm_list.get_and_step(); 02768 FacetEntity *facet_point = chpnt_ptr->get_facets(); 02769 if (facet_point) 02770 { 02771 CubitPoint *point_ptr = CAST_TO(facet_point, CubitPoint); 02772 CubitVector pt = point_ptr->coordinates(); 02773 fprintf(fp, " (%d) x = %8.4f y = %8.4f z = %8.4f\n", 02774 chpnt_ptr->get_id(), pt.x(), pt.y(), pt.z()); 02775 } 02776 } 02777 } 02778 } 02779 fclose(fp); 02780 } 02781 02782 //=============================================================================== 02783 //Function: dump (PUBLIC) 02784 //Description: debug 02785 //=============================================================================== 02786 void ChollaEngine::dump( const char *filename, double angle ) 02787 { 02788 int include_results = 0; 02789 int num_face = faceList.size(); 02790 int num_edge = edgeList.size(); 02791 int num_vert = pointList.size(); 02792 int *face_edge = new int [3*num_face]; 02793 int *edge_vert = new int [2*num_edge]; 02794 double *vert = new double [3*num_vert]; 02795 02796 int ii; 02797 CubitVector loc; 02798 CubitPoint *point_ptr; 02799 pointList.reset(); 02800 for (ii=0; ii<num_vert; ii++) 02801 { 02802 point_ptr = dynamic_cast<CubitPoint *>(pointList.get_and_step()); 02803 point_ptr->set_id( ii ); 02804 loc = point_ptr->coordinates(); 02805 vert[ii*3] = loc.x(); 02806 vert[ii*3+1] = loc.y(); 02807 vert[ii*3+2] = loc.z(); 02808 } 02809 02810 CubitFacetEdge *edge_ptr; 02811 edgeList.reset(); 02812 for (ii=0; ii<num_edge; ii++) 02813 { 02814 edge_ptr = dynamic_cast<CubitFacetEdge *>(edgeList.get_and_step()); 02815 edge_ptr->set_id( ii ); 02816 edge_vert[ii*2] = edge_ptr->point( 0 )->id(); 02817 edge_vert[ii*2+1] = edge_ptr->point( 1 )->id(); 02818 } 02819 02820 CubitFacet *facet_ptr; 02821 faceList.reset(); 02822 for(ii=0; ii<num_face; ii++) 02823 { 02824 facet_ptr = dynamic_cast<CubitFacet *>(faceList.get_and_step()); 02825 face_edge[ii*3] = facet_ptr->edge( 0 )->id(); 02826 face_edge[ii*3+1] = facet_ptr->edge( 1 )->id(); 02827 face_edge[ii*3+2] = facet_ptr->edge( 2 )->id(); 02828 } 02829 02830 double *edge_control_points = new double [3*3*num_edge]; 02831 double *tri_control_points = new double [3*6*num_face]; 02832 double *quad_control_points = NULL; 02833 02834 char mesh_filename[256]; 02835 sprintf(mesh_filename, "%s.mesh", filename); 02836 dumpMesh(mesh_filename, include_results, angle, num_face, 0, num_edge, 02837 num_vert, face_edge, NULL, edge_vert, vert, edge_control_points, 02838 tri_control_points, quad_control_points); 02839 02840 constructBezier( angle, num_face, 0, num_edge, num_vert, face_edge, NULL, 02841 edge_vert, vert, edge_control_points, tri_control_points, 02842 quad_control_points ); 02843 02844 char result_filename[256]; 02845 sprintf(result_filename, "%s.results", filename); 02846 dumpResults(result_filename, num_edge, num_face, 0, 02847 edge_control_points, tri_control_points, quad_control_points ); 02848 02849 include_results = 1; 02850 char full_filename[256]; 02851 sprintf(full_filename, "%s.full", filename); 02852 dumpMesh(full_filename, include_results, angle, num_face, 0, num_edge, 02853 num_vert, face_edge, NULL, edge_vert, vert, edge_control_points, 02854 tri_control_points, quad_control_points); 02855 02856 delete [] face_edge; 02857 delete [] edge_vert; 02858 delete [] vert; 02859 delete [] edge_control_points; 02860 delete [] tri_control_points; 02861 } 02862 02863 //=============================================================================== 02864 //Function: mark_features (PUBLIC) 02865 //Description: Calling this before ChollaEngine create geometry / topology 02866 // allows you to define features points. This can be used in conjunction 02867 // with the feature angle option or exclusively (original intention). 02868 //=============================================================================== 02869 void ChollaEngine::mark_features (DLIList<CubitPoint*> &feature_points) 02870 { 02871 int ii; 02872 TDGeomFacet *td_gm = NULL; 02873 CubitPoint *curr_pt = NULL; 02874 02875 // loop through supplied CubitPoint* 02876 // set the hit flag on each one 02877 02878 for (ii=0; ii < feature_points.size(); ++ii) 02879 { 02880 curr_pt = feature_points.get_and_step(); 02881 TDGeomFacet::add_geom_facet(curr_pt, -1); 02882 td_gm = TDGeomFacet::get_geom_facet(curr_pt); 02883 td_gm->set_hit_flag(1); 02884 curr_pt->set_as_feature(); 02885 } 02886 } 02887 02888 //=============================================================================== 02889 //Function: mark_features (PUBLIC) 02890 //Description: Calling this before ChollaEngine create geometry / topology 02891 // allows you to define features points. This can be used in conjunction 02892 // with the feature angle option or exclusively (original intention). 02893 //=============================================================================== 02894 void ChollaEngine::mark_features (DLIList<CubitFacetEdge*> &feature_edges) 02895 { 02896 int ii; 02897 CubitFacetEdge *curr_edge = NULL; 02898 02899 // loop through supplied CubitFaceEdge* 02900 // set the hit flag on each one 02901 02902 for (ii=0; ii < feature_edges.size(); ++ii) 02903 { 02904 curr_edge = feature_edges.get_and_step(); 02905 curr_edge->set_as_feature(); 02906 } 02907 } 02908 02909 02910 static CubitStatus create_tri_facets(int *face_list,int current_position, 02911 CubitPoint **point_list, 02912 DLIList <CubitFacet*> &facet_list) 02913 { 02914 int step = face_list[current_position]; 02915 //This function is hard coded to work for splitting 4, 5, and 6 02916 //faceted points into triangles. 02917 if ( step > 6 || step < 4 ) 02918 { 02919 PRINT_ERROR("Trying to split facets with wrong function.\n"); 02920 return CUBIT_FAILURE; 02921 } 02922 //Basically get the points in a list first. 02923 int ii = current_position + 1, jj; 02924 DLIList <CubitPoint*> temp_points; 02925 02926 for( jj = ii; jj < ii+step; jj++ ) 02927 { 02928 int index_to_point = face_list[jj]; 02929 assert(index_to_point >= 0 ); 02930 temp_points.append(point_list[index_to_point]); 02931 } 02932 //Now cycle through the points and creat facets from them. 02933 CubitPoint *point_1, *point_2, *point_3; 02934 //This definatly could be improved to get more optimal triangles... 02935 //Create the first two facets in the normal way. This is the 02936 //same for 4, 5 and 6 points. 02937 for ( jj = 0; jj < 2; jj++ ) 02938 { 02939 point_1 = temp_points.get_and_step(); 02940 point_2 = temp_points.get_and_step(); 02941 point_3 = temp_points.get(); 02942 //If these are colinear we are screwed... 02943 CubitFacet *new_facet = (CubitFacet *) 02944 new CubitFacetData(point_1, point_2, point_3); 02945 facet_list.append(new_facet); 02946 } 02947 //create the third facet for 5 points. 02948 if ( step == 5 ) 02949 { 02950 //Now create the last facet with the first point, last point and 02951 //third point. 02952 temp_points.reset(); 02953 point_1 = temp_points.prev(); 02954 point_2 = temp_points.get(); 02955 point_3 = temp_points.next(2); 02956 CubitFacet *new_facet = (CubitFacet *) 02957 new CubitFacetData(point_1, point_2, point_3); 02958 facet_list.append(new_facet); 02959 } 02960 //create the third and fourth for 6 points. 02961 else if ( step == 6 ) 02962 { 02963 //get the current point (should be position 5/6) 02964 point_1 = temp_points.get(); 02965 //get the next point. (should be position 6/6) 02966 point_2 = temp_points.next(); 02967 //get the prev(2) point. ( should be position 3/6) 02968 point_3 = temp_points.prev(2); 02969 CubitFacet *new_facet = (CubitFacet *) 02970 new CubitFacetData(point_1, point_2, point_3); 02971 facet_list.append(new_facet); 02972 // get the next point. (should be 6/6) 02973 point_1 = temp_points.next(); 02974 // get the next 2 point ( should be 1/6) 02975 point_2 = temp_points.next(2); 02976 //point3 stays the same (position 3/6). 02977 new_facet = (CubitFacet *) 02978 new CubitFacetData(point_1, point_2, point_3); 02979 facet_list.append(new_facet); 02980 } 02981 return CUBIT_SUCCESS; 02982 } 02983 02984 //=================================================================================== 02985 // Description: given facets in the form of a GMem data structure create new 02986 // CubitFacet and CubitPoint classes and return in lists 02987 // Notes: 02988 // Author: 02989 // Date: 02990 //=================================================================================== 02991 CubitStatus ChollaEngine::get_facets(GMem& gMem, DLIList<CubitFacet*> &facet_list, 02992 DLIList<CubitPoint*> &dl_point_list, 02993 bool insert_null_facets ) 02994 { 02995 if(gMem.fListCount == 0) 02996 return CUBIT_FAILURE; 02997 02998 GPoint* plist = gMem.point_list(); 02999 CubitPoint **point_list = (CubitPoint **) 03000 new CubitPointData *[gMem.pointListCount]; 03001 double x, y, z; 03002 int i,j; 03003 for (i = 0; i<gMem.pointListCount; i++) 03004 { 03005 x = plist[i].x; 03006 y = plist[i].y; 03007 z = plist[i].z; 03008 CubitPoint *new_point = (CubitPoint *) new CubitPointData(x, y, z); 03009 point_list[i] = new_point; 03010 dl_point_list.append(new_point); 03011 } 03012 int *face_list = gMem.facet_list(); 03013 int step; 03014 DLIList<CubitPoint*> temp_points; 03015 CubitFacet *new_facet; 03016 int ii, index_to_point; 03017 CubitStatus stat1; 03018 for ( i = 0; i < gMem.fListCount; i++ ) 03019 { 03020 step = face_list[i]; 03021 //Now get the points for this facet. 03022 switch (step) 03023 { 03024 case 3: 03025 ii = i + 1; 03026 temp_points.clean_out(); 03027 for( j = ii; j < ii+step; j++ ) 03028 { 03029 index_to_point = face_list[j]; 03030 assert(index_to_point >= 0 && index_to_point <= gMem.pointListCount ); 03031 temp_points.append(point_list[index_to_point]); 03032 } 03033 03034 if( temp_points.get() != temp_points.next() && 03035 temp_points.get() != temp_points.next(2) && 03036 temp_points.next() != temp_points.next(2) ) 03037 { 03038 new_facet = (CubitFacet *) 03039 new CubitFacetData(temp_points.get(), 03040 temp_points.next(), 03041 temp_points.next(2) ); 03042 facet_list.append(new_facet); 03043 } 03044 i = i+step; 03045 break; 03046 case 4: 03047 case 5: 03048 case 6: 03049 stat1 = create_tri_facets(face_list,i, point_list, 03050 facet_list); 03051 if ( stat1 != CUBIT_SUCCESS ) 03052 { 03053 PRINT_ERROR("Facets were not triangular and couldn't be split\n"); 03054 return stat1; 03055 } 03056 i = i+step; 03057 break; 03058 default: 03059 //We currently can't handle this... 03060 //Eventually we will have to split this polygon into more facets. 03061 PRINT_ERROR("Facets were not triangular, and couldn't be made so.\n"); 03062 PRINT_ERROR("Surface has: %d points forming a facet.\n", step); 03063 if( insert_null_facets ) 03064 facet_list.append( NULL ); 03065 return CUBIT_FAILURE; 03066 } 03067 } 03068 delete [] point_list; 03069 return CUBIT_SUCCESS; 03070 } 03071 03072 //============================================================================= 03073 //Function: collapses a given curve to a given point_to_keep 03074 // 03075 //Description: 03076 //Note: the hashing and other data structures are not updated during collapse. 03077 //Author: william roshan quadros 03078 //Date: 12/15/08 03079 //============================================================================= 03080 CubitStatus ChollaEngine::collapse_curve( ChollaCurve *cholla_curve, ChollaPoint *point_to_keep ) 03081 { 03082 // Make sure there are no underlying facet edges connected with this curve 03083 if( cholla_curve->get_facet_list().size() ) 03084 return CUBIT_FAILURE; 03085 03086 // Disassociate from cholla_surfaces 03087 DLIList<ChollaSurface *> &ref_surfaces = cholla_curve->get_surfaces(); 03088 int i; 03089 ChollaSurface *cholla_surface; 03090 for( i = 0; i < ref_surfaces.size(); i++ ) 03091 { 03092 cholla_surface = ref_surfaces.get_and_step(); 03093 cholla_surface->remove_curve( cholla_curve ); 03094 } 03095 ref_surfaces.clean_out(); 03096 03097 // Disassociate from cholla point_to_delete 03098 // Make sure curve has at least one point 03099 DLIList<ChollaPoint *> &cholla_pnts = cholla_curve->get_points(); 03100 if( 0 == cholla_pnts.size() ) 03101 return CUBIT_FAILURE; 03102 03103 // free eval tool 03104 if( cholla_curve->get_eval_tool() ) 03105 { 03106 delete cholla_curve->get_eval_tool(); 03107 } 03108 03109 // find the point to delete 03110 ChollaPoint *first_pnt = cholla_pnts.get_and_step(); 03111 ChollaPoint *last_pnt = cholla_pnts.get(); 03112 ChollaPoint *point_to_del = NULL; 03113 switch( cholla_pnts.size() ) 03114 { 03115 03116 case 2: 03117 if( point_to_keep == last_pnt ) 03118 { 03119 point_to_del = first_pnt; 03120 } 03121 else 03122 { 03123 if( point_to_keep == first_pnt ) 03124 { 03125 point_to_del = last_pnt; 03126 } 03127 } 03128 03129 // disassociate end points from cholla_curve 03130 if( point_to_del ) 03131 { 03132 point_to_del->remove_curve( cholla_curve ); 03133 cholla_pnts.remove( point_to_del ); 03134 } 03135 if( point_to_keep ) 03136 { 03137 point_to_keep->remove_curve( cholla_curve ); 03138 cholla_pnts.remove( point_to_keep ); 03139 } 03140 03141 // Merge two points 03142 merge_two_points( point_to_keep, point_to_del ); 03143 03144 break; 03145 03146 case 1: 03147 // disassociate end points from cholla_curve 03148 point_to_del = first_pnt; 03149 point_to_del->remove_curve( cholla_curve ); 03150 cholla_pnts.remove( point_to_del ); 03151 03152 if( 0 == point_to_del->get_curve_list_ptr()->size() ) 03153 { 03154 // remove point_to_del from ChollaEngine 03155 remove_point( point_to_del ); 03156 03157 // free point_to_del 03158 delete point_to_del; 03159 } 03160 break; 03161 03162 default: 03163 return CUBIT_FAILURE; 03164 } 03165 03166 03167 // Disassociate curve from chollaEngine 03168 this->remove_curve( cholla_curve ); 03169 03170 // free the cholla_curve 03171 delete cholla_curve; 03172 03173 return CUBIT_SUCCESS; 03174 } 03175 03176 // Merge two points 03177 CubitStatus ChollaEngine::merge_two_points( ChollaPoint *point_to_keep, ChollaPoint *point_to_del ) 03178 { 03179 // move cholla curves from point_to_del to point_to_keep 03180 DLIList<ChollaCurve *> &del_pnt_curves = point_to_del->get_curves(); 03181 int i; 03182 ChollaCurve *cholla_curve; 03183 for( i = 0; i < del_pnt_curves.size(); i++ ) 03184 { 03185 cholla_curve = del_pnt_curves.get_and_step(); 03186 03187 cholla_curve->remove_point( point_to_del ); 03188 cholla_curve->add_point( point_to_keep ); 03189 point_to_keep->add_curve( cholla_curve ); 03190 } 03191 del_pnt_curves.clean_out(); 03192 03193 // if point_to_keep facet is null use point_to_del's facet 03194 if( NULL == point_to_keep->get_facets() && point_to_del->get_facets() ) 03195 { 03196 point_to_keep->add_facet( point_to_del->get_facets() ); 03197 } 03198 03199 // what we should do with data member id? should we move if point_to_keep->get_id() != 0? 03200 03201 // remove point_to_del from ChollaEngine 03202 remove_point( point_to_del ); 03203 03204 // free point_to_del 03205 delete point_to_del; 03206 03207 return CUBIT_SUCCESS; 03208 } 03209 03210 03211 03212 CubitStatus ChollaEngine::disassociate_surface( ChollaSurface *cholla_surf ) 03213 { 03214 // remove surface from volume 03215 DLIList<ChollaVolume *> cholla_volumes; 03216 cholla_surf->get_volumes(cholla_volumes); 03217 int i; 03218 ChollaVolume *cholla_volume; 03219 for (i=0; i<cholla_volumes.size(); i++) 03220 { 03221 cholla_volume = cholla_volumes.get_and_step(); 03222 cholla_volume->remove_surface( cholla_surf ); 03223 } 03224 03225 // Disassociate curves from suface 03226 DLIList< ChollaCurve *> cholla_curves; 03227 cholla_surf->get_curves( cholla_curves ); 03228 03229 ChollaCurve *cholla_curve; 03230 for( i = 0; i < cholla_curves.size(); i++ ) 03231 { 03232 cholla_curve = cholla_curves.get_and_step(); 03233 03234 cholla_curve->remove_surface( cholla_surf ); 03235 cholla_surf->remove_curve( cholla_curve ); 03236 } 03237 cholla_curves.clean_out(); 03238 03239 // Remove facet tool if available ? 03240 if( cholla_surf->get_eval_tool() ) 03241 { 03242 #ifdef _DEBUG 03243 //PRINT_INFO("WARNING: delete ch_surf->facet_eval_tool safely \n");// 03244 #endif 03245 //delete cholla_surf->get_eval_tool(); 03246 // set eval tool to NULL 03247 } 03248 03249 // remove from ChollaEngine 03250 remove_surface( cholla_surf ); 03251 03252 return CUBIT_SUCCESS; 03253 03254 } 03255 //============================================================================= 03256 //Function: collapses a given surface 03257 //Description: currently it disassociates surface with its curves and ChollaEngine 03258 //Note: make sure there are no underlying facets and model is automatically watertight when input cholla_surf is deleted 03259 //Author: william roshan quadros 03260 //Date: 12/15/08 03261 //============================================================================= 03262 03263 CubitStatus ChollaEngine::collapse_surface( ChollaSurface *cholla_surf ) 03264 { 03265 // Make sure there are no facets 03266 if( cholla_surf->get_facet_list().size() ) 03267 return CUBIT_FAILURE; 03268 03269 disassociate_surface( cholla_surf ); 03270 03271 // free cholla surface 03272 delete cholla_surf; 03273 03274 return CUBIT_SUCCESS; 03275 } 03276 03277 CubitStatus ChollaEngine::remove_facet_entity( CubitFacet *facet, ChollaSurface *cholla_surf ) 03278 { 03279 this->faceList.remove( facet ); 03280 03281 if( cholla_surf ) 03282 cholla_surf->remove_facet( facet ); 03283 03284 return CUBIT_SUCCESS; 03285 } 03286 03287 CubitStatus ChollaEngine::remove_facet_entity( CubitFacetEdge *facet_edge, ChollaCurve *cholla_curve ) 03288 { 03289 this->edgeList.remove( facet_edge ); 03290 03291 if( cholla_curve ) 03292 cholla_curve->remove_facet( facet_edge ); 03293 03294 return CUBIT_SUCCESS; 03295 } 03296 03297 CubitStatus ChollaEngine::remove_facet_entity( CubitPoint *facet_pnt, ChollaPoint *cholla_point ) 03298 { 03299 this->pointList.remove( facet_pnt ); 03300 03301 if( cholla_point ) 03302 cholla_point->remove_facet(/* facet_pnt */); 03303 03304 return CUBIT_SUCCESS; 03305 } 03306 03307 CubitStatus ChollaEngine::remove_facet_entity( CubitFacet *facet, std::set<ChollaEntity *> &cholla_surfs ) 03308 { 03309 std::set<ChollaEntity *>::iterator set_it; 03310 for( set_it = cholla_surfs.begin(); set_it != cholla_surfs.end(); set_it++ ) 03311 { 03312 if( dynamic_cast< ChollaSurface *>(*set_it) ) 03313 { 03314 static_cast<ChollaSurface *>(*set_it)->remove_facet( facet ); 03315 } 03316 } 03317 03318 this->faceList.remove( facet ); 03319 03320 return CUBIT_SUCCESS; 03321 } 03322 03323 CubitStatus ChollaEngine::remove_facet_entity( CubitFacetEdge *facet_edge, std::set<ChollaEntity *> &cholla_curves ) 03324 { 03325 03326 std::set<ChollaEntity *>::iterator set_it; 03327 for( set_it = cholla_curves.begin(); set_it != cholla_curves.end(); set_it++ ) 03328 { 03329 if( dynamic_cast<ChollaCurve*>(*set_it) ) 03330 { 03331 dynamic_cast<ChollaCurve*>(*set_it)->remove_facet( facet_edge ); 03332 } 03333 } 03334 03335 this->edgeList.remove( facet_edge ); 03336 03337 return CUBIT_SUCCESS; 03338 } 03339 03340 CubitStatus ChollaEngine::replace_facet_entity( CubitFacetEdge *remove_edge, CubitFacetEdge *replace_edge, std::set<ChollaEntity *> cholla_curves ) 03341 { 03342 std::set<ChollaEntity *>::iterator set_it; 03343 for( set_it = cholla_curves.begin(); set_it != cholla_curves.end(); set_it++ ) 03344 { 03345 if( dynamic_cast<ChollaCurve*>(*set_it) ) 03346 { 03347 static_cast<ChollaCurve*>(*set_it)->replace_facet( remove_edge, replace_edge ); 03348 } 03349 } 03350 03351 return CUBIT_SUCCESS; 03352 } 03353 03354 03355 CubitStatus ChollaEngine::remove_facet_entity( CubitPoint *facet_pnt, std::set<ChollaEntity *> &cholla_points ) 03356 { 03357 this->pointList.remove( facet_pnt ); 03358 03359 std::set<ChollaEntity *>::iterator set_it; 03360 for( set_it = cholla_points.begin(); set_it != cholla_points.end(); set_it++ ) 03361 { 03362 if( dynamic_cast<ChollaPoint*>(*set_it) ) 03363 { 03364 static_cast<ChollaPoint*>(*set_it)->remove_facet( facet_pnt ); 03365 } 03366 } 03367 03368 return CUBIT_SUCCESS; 03369 } 03370 03371 /* 03372 // disassoicate ch_entity from ch_points, ch_curve, ch_surf, and ch_engine 03373 CubitStatus ChollaEngine::disassociate_curve( ChollaCurve *ch_curve ) 03374 { 03375 03376 // disassociate from cholla points 03377 ch_curve->disassociate_from_points(); 03378 03379 // disassociate from cholla surface 03380 ch_curve->disassociate_from_surfaces(); 03381 03382 // disassociate from cholla engine 03383 remove_curve( ch_curve ); 03384 03385 return CUBIT_SUCCESS; 03386 } 03387 */ 03388 03389 CubitStatus ChollaEngine::create_surface( int block_id, 03390 ChollaSurface *&new_ch_surf ) 03391 { 03392 new_ch_surf = new ChollaSurface( block_id ); 03393 03394 // add it to cholla engine 03395 chollaSurfaceList.append( new_ch_surf ); 03396 03397 return CUBIT_SUCCESS; 03398 } 03399 03400 // Create new ch_curve and associate with end ch_points. Add ch_curve to chollaEngine 03401 CubitStatus ChollaEngine::create_curve(int block_id, 03402 ChollaPoint *new_ch_pnt0, 03403 ChollaPoint *new_ch_pnt1, 03404 ChollaCurve *&new_ch_curve 03405 ) 03406 { 03407 03408 03409 new_ch_curve = new ChollaCurve( block_id ); 03410 03411 // associate with cholla points 03412 new_ch_curve->add_point( new_ch_pnt0 ); 03413 new_ch_pnt0->add_curve( new_ch_curve ); 03414 new_ch_curve->add_point( new_ch_pnt1 ); 03415 new_ch_pnt1->add_curve( new_ch_curve ); 03416 03417 03418 // update start and end facet points 03419 new_ch_curve->set_start( CAST_TO( new_ch_pnt0->get_facets(), CubitPointData) ); 03420 new_ch_curve->set_end( CAST_TO( new_ch_pnt1->get_facets(), CubitPointData) ); 03421 03422 // add it to cholla engine 03423 chollaCurveList.append( new_ch_curve ); 03424 03425 return CUBIT_SUCCESS; 03426 } 03427 03428 CubitStatus ChollaEngine::create_point( CubitPoint *pnt, ChollaPoint * &new_ch_pnt ) 03429 { 03430 new_ch_pnt = new ChollaPoint(); 03431 new_ch_pnt->add_facet( pnt ); 03432 double *coordinate = new double[3]; 03433 CubitVector coord_vect = pnt->coordinates(); 03434 coordinate[0] = coord_vect[0]; 03435 coordinate[1] = coord_vect[1]; 03436 coordinate[2] = coord_vect[2]; 03437 new_ch_pnt->assign_geometric_point( (void*) coordinate ); 03438 03439 return CUBIT_SUCCESS; 03440 } 03441 03442 03443 // disassoicate ch_curve from ch_points, ch_surfs, and ch_engine 03444 CubitStatus ChollaEngine::disassociate_curve( ChollaCurve *ch_curve, bool disassociate_with_vert, bool disassociate_with_surf, bool disassociate_with_model ) 03445 { 03446 // remove ch_curve from ch_point 03447 int i; 03448 if( disassociate_with_vert ) 03449 { 03450 for( i = 0; i < ch_curve->get_points().size(); i++ ) 03451 { 03452 ch_curve->get_points().get_and_step()->remove_curve( ch_curve ); 03453 } 03454 // remove ch_points 03455 ch_curve->get_points().clean_out(); 03456 } 03457 03458 if( disassociate_with_surf ) 03459 { 03460 // remove ch_curve in ch_surface 03461 ChollaSurface *ptr_ch_surf; 03462 for( i = 0; i < ch_curve->get_surfaces().size(); i++ ) 03463 { 03464 ptr_ch_surf = ch_curve->get_surfaces().get_and_step(); 03465 ptr_ch_surf->remove_curve( ch_curve ); 03466 } 03467 // remove ch_surface 03468 ch_curve->get_surfaces().clean_out(); 03469 } 03470 03471 if( disassociate_with_model ) 03472 { 03473 // remove from ch_engie 03474 this->remove_curve( ch_curve ); 03475 } 03476 03477 return CUBIT_SUCCESS; 03478 } 03479 03480 //============================================================================= 03481 //Function: detach_volumes 03482 //Description: Create independent manifold volumes from the non-manifold set 03483 //Note: 03484 //Author:sjowen 03485 //Date: 09/10/09 03486 //============================================================================= 03487 CubitStatus ChollaEngine::detach_volumes() 03488 { 03489 CubitStatus rv = CUBIT_SUCCESS; 03490 03491 // define maps between the original entities and their copies so we can 03492 // use them for detaching the facets 03493 03494 std::map<ChollaSurface *, ChollaSurface *> surf_map; 03495 std::multimap<ChollaCurve *, ChollaCurve *> curve_map; 03496 std::multimap<ChollaPoint *, ChollaPoint *> point_map; 03497 03498 for( int i=chollaVolumeList.size(); i--; ) 03499 { 03500 ChollaVolume *chvol = chollaVolumeList.get_and_step(); 03501 DLIList<ChollaSurface*> ch_surfaces; 03502 chvol->get_surfaces( ch_surfaces ); 03503 03504 std::map<ChollaCurve *, ChollaCurve *> tmp_curve_map; 03505 std::map<ChollaPoint *, ChollaPoint *> tmp_point_map; 03506 03507 DLIList<ChollaSurface*> surfaces_to_detach; 03508 DLIList<ChollaCurve*> curves_to_detach; 03509 for( int j=ch_surfaces.size(); j--; ) 03510 { 03511 ChollaSurface *chsurf_ptr = ch_surfaces.get_and_step(); 03512 03513 // look for any surfaces that are associated with exactly two volumes 03514 if (chsurf_ptr->num_volumes() == 2) 03515 surfaces_to_detach.append( chsurf_ptr ); 03516 else 03517 { 03518 //look for any curves that are attached to two volumes 03519 DLIList<ChollaCurve*> ch_curves; 03520 chsurf_ptr->get_curves( ch_curves ); 03521 for( int k=ch_curves.size(); k--; ) 03522 { 03523 ChollaCurve *tmp_curve = ch_curves.get_and_step(); 03524 if( tmp_curve->num_volumes() > 1 ) 03525 curves_to_detach.append( tmp_curve ); 03526 } 03527 } 03528 } 03529 03530 //filter out curves that are in surfs in 'surfaces_to_detach' 03531 //since they will get detached when the parent surface gets detached 03532 for( int j=curves_to_detach.size(); j--; ) 03533 { 03534 ChollaCurve *tmp_curve = curves_to_detach.get(); 03535 DLIList<ChollaSurface*> tmp_surfs = tmp_curve->get_surfaces(); 03536 03537 for( int k=tmp_surfs.size(); k--; ) 03538 { 03539 ChollaSurface *tmp_surf = tmp_surfs.get_and_step(); 03540 if( surfaces_to_detach.is_in_list( tmp_surf ) ) 03541 { 03542 curves_to_detach.change_to(NULL); 03543 break; 03544 } 03545 } 03546 curves_to_detach.step(); 03547 } 03548 03549 curves_to_detach.remove_all_with_value( NULL ); 03550 curves_to_detach.uniquify_unordered(); 03551 03552 if( surfaces_to_detach.size() || curves_to_detach.size() ) 03553 { 03554 rv = detach_surfaces( surfaces_to_detach, curves_to_detach, chvol, surf_map, tmp_curve_map, tmp_point_map ); 03555 if (rv != CUBIT_SUCCESS) 03556 return CUBIT_FAILURE; 03557 03558 //for all detached surfaces, detach all the facets and create new ones for 03559 //the detached surfaces 03560 rv = detach_facets(surfaces_to_detach, curves_to_detach, chvol, surf_map, tmp_curve_map, tmp_point_map); 03561 if (rv != CUBIT_SUCCESS) 03562 return rv; 03563 03564 // set the cubitpoints at the correct start/end locations on the cholla curves 03565 rv = set_curve_endpoints(tmp_point_map, tmp_curve_map ); 03566 if (rv != CUBIT_SUCCESS) 03567 return rv; 03568 } 03569 03570 //append the map to the multi-map 03571 std::map<ChollaCurve*, ChollaCurve*>::iterator iter = tmp_curve_map.begin(); 03572 for( ; iter!=tmp_curve_map.end(); iter++) 03573 curve_map.insert( std::pair<ChollaCurve*,ChollaCurve*>(iter->first, iter->second) ); 03574 03575 //append the map to the multi-map 03576 std::map<ChollaPoint*, ChollaPoint*>::iterator pt_iter = tmp_point_map.begin(); 03577 for( ; pt_iter!=tmp_point_map.end(); pt_iter++) 03578 point_map.insert( std::pair<ChollaPoint*,ChollaPoint*>(pt_iter->first, pt_iter->second) ); 03579 } 03580 03581 // create the evaluation tools on the new entities 03582 03583 CubitBoolean use_feature_angle = CUBIT_FALSE; 03584 double min_dot = 0.0; 03585 int interp_order = 0; 03586 CubitBoolean smooth_non_manifold = CUBIT_FALSE; 03587 CubitBoolean split_surfaces = CUBIT_FALSE; 03588 DLIList<ChollaSurface *> cholla_surfaces; 03589 DLIList<ChollaCurve *> cholla_curves; 03590 03591 // get lists of new surfaces and curves from the maps 03592 03593 std::map<ChollaSurface *, ChollaSurface *>::iterator smap_it; 03594 for (smap_it=surf_map.begin(); smap_it != surf_map.end(); smap_it++) 03595 { 03596 cholla_surfaces.append(smap_it->second); 03597 } 03598 03599 std::multimap<ChollaCurve *, ChollaCurve *>::iterator cmap_it; 03600 for (cmap_it=curve_map.begin(); cmap_it != curve_map.end(); cmap_it++) 03601 { 03602 cholla_curves.append(cmap_it->second); 03603 } 03604 03605 // rebuild the new curves so the edges are oriented correctly 03606 03607 for (int ii=0; ii<cholla_curves.size(); ii++) 03608 { 03609 ChollaCurve *cholla_curve = cholla_curves.get_and_step(); 03610 DLIList<ChollaPoint *> cholla_points = cholla_curve->get_points(); 03611 int periodic = 0; 03612 if (cholla_points.size() == 1) 03613 periodic = 1; 03614 else 03615 assert(cholla_points.size() == 2); // assuming we have exactly two end points so far 03616 CubitPoint *start_point, *end_point; 03617 cholla_curve->get_ends(start_point, end_point); 03618 int max_edges = cholla_curve->num_edges(); 03619 cholla_curve->clean_out_edges(); // edges will be added in build_curve_from_edges 03620 rv = cholla_curve->build_curve_from_edges( start_point, periodic, max_edges, NULL, cholla_curve ); 03621 if (rv != CUBIT_SUCCESS) 03622 return rv; 03623 } 03624 03625 // replace the facets on the existing eval tools on the curves and surfaces bounding the interface. 03626 // for simplicity, just replace them on all the existing eval tools on 03627 03628 for (int icurv = 0; icurv < chollaCurveList.size(); icurv++) 03629 { 03630 ChollaCurve *chcurv_ptr = chollaCurveList.get_and_step(); 03631 CurveFacetEvalTool *ceval = chcurv_ptr->get_eval_tool(); 03632 if (ceval != NULL) 03633 { 03634 DLIList<FacetEntity *> fedges = chcurv_ptr->get_facet_list(); 03635 DLIList<CubitFacetEdge *> edges; 03636 CAST_LIST( fedges, edges, CubitFacetEdge ); 03637 ceval->replace_facets(edges); 03638 } 03639 } 03640 03641 for (int isurf=0; isurf<chollaSurfaceList.size(); isurf++) 03642 { 03643 ChollaSurface *chsurf_ptr = chollaSurfaceList.get_and_step(); 03644 FacetEvalTool *seval = chsurf_ptr->get_eval_tool(); 03645 if (seval != NULL) 03646 { 03647 DLIList<FacetEntity *> ffacets = chsurf_ptr->get_facet_list(); 03648 DLIList<CubitFacet *> facets; 03649 CAST_LIST( ffacets, facets, CubitFacet ); 03650 seval->replace_facets(facets); 03651 } 03652 } 03653 03654 03655 // build the eval tools 03656 03657 rv = build_eval_tools(cholla_surfaces, 03658 cholla_curves, 03659 interp_order, use_feature_angle, 03660 min_dot, smooth_non_manifold, 03661 split_surfaces ); 03662 03663 return rv; 03664 } 03665 03666 //============================================================================= 03667 //Function: detach_surface 03668 //Description: given a non-manifold surface in a cholla model, create a copy 03669 // and update child entities 03670 //Notes: assumes that chsurf_ptr has exactly 2 adjacent volumes 03671 //Author:sjowen 03672 //Date: 09/18/09 03673 //============================================================================= 03674 CubitStatus ChollaEngine::detach_surfaces(DLIList<ChollaSurface*> &chsurfs, 03675 DLIList<ChollaCurve*> &chcurves, 03676 ChollaVolume *vol_getting_new_surfs, 03677 std::map<ChollaSurface *, ChollaSurface *> &surf_map, 03678 std::map<ChollaCurve *, ChollaCurve *> &curve_map, 03679 std::map<ChollaPoint *, ChollaPoint *> &point_map) 03680 { 03681 CubitStatus rv = CUBIT_SUCCESS; 03682 03683 // detach the surface from its volumes 03684 03685 DLIList<ChollaCurve*> all_curves_in_surfs; 03686 DLIList<ChollaPoint*> all_points_in_surfs; 03687 03688 std::multimap<ChollaCurve*, ChollaSurface*> orig_curve_to_new_surf_map; 03689 03690 for( int i=chsurfs.size(); i--; ) 03691 { 03692 ChollaSurface *chsurf_ptr = chsurfs.get_and_step(); 03693 DLIList<ChollaVolume *> chvol_list; 03694 chsurf_ptr->get_volumes(chvol_list); 03695 ChollaVolume *chvol1_ptr = chvol_list.get_and_step(); 03696 ChollaVolume *chvol2_ptr = chvol_list.get(); 03697 03698 if( chvol2_ptr != vol_getting_new_surfs ) 03699 { 03700 chvol1_ptr = chvol2_ptr; 03701 chvol2_ptr = vol_getting_new_surfs; 03702 } 03703 03704 if (NULL == chvol1_ptr || NULL == chvol2_ptr) { 03705 PRINT_ERROR("Unexpected NULL pointer for cholla volume.\n"); 03706 return CUBIT_FAILURE; 03707 } 03708 assert(chvol1_ptr != chvol2_ptr); 03709 03710 // create a copy of the non-manifold surface and attach it to volume 2 03711 03712 ChollaSurface *newchsurf_ptr = new ChollaSurface( chsurf_ptr->get_block_id() ); 03713 chollaSurfaceList.append(newchsurf_ptr); 03714 surf_map.insert(std::pair<ChollaSurface *, ChollaSurface *>(chsurf_ptr, newchsurf_ptr)); 03715 03716 chvol2_ptr->remove_surface(chsurf_ptr); 03717 chsurf_ptr->remove_volume(chvol2_ptr); 03718 chvol2_ptr->add_surface(newchsurf_ptr); 03719 newchsurf_ptr->add_volume(chvol2_ptr); 03720 03721 chsurf_ptr->set_merge_partner(newchsurf_ptr); 03722 newchsurf_ptr->set_merge_partner(chsurf_ptr); 03723 03724 // detach the curves 03725 DLIList<ChollaCurve *> chcurv_list; 03726 chsurf_ptr->get_curves(chcurv_list); 03727 03728 for( int k=chcurv_list.size(); k--; ) 03729 { 03730 ChollaCurve *chcurve = chcurv_list.get_and_step(); 03731 orig_curve_to_new_surf_map.insert( std::pair<ChollaCurve*, ChollaSurface*>( chcurve, newchsurf_ptr ) ); 03732 } 03733 03734 all_curves_in_surfs += chcurv_list; 03735 03736 DLIList<ChollaPoint*> chpt_list; 03737 chsurf_ptr->get_vertices( chpt_list ); 03738 all_points_in_surfs += chpt_list; 03739 } 03740 03741 all_curves_in_surfs.uniquify_unordered(); 03742 03743 for(int icurv = 0; icurv < all_curves_in_surfs.size(); icurv++) 03744 { 03745 ChollaCurve *chcurv_ptr = all_curves_in_surfs.get_and_step(); 03746 03747 std::multimap<ChollaCurve*, ChollaSurface*>::iterator iter, upper_iter; 03748 DLIList<ChollaSurface*> new_surfs; 03749 03750 iter = orig_curve_to_new_surf_map.find( chcurv_ptr ); 03751 03752 assert( iter != orig_curve_to_new_surf_map.end() ); 03753 03754 upper_iter = orig_curve_to_new_surf_map.upper_bound( iter->first ); 03755 03756 for(; iter!=upper_iter; ++iter ) 03757 new_surfs.append( iter->second ); 03758 03759 rv = detach_curve( chcurv_ptr, new_surfs, vol_getting_new_surfs, curve_map, point_map ); 03760 if (rv != CUBIT_SUCCESS) 03761 return rv; 03762 } 03763 03764 for( int i=chcurves.size(); i--; ) 03765 { 03766 DLIList<ChollaPoint*> tmp_pts = chcurves.get_and_step()->get_points(); 03767 all_points_in_surfs += tmp_pts; 03768 } 03769 03770 rv = detach_curves( chcurves, vol_getting_new_surfs, curve_map, point_map ); 03771 if( rv != CUBIT_SUCCESS ) 03772 return rv; 03773 03774 //add the points in the cholla 03775 all_points_in_surfs.uniquify_unordered(); 03776 for (int ipt = 0; ipt < all_points_in_surfs.size(); ipt++) 03777 { 03778 ChollaPoint *chpt_ptr = all_points_in_surfs.get_and_step(); 03779 03780 rv = detach_point( chpt_ptr, vol_getting_new_surfs, point_map, curve_map ); 03781 if (rv != CUBIT_SUCCESS) 03782 return rv; 03783 } 03784 03785 return rv; 03786 } 03787 03788 CubitStatus ChollaEngine::detach_curves( DLIList<ChollaCurve*> &curves, 03789 ChollaVolume *detaching_volume, 03790 std::map<ChollaCurve *, ChollaCurve *> &curve_map, 03791 std::map<ChollaPoint *, ChollaPoint *> &point_map ) 03792 { 03793 CubitStatus rv = CUBIT_SUCCESS; 03794 03795 DLIList<ChollaSurface*> tmp_surfs; 03796 DLIList<ChollaPoint*> points_to_detach; 03797 for( int i=curves.size(); i--; ) 03798 { 03799 ChollaCurve *tmp_curve = curves.get_and_step(); 03800 03801 //get the surfaces in 'detaching_volume' 03802 tmp_surfs.clean_out(); 03803 tmp_surfs = tmp_curve->get_surfaces(); 03804 for( int k=0; k<tmp_surfs.size(); k++ ) 03805 { 03806 if( !tmp_surfs[k]->is_in_volume( detaching_volume) ) 03807 tmp_surfs[k] = NULL; 03808 } 03809 tmp_surfs.remove_all_with_value(NULL); 03810 03811 rv = detach_curve( tmp_curve, tmp_surfs, detaching_volume, curve_map, point_map ); 03812 if (rv != CUBIT_SUCCESS) 03813 return rv; 03814 03815 DLIList<ChollaPoint*> tmp_pts = tmp_curve->get_points(); 03816 points_to_detach += tmp_pts; 03817 } 03818 03819 //go through the map, setting up merge partners 03820 std::map<ChollaCurve*, ChollaCurve*>::iterator iter = curve_map.begin(); 03821 for( ; iter != curve_map.end(); iter++ ) 03822 { 03823 ChollaCurve *ch_curv = iter->first; 03824 ChollaCurve *new_ch_curv = iter->second; 03825 03826 ch_curv->set_merge_partner( new_ch_curv ); 03827 new_ch_curv->set_merge_partner( ch_curv ); 03828 } 03829 return rv; 03830 } 03831 03832 //============================================================================= 03833 //Function: detach_curve 03834 //Description: given a non-manifold curve in a cholla model, create a copy 03835 // and update child entities. updates the curve_map 03836 //Author:sjowen 03837 //Date: 09/18/09 03838 //============================================================================= 03839 CubitStatus ChollaEngine::detach_curve(ChollaCurve *chcurv_ptr, 03840 DLIList<ChollaSurface*> &new_surfs, 03841 ChollaVolume *chvol2_ptr, 03842 std::map<ChollaCurve*, ChollaCurve*> &curve_map, 03843 std::map<ChollaPoint*, ChollaPoint*> &point_map ) 03844 { 03845 // create a copy of the curve on the surface and add it to volume 2 03846 03847 ChollaCurve *newchcurv_ptr = new ChollaCurve( chcurv_ptr->get_block_id() ); 03848 chollaCurveList.append( newchcurv_ptr ); 03849 curve_map.insert(std::pair<ChollaCurve *, ChollaCurve *>(chcurv_ptr, newchcurv_ptr)); 03850 03851 for( int i=new_surfs.size(); i--; ) 03852 { 03853 ChollaSurface *newchsurf_ptr = new_surfs.get_and_step(); 03854 newchsurf_ptr->add_curve(newchcurv_ptr); 03855 newchcurv_ptr->add_surface(newchsurf_ptr); 03856 } 03857 03858 // any surfaces attached to this chcurv that are in vol2 are removed and the newchcurv is added 03859 DLIList<ChollaSurface *> chcsurf_list = chcurv_ptr->get_surfaces(); 03860 for (int icsurf = 0; icsurf < chcsurf_list.size(); icsurf++) 03861 { 03862 ChollaSurface *chcsurf_ptr = chcsurf_list.get_and_step(); 03863 03864 //if the adjacent surfaces are in both volumes, don't do anything 03865 if(chcsurf_ptr->is_in_volume(chvol2_ptr) ) 03866 { 03867 chcurv_ptr->remove_surface(chcsurf_ptr); 03868 chcsurf_ptr->remove_curve(chcurv_ptr); 03869 newchcurv_ptr->add_surface(chcsurf_ptr); 03870 chcsurf_ptr->add_curve_unique(newchcurv_ptr); 03871 } 03872 } 03873 03874 return CUBIT_SUCCESS; 03875 } 03876 03877 //============================================================================= 03878 //Function: detach_point 03879 //Description: given a non-manifold point in a cholla model, create a copy 03880 // and update connectivity. updates the point_map 03881 //Author:sjowen 03882 //Date: 09/18/09 03883 //============================================================================= 03884 CubitStatus ChollaEngine::detach_point(ChollaPoint *chpt_ptr, 03885 ChollaVolume *chvol2_ptr, 03886 std::map<ChollaPoint *, ChollaPoint *> &point_map, 03887 std::map<ChollaCurve *, ChollaCurve *> &curve_map ) 03888 { 03889 03890 03891 ChollaPoint *newchpt_ptr = new ChollaPoint(); 03892 chollaPointList.append( newchpt_ptr ); 03893 point_map.insert(std::pair<ChollaPoint*, ChollaPoint*>(chpt_ptr, newchpt_ptr)); 03894 03895 //find the curves that it is in 03896 DLIList<ChollaCurve *> chptcurv_list = chpt_ptr->get_curves(); 03897 for (int iptcurv = 0; iptcurv < chptcurv_list.size(); iptcurv++) 03898 { 03899 ChollaCurve *chptcurv_ptr = chptcurv_list.get_and_step(); 03900 03901 // for curves that were copied (on the interface), add the new chollapoint to the new curve 03902 03903 std::map<ChollaCurve *, ChollaCurve *>::iterator cmap_it; 03904 cmap_it = curve_map.find(chptcurv_ptr); 03905 if (cmap_it != curve_map.end()) 03906 { 03907 ChollaCurve *new_chcurv_ptr = cmap_it->second; 03908 new_chcurv_ptr->add_point(newchpt_ptr); 03909 newchpt_ptr->add_curve(new_chcurv_ptr); 03910 03911 chpt_ptr->set_merge_partner( newchpt_ptr ); 03912 newchpt_ptr->set_merge_partner( chpt_ptr ); 03913 } 03914 else 03915 { 03916 // remove curve in vol 2 (not on interface) from the original point and add it to the new point 03917 03918 if (chptcurv_ptr->is_in_volume(chvol2_ptr)) 03919 { 03920 chpt_ptr->remove_curve(chptcurv_ptr); 03921 chptcurv_ptr->remove_point(chpt_ptr); 03922 newchpt_ptr->add_curve(chptcurv_ptr); 03923 chptcurv_ptr->add_point(newchpt_ptr); 03924 03925 chpt_ptr->set_merge_partner( newchpt_ptr ); 03926 newchpt_ptr->set_merge_partner( chpt_ptr ); 03927 } 03928 } 03929 } 03930 03931 return CUBIT_SUCCESS; 03932 } 03933 03934 03935 //============================================================================= 03936 //Function: detach_facets 03937 //Description: detach the individual facets to create a manifold representation 03938 //Note: makes a copy of the facets on the merged surface and its child entities 03939 // and reconnects them locally 03940 //Author:sjowen 03941 //Date: 09/10/09 03942 //============================================================================= 03943 CubitStatus ChollaEngine::detach_facets(DLIList<ChollaSurface*> &chsurfs, 03944 DLIList<ChollaCurve*> &chcurves, 03945 ChollaVolume *chvol, 03946 std::map<ChollaSurface *, ChollaSurface *> &surf_map, 03947 std::map<ChollaCurve *, ChollaCurve *> &curve_map, 03948 std::map<ChollaPoint *, ChollaPoint *> &point_map) 03949 { 03950 03951 CubitStatus rv = CUBIT_SUCCESS; 03952 03953 std::vector<CubitPoint *> new_points; 03954 std::vector<CubitFacetEdge *> new_edges; 03955 03956 rv = copy_facets_at_interface( chsurfs, chcurves, new_points, new_edges, 03957 surf_map, curve_map, point_map ); 03958 if (rv != CUBIT_SUCCESS) 03959 return rv; 03960 03961 rv = connect_facets_at_interface( chsurfs, chcurves, chvol, new_points, new_edges ); 03962 if (rv != CUBIT_SUCCESS) 03963 return rv; 03964 03965 return rv; 03966 } 03967 03968 //============================================================================= 03969 //Function: copy_facets_at_interface 03970 //Description: 03971 //Author:sjowen 03972 //Date: 09/18/09 03973 //============================================================================= 03974 CubitStatus ChollaEngine::copy_facets_at_interface(DLIList<ChollaSurface*> &chsurfs, 03975 DLIList<ChollaCurve*> &chcurves, 03976 std::vector<CubitPoint *> &new_points, 03977 std::vector<CubitFacetEdge *> &new_edges, 03978 std::map<ChollaSurface *, ChollaSurface *> &surf_map, 03979 std::map<ChollaCurve *, ChollaCurve *> &curve_map, 03980 std::map<ChollaPoint *, ChollaPoint *> &point_map) 03981 03982 { 03983 CubitStatus rv = CUBIT_SUCCESS; 03984 03985 // first set the marked flags on all facets entities on this surface to -1 03986 03987 int ifacet; 03988 DLIList<FacetEntity *> facet_list; 03989 for( int i=chsurfs.size(); i--; ) 03990 { 03991 ChollaSurface *chsurf_ptr = chsurfs.get_and_step(); 03992 chsurf_ptr->get_facets( facet_list ); 03993 } 03994 03995 for( int i=chcurves.size(); i--; ) 03996 { 03997 DLIList<FacetEntity*> tmp_facets = chcurves.get_and_step()->get_facet_list(); 03998 facet_list += tmp_facets; 03999 } 04000 04001 FacetDataUtil::mark_facets(facet_list, FACET_ENTITY_UNINITIALIZED); 04002 04003 // create a copy of each of the facet entities on the surface. The marked flag in the facet will 04004 // keep track of the new entity created. It will be a location in the new_points or new_edges 04005 // array. Once we are finished with creating points and edges, we can create the new facets 04006 // given the references in the marked flags. 04007 04008 // create new points 04009 04010 rv = copy_points_at_interface(facet_list, new_points, surf_map, curve_map, point_map); 04011 if (rv != CUBIT_SUCCESS) 04012 return rv; 04013 04014 // create new edges 04015 04016 rv = copy_edges_at_interface(facet_list, new_points, new_edges, surf_map, curve_map, point_map); 04017 if (rv != CUBIT_SUCCESS) 04018 return rv; 04019 04020 // create new facets 04021 04022 DLIList<CubitFacet *> new_facets; 04023 for (ifacet = 0; ifacet<facet_list.size(); ifacet++) 04024 { 04025 FacetEntity *facet_ptr = facet_list.get_and_step(); 04026 CubitFacet *cfacet_ptr = dynamic_cast<CubitFacet *> (facet_ptr); 04027 if( cfacet_ptr ) 04028 { 04029 CubitFacetEdge *fedge, *newfedges[3]; 04030 CubitFacet *newcfacet_ptr; 04031 for (int ii=0; ii<3; ii++) 04032 { 04033 fedge = cfacet_ptr->edge(ii); 04034 int idx = fedge->marked(); 04035 newfedges[ii] = new_edges[idx]; 04036 } 04037 newcfacet_ptr = (CubitFacet *) new CubitFacetData(newfedges[0], newfedges[1], newfedges[2]); 04038 new_facets.append( newcfacet_ptr ); 04039 FacetEntity *newfacet_ptr = dynamic_cast<FacetEntity *> (newcfacet_ptr); 04040 set_new_facet_owners( 2, facet_ptr, newfacet_ptr, surf_map, curve_map, point_map ); 04041 } 04042 } 04043 04044 // make sure facets are oriented consistently on new volume 04045 if( new_facets.size() ) 04046 { 04047 CubitFacet *start_facet = new_facets.get(); 04048 CubitBoolean do_flip = CUBIT_TRUE; 04049 int nfacets; 04050 int mydebug = 0; 04051 rv = check_facet_orientation(start_facet, do_flip, nfacets, mydebug ); 04052 } 04053 04054 return rv; 04055 } 04056 04057 04058 CubitStatus ChollaEngine::detach_facet_edges(DLIList<ChollaCurve*> &chcurves, 04059 ChollaVolume *detaching_volume, 04060 std::map<ChollaCurve *, ChollaCurve *> &curve_map, 04061 std::map<ChollaPoint *, ChollaPoint *> &point_map ) 04062 { 04063 04064 CubitStatus rv = CUBIT_SUCCESS; 04065 04066 std::vector<CubitPoint *> new_points; 04067 std::vector<CubitFacetEdge *> new_edges; 04068 04069 rv = copy_facet_edges_at_interface( chcurves, new_points, new_edges, curve_map, point_map ); 04070 if (rv != CUBIT_SUCCESS) 04071 return rv; 04072 04073 for (int i=chcurves.size(); i--; ) 04074 { 04075 ChollaCurve *chcurv_ptr = chcurves.get_and_step(); 04076 rv = connect_points_at_interface( chcurv_ptr, detaching_volume, new_points ); 04077 if (rv != CUBIT_SUCCESS) 04078 return rv; 04079 04080 rv = connect_edges_at_interface( chcurv_ptr, detaching_volume, new_edges ); 04081 if (rv != CUBIT_SUCCESS) 04082 return rv; 04083 } 04084 04085 return rv; 04086 } 04087 04088 04089 CubitStatus ChollaEngine::copy_facet_edges_at_interface(DLIList<ChollaCurve*> &chcurves, 04090 std::vector<CubitPoint *> &new_points, 04091 std::vector<CubitFacetEdge *> &new_edges, 04092 std::map<ChollaCurve *, ChollaCurve *> &curve_map, 04093 std::map<ChollaPoint *, ChollaPoint *> &point_map) 04094 04095 { 04096 CubitStatus rv = CUBIT_SUCCESS; 04097 04098 // first set the marked flags on all facets entities to -1 04099 DLIList<FacetEntity *> facet_list; 04100 for( int i=chcurves.size(); i--; ) 04101 { 04102 ChollaCurve *chcurv_ptr = chcurves.get_and_step(); 04103 DLIList<FacetEntity*> tmp_facet_list = chcurv_ptr->get_facet_list(); 04104 facet_list += tmp_facet_list; 04105 } 04106 04107 FacetDataUtil::mark_facets(facet_list, FACET_ENTITY_UNINITIALIZED); 04108 04109 // create a copy of each of the facet entities on the surface. The marked flag in the facet will 04110 // keep track of the new entity created. It will be a location in the new_points or new_edges 04111 // array. Once we are finished with creating points and edges, we can create the new facets 04112 // given the references in the marked flags. 04113 04114 // create new points 04115 04116 std::map<ChollaSurface *, ChollaSurface *> dummy_surf_map; 04117 04118 rv = copy_points_at_interface(facet_list, new_points, dummy_surf_map, curve_map, point_map); 04119 if (rv != CUBIT_SUCCESS) 04120 return rv; 04121 04122 // create new edges 04123 04124 rv = copy_edges_at_interface(facet_list, new_points, new_edges, dummy_surf_map, curve_map, point_map); 04125 if (rv != CUBIT_SUCCESS) 04126 return rv; 04127 04128 return rv; 04129 } 04130 04131 //============================================================================= 04132 //Function: copy_points_at_interface 04133 //Description: copy the points at the interface 04134 //Author:sjowen 04135 //Date: 09/18/09 04136 //============================================================================= 04137 CubitStatus ChollaEngine::copy_points_at_interface(DLIList<FacetEntity *> &facet_list, 04138 std::vector<CubitPoint *> &new_points, 04139 std::map<ChollaSurface *, ChollaSurface *> &surf_map, 04140 std::map<ChollaCurve *, ChollaCurve *> &curve_map, 04141 std::map<ChollaPoint *, ChollaPoint *> &point_map) 04142 { 04143 int iploc = 0; 04144 04145 FacetEntity *fe_ptr, *newfe_ptr; 04146 CubitPoint *point_ptr, *newpoint_ptr; 04147 04148 for (int ifacet = 0; ifacet<facet_list.size(); ifacet++) 04149 { 04150 FacetEntity *facet_ptr = facet_list.get_and_step(); 04151 CubitFacet *cfacet_ptr = dynamic_cast<CubitFacet*>(facet_ptr); 04152 if( cfacet_ptr ) 04153 { 04154 for (int ii=0; ii<3; ii++) 04155 { 04156 point_ptr = cfacet_ptr->point(ii); 04157 if (point_ptr->marked() == FACET_ENTITY_UNINITIALIZED) 04158 { 04159 newpoint_ptr = (CubitPoint *) new CubitPointData( point_ptr->x(), point_ptr->y(), point_ptr->z() ); 04160 new_points.push_back(newpoint_ptr); 04161 point_ptr->marked(iploc++); 04162 fe_ptr = dynamic_cast<FacetEntity *> (point_ptr); 04163 newfe_ptr = dynamic_cast<FacetEntity *> (newpoint_ptr); 04164 set_new_facet_owners(0, fe_ptr, newfe_ptr, surf_map, curve_map, point_map ); 04165 } 04166 } 04167 } 04168 else 04169 { 04170 CubitFacetEdge *cfacet_edge_ptr = dynamic_cast<CubitFacetEdge*>(facet_ptr); 04171 for (int ii=0; ii<2; ii++) 04172 { 04173 point_ptr = cfacet_edge_ptr->point(ii); 04174 if (point_ptr->marked() == FACET_ENTITY_UNINITIALIZED) 04175 { 04176 newpoint_ptr = (CubitPoint *) new CubitPointData( point_ptr->x(), point_ptr->y(), point_ptr->z() ); 04177 new_points.push_back(newpoint_ptr); 04178 point_ptr->marked(iploc++); 04179 fe_ptr = dynamic_cast<FacetEntity *> (point_ptr); 04180 newfe_ptr = dynamic_cast<FacetEntity *> (newpoint_ptr); 04181 set_new_facet_owners(0, fe_ptr, newfe_ptr, surf_map, curve_map, point_map ); 04182 } 04183 } 04184 } 04185 } 04186 04187 return CUBIT_SUCCESS; 04188 } 04189 04190 //============================================================================= 04191 //Function: copy_edges_at_interface 04192 //Description: copy the edges at the interface 04193 //Author:sjowen 04194 //Date: 09/18/09 04195 //============================================================================= 04196 CubitStatus ChollaEngine::copy_edges_at_interface(DLIList<FacetEntity *> &facet_list, 04197 std::vector<CubitPoint *> &new_points, 04198 std::vector<CubitFacetEdge *> &new_edges, 04199 std::map<ChollaSurface *, ChollaSurface *> &surf_map, 04200 std::map<ChollaCurve *, ChollaCurve *> &curve_map, 04201 std::map<ChollaPoint *, ChollaPoint *> &point_map) 04202 { 04203 int ieloc = 0; 04204 CubitFacetEdge *edge_ptr, *newedge_ptr; 04205 for (int ifacet = 0; ifacet<facet_list.size(); ifacet++) 04206 { 04207 FacetEntity *facet_ptr = facet_list.get_and_step(); 04208 CubitFacet *cfacet_ptr = dynamic_cast<CubitFacet *> (facet_ptr); 04209 if( cfacet_ptr ) 04210 { 04211 for (int ii=0; ii<3; ii++) 04212 { 04213 edge_ptr = cfacet_ptr->edge(ii); 04214 if (edge_ptr->marked() == FACET_ENTITY_UNINITIALIZED) 04215 { 04216 CubitPoint *p0 = edge_ptr->point( 0 ); 04217 CubitPoint *p1 = edge_ptr->point( 1 ); 04218 int idx0 = p0->marked(); 04219 int idx1 = p1->marked(); 04220 CubitPoint *newp0 = new_points[idx0]; 04221 CubitPoint *newp1 = new_points[idx1]; 04222 newedge_ptr = (CubitFacetEdge *) new CubitFacetEdgeData( newp0, newp1 ); 04223 new_edges.push_back(newedge_ptr); 04224 edge_ptr->marked(ieloc++); 04225 FacetEntity *fe_ptr = dynamic_cast<FacetEntity *> (edge_ptr); 04226 FacetEntity *newfe_ptr = dynamic_cast<FacetEntity *> (newedge_ptr); 04227 set_new_facet_owners( 1, fe_ptr, newfe_ptr, surf_map, curve_map, point_map ); 04228 } 04229 } 04230 } 04231 else 04232 { 04233 CubitFacetEdge *edge_ptr = dynamic_cast<CubitFacetEdge*>(facet_ptr); 04234 if (edge_ptr->marked() == FACET_ENTITY_UNINITIALIZED) 04235 { 04236 CubitPoint *p0 = edge_ptr->point( 0 ); 04237 CubitPoint *p1 = edge_ptr->point( 1 ); 04238 int idx0 = p0->marked(); 04239 int idx1 = p1->marked(); 04240 CubitPoint *newp0 = new_points[idx0]; 04241 CubitPoint *newp1 = new_points[idx1]; 04242 newedge_ptr = (CubitFacetEdge *) new CubitFacetEdgeData( newp0, newp1 ); 04243 new_edges.push_back(newedge_ptr); 04244 edge_ptr->marked(ieloc++); 04245 FacetEntity *fe_ptr = dynamic_cast<FacetEntity *> (edge_ptr); 04246 FacetEntity *newfe_ptr = dynamic_cast<FacetEntity *> (newedge_ptr); 04247 set_new_facet_owners( 1, fe_ptr, newfe_ptr, surf_map, curve_map, point_map ); 04248 } 04249 } 04250 } 04251 return CUBIT_SUCCESS; 04252 } 04253 04254 //============================================================================= 04255 //Function: connect_facets_at_interface 04256 //Description: detach the facets from original points and edges and reattach to new copy 04257 //Author:sjowen 04258 //Date: 09/18/09 04259 //============================================================================= 04260 CubitStatus ChollaEngine::connect_facets_at_interface(DLIList<ChollaSurface*> &chsurfs, 04261 DLIList<ChollaCurve*> &chcurves, 04262 ChollaVolume *chvol_ptr, 04263 std::vector<CubitPoint *> &new_points, 04264 std::vector<CubitFacetEdge *> &new_edges) 04265 { 04266 CubitStatus rv = CUBIT_SUCCESS; 04267 DLIList<ChollaCurve *> chcurv_list; 04268 04269 for( int i=chsurfs.size(); i--; ) 04270 { 04271 ChollaSurface *tmp_surf = chsurfs.get_and_step(); 04272 DLIList<ChollaCurve*> tmp_curves; 04273 tmp_surf->get_curves( tmp_curves ); 04274 chcurv_list += tmp_curves; 04275 } 04276 04277 chcurv_list += chcurves; 04278 chcurv_list.uniquify_unordered(); 04279 04280 for (int icrv = 0; icrv < chcurv_list.size(); icrv++) 04281 { 04282 ChollaCurve *chcurv_ptr = chcurv_list.get_and_step(); 04283 rv = connect_points_at_interface( chcurv_ptr, chvol_ptr, new_points ); 04284 if (rv != CUBIT_SUCCESS) 04285 return rv; 04286 04287 rv = connect_edges_at_interface( chcurv_ptr, chvol_ptr, new_edges ); 04288 if (rv != CUBIT_SUCCESS) 04289 return rv; 04290 } 04291 04292 return rv; 04293 } 04294 04295 //============================================================================= 04296 //Function: connect_points_at_interface 04297 //Description: find adjacent CubitFacetEdges on volume 2 that needs updating 04298 //Notes: chcurv_ptr is a curve at the interface on the original volume 04299 // chvol_ptr is the second volume (new (copied) entities belong to vol 2) 04300 // This functions gets all edges attached to the original CubitPoints on the 04301 // original curve 'chcurv_ptr'. If any edge is on volume 2 (the volume we are 04302 // splitting off) we need to update the edges on that volume to contain the 04303 // the new CubitPoint. 04304 //Author:sjowen 04305 //Date: 09/18/09 04306 //============================================================================= 04307 CubitStatus ChollaEngine::connect_points_at_interface(ChollaCurve *chcurv_ptr, 04308 ChollaVolume *chvol_ptr, 04309 std::vector<CubitPoint *> &new_points) 04310 { 04311 DLIList<CubitPoint *> cp_list; 04312 chcurv_ptr->get_facet_points(cp_list, CUBIT_TRUE); 04313 for (int ip = 0; ip<cp_list.size(); ip++) 04314 { 04315 CubitPoint *cp_ptr = cp_list.get_and_step(); 04316 CubitPoint *newcp_ptr = new_points[cp_ptr->marked()]; 04317 04318 // set the point into edges that are on volume 2. 04319 // Note that there is no direct reference from points to edges in our data structure 04320 // so no need to add/remove the edge from the point 04321 04322 DLIList<CubitFacetEdge *> pedge_list; 04323 cp_ptr->edges(pedge_list); 04324 for (int iedge=0; iedge<pedge_list.size(); iedge++) 04325 { 04326 CubitFacetEdge *edge_ptr = pedge_list.get_and_step(); 04327 TDGeomFacet *td_geom = TDGeomFacet::get_geom_facet( edge_ptr ); 04328 if (td_geom->is_in_volume( chvol_ptr )) 04329 { 04330 CubitPoint *p0 = edge_ptr->point(0); 04331 CubitPoint *p1 = edge_ptr->point(1); 04332 CubitFacetEdgeData *cfed_ptr = dynamic_cast<CubitFacetEdgeData *> (edge_ptr); 04333 if (p0 == cp_ptr) 04334 cfed_ptr->set_point( newcp_ptr, 0 ); 04335 else if (p1 == cp_ptr) 04336 cfed_ptr->set_point( newcp_ptr, 1 ); 04337 } 04338 } 04339 04340 // remove facets in volume 2 from the point and add the to the new point 04341 // update the point reference on the facet 04342 04343 DLIList<CubitFacet *> pfacet_list; 04344 cp_ptr->facets(pfacet_list); 04345 for (int ifacet = 0; ifacet < pfacet_list.size(); ifacet++) 04346 { 04347 CubitFacet *facet_ptr = pfacet_list.get_and_step(); 04348 TDGeomFacet *td_geom = TDGeomFacet::get_geom_facet( facet_ptr ); 04349 if (td_geom->is_in_volume( chvol_ptr )) 04350 { 04351 cp_ptr->remove_facet( facet_ptr ); 04352 newcp_ptr->add_facet( facet_ptr ); 04353 int ptidx = facet_ptr->point_index(cp_ptr); 04354 CubitFacetData *cfd_ptr = dynamic_cast<CubitFacetData *> (facet_ptr); 04355 cfd_ptr->set_point(newcp_ptr, ptidx); 04356 } 04357 } 04358 } 04359 return CUBIT_SUCCESS; 04360 } 04361 04362 //============================================================================= 04363 //Function: connect_edges_at_interface 04364 //Description: detach the facet edges from original facets and reattach to new copy 04365 //Notes: chcurv_ptr is a curve at the interface on the original volume 04366 // chvol_ptr is the second volume (new (copied) entities belong to vol 2) 04367 // This functions gets all CubitFacets attached to any CubitFacetEdges on the 04368 // original curve 'chcurv_ptr'. If any facet is on volume 2 (the volume we are 04369 // splitting off) we need to update the edges on that facet on the new volume 04370 // to contain the new CubitFacetEdge. 04371 //Author:sjowen 04372 //Date: 09/18/09 04373 //============================================================================= 04374 CubitStatus ChollaEngine::connect_edges_at_interface(ChollaCurve *chcurv_ptr, 04375 ChollaVolume *chvol_ptr, 04376 std::vector<CubitFacetEdge *> &new_edges) 04377 { 04378 DLIList<FacetEntity *> fe_list = chcurv_ptr->get_facet_list(); 04379 for (int ie=0; ie<fe_list.size(); ie++) 04380 { 04381 FacetEntity *fe_ptr = fe_list.get_and_step(); 04382 CubitFacetEdge *edge_ptr = dynamic_cast<CubitFacetEdge *> (fe_ptr); 04383 assert(edge_ptr != NULL); 04384 DLIList<CubitFacet *> efacet_list; 04385 edge_ptr->facets(efacet_list); 04386 for (int ifacet=0; ifacet<efacet_list.size(); ifacet++) 04387 { 04388 CubitFacet *facet_ptr = efacet_list.get_and_step(); 04389 TDGeomFacet *td_geom = TDGeomFacet::get_geom_facet( facet_ptr ); 04390 if (td_geom->is_in_volume( chvol_ptr )) 04391 { 04392 edge_ptr->remove_facet( facet_ptr ); 04393 CubitFacetEdge *newedge_ptr = new_edges[edge_ptr->marked()]; 04394 newedge_ptr->add_facet( facet_ptr ); 04395 int edidx = facet_ptr->edge_index(edge_ptr); 04396 CubitFacetData *cfd_ptr = dynamic_cast<CubitFacetData *> (facet_ptr); 04397 cfd_ptr->edge(newedge_ptr, edidx); 04398 } 04399 } 04400 } 04401 return CUBIT_SUCCESS; 04402 } 04403 04404 //============================================================================= 04405 //Function: set_new_facet_owners 04406 //Description: update the ownenrship of the new detached facet entity based upon 04407 // the map set up in detach_volumes 04408 // 04409 //Author:sjowen 04410 //Date: 09/14/09 04411 //============================================================================= 04412 CubitStatus ChollaEngine::set_new_facet_owners(int type, //0, 1, or 2 based on dimension of facet entity 04413 FacetEntity *fe_ptr, FacetEntity *newfe_ptr, 04414 std::map<ChollaSurface *, ChollaSurface *> &surf_map, 04415 std::map<ChollaCurve *, ChollaCurve *> &curve_map, 04416 std::map<ChollaPoint *, ChollaPoint *> &point_map ) 04417 { 04418 04419 // The tooldata on the original facet entity should tell us what cholla entity it belongs 04420 // to. Using the map, we can then determine its new cholla entity partner. With the 04421 // new merge partner, set the ownership of the new facet. Note that this manages one-to-many 04422 // ownership cases where a facet lies on (or is owned by) any number of geometric entities 04423 04424 TDGeomFacet *td_geom = TDGeomFacet::get_geom_facet( fe_ptr ); 04425 TDGeomFacet::add_geom_facet(newfe_ptr, td_geom->get_block_id()); 04426 04427 // the original facet entity is owned by one or more surfaces 04428 04429 DLIList<ChollaSurface *> surf_list; 04430 td_geom->get_cholla_surfs( surf_list ); 04431 for (int jj=0; jj<surf_list.size(); jj++) 04432 { 04433 ChollaSurface *surf_ptr = surf_list.get_and_step(); 04434 std::map<ChollaSurface *, ChollaSurface *>::iterator map_it; 04435 map_it = surf_map.find( surf_ptr ); 04436 assert(map_it != surf_map.end()); 04437 ChollaSurface *newsurf_ptr = map_it->second; 04438 TDGeomFacet *newtdgeom = TDGeomFacet::get_geom_facet( newfe_ptr ); 04439 newtdgeom->add_cholla_surf( newsurf_ptr ); 04440 04441 // add this facet entity to the cholla surface only if this is a facet 04442 04443 if (type == 2) 04444 newsurf_ptr->add_facet(newfe_ptr); 04445 } 04446 04447 04448 // the original facet entity is owned by one or more curves 04449 04450 DLIList<ChollaCurve *> curv_list; 04451 td_geom->get_cholla_curves( curv_list ); 04452 for (int jj=0; jj<curv_list.size(); jj++) 04453 { 04454 ChollaCurve *curv_ptr = curv_list.get_and_step(); 04455 std::map<ChollaCurve *, ChollaCurve *>::iterator map_it, upper_iter; 04456 map_it = curve_map.find( curv_ptr ); 04457 assert(map_it != curve_map.end()); 04458 ChollaCurve *newcurv_ptr = NULL; 04459 newcurv_ptr = map_it->second; 04460 04461 TDGeomFacet *newtdgeom = TDGeomFacet::get_geom_facet( newfe_ptr ); 04462 newtdgeom->add_cholla_curve( newcurv_ptr ); 04463 04464 // add this facet entity to the cholla curve only if this is a facetedge 04465 04466 if (type == 1) 04467 newcurv_ptr->add_facet(newfe_ptr); 04468 } 04469 04470 // the original facet entity is owned by one or more points (vertices) 04471 04472 DLIList<ChollaPoint *> point_list; 04473 td_geom->get_cholla_points( point_list ); 04474 for (int jj=0; jj<point_list.size(); jj++) 04475 { 04476 ChollaPoint *point_ptr = point_list.get_and_step(); 04477 std::map<ChollaPoint *, ChollaPoint *>::iterator map_it, upper_iter; 04478 map_it = point_map.find( point_ptr ); 04479 assert(map_it != point_map.end()); 04480 ChollaPoint *newchpoint_ptr = NULL; 04481 newchpoint_ptr = map_it->second; 04482 04483 TDGeomFacet *newtdgeom = TDGeomFacet::get_geom_facet( newfe_ptr ); 04484 newtdgeom->add_cholla_point( newchpoint_ptr ); 04485 04486 // add this facet entity to the cholla point only if this is a cubitpoint 04487 04488 if (type == 0) 04489 newchpoint_ptr->add_facet(newfe_ptr); 04490 } 04491 return CUBIT_SUCCESS; 04492 04493 } 04494 04495 //============================================================================= 04496 //Function: verify_points_to_curves 04497 //Description: verify the connectivity between points and curves 04498 //Author:sjowen 04499 //Date: 09/16/09 04500 //============================================================================= 04501 CubitStatus ChollaEngine::verify_points_to_curves() 04502 { 04503 for (int ii=0; ii<chollaPointList.size(); ii++) 04504 { 04505 ChollaPoint *chpt = chollaPointList.get_and_step(); 04506 if (!chpt->verify_curves()) 04507 { 04508 PRINT_ERROR("ChollaPoint %d not associated with one of its curves.\n", chpt->get_id()); 04509 return CUBIT_FAILURE; 04510 } 04511 } 04512 for (int ii=0; ii<chollaCurveList.size(); ii++) 04513 { 04514 ChollaCurve *chcrv = chollaCurveList.get_and_step(); 04515 if (!chcrv->verify_points()) 04516 { 04517 PRINT_ERROR("ChollaCurve %d not associated with one of its points.\n", chcrv->get_id()); 04518 return CUBIT_FAILURE; 04519 } 04520 } 04521 return CUBIT_SUCCESS; 04522 } 04523 04524 CubitStatus ChollaEngine::set_curve_endpoints(std::map<ChollaPoint *, ChollaPoint *> &point_map, 04525 std::map<ChollaCurve *, ChollaCurve *> &curve_map ) 04526 04527 { 04528 DLIList<ChollaPoint*> original_chpts; 04529 DLIList<ChollaPoint*> new_chpts; 04530 DLIList<ChollaCurve*> original_chcurves; 04531 DLIList<ChollaCurve*> new_chcurves; 04532 04533 std::map<ChollaCurve*, ChollaCurve*>::iterator curv_iter = curve_map.begin(); 04534 for(; curv_iter!=curve_map.end(); curv_iter++ ) 04535 { 04536 ChollaCurve *orig_curve = curv_iter->first; 04537 ChollaCurve *new_curve = curv_iter->second; 04538 04539 //curves 04540 original_chcurves.append( orig_curve ); 04541 new_chcurves.append( new_curve ); 04542 04543 //points 04544 DLIList<ChollaPoint*> tmp_pts = orig_curve->get_points(); 04545 original_chpts += tmp_pts; 04546 04547 tmp_pts.clean_out(); 04548 tmp_pts = new_curve->get_points(); 04549 new_chpts += tmp_pts; 04550 } 04551 04552 original_chpts.uniquify_unordered(); 04553 original_chcurves.uniquify_unordered(); 04554 new_chpts.uniquify_unordered(); 04555 new_chcurves.uniquify_unordered(); 04556 04557 std::map<ChollaPoint*,ChollaPoint*>::iterator pt_iter; 04558 for( int i=original_chpts.size(); i--; ) 04559 { 04560 ChollaPoint *orig_pt = original_chpts.get_and_step(); 04561 04562 pt_iter = point_map.find( orig_pt ); 04563 assert( pt_iter != point_map.end() ); 04564 04565 ChollaPoint *new_pt = pt_iter->second; 04566 04567 CubitPoint *new_cp = dynamic_cast<CubitPoint *>(new_pt->get_facets()); 04568 CubitPoint *orig_cp = dynamic_cast<CubitPoint *>(orig_pt->get_facets()); 04569 04570 //get the curves attached to it that are in the original surface 04571 DLIList<ChollaCurve*> adj_curves = orig_pt->get_curves(); 04572 04573 for( int j=adj_curves.size(); j--; ) 04574 { 04575 ChollaCurve *orig_curve = adj_curves.get_and_step(); 04576 04577 curv_iter = curve_map.find( orig_curve ); 04578 04579 //use the original curve's start/end pts as a guide to set the new curve's start/end pts 04580 if( curv_iter != curve_map.end() ) 04581 { 04582 //if there is a corresponding new curve, get it 04583 ChollaCurve *new_curve_in_new_surf = curv_iter->second; 04584 04585 CubitPoint *start, *end; 04586 orig_curve->get_ends(start, end); 04587 assert(orig_cp != NULL); 04588 assert(start!= NULL); 04589 assert(end != NULL); 04590 04591 if ( orig_cp == start ) 04592 { 04593 new_curve_in_new_surf->set_start(new_cp); 04594 } 04595 if ( orig_cp == end ) 04596 { 04597 new_curve_in_new_surf->set_end(new_cp); 04598 } 04599 } 04600 } 04601 } 04602 04603 //for each new point 04604 for( int i=new_chpts.size(); i--; ) 04605 { 04606 ChollaPoint *new_point = new_chpts.get_and_step(); 04607 04608 DLIList<ChollaCurve*> curves_in_pt = new_point->get_curves(); 04609 04610 for( int k=curves_in_pt.size(); k--; ) 04611 { 04612 ChollaCurve *curve_in_pt = curves_in_pt.get_and_step(); 04613 04614 //get adjacent curves that are not new (not in 'new_curves') 04615 if( !original_chcurves.is_in_list( curve_in_pt ) ) 04616 { 04617 DLIList<ChollaPoint *> chpts_on_curve = curve_in_pt->get_points(); 04618 04619 // one point on the curve assumes a periodic curve. set both ends the same 04620 04621 if (chpts_on_curve.size() == 1) 04622 { 04623 ChollaPoint *chpt_on_crv = chpts_on_curve.get(); 04624 CubitPoint *cp = dynamic_cast<CubitPoint *> (chpt_on_crv->get_facets()); 04625 curve_in_pt->set_start(cp); 04626 curve_in_pt->set_end(cp); 04627 } 04628 04629 // standard case. one point of curve is on the interface and one is not. 04630 // In this case, one of the points has been replaced with a new point. 04631 // so one of the end point pointers are out of date. Determine which one 04632 // and then set it. 04633 04634 else if (chpts_on_curve.size() == 2) 04635 { 04636 ChollaPoint *chpt1_on_crv = chpts_on_curve.get_and_step(); 04637 ChollaPoint *chpt2_on_crv = chpts_on_curve.get(); 04638 CubitPoint *cp1 = dynamic_cast<CubitPoint *> (chpt1_on_crv->get_facets()); 04639 CubitPoint *cp2 = dynamic_cast<CubitPoint *> (chpt2_on_crv->get_facets()); 04640 CubitPoint *curstart, *curend; 04641 curve_in_pt->get_ends(curstart, curend); 04642 assert(curstart != NULL); 04643 assert(curend != NULL); 04644 04645 if (curstart == cp1) 04646 { 04647 curve_in_pt->set_end(cp2); 04648 } 04649 else if (curstart == cp2) 04650 { 04651 curve_in_pt->set_end(cp1); 04652 } 04653 else if (curend == cp2) 04654 { 04655 curve_in_pt->set_start(cp1); 04656 } 04657 else if (curend == cp1) 04658 { 04659 curve_in_pt->set_start(cp2); 04660 } 04661 else 04662 { 04663 //do this by proximity 04664 double dist1 = curstart->coordinates().distance_between( cp1->coordinates() ); 04665 double dist2 = curstart->coordinates().distance_between( cp2->coordinates() ); 04666 04667 if( dist1 < dist2 ) 04668 curve_in_pt->set_start( cp1 ); 04669 else if(dist2 < dist1 ) 04670 curve_in_pt->set_start( cp2 ); 04671 else 04672 assert(0); 04673 } 04674 } 04675 else 04676 assert(0); 04677 } 04678 } 04679 } 04680 return CUBIT_SUCCESS; 04681 } 04682 04683 // EOF