cgma
|
00001 #include <map> 00002 #include "CubitOctreeNode.hpp" 00003 #include "CubitOctreeCell.hpp" 00004 #include "CubitOctree.hpp" 00005 #include "RefFace.hpp" 00006 #include "CubitOctreeConstants.hpp" 00007 #include "CubitFacet.hpp" 00008 #include "CubitPoint.hpp" 00009 #include "GfxDebug.hpp" 00010 #include "PriorityQueue.hpp" 00011 #include "CubitOctreeGenerator.hpp" 00012 #include "GMem.hpp" 00013 #include "RTree.hpp" 00014 #include "RefEdge.hpp" 00015 #include "GeometryQueryTool.hpp" 00016 #include "DLIList.hpp" 00017 #include "RefFace.hpp" 00018 #include "GeomMeasureTool.hpp" 00019 #include "OctreeIntersectionData.hpp" 00020 00021 00022 //#include "SVDrawTool.hpp" 00023 00024 int CubitOctreeNode::mCounter = -1; 00025 00026 int sort_by_size( CubitOctreeNode * &node1, CubitOctreeNode *&node2 ) 00027 { 00028 if (node1->get_size(OCTREE_SIZE_DEFAULT) <= node2->get_size(OCTREE_SIZE_DEFAULT)) {return -1;} 00029 else {return 1;} 00030 } 00031 00032 00033 /* --------------- Methods of CubitOctreeNode ------------- */ 00034 CubitOctreeNode::CubitOctreeNode( const CubitVector &cen, CubitOctreeCell *parent_cell, const int x_index, const int y_index, const int z_index ) 00035 { 00036 initialize_constructor( cen.x(), cen.y(), cen.z() ); 00037 adjCell[x_index][y_index][z_index] = parent_cell; 00038 } 00039 00040 CubitOctreeNode::CubitOctreeNode( const double &x, const double &y, const double &z ) 00041 { 00042 initialize_constructor( x, y, z ); 00043 } 00044 00045 CubitOctreeNode::~CubitOctreeNode(void) 00046 { 00047 int i; 00048 OctreeIntersectionData *idata; 00049 00050 for (i=0; i < octreeIntersectionDataList.size(); ++i) 00051 { 00052 idata = octreeIntersectionDataList.get_and_step(); 00053 if (idata != NULL) 00054 { 00055 delete idata; 00056 } 00057 } 00058 00059 octreeIntersectionDataList.clean_out(); 00060 } 00061 00063 void CubitOctreeNode::initialize_constructor( const double &x, const double &y, const double &z ){ 00064 00065 00066 int i, j, k; 00067 color = CUBIT_GREY_INDEX; // boundary nodes are colored white and inside nodes black 00068 // during facet intersection the white nodes dominates black 00069 visit = CUBIT_FALSE; // mat generation 00070 mark = CUBIT_FALSE; 00071 00072 halfspaceDirection = OCTREE_NEGATIVE; 00073 num = get_counter(); 00074 00075 size = 0.0; 00076 00077 distance = CUBIT_DBL_MAX; 00078 00079 cellDepthDifference = 0; 00080 minDepthCell = NULL; 00081 00082 mNormal.x(0.0); 00083 mNormal.y(0.0); 00084 mNormal.z(0.0); 00085 00086 coord.x(x); 00087 coord.y(y); 00088 coord.z(z); 00089 00090 for( i = 0; i < 2; i++ ){ 00091 for( j = 0; j < 2; j++ ){ 00092 for( k = 0; k < 2; k++ ){ 00093 adjCell[i][j][k] = NULL; 00094 } 00095 } 00096 } 00097 00098 // LRBTFN 00099 for( i = 0; i < 6; i++ ){ 00100 adjGridNode[i] = NULL; 00101 adjNodeDistance[i] = -1; // ? 00102 } 00103 00104 refFace = NULL; 00105 } 00106 00107 int CubitOctreeNode::get_counter() 00108 { 00109 //static int counter = -1; 00110 mCounter++; 00111 return(mCounter); 00112 } 00113 00114 void CubitOctreeNode::display( OctreeNodeConstant type, float draw_size ) 00115 { 00116 switch( type ){ 00117 case NODE_SIZE: 00118 if (draw_size < 0) 00119 { 00120 draw_size = size; 00121 } 00122 //SkeletonDebug::draw_point( coord, draw_size ); 00123 break; 00124 00125 case NODE_DISTANCE: 00126 if( color == CUBIT_BLACK_INDEX ){ 00127 //SkeletonDebug::draw_point( coord, (float)draw_size ) ; 00128 } 00129 break; 00130 00131 case NODE_FACE_NUM: 00132 if( refFace != NULL ){ 00133 //SkeletonDebug::draw_point( coord, (float)(( refFace->id() % 18) * 0.5) ); 00134 } 00135 else{ 00136 PRINT_INFO("ERROR: Face Ptr Doesn't Exist in White Grid Node \n"); 00137 } 00138 break; 00139 00140 case NODE_NORMAL: 00141 if( color == CUBIT_BLACK_INDEX ){ 00142 //SkeletonDebug::draw_line(coord, draw_size, coord+mNormal,draw_size); 00143 00144 } 00145 break; 00146 00147 00148 00149 default: 00150 //SkeletonDebug::draw_point( coord, 1 ); 00151 break; 00152 } 00153 } 00154 00155 00156 00157 double CubitOctreeNode::get_size( OctreeSourceEntityType type ) const 00158 { 00159 return size; 00160 00161 } 00162 00163 void CubitOctreeNode::set_size( double s, int type ){ 00164 00165 size = s; 00166 } 00167 00168 00169 CubitOctreeNode* CubitOctreeNode::get_adj_node(int select) 00170 { 00171 switch (select) 00172 { 00173 case O_LEFT: 00174 return adjGridNode[O_LEFT]; 00175 00176 case O_RIGHT: 00177 return adjGridNode[O_RIGHT]; 00178 00179 case O_BOTTOM: 00180 return adjGridNode[O_BOTTOM]; 00181 00182 case O_TOP: 00183 return adjGridNode[O_TOP]; 00184 00185 case O_BACK: 00186 return adjGridNode[O_BACK]; 00187 00188 case O_FRONT: 00189 return adjGridNode[O_FRONT]; 00190 00191 default: 00192 PRINT_INFO("ERROR: AdjNode index exceeded\n"); 00193 return NULL; 00194 } 00195 } 00196 00197 void CubitOctreeNode::set_adj_node(enum OctreePosition select, CubitOctreeNode *ptr_node) 00198 { 00199 switch( select ) 00200 { 00201 case O_LEFT: 00202 adjGridNode[O_LEFT] = ptr_node; 00203 break; 00204 00205 case O_RIGHT: 00206 adjGridNode[O_RIGHT] = ptr_node; 00207 break; 00208 00209 case O_BOTTOM: 00210 adjGridNode[O_BOTTOM] = ptr_node; 00211 break; 00212 00213 case O_TOP: 00214 adjGridNode[O_TOP] = ptr_node; 00215 break; 00216 00217 case O_BACK: 00218 adjGridNode[O_BACK] = ptr_node; 00219 break; 00220 00221 case O_FRONT: 00222 adjGridNode[O_FRONT] = ptr_node; 00223 break; 00224 00225 default: 00226 PRINT_INFO("ERROR: AdjNode index exceeded"); 00227 00228 } 00229 00230 } 00231 00232 00233 void CubitOctreeNode::set_adj_node_distance( enum OctreePosition select, int dist ){ 00234 00235 switch( select ){ 00236 00237 case O_LEFT: 00238 adjNodeDistance[O_LEFT] = dist; 00239 break; 00240 00241 case O_RIGHT: 00242 adjNodeDistance[O_RIGHT] = dist; 00243 break; 00244 00245 case O_BOTTOM: 00246 adjNodeDistance[O_BOTTOM] = dist; 00247 break; 00248 00249 case O_TOP: 00250 adjNodeDistance[O_TOP] = dist; 00251 break; 00252 00253 case O_BACK: 00254 adjNodeDistance[O_BACK] = dist; 00255 break; 00256 00257 case O_FRONT: 00258 adjNodeDistance[O_FRONT] = dist; 00259 break; 00260 00261 default: 00262 PRINT_INFO(" ERROR: AdjNode index exceeded"); 00263 00264 } 00265 00266 } 00267 00268 00269 double CubitOctreeNode::manhattan_distance_adj_node( int index ){ 00270 00271 switch( index ){ 00272 00273 case O_FRONT: 00274 return fabs( coord.x() - adjGridNode[index]->coord.x() ); 00275 00276 case O_BACK: 00277 return fabs( coord.x() - adjGridNode[index]->coord.x() ); 00278 00279 case O_RIGHT: 00280 return fabs( coord.y() - adjGridNode[index]->coord.y() ); 00281 00282 case O_LEFT: 00283 return fabs( coord.y() - adjGridNode[index]->coord.y() ); 00284 00285 case O_TOP: 00286 return fabs( coord.z() - adjGridNode[index]->coord.z() ); 00287 00288 case O_BOTTOM: 00289 return fabs( coord.z() - adjGridNode[index]->coord.z() ); 00290 00291 default: 00292 PRINT_INFO("WARNING: Adjacent grid node index doesn't exist"); 00293 return 1.0; 00294 } 00295 00296 } 00297 00298 double CubitOctreeNode::manhattan_distance_adj_node( CubitOctreeNode *ptr_adj_node ){ 00299 return fabs( coord.x() - ptr_adj_node->coord.x() ) + fabs(coord.y() - ptr_adj_node->coord.y()) + fabs(coord.z() - ptr_adj_node->coord.z()); 00300 } 00301 00302 int CubitOctreeNode::get_adj_node_distance( enum OctreePosition select){ 00303 00304 switch( select ){ 00305 00306 case O_LEFT: 00307 return adjNodeDistance[O_LEFT]; 00308 00309 case O_RIGHT: 00310 return adjNodeDistance[O_RIGHT]; 00311 00312 case O_BOTTOM: 00313 return adjNodeDistance[O_BOTTOM]; 00314 00315 case O_TOP: 00316 return adjNodeDistance[O_TOP]; 00317 00318 case O_BACK: 00319 return adjNodeDistance[O_BACK]; 00320 00321 case O_FRONT: 00322 return adjNodeDistance[O_FRONT]; 00323 00324 default: 00325 PRINT_INFO("ERROR: AdjNode index exceeded"); 00326 return CUBIT_TRUE; 00327 00328 } 00329 00330 } 00331 00332 int CubitOctreeNode::find_min_depth_cell_and_depth_difference( void ){ 00333 00334 int i, j, k; 00335 int depth_min_depth_cell = CUBIT_INT_MAX; 00336 int depth_max_detph_cell = -CUBIT_INT_MAX; 00337 int depth; 00338 00339 for( i = 0; i < 2; i++ ){ 00340 for( j = 0; j < 2; j++ ){ 00341 for( k = 0; k < 2; k++ ){ 00342 if( adjCell[i][j][k] != NULL ){ 00343 depth = adjCell[i][j][k]->get_depth(); 00344 if( depth < depth_min_depth_cell ){ 00345 depth_min_depth_cell = depth; 00346 minDepthCell = adjCell[i][j][k]; 00347 } 00348 if( depth > depth_max_detph_cell ){ 00349 depth_max_detph_cell = depth; 00350 } 00351 } 00352 } 00353 } 00354 } 00355 00356 if( depth_min_depth_cell != CUBIT_INT_MAX && depth_max_detph_cell != -CUBIT_INT_MAX ){ 00357 cellDepthDifference = depth_max_detph_cell - depth_min_depth_cell; 00358 } 00359 else{ 00360 cellDepthDifference = 0; 00361 } 00362 00363 return cellDepthDifference; 00364 } 00365 00366 void CubitOctreeNode::calculate_size_based_on_cell_dimension( double bbox_dimension ) 00367 { 00368 int i; 00369 int counter = 0; 00370 double sum = 0.0; 00371 00372 for( i = 0; i < 6; i++ ){ 00373 00374 if( adjNodeDistance[i] >= 0 ){ 00375 sum += 1.0 / pow( 2.0, adjNodeDistance[i] ); 00376 counter++; 00377 } 00378 } 00379 00380 size = sum / counter * bbox_dimension; 00381 } 00382 00383 int CubitOctreeNode::find_half_space( CubitFacet *ptr_facet ) 00384 { 00385 if( (coord - ptr_facet->point(0)->coordinates()) % (ptr_facet->normal()) >= 0 ) 00386 { 00387 halfspaceDirection = OCTREE_POSITIVE; 00388 } 00389 00390 return halfspaceDirection; 00391 } 00392 00393 00394 00395 void CubitOctreeNode::calc_facet_patch_distance_normal(DLIList<OctreeIntersectionData*> &idatas, int num_use_idatas, double &patch_distance, CubitVector &patch_normal, CubitBoolean sort, CubitBoolean set_Refface) 00396 { 00397 int i, j; 00398 CubitBoolean duplicate = CUBIT_FALSE; 00399 for (i=0; i < idatas.size(); ++i) 00400 { 00401 idatas.reset(); 00402 idatas.step(i); 00403 OctreeIntersectionData *first = idatas.get(); 00404 00405 00406 for (j=i+1; j < idatas.size(); ++j) 00407 { 00408 idatas.reset(); 00409 idatas.step(j); 00410 if (idatas.get() == first) {duplicate = CUBIT_TRUE;} 00411 break; 00412 } 00413 if (duplicate == CUBIT_TRUE) {break;} 00414 00415 } 00416 if (duplicate) {PRINT_INFO("Duplicate idatas found for node %d\n", this->get_num());} 00417 00418 if (sort) {idatas.sort(OctreeIntersectionData::compare_function);} 00419 00420 idatas.reset(); 00421 if (sort) 00422 { 00423 patch_distance = /*(coord - idatas.get()->get_int_point())%idatas.get()->get_facet_normal();*/ idatas.get()->get_length(); 00424 // CubitFacet *ptr_facet = idatas.get()->get_facet_ptr(); 00425 // CubitVector closest_point_on_facet = idatas.get()->get_int_point(), facet_normal = idatas.get()->get_facet_normal(); 00426 00427 /* if (fabs((coord - closest_point_on_facet)%facet_normal) != (coord-closest_point_on_facet).length()) 00428 { 00429 SVDrawTool::clear_non_retained(); 00430 SVDrawTool::draw_vector(coord, closest_point_on_facet, CUBIT_YELLOW_INDEX); 00431 PRINT_INFO("closest length is %lf\n", idatas.get()->get_length()); 00432 DLIList<CubitFacet*> temp_facets; 00433 temp_facets.append(ptr_facet); 00434 00435 SVDrawTool::draw_facets(temp_facets, CUBIT_YELLOW_INDEX); 00436 temp_facets.clean_out(); 00437 for (i=0; i < idatas.size(); ++i) 00438 { 00439 CubitFacet *facet = idatas.get()->get_facet_ptr(); 00440 if (facet != ptr_facet) 00441 { 00442 SVDrawTool::draw_vector(coord, idatas.get()->get_int_point(), CUBIT_RED_INDEX); 00443 PRINT_INFO("Other length is %lf\n", idatas.get()->get_length()); 00444 } 00445 00446 idatas.step(); 00447 temp_facets.append(facet); 00448 } 00449 temp_facets.remove(ptr_facet); 00450 SVDrawTool::draw_facets(temp_facets, CUBIT_RED_INDEX); 00451 int j,k; 00452 00453 for (i=0; i < 2; ++i) 00454 { 00455 for (j=0; j < 2; ++j) 00456 { 00457 00458 for (k=0; k < 2; ++k) 00459 { 00460 00461 CubitOctreeCell *CubitOctree_cell = adjCell[i][j][k]; 00462 if (CubitOctree_cell == NULL) {continue;} 00463 double corners[3]; 00464 double half_edge_length = CubitOctree_cell->get_dimension()/2.0; 00465 CubitVector center = CubitOctree_cell->get_center(); 00466 center.get_xyz(corners); 00467 float box[6] = {corners[0]-half_edge_length, corners[1]-half_edge_length, corners[2]-half_edge_length, 00468 corners[0]+half_edge_length, corners[1]+half_edge_length, corners[2]+half_edge_length}; 00469 SVDrawTool::draw_cube(box, CUBIT_GREEN_INDEX, SVDrawTool::WIRE); 00470 } 00471 } 00472 } 00473 00474 SVDrawTool::mouse_xforms(); 00475 00476 }*/ 00477 } 00478 else {patch_distance = -1;} 00479 00480 if (set_Refface) {refFace = idatas.get()->get_face();} 00481 00482 if (num_use_idatas == -1) {num_use_idatas = idatas.size();} 00483 00484 patch_normal = CubitVector(0,0,0); 00485 00486 /*for (i=0; i < num_use_idatas; ++i) 00487 { 00488 double len = idatas.get()->get_length(); 00489 if (len < OCTREE_EPSILON) {len = OCTREE_EPSILON;} 00490 normal += idatas.get()->get_facet_normal() * 1/(len); 00491 idatas.step(); 00492 } 00493 normal.normalize(); */ 00494 00495 OctreeIntersectionData *ptr_data; 00496 //double denominator = 0.0; 00497 double length; 00498 00499 //distance = 0.0; 00500 for( i=0; i < num_use_idatas; i++ ) 00501 { 00502 ptr_data = idatas.get_and_step(); // VED: important 00503 00504 length = ptr_data->get_length(); 00505 if( length < OCTREE_EPSILON ){ 00506 patch_normal += ptr_data->get_normal() * (1/(OCTREE_EPSILON*OCTREE_EPSILON)); 00507 //distance += ( ptr_data->get_normal()%( coord - ptr_data->get_int_point() ) ) * (1/OCTREE_EPSILON)/denominator; 00508 } 00509 else{ 00510 patch_normal += ptr_data->get_normal() * (1/(length*length)); 00511 //distance += ( ptr_data->get_normal()%( coord - ptr_data->get_int_point() ) ) * (1/length)/denominator; 00512 } 00513 } 00514 patch_normal.normalize(); 00515 } 00516 00517 00518 void CubitOctreeNode::SAT_find_face_distance_average_normal () 00519 { 00520 // three cases: 00521 // 1) One facet (one RefFace) => use facet's normal and distance to facet, RefFace is set to facet's owning face 00522 // 2) Multiple facets, one refFace => use distance to closest facet and its owning RefFace, IDW normal from N closest facets 00523 // 3) Multiple facets, multiple RefFaces => use distance to closest facet and its owning RefFace, IDW normal from N closest facets 00524 00525 //int i, j, k; 00526 00527 // case: no intersection datas, this should not happen. I should prolly put an cassertere. 00528 if (octreeIntersectionDataList.size() == 0) 00529 { 00530 PRINT_ERROR("No OctreeIntersectionDatas attached to black grid node in queue for MAT generation!\n"); 00531 return; 00532 } 00533 00534 // case: one facet, just get distance, normal, and face from facet 00535 if (octreeIntersectionDataList.size() == 1) 00536 { 00537 distance = octreeIntersectionDataList.get()->get_length(); 00538 mNormal = octreeIntersectionDataList.get()->get_facet_normal(); 00539 refFace = octreeIntersectionDataList.get()->get_face(); 00540 00541 00542 // remember to delete the idata - check if this is ok 00543 delete octreeIntersectionDataList.get(); 00544 octreeIntersectionDataList.clean_out(); 00545 return; 00546 } 00547 00548 00549 00550 // case: multiple facets, one face 00551 // just initialize normal, distance, and Refface 00552 00553 // case: two faces 00554 // determine if disconnected and if normals diverge => EWC case 1 00555 // else check angle 00556 00557 00558 00559 // now find N closest facets (keep list of idatas though) 00560 // choose closest one, use distance to it and use its RefFace 00561 // then use all and IDW to get normal 00562 00563 int num_facets_to_use; 00564 if (N_CLOSEST_FACETS_FACTOR_FOR_FRONT_NORMALS == 0.00) {num_facets_to_use = 1;} 00565 else if (N_CLOSEST_FACETS_FACTOR_FOR_FRONT_NORMALS == 1.00) {num_facets_to_use = octreeIntersectionDataList.size();} 00566 else {num_facets_to_use = (int)(N_CLOSEST_FACETS_FACTOR_FOR_FRONT_NORMALS * octreeIntersectionDataList.size());} 00567 if (num_facets_to_use == 0) {num_facets_to_use = 1;} 00568 else if (num_facets_to_use > octreeIntersectionDataList.size()) {num_facets_to_use = octreeIntersectionDataList.size();} 00569 00570 /*DLIList<OctreeIntersectionData*> n_closest_idatas; 00571 00572 RTree<OctreeIntersectionData*> *rtree = new RTree<OctreeIntersectionData*>; 00573 double closest = CUBIT_DBL_MAX; 00574 for (i=0; i < octreeIntersectionDataList.size(); ++i) 00575 { 00576 rtree->add(octreeIntersectionDataList.get_and_step()); 00577 } 00578 rtree->k_nearest_neighbor(coord, num_facets_to_use, closest, n_closest_idatas, OctreeIntersectionData::dist_sqr_to_vec); 00579 delete rtree; 00580 00581 normal = CubitVector(0,0,0); 00582 // calc_facet_patch_distance_normal(octreeIntersectionDataList, num_facets_to_use, distance, normal, CUBIT_TRUE, CUBIT_TRUE); 00583 00584 00585 refFace = n_closest_idatas.get()->get_face(); 00586 00587 00588 distance = n_closest_idatas.get()->get_length(); 00589 00590 for (i=0; i < num_facets_to_use; ++i) 00591 { 00592 double len = n_closest_idatas.get()->get_length(); 00593 normal += n_closest_idatas.get_and_step()->get_facet_normal() * 1/(len); 00594 } 00595 00596 normal.normalize();*/ 00597 00598 00599 mNormal = CubitVector(0,0,0); 00600 calc_facet_patch_distance_normal(octreeIntersectionDataList, num_facets_to_use, distance, mNormal, CUBIT_TRUE, CUBIT_TRUE); 00601 00602 /* 00603 octreeIntersectionDataList.sort(OctreeIntersectionData::compare_function); 00604 octreeIntersectionDataList.reset(); 00605 00606 00607 00608 00609 refFace = octreeIntersectionDataList.get()->get_face(); 00610 00611 00612 distance = octreeIntersectionDataList.get()->get_length(); 00613 00614 for (i=0; i < num_facets_to_use; ++i) 00615 { 00616 double len = octreeIntersectionDataList.get()->get_length(); 00617 normal += octreeIntersectionDataList.get_and_step()->get_facet_normal() * 1/(len); 00618 } 00619 00620 normal.normalize(); 00621 */ 00622 // now normal, distance to boundary, and Refface have been set 00623 00624 } 00625 00626 00627 // checks intesection between the lines joining grid node and adjacent nodes with the facet. 00628 00629 void CubitOctreeNode::find_intersection_with_facet( CubitOctreeType type, RefFace *ptr_face, CubitFacet *ptr_facet, DLIList<CubitOctreeNode*> &boundary_white_node_list ) 00630 { 00631 00632 int i; 00633 CubitBoolean result; 00634 CubitVector int_point; 00635 CubitVector facet_normal; 00636 double para; 00637 00638 facet_normal = ptr_facet->normal(); 00639 00640 for( i = 0; i < 6; i++ ){ 00641 00642 result = CUBIT_FALSE; 00643 00644 if( adjGridNode[i] != NULL ){ 00645 if( adjGridNode[i]->halfspaceDirection == OCTREE_NEGATIVE && adjGridNode[i]->mark == CUBIT_TRUE ){ 00646 //- adj_node[0] = O_FRONT Node 00647 //- adj_node[1] = O_BACK Node 00648 //- adj_node[2] = O_RIGHT Node 00649 //- adj_node[3] = O_LEFT Node 00650 //- adj_node[4] = O_TOP Node 00651 //- adj_node[5] = O_BOTTOM Node 00652 00653 switch( i ){ 00654 00655 case O_FRONT: 00656 result = find_intersection_point( OCTREE_X, coord, adjGridNode[i]->coord, facet_normal, ptr_facet->point(0)->coordinates(), ptr_facet->point(1)->coordinates(), ptr_facet->point(2)->coordinates(), int_point, para ); 00657 break; 00658 00659 case O_BACK: 00660 result = find_intersection_point( OCTREE_X, coord, adjGridNode[i]->coord, facet_normal, ptr_facet->point(0)->coordinates(), ptr_facet->point(1)->coordinates(), ptr_facet->point(2)->coordinates(), int_point, para ); 00661 break; 00662 00663 00664 case O_RIGHT: 00665 result = find_intersection_point( OCTREE_Y, coord, adjGridNode[i]->coord, facet_normal, ptr_facet->point(0)->coordinates(), ptr_facet->point(1)->coordinates(), ptr_facet->point(2)->coordinates(), int_point, para ); 00666 break; 00667 00668 00669 case O_LEFT: 00670 result = find_intersection_point( OCTREE_Y, coord, adjGridNode[i]->coord, facet_normal, ptr_facet->point(0)->coordinates(), ptr_facet->point(1)->coordinates(), ptr_facet->point(2)->coordinates(), int_point, para ); 00671 break; 00672 00673 00674 case O_TOP: 00675 result = find_intersection_point( OCTREE_Z, coord, adjGridNode[i]->coord, facet_normal, ptr_facet->point(0)->coordinates(), ptr_facet->point(1)->coordinates(), ptr_facet->point(2)->coordinates(), int_point, para ); 00676 break; 00677 00678 00679 case O_BOTTOM: 00680 result = find_intersection_point( OCTREE_Z, coord, adjGridNode[i]->coord, facet_normal, ptr_facet->point(0)->coordinates(), ptr_facet->point(1)->coordinates(), ptr_facet->point(2)->coordinates(), int_point, para ); 00681 break; 00682 00683 default: 00684 break; 00685 00686 } 00687 } 00688 } 00689 00690 00691 if( result == CUBIT_TRUE ){ 00692 OctreeIntersectionData * ptr_data; 00693 00694 switch( type ){ 00695 case CUBIT_OCTREE_VOLUME: 00696 // update color of boundary node 00697 if( color != CUBIT_WHITE_INDEX ){ 00698 if( color == CUBIT_BLACK_INDEX ){ 00699 // Mark the common cells incident on both end points of the edge as GREY 00700 // To resolve the intersection problems I added the SAT intersection code -ved 00701 } 00702 00703 boundary_white_node_list.push( this ); 00704 refFace = ptr_face; 00705 //PRINT_DEBUG_157(" Testing: Face Num = %d\n", RefFace->id() ); 00706 color = CUBIT_WHITE_INDEX; 00707 distance = -1; 00708 } 00709 // WARNING: devided by zero. 00710 ptr_data = new OctreeIntersectionData( this, facet_normal * -1, int_point, (adjGridNode[i]->coord - int_point).length(), ptr_face ); 00711 adjGridNode[i]->append_list_item( ptr_data ); 00712 break; 00713 00714 case CUBIT_OCTREE_FACE: 00715 refFace = ptr_face; 00716 color = CUBIT_BLACK_INDEX; 00717 distance = -1; 00718 adjGridNode[i]->color = CUBIT_BLACK_INDEX; 00719 break; 00720 00721 default: 00722 PRINT_INFO("This case not yet implemented \n"); 00723 break; 00724 } 00725 } 00726 } 00727 } 00728 00729 00730 00731 00732 00733 // returns true if the intersection between the line segment and facet takes place 00734 // para stores the parameter of intersection point int_point 00735 CubitBoolean CubitOctreeNode::find_intersection_point( int axis, CubitVector grid_node0, CubitVector grid_node1, CubitVector &facet_normal, CubitVector facet_vert0, CubitVector facet_vert1, CubitVector facet_vert2, CubitVector &int_point, double ¶ ){ 00736 00737 double A, B, C, D; 00738 double nominator, denominator; 00739 00740 D = - ( facet_normal%(facet_vert1 - grid_node0) ); 00741 A = facet_normal.x(); 00742 B = facet_normal.y(); 00743 C = facet_normal.z(); 00744 00745 switch( axis ){ 00746 00747 case OCTREE_X: 00748 if( fabs(A) < OCTREE_EPSILON ){ 00749 //line parallel to facet 00750 // both end points are intersection points 00751 00752 return CUBIT_FALSE; 00753 } 00754 else{ 00755 nominator = D; 00756 denominator = A * ( grid_node0.x() - grid_node1.x() ); 00757 para = nominator / denominator; 00758 } 00759 break; 00760 00761 00762 case OCTREE_Y: 00763 if( fabs(B) < OCTREE_EPSILON ){ 00764 //line parallel to facet 00765 // both end points are intersection points 00766 00767 return CUBIT_FALSE; 00768 } 00769 else{ 00770 nominator = D; 00771 denominator = B * ( grid_node0.y() - grid_node1.y() ); 00772 para = nominator / denominator; 00773 } 00774 break; 00775 00776 00777 case OCTREE_Z: 00778 if( fabs(C) < OCTREE_EPSILON ){ 00779 //line parallel to facet 00780 // both end points are intersection points 00781 00782 return CUBIT_FALSE; 00783 } 00784 else{ 00785 nominator = D; 00786 denominator = C * ( grid_node0.z() - grid_node1.z() ); 00787 para = nominator / denominator; 00788 } 00789 break; 00790 00791 default: 00792 break; 00793 } 00794 00795 int_point = grid_node0 + para * ( grid_node1 - grid_node0 ); 00796 return( is_intersection_point_contained_inside_facet( int_point, facet_vert0, facet_vert1, facet_vert2 ) ); 00797 00798 00799 } 00800 00801 00802 CubitBoolean CubitOctreeNode::is_same_side(const CubitVector &p1, const CubitVector &p2, const CubitVector &a, const CubitVector &b) 00803 { 00804 static CubitVector edge; 00805 edge = b-a; 00806 //cp1 = edge*(p1-a); 00807 //cp2 = edge*(p2-a); 00808 if ( (edge*(p1-a)) % (edge*(p2-a)) >= 0) {return CUBIT_TRUE;} 00809 return CUBIT_FALSE; 00810 } 00811 00812 00813 // returns true if intersection point is contained inside the facet 00814 // interior angle at the intersecton point should add up to 360 deg. 00815 CubitBoolean CubitOctreeNode::is_intersection_point_contained_inside_facet( const CubitVector &int_point, const CubitVector &facet_vert0, const CubitVector &facet_vert1, const CubitVector &facet_vert2 ){ 00816 if ( fabs((int_point-facet_vert0)%( (facet_vert1-facet_vert0) * (facet_vert2-facet_vert0) )) > OCTREE_EPSILON) 00817 { 00818 return CUBIT_FALSE; 00819 } 00820 00821 if (is_same_side(int_point,facet_vert0, facet_vert1,facet_vert2) && is_same_side(int_point,facet_vert1, facet_vert0,facet_vert2) && is_same_side(int_point,facet_vert2, facet_vert0,facet_vert1)) {return CUBIT_TRUE;} 00822 return CUBIT_FALSE; 00823 00824 /*CubitVector line0, line1, line2; 00825 double ang0, ang1, ang2; 00826 00827 line0 = facet_vert0 - int_point ; 00828 line0 = line0 / line0.length(); 00829 00830 00831 line1 = facet_vert1 - int_point ; 00832 line1 = line1 / line1.length(); 00833 00834 line2 = facet_vert2 - int_point ; 00835 line2 = line2 / line2.length(); 00836 //Added (M. Brewer) to check for an invalid number passed to acos 00837 //compute ang0 00838 double temp_double = line0 % line1; 00839 if(temp_double>1.0) 00840 temp_double=1.0; 00841 else if (temp_double<-1.0) 00842 temp_double=-1.0; 00843 ang0 = acos( temp_double ); 00844 //compute ang1 00845 temp_double = line1 % line2; 00846 if(temp_double>1.0) 00847 temp_double=1.0; 00848 else if (temp_double<-1.0) 00849 temp_double=-1.0; 00850 ang1 = acos( temp_double ); 00851 //compute ang2 00852 temp_double = line2 % line0; 00853 if(temp_double>1.0) 00854 temp_double=1.0; 00855 else if (temp_double<-1.0) 00856 temp_double=-1.0; 00857 ang2 = acos( temp_double ); 00858 00859 if( fabs ( ( ang0 + ang1 + ang2 ) - CUBIT_PI * 2 ) < OCTREE_EPSILON ){ 00860 return CUBIT_TRUE; 00861 } 00862 else{ 00863 return CUBIT_FALSE; 00864 }*/ 00865 } 00866 00867 00868 00869 00870 00871 CubitBoolean CubitOctreeNode::find_size_using_adj_node() 00872 { 00873 int i; 00874 double sum = 0.0; 00875 int count = 0; 00876 for( i = 0; i < 6; i ++ ){ 00877 if( adjGridNode[i] != NULL ){ 00878 // WARNING: Why we need to check for -1 00879 //if( adjGridNode[i]->size != -1 && adjGridNode[i]->size != CUBIT_DBL_MAX && adjGridNode[i]->size != 0){ 00880 //if( adjGridNode[i]->size != CUBIT_DBL_MAX && adjGridNode[i]->size != 0.0 ){ 00881 if( adjGridNode[i]->size != 0.0 ){ 00882 sum += adjGridNode[i]->size; 00883 count++; 00884 } 00885 } 00886 } 00887 00888 if( sum != 0.0 ){ 00889 size = sum / count; 00890 return CUBIT_TRUE; 00891 } 00892 else 00893 return CUBIT_FALSE; 00894 } 00895 00896 00897 00898 CubitBoolean CubitOctreeNode::compare_function( CubitOctreeNode *&a, CubitOctreeNode *&b ){ 00899 00900 if( a->get_distance() < b->get_distance() ) 00901 return CUBIT_TRUE; 00902 else 00903 return CUBIT_FALSE; 00904 00905 } 00906 00907 void CubitOctreeNode::find_distance_at_adj_node(PriorityQueue<CubitOctreeNode *> *heap ) 00908 { 00909 int i; 00910 CubitVector mat_pnt_center; 00911 double new_node_distance; 00912 00913 // PRINT_INFO("Testing: Face id = %d\n", mrefFace->id()); 00914 visit = CUBIT_TRUE; 00915 00916 for( i = 0; i < 6; i++ ){ 00917 00918 // at the boundary of solid 00919 if( adjGridNode[i] == NULL ) 00920 continue; 00921 00922 00923 // *************** WARNING ********* 00924 00925 00926 // if the adjGridNode is on boundary or outside don't do anything 00927 // Just testing white node is enough because we assume the facet and the grid 00928 // intersection done during octree generation is correct 00929 // At this point only at the boundary there is white and black nodes because of facet/octree intersection 00930 // and both at interior and outside we grey node 00931 //if( adjGridNode[i]->get_color() == CUBIT_WHITE_INDEX || adjGridNode[i]->get_color() == CUBIT_GREY_INDEX ) 00932 if( adjGridNode[i]->get_color() == CUBIT_WHITE_INDEX || adjGridNode[i]->get_color() == CUBIT_YELLOW_INDEX) 00933 continue; 00934 00935 // meeting of the front should be the major 00936 // criteria not the size value. check for null of 00937 // grid_node->face. then check for adjacency, black_white, and size... 00938 new_node_distance = distance + ( adjGridNode[i]->coord - coord )%mNormal; 00939 00940 // WARNING: The below condition is very important. 00941 // Therefore I think the normal calculation is wrong 00942 // Front should always go forward. 00943 00944 if(new_node_distance <= distance) 00945 { 00946 00947 // OPEN IT 00948 // this happens at the concave region containing many surfaces. 00949 //PRINT_DEBUG_157(" Distance Calculation is wrong (discresing)\n"); 00950 00951 00952 if (adjGridNode[i]->refFace != NULL) 00953 { 00954 //if (adjGridNode[i]->mrefFace != mrefFace) 00955 // { 00956 continue; 00957 //} 00958 } 00959 00960 00961 //if (adjGridNode[i]->mrefFace != mrefFace) 00962 //{ 00963 adjGridNode[i]->color = CUBIT_BLACK_INDEX; 00964 //new_node_distance = distance; 00965 continue; 00966 //} 00967 00968 00969 //SVDrawTool::draw_vector(adjGridNode[i]->coord, closest, CUBIT_RED_INDEX); 00970 00971 00972 } 00973 //if( adjGridNode[i]->mrefFace != mrefFace ) 00974 //{ 00975 adjGridNode[i]->color = CUBIT_BLACK_INDEX; 00976 //} 00977 00978 if( adjGridNode[i]->refFace == NULL ){ 00979 // internal black nodes 00980 // not near skeleton 00981 adjGridNode[i]->distance = new_node_distance; 00982 adjGridNode[i]->refFace = refFace; 00983 adjGridNode[i]->mNormal = mNormal; 00984 heap->push( adjGridNode[i] ); 00985 } 00986 else{ 00987 00988 00989 } 00990 } 00991 00992 } 00993 00994 00995 00996 00997 00998 //EOF