cgma
|
00001 //- Class: TDOctreeRefFace 00002 //- Description: Tool data for storing additional information needed for MAT generation. 00003 //- Owner: W. R. Quadors 00004 //- Checked by: 00005 //- Version: 00006 00007 #include "TDOctreeRefFace.hpp" 00008 #include "CubitDefines.h" 00009 #include "ToolData.hpp" 00010 #include "MemoryManager.hpp" 00011 #include "DLIList.hpp" 00012 #include "CubitVector.hpp" 00013 #include "CastTo.hpp" 00014 00015 #include "CubitTransformMatrix.hpp" 00016 #include "RefFace.hpp" 00017 #include "CubitFacet.hpp" 00018 #include "CubitFacetData.hpp" 00019 #include "CubitFacetEdge.hpp" 00020 #include "CubitFacetEdgeData.hpp" 00021 #include "CubitPointData.hpp" 00022 #include "CubitOctreeConstants.hpp" 00023 #include "FacetDataUtil.hpp" 00024 00025 00026 // Constructor 00027 TDOctreeRefFace::TDOctreeRefFace(){ 00028 00029 ptrCubitPointList = NULL; 00030 ptrCubitFacetEdgeList = NULL; 00031 ptrCubitFacetList = NULL; 00032 visit = CUBIT_FALSE; 00033 create_2dmat = CUBIT_TRUE; 00034 } 00035 00036 // Distructor 00037 TDOctreeRefFace::~TDOctreeRefFace() 00038 { 00039 if (ptrCubitFacetList != NULL) 00040 { 00041 FacetDataUtil::delete_facets(*ptrCubitFacetList); 00042 if( ptrCubitFacetList ) 00043 delete ptrCubitFacetList; 00044 ptrCubitFacetList = NULL; 00045 00046 if( ptrCubitFacetEdgeList ) 00047 delete ptrCubitFacetEdgeList; 00048 ptrCubitFacetEdgeList = NULL; 00049 00050 if( ptrCubitPointList ) 00051 delete ptrCubitPointList; 00052 ptrCubitPointList = NULL; 00053 } 00054 00055 //PRINT_INFO("Inside ~TDOctreeRefFace\n"); 00056 } 00057 00058 //------------------------------------------------------------------------- 00059 // Purpose : To create TDOctreeRefFace to RefFace 00060 // 00061 // Special Notes : 00062 // 00063 // Creator : W R Quadros 00064 // 00065 // Creation Date : 07/03 00066 //------------------------------------------------------------------------- 00067 CubitStatus TDOctreeRefFace::add_td( RefFace *ref_face ) 00068 { 00069 ToolData *td; 00070 td = ref_face->get_TD(&TDOctreeRefFace::is_td_octree_ref_face); 00071 if ( td == NULL ) 00072 { 00073 TDOctreeRefFace *td_gm = new TDOctreeRefFace; 00074 ref_face->add_TD( td_gm); 00075 td_gm->set_ref_face( ref_face ); 00076 } 00077 else 00078 { 00079 TDOctreeRefFace *td_gm = CAST_TO(td, TDOctreeRefFace); 00080 td_gm->set_ref_face( ref_face ); 00081 00082 } 00083 return CUBIT_SUCCESS; 00084 } 00085 00086 //------------------------------------------------------------------------- 00087 // Purpose : get the TDOctreeRefFace for a RefFace 00088 // 00089 // Special Notes : 00090 // 00091 // Creator : W R Quadros 00092 // 00093 // Creation Date : 07/03 00094 //------------------------------------------------------------------------- 00095 TDOctreeRefFace* TDOctreeRefFace::get_td( RefFace *ref_face ) 00096 { 00097 ToolData *td; 00098 td = ref_face->get_TD(&TDOctreeRefFace::is_td_octree_ref_face); 00099 if ( td != NULL ) 00100 { 00101 TDOctreeRefFace *td_gm = CAST_TO(td, TDOctreeRefFace); 00102 return td_gm; 00103 } 00104 return (TDOctreeRefFace*) NULL; 00105 } 00106 CubitBoolean TDOctreeRefFace::is_adj_curves( int id1, int id2 ){ 00107 00108 int loop_index1, loop_index2; 00109 int i; 00110 int first_curve_id, last_curve_id, start_curve_id; 00111 00112 loopIndex.reset(); 00113 loop_index1 = CUBIT_INT_MAX; 00114 // i indicates loop index 00115 for( i = 0; i < loopIndex.size(); i++ ){ 00116 start_curve_id = loopIndex.get_and_step(); 00117 if( id1 < start_curve_id ){ 00118 loop_index1 = i - 1; 00119 break; 00120 } 00121 } 00122 if( loop_index1 == CUBIT_INT_MAX ){ 00123 loop_index1 = i - 1; 00124 } 00125 00126 loopIndex.reset(); 00127 loop_index2 = CUBIT_INT_MAX; 00128 // i indicates loop index 00129 for( i = 0; i < loopIndex.size(); i++ ){ 00130 start_curve_id = loopIndex.get_and_step(); 00131 if( id2 < start_curve_id ){ 00132 loop_index2 = i - 1; 00133 break; 00134 } 00135 } 00136 00137 if( loop_index2 == CUBIT_INT_MAX ){ 00138 loop_index2 = i - 1; 00139 } 00140 00141 if( loop_index1 != loop_index2 ){ 00142 // curves are not in same loop 00143 return CUBIT_FALSE; 00144 } 00145 else{ 00146 if( abs(id1 - id2) == 1 ){ 00147 // adj curves of same loop 00148 return CUBIT_TRUE; 00149 } 00150 loopIndex.reset(); 00151 loopIndex.step( loop_index1 ); 00152 first_curve_id = loopIndex.get_and_step(); 00153 last_curve_id = loopIndex.get() - 1; 00154 00155 if( last_curve_id < first_curve_id ){ 00156 // PRINT_DEBUG_157(" id1 = %d and id2 = %d", id1, id2 ); 00157 // PRINT_DEBUG_157(" Note: Last curve id ( %d ) is less than first curve id ( %d ) \n", last_curve_id, first_curve_id ); 00158 last_curve_id = lastCurveID; 00159 // PRINT_DEBUG_157(" last_curve_id is reset to %d \n", lastCurveID ); 00160 } 00161 00162 if( abs(id1 - id2) == (last_curve_id - first_curve_id ) ){ 00163 // firs and last curve of same loop 00164 return CUBIT_TRUE; 00165 } 00166 00167 // part of same curve 00168 if( abs(id1 - id2) == 0 ){ 00169 return CUBIT_TRUE; 00170 } 00171 00172 // same loop but non-adj curves 00173 return CUBIT_FALSE; 00174 } 00175 } 00176 00177 CubitBoolean TDOctreeRefFace::split_facet_type_03( CubitFacet *target_facet, DLIList<CubitFacet*> &facet_list, DLIList<CubitFacetEdge*> &facet_edge_list, DLIList<CubitPoint*> &point_list ){ 00178 00179 // Do Nothing 00180 // During CAT centroid will give the approximate branch point 00181 return CUBIT_TRUE; 00182 } 00183 00184 CubitBoolean TDOctreeRefFace::split_facet_type_13( CubitFacet *target_facet, DLIList<CubitFacet*> &facet_list, DLIList<CubitFacetEdge*> &facet_edge_list, DLIList<CubitPoint*> &point_list ){ 00185 int i; 00186 CubitFacetEdge *boundary_edge = NULL, *ptr_edge; 00187 CubitPoint *boundary_edge_pnt0, *boundary_edge_pnt1, *other_boundary_point; 00188 double internal_angle; 00189 int num_of_segments; 00190 00191 for( i = 0; i < 3; i++ ){ 00192 ptr_edge = target_facet->edge(i); 00193 if( abs( ptr_edge->marked() ) == 1 ){ 00194 boundary_edge = ptr_edge; 00195 break; 00196 } 00197 } 00198 00199 boundary_edge_pnt0 = boundary_edge->point(0); 00200 boundary_edge_pnt1 = boundary_edge->point(1); 00201 00202 for( i = 0; i < 3; i++ ){ 00203 other_boundary_point = target_facet->point(i); 00204 if( other_boundary_point->id() != boundary_edge_pnt0->id() && other_boundary_point->id() != boundary_edge_pnt1->id() ){ 00205 break; 00206 } 00207 } 00208 00209 internal_angle = target_facet->angle( other_boundary_point ); 00210 00211 num_of_segments = (int)(floor( (internal_angle / (FACET_SPLITTING_INTERNAL_ANGLE )) + 0.5)); 00212 00213 if( num_of_segments > 1 ) 00214 split_facet_locally_along_edge( target_facet, boundary_edge_pnt0, boundary_edge_pnt1, boundary_edge, num_of_segments, facet_list, facet_edge_list, point_list ); 00215 00216 return CUBIT_TRUE; 00217 } 00218 00219 CubitBoolean TDOctreeRefFace::split_facet_type_23( CubitFacet *target_facet, DLIList<CubitFacet*> &facet_list, DLIList<CubitFacetEdge*> &facet_edge_list, DLIList<CubitPoint*> &point_list ){ 00220 00221 int i; 00222 CubitFacetEdge *ptr_edge, *boundary_edge1, *boundary_edge2 = NULL, 00223 *boundary_split_edge; 00224 CubitPoint *other_boundary_point; 00225 double internal_angle; 00226 int num_of_segments; 00227 00228 boundary_edge1 = NULL; 00229 for( i = 0; i < 3; i++ ){ 00230 ptr_edge = target_facet->edge(i); 00231 if( abs( ptr_edge->marked() ) == 1 ){ 00232 if( boundary_edge1 == NULL ){ 00233 boundary_edge1 = ptr_edge; 00234 } 00235 else{ 00236 boundary_edge2 = ptr_edge; 00237 break; 00238 } 00239 } 00240 } 00241 00242 00243 CubitFacetEdgeData *boundary_edge1_data = dynamic_cast<CubitFacetEdgeData*>( boundary_edge1 ); 00244 CubitFacetEdgeData *boundary_edge2_data = dynamic_cast<CubitFacetEdgeData*>( boundary_edge2 ); 00245 00246 if( boundary_edge1_data->length() > boundary_edge2_data->length() ){ 00247 boundary_split_edge = boundary_edge1; 00248 } 00249 else{ 00250 boundary_split_edge = boundary_edge2; 00251 } 00252 00253 for( i = 0; i < 3; i++ ){ 00254 other_boundary_point = target_facet->point(i); 00255 if( other_boundary_point->id() != boundary_split_edge->point(0)->id() && other_boundary_point->id() != boundary_split_edge->point(1)->id() ){ 00256 break; 00257 } 00258 } 00259 00260 internal_angle = target_facet->angle( other_boundary_point ); 00261 00262 num_of_segments = (int)(floor( (internal_angle / (FACET_SPLITTING_INTERNAL_ANGLE )) + 0.5)); 00263 00264 if( num_of_segments > 1 ) 00265 split_facet_locally_along_edge( target_facet, boundary_split_edge->point(0), boundary_split_edge->point(1), boundary_split_edge, num_of_segments, facet_list, facet_edge_list, point_list ); 00266 00267 return CUBIT_TRUE; 00268 } 00269 00270 CubitBoolean TDOctreeRefFace::split_facet_type_33( CubitFacet *target_facet, DLIList<CubitFacet*> &facet_list, DLIList<CubitFacetEdge*> &facet_edge_list, DLIList<CubitPoint*> &point_list ){ 00271 00272 // Do Nothing 00273 // 00274 // WARNING: Degenerate Case 00275 // A triangualar surface patch is a facet. 00276 // Skeleton should be calculated by taking circum/in center and radius. 00277 return CUBIT_TRUE; 00278 } 00279 00280 CubitBoolean TDOctreeRefFace::split_facet_locally_along_edge( CubitFacet *target_facet, CubitPoint *edge1_pt, CubitPoint *edge2_pt, CubitFacetEdge *ptr_edge, int num_of_segments, DLIList<CubitFacet*> &facet_list, DLIList<CubitFacetEdge*> &facet_edge_list, DLIList<CubitPoint*> &point_list){ 00281 int i; 00282 CubitFacet *new_facet; 00283 CubitVector position, delta_length; 00284 00285 delta_length = (edge2_pt->coordinates() - edge1_pt->coordinates()) / num_of_segments; 00286 00287 for( i = num_of_segments - 1; i >= 1; i-- ){ 00288 position = edge1_pt->coordinates() + ( delta_length * i ); 00289 00290 CubitPointData* new_pt_data = new CubitPointData( position ); 00291 00292 // update TD and append the list 00293 CubitPoint *new_pt = CAST_TO(new_pt_data, CubitPoint); 00294 new_facet = split_facet_into_two_facets( target_facet, edge1_pt, edge2_pt, ptr_edge, new_pt, facet_list, facet_edge_list, point_list ); 00295 00296 // mark the newly created facets so that they are not checked for 00297 // further splitting. "this" facet is marked in Octree.cpp. 00298 new_facet->marked( -1 ); 00299 edge2_pt = new_pt; 00300 } 00301 return CUBIT_TRUE; 00302 } 00303 00304 CubitFacet *TDOctreeRefFace::split_facet_into_two_facets( CubitFacet *target_facet, CubitPoint* edge1_pt, CubitPoint* edge2_pt, CubitFacetEdge *edge, CubitPoint* new_pt, DLIList<CubitFacet*> &facet_list, DLIList<CubitFacetEdge*> &facet_edge_list, DLIList<CubitPoint*> &point_list){ 00305 00306 //add new_pt to point_list 00307 point_list.append( new_pt ); 00308 new_pt->marked( abs( edge->marked() )); 00309 00310 // split triangle 00311 CubitFacetData* facet_d = dynamic_cast<CubitFacetData*>(target_facet); 00312 assert(!!facet_d); 00313 00314 // fix up existing facet 00315 int pt2_index = target_facet->point_index( edge2_pt ); 00316 bool edge_reversed = ( edge1_pt == target_facet->point( (pt2_index+1) % 3 ) ); 00317 int edge_index = (pt2_index + 1 + edge_reversed) % 3; 00318 00319 edge2_pt->remove_facet( target_facet ); 00320 facet_d->set_point( new_pt, pt2_index ); 00321 new_pt->add_facet( target_facet ); 00322 target_facet->update_plane(); 00323 00324 // make new facet and update facet list 00325 CubitPoint* other_pt = target_facet->point( edge_index ); 00326 CubitFacetData* new_facet; 00327 if( edge_reversed ) 00328 new_facet = new CubitFacetData( other_pt, edge2_pt, new_pt ); 00329 else 00330 new_facet = new CubitFacetData( other_pt, new_pt, edge2_pt ); 00331 00332 // facet constructor takes care of this 00333 // update the facets in points 00334 // this takes care of adj facets of new edges and 00335 // conversely edges of two facets 00336 //edge2_pt->add_facet( new_facet ); 00337 //new_pt->add_facet( new_facet ); 00338 //other_pt->add_facet( new_facet ); 00339 00340 00341 // Facets list in the points should be updated before creating new edge 00342 // the edge constructor generates adjacet facets. 00343 // split edge, if there is one 00344 //CubitFacetEdge* edge = edge1_pt->shared_edge( edge2_pt ); 00345 CubitFacetEdgeData* new_edge = 0; 00346 if( edge ){ 00347 CubitFacetEdgeData* edge_d = dynamic_cast<CubitFacetEdgeData*>(edge); 00348 assert(!!edge_d); 00349 00350 00351 // make sure new edge has same orientation as old edge 00352 new_edge = dynamic_cast<CubitFacetEdgeData*>(new_pt->shared_edge(edge2_pt)); 00353 if( edge->point(0) == edge1_pt ){ 00354 edge_d->set_point(new_pt, 1); 00355 if ( !new_edge ) 00356 new_edge = new CubitFacetEdgeData( new_pt, edge2_pt ); 00357 else if( new_edge->point(0) != new_pt ) 00358 new_edge->flip(); 00359 } 00360 else { 00361 edge_d->set_point(new_pt, 0); 00362 if ( !new_edge ) 00363 new_edge = new CubitFacetEdgeData( edge2_pt, new_pt ); 00364 else if( new_edge->point(1) != new_pt ) 00365 new_edge->flip(); 00366 } 00367 00368 new_edge->marked( abs( edge->marked() ) ); 00369 facet_edge_list.append( new_edge ); 00370 } 00371 else{ 00372 PRINT_INFO("ERROR:Edge is doesn't exist. Splitting is not possible"); 00373 } 00374 00375 int sense; 00376 00377 /* 00378 // constructor takes care of this 00379 if ( new_edge ) { 00380 assert(!new_facet->edge(0)); 00381 new_facet->edge( new_edge, 0 ); 00382 new_edge->add_facet( new_facet ); 00383 sense = new_facet->point( 1 ) == new_edge->point(0) ? 1 : -1; 00384 new_facet->edge_use( sense, 0 ); 00385 } 00386 */ 00387 // facet_list appended 00388 facet_list.append( new_facet ); 00389 00390 // move other edge, if there is one 00391 int pt1_index = ( pt2_index + 2 - edge_reversed ) % 3; 00392 CubitFacetEdge* other_edge = target_facet->edge( pt1_index ); 00393 int e_index; 00394 if( other_edge ){ 00395 other_edge->remove_facet(target_facet); 00396 //target_facet->edge( 0, pt1_index ); 00397 e_index = 1 + edge_reversed; 00398 assert(!new_facet->edge(e_index)); 00399 new_facet->edge( other_edge, e_index ); 00400 other_edge->add_facet( new_facet ); 00401 sense = new_facet->point( ( e_index + 1 ) % 3 ) == other_edge->point(0) ? 1 : -1; 00402 new_facet->edge_use( sense, e_index ); 00403 } 00404 00405 // Add new mid edge in two facets 00406 00407 CubitFacetEdgeData *new_mid_edge_data; 00408 CubitFacetEdge *new_mid_edge; 00409 if( edge_reversed ) 00410 new_mid_edge_data = new CubitFacetEdgeData( other_pt, new_pt ); 00411 else 00412 new_mid_edge_data = new CubitFacetEdgeData( new_pt, other_pt ); 00413 00414 new_mid_edge = CAST_TO( new_mid_edge_data, CubitFacetEdge ); 00415 00416 new_mid_edge->marked(2); 00417 00418 // new_mid_edge is appended 00419 facet_edge_list.append( new_mid_edge ); 00420 00421 /* ////edge constructor takes care of this 00422 target_facet->edge( new_mid_edge, pt1_index ); 00423 00424 if( !edge_reversed ){ // new_mid_edge index 2 00425 new_facet->edge( new_mid_edge, ( e_index + 1 ) % 3 ); 00426 sense = new_facet->point( ( e_index + 2 ) % 3 ) == new_mid_edge->point(0) ? 1 : -1; 00427 new_facet->edge_use( sense, (e_index + 1 ) % 3); 00428 } 00429 else{ // edge index 1 00430 new_facet->edge( new_mid_edge, ( e_index - 1 ) % 3 ); 00431 sense = new_facet->point( ( e_index ) % 3 ) == new_mid_edge->point(0) ? 1 : -1; 00432 new_facet->edge_use( sense, (e_index - 1 ) % 3); 00433 } 00434 */ 00435 00436 00437 #ifndef NDEBUG 00438 /* ---------------------- TESTING ----------------------- */ 00439 // Testing the oerientation of faces w.r.t. the common edge 00440 00441 int index0, index1; 00442 00443 if( new_mid_edge->num_adj_facets() != 2 ){ 00444 PRINT_INFO("ERROR:number of adjacent faces of new mid edge is not equal to 2 \n"); 00445 assert(0); 00446 } 00447 00448 CubitFacet *ptr_facet0 = new_mid_edge->adj_facet(0); 00449 CubitFacet *ptr_facet1 = new_mid_edge->adj_facet(1); 00450 00451 for( index0 = 0; index0 < 3; index0++ ){ 00452 if( ptr_facet0->edge(index0) == new_mid_edge ) 00453 break; 00454 } 00455 00456 for( index1 = 0; index1 < 3; index1++ ){ 00457 if( ptr_facet1->edge(index1) == new_mid_edge ) 00458 break; 00459 } 00460 00461 if( index0 == 3 || index1 == 3 ){ 00462 PRINT_INFO("ERROR: new edge doesn't exist at the adjacent facets \n"); 00463 assert(0); 00464 } 00465 00466 if( ptr_facet0->edge_use(index0) == ptr_facet1->edge_use(index1) ){ 00467 PRINT_INFO("ERROR: The orientation of edges is adjacent facet is not proper \n"); 00468 assert(0); 00469 } 00470 00471 #endif 00472 00473 //PRINT_DEBUG_157("Passes\n"); 00474 00475 return CAST_TO( new_facet, CubitFacet ); 00476 } 00477 00478 // This only checks gfx facet edge valence right now (should be == 2) 00479 CubitBoolean TDOctreeRefFace::check_valid_facets(CubitBoolean disable_if_bad) 00480 { 00481 int i; 00482 CubitBoolean good_facets = CUBIT_TRUE; 00483 CubitFacetEdge *facet_edge; 00484 00485 for (i=0; i < ptrCubitFacetEdgeList->size(); ++i) 00486 { 00487 facet_edge = ptrCubitFacetEdgeList->get_and_step(); 00488 if (facet_edge->num_adj_facets() > 2) 00489 { 00490 good_facets = CUBIT_FALSE; 00491 break; 00492 } 00493 } 00494 00495 if (disable_if_bad && !good_facets) {set_create_2dmat(CUBIT_FALSE);} 00496 return good_facets; 00497 } 00498 00499 //EOF 00500