cgma
CubitOctreeNode.cpp
Go to the documentation of this file.
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 &para ){
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines