MeshKit  1.0
EBMesher.cpp
Go to the documentation of this file.
00001 #include "meshkit/EBMesher.hpp"
00002 #include "meshkit/SCDMesh.hpp"
00003 #include "meshkit/MKCore.hpp"
00004 #include "meshkit/ModelEnt.hpp"
00005 #include "meshkit/SizingFunction.hpp"
00006 #include "moab/ReadUtilIface.hpp"
00007 #include "meshkit/iGeom.hpp"
00008 #include "meshkit/RegisterMeshOp.hpp"
00009 
00010 #ifdef HAVE_MOAB
00011 #include "moab/Core.hpp"
00012 #include "MBRange.hpp"
00013 #include "MBCartVect.hpp"
00014 #include "moab/EntityType.hpp"
00015 #include "moab/HomXform.hpp"
00016 #include "moab/GeomTopoTool.hpp"
00017 #endif
00018 
00019 #ifdef HAVE_CGM
00020 #include "CubitDefines.h"
00021 #include "GeometryQueryTool.hpp"
00022 #include "RefFace.hpp"
00023 #endif
00024 
00025 #define PI 3.14159265
00026 #define ERRORRF(a) {if (iBase_SUCCESS != err) {std::cerr << a << std::endl; return false;}}
00027 
00028 double rayDir[3][3] = {{1., 0., 0.}, {0., 1., 0.}, {0., 0., 1.}};
00029 
00030 const bool debug_ebmesh = false;
00031 inline bool less_intersect(const IntersectDist d1, const IntersectDist d2) {
00032   return d1.distance < d2.distance;
00033 }
00034 
00035 inline bool equal_intersect(const IntersectDist d1, const IntersectDist d2) {
00036   return abs(d1.distance - d2.distance) < 10e-7;
00037 }
00038 
00039 namespace MeshKit 
00040 {
00041 // static registration of this  mesh scheme
00042 moab::EntityType EBMesher_tps[] = {moab::MBVERTEX, moab::MBHEX, moab::MBMAXTYPE};
00043 const moab::EntityType* EBMesher::output_types()
00044   { return EBMesher_tps; }
00045 
00046 EBMesher::EBMesher(MKCore *mkcore, const MEntVector &me_vec,
00047                    double size, bool use_geom, int add_layer)
00048   : MeshScheme(mkcore, me_vec), m_nAddLayer(add_layer),  m_dInputSize(size), m_bUseGeom(use_geom)
00049 {
00050   m_mesh = mkcore->imesh_instance()->instance();
00051   m_hRootSet = mkcore->imesh_instance()->getRootSet();
00052   m_nStatus = OUTSIDE;
00053   m_iStartHex = 0;
00054   m_hObbTree = NULL;
00055   m_hTreeRoot = 0;
00056 
00057 #ifdef HAVE_MOAB
00058   // create tags with MOAB for dense tags
00059   int outside = 1;
00060   const void *out = &outside;
00061   m_elemStatusTag = get_tag("ELEM_STATUS_TAG", 1,
00062                             MB_TAG_DENSE, MB_TYPE_INTEGER, out);
00063   
00064   int length = 1;
00065   const void *leng = &length;
00066   m_edgeCutFracLengthTag = get_tag("EDGE_CUT_FRAC_LENGTH_TAG", // # of fractions
00067                                    3,
00068                                    //MB_TAG_SPARSE, // using dense for hdf5 exporting performance
00069                                    MB_TAG_DENSE,
00070                                    MB_TYPE_INTEGER, leng);
00071 
00072   m_edgeCutFracTag = get_various_length_tag("EDGE_CUT_FRAC_TAG",
00073                                             //MB_TAG_SPARSE,
00074                                             MB_TAG_DENSE,
00075                                             MB_TYPE_DOUBLE);
00076 
00077   int m_id = 1;
00078   const void *id = &m_id;
00079   m_volFracLengthTag = get_tag("VOL_FRAC_LENGTH_TAG", 1,
00080                                MB_TAG_SPARSE, MB_TYPE_INTEGER, id);
00081   
00082   m_volFracHandleTag = get_various_length_tag("VOL_FRAC_HANDLE_TAG",
00083                                           MB_TAG_SPARSE, MB_TYPE_INTEGER);
00084 
00085   m_volFracTag = get_various_length_tag("VOL_FRAC_TAG",
00086                                         MB_TAG_SPARSE, MB_TYPE_DOUBLE);
00087   
00088   // set bounding box size tag
00089   double bb_default[6] = { 0., 0., 0., 0., 0., 0. };
00090   m_bbTag = get_tag("BOUNDING_BOX_SIZE", 6,
00091                     MB_TAG_SPARSE, MB_TYPE_DOUBLE, bb_default);
00092   
00093   m_GeomTopoTool = new moab::GeomTopoTool( moab_instance() );
00094 #endif
00095 }
00096 
00097 EBMesher::~EBMesher()
00098 {
00099   delete m_GeomTopoTool;
00100 }
00101 
00102 bool EBMesher::can_mesh(ModelEnt *me) 
00103 {
00104   if (me->dimension() == 3) return true;
00105   else return false;
00106 }
00107     
00108 bool EBMesher::add_modelent(ModelEnt *model_ent) 
00109 {
00110     // make sure this represents geometric volumes
00111   if (3 != model_ent->dimension()) 
00112     throw Error(MK_WRONG_DIMENSION, "Wrong dimension entity added to EBMesher.");
00113 
00114   return MeshOp::add_modelent(model_ent);
00115 }
00116 
00117 MeshOp *EBMesher::get_scd_mesher()
00118 {
00119   MeshOpProxy* proxy = NULL;
00120   proxy = MKCore::meshop_proxy("SCDMesh");
00121   if (proxy == NULL) throw Error(MK_FAILURE, "Couldn't find a MeshOp capable of producing the given mesh type.");
00122   return mk_core()->construct_meshop(proxy);
00123 }
00124 
00125 void EBMesher::setup_this()
00126 {
00127   MeshOp *scd_mesher = NULL;
00128   std::vector<MeshOp*> meshops;
00129   bool inserted = false;
00130 
00131   for (MEntSelection::iterator sit = mentSelection.begin(); sit != mentSelection.end(); sit++) {
00132     ModelEnt *me = (*sit).first;
00133     bool found = false;
00134     if (!scd_mesher) scd_mesher = get_scd_mesher();
00135     meshops.clear();
00136     me->get_meshops(meshops);
00137     int n_meshops = meshops.size();
00138 
00139     if (n_meshops > 0) {
00140       for (int i = 0; i < n_meshops; i++) {
00141         if (meshops[i] == scd_mesher) {
00142           found = true;
00143           break;
00144         }
00145       }
00146     }
00147 
00148     if (!found) { // if no scd meshop
00149       // add this entity to it, and if first, make sure it's added upstream
00150       scd_mesher->add_modelent(me);
00151       if (!inserted) {
00152         mk_core()->insert_node(scd_mesher, this);
00153         inserted = true;
00154       }
00155     }
00156 
00157     // no need to traverse all geometry for using whole geometry
00158     if (m_bUseWholeGeom) break;
00159   }
00160 
00161   SCDMesh *sm = (SCDMesh*) scd_mesher;
00162   sm->set_interface_scheme(SCDMesh::full);
00163   sm->set_grid_scheme(SCDMesh::cfMesh);
00164   
00165   sm->set_axis_scheme(SCDMesh::cartesian);
00166   sm->set_box_increase_ratio(m_boxIncrease); // add some extra layer to box
00167 
00168   if (m_bUseWholeGeom) sm->set_geometry_scheme(SCDMesh::all);
00169   else sm->set_geometry_scheme(SCDMesh::individual);
00170 
00171   // use mesh based geometry in SCDMesh and make tree to get box dimension
00172   if (m_bUseMeshGeom) {
00173     sm->use_mesh_geometry(true);
00174     sm->set_cart_box_min_max(m_minCoord, m_maxCoord, m_boxIncrease);
00175   }
00176 
00177   // set # of intervals for 3 directions
00178   std::vector<int> fine_i (m_nDiv[0], 1);
00179   sm->set_coarse_i_grid(m_nDiv[0]);
00180   sm->set_fine_i_grid(fine_i);
00181   std::vector<int> fine_j (m_nDiv[1], 1);
00182   sm->set_coarse_j_grid(m_nDiv[1]);
00183   sm->set_fine_j_grid(fine_j);
00184   std::vector<int> fine_k (m_nDiv[2], 1);
00185   sm->set_coarse_k_grid(m_nDiv[2]);
00186   sm->set_fine_k_grid(fine_k);
00187 }
00188 
00189 void EBMesher::execute_this() 
00190 {
00191   iBase_ErrorType  err;
00192   GraphNode *scd_node = other_node(in_arcs());
00193 
00194 #ifdef HAVE_MOAB
00195   double obb_time = .0;
00196   double intersection_time = .0;
00197   double set_info_time = .0;
00198   time_t time1, time2, time3, time4;
00199   unsigned long mem1, mem2, mem3, mem4;
00200   moab_instance()->estimated_memory_use(0, 0, 0, &mem1);
00201   moab::ErrorCode rval;
00202 
00203   if (debug_ebmesh) {
00204     rval = mk_core()->moab_instance()->write_mesh("input.vtk");
00205     MBERRCHK(rval, mk_core()->moab_instance());
00206   }
00207 
00208   time(&time1);
00209   if (m_bUseGeom && !m_bUseMeshGeom) { // construct obb tree for geometry surfaces and volumes by GeomTopoTool
00210     rval = m_GeomTopoTool->construct_obb_trees(m_bUseWholeGeom);
00211     MBERRCHK(rval, mk_core()->moab_instance());
00212   }
00213   time(&time2);
00214   obb_time += difftime(time2, time1);
00215 
00216   for (MEntSelection::iterator sit = mentSelection.begin(); sit != mentSelection.end(); sit++) {
00217     // 1. set division
00218     double box_min_max[6];
00219     if (m_bUseWholeGeom) {
00220       static_cast<SCDMesh*> (scd_node)->get_box_dimension(box_min_max, &box_min_max[3]);
00221     }
00222     else {
00223       err = mk_core()->imesh_instance()->getData(reinterpret_cast< iBase_EntityHandle >
00224                                                  (sit ->first->mesh_handle()), m_bbTag, &box_min_max[0]);
00225       IBERRCHK(err, "Failed to get hexes.\n");
00226     }
00227     set_division(box_min_max, &box_min_max[3]);
00228 
00229     // 2. set or construct obb tree
00230     time(&time1);
00231     set_tree_root(sit->first);
00232     time(&time2);
00233     obb_time += difftime(time2, time1);
00234 
00235     // 3. find intersected geometry surfaces by rays
00236     find_intersections();
00237     time(&time3);
00238     intersection_time += difftime(time3, time2);
00239     moab_instance()->estimated_memory_use(0, 0, 0, &mem3);
00240     
00241     // 4. set hex status and boundary hex cut fraction info
00242     set_tag_info();
00243     time(&time4);
00244     set_info_time += difftime(time4, time3);
00245     moab_instance()->estimated_memory_use(0, 0, 0, &mem4);
00246 
00247     if (m_bUseWholeGeom) break;
00248   }
00249 #endif
00250   
00251   if (debug_ebmesh) {
00252     std::cout << "OBB_tree_construct_time: " << obb_time
00253               << ", intersection_time: " << intersection_time
00254               << ", set_info_time: " << set_info_time << std::endl;
00255     std::cout << "start_memory: " << mem1
00256               << ", OBB_tree_construct_moemory: " << mem2
00257               << ", intersection_memory: " << mem3
00258               << ", set_info_memory: " << mem4
00259               << std::endl;
00260   }
00261 }
00262 
00263 void EBMesher::set_num_interval(int* n_interval)
00264 {
00265   for (int i = 0; i < 3; i++) {
00266     m_nDiv[i] = n_interval[i];
00267   }
00268 }
00269 
00270 #ifdef HAVE_MOAB
00271 void EBMesher::set_tree_root(ModelEnt* me)
00272 {
00273   moab::ErrorCode rval;
00274   if (m_bUseGeom) {
00275     if (m_hObbTree == NULL) {
00276       m_hObbTree = m_GeomTopoTool->obb_tree();
00277     }
00278     if (m_bUseWholeGeom) {
00279       if (!m_bUseMeshGeom) m_hTreeRoot = m_GeomTopoTool->get_one_vol_root();
00280     }
00281     else {
00282       rval = m_GeomTopoTool->get_root(me->mesh_handle(), m_hTreeRoot);
00283       MBERRCHK(rval, mk_core()->moab_instance());
00284     }
00285   }
00286   else { // facet data input case
00287     MBEntityHandle meshset;
00288     if (m_bUseWholeGeom) meshset = 0;
00289     else meshset = me->mesh_handle();
00290 
00291     // get triangles
00292     MBRange tris;
00293     rval = moab_instance()->get_entities_by_dimension(meshset, 2, tris);
00294     MBERRCHK(rval, mk_core()->moab_instance());
00295     
00296     // make tree
00297     if (m_hObbTree == NULL) {
00298       m_hObbTree = new MBOrientedBoxTreeTool( moab_instance() );
00299     }
00300     rval = m_hObbTree->build(tris, m_hTreeRoot);
00301     MBERRCHK(rval, mk_core()->moab_instance());
00302   }
00303 }
00304 
00305 void EBMesher::find_intersections()
00306 {
00307   std::cout << "starting to find intersections." << std::endl;
00308   int i;
00309   //m_vnHexStatus.resize(m_nHex, 1); // initialize all hex as outside
00310   m_vnHexStatus.resize(m_nHex, 0); // initialize all hex as inside
00311 
00312   // fire rays to 3 directions
00313   for (i = 0; i < 3; i++) {
00314     //m_vnEdgeStatus[i].resize(m_nDiv[i]*m_nDiv[(i + 1)%3]*m_nDiv[(i + 2)%3], OUTSIDE);
00315     m_vnEdgeStatus[i].resize(m_nDiv[i]*m_nDiv[(i + 1)%3]*m_nDiv[(i + 2)%3], INSIDE);
00316     fire_rays(i);
00317   }
00318   std::cout << "finished to find intersections." << std::endl;
00319 }
00320 
00321 void EBMesher::export_mesh(const char* file_name, bool separate)
00322 { 
00323   // get all hexes
00324   time_t time1, time2, time3;
00325   time(&time1);
00326   int i;
00327   iBase_ErrorType err;
00328   std::vector<iBase_EntityHandle> hex_handles;
00329   err = mk_core()->imesh_instance()->getEntities(m_hRootSet, iBase_REGION,
00330                                                  iMesh_HEXAHEDRON, hex_handles);
00331   IBERRCHK(err, "Failed to get hexes.\n");
00332   /*
00333   int hex_size = hex_handles.size();
00334   int* hex_status = new int[hex_size];
00335   int* hex_status = NULL;
00336   std::vector<int> hex_status(hex_size);
00337   err = mk_core()->imesh_instance()->getIntArrData(&hex_handles[0], hex_size,
00338   m_elemStatusTag, &hex_status[0]);*/
00339 
00340   int error;
00341   int hex_size = hex_handles.size();
00342   int* hex_status = new int[hex_size];
00343   int hex_status_alloc = sizeof(int)*hex_size;
00344   int hex_status_size = 0;
00345   iMesh_getIntArrData(m_mesh, &hex_handles[0],
00346                       hex_size, m_elemStatusTag,
00347                       &hex_status, &hex_status_alloc,
00348                       &hex_status_size, &error);
00349   IBERRCHK(error, "Failed to get hex status.\n");
00350   time(&time2);
00351 
00352   if (separate) {
00353     int n_inside_hex = 0;
00354     int n_outside_hex = 0;
00355     int n_boundary_hex = 0;
00356     int hex_stat;
00357     (void) hex_stat;
00358     std::vector<iBase_EntityHandle> insideHex, outsideHex, bndrHex;
00359     for (i = 0; i < hex_size; i++) {
00360       if (hex_status[i] == 0) {
00361         n_inside_hex++;
00362         hex_stat = 0;
00363         insideHex.push_back(hex_handles[i]);
00364       }
00365       else if (hex_status[i] == 1) {
00366         n_outside_hex++;
00367         hex_stat = 1;
00368         outsideHex.push_back(hex_handles[i]);
00369       }
00370       else if (hex_status[i] == 2) {
00371         n_boundary_hex++;
00372         hex_stat = 2;
00373         bndrHex.push_back(hex_handles[i]);
00374       }
00375       else {
00376         throw Error(MK_FAILURE, "Hex element status should be inside/outside/boundary.");
00377       }
00378     }
00379     
00380     std::cout << "# of exported inside hex:" << n_inside_hex
00381               << ", # of exported outside hex:" << n_outside_hex
00382               << ", # of exported boundary hex:" << n_boundary_hex
00383               << ", geom vol:"
00384               << n_inside_hex*m_dIntervalSize[0]*m_dIntervalSize[1]*m_dIntervalSize[2]
00385               << ", vox vol:" << hex_size*m_dIntervalSize[0]*m_dIntervalSize[1]*m_dIntervalSize[2]
00386               << std::endl;
00387     time(&time3);
00388 
00389     // save inside/outside/boundary elements separately
00390     if (n_inside_hex > 0) {
00391       write_mesh(file_name, 0, &insideHex[0], n_inside_hex);
00392     }
00393     if (n_boundary_hex > 0) {
00394       write_mesh(file_name, 2, &bndrHex[0], n_boundary_hex);
00395     }
00396     if (n_outside_hex > 0) {
00397       write_mesh(file_name, 1, &outsideHex[0], n_outside_hex);
00398     }
00399 
00400     if (debug_ebmesh) {
00401       std::cout << "hex_handle_get_time: "
00402                 << difftime(time2, time1)
00403                 << ", separate_write_time: "
00404                 << difftime(time3, time2)
00405                 << std::endl;
00406     }
00407   }
00408   else {
00409     write_mesh(file_name, 3, &hex_handles[0], hex_size);
00410     time3 = clock();
00411     if (debug_ebmesh) {
00412       std::cout << "hex_handle_get_time: "
00413                 << difftime(time2, time1)
00414                 << ", actual_write_time: "
00415                 << difftime(time3, time2)
00416                 << std::endl;
00417     }
00418   }
00419   delete [] hex_status;
00420 }
00421 
00422 void EBMesher::write_mesh(const char* file_name, int type,
00423                           iBase_EntityHandle* handles, int& n_elem)
00424 {
00425   time_t time1, time2, time3;
00426   time(&time1);
00427   int is_list = 1;
00428   moab::ErrorCode rval;
00429   iBase_EntitySetHandle set;
00430   iBase_ErrorType err;
00431 
00432   err = mk_core()->imesh_instance()->createEntSet(is_list, set);
00433   IBERRCHK(err, "Couldn't create set.");
00434 
00435   err = mk_core()->imesh_instance()->addEntArrToSet(handles, n_elem, set);
00436   IBERRCHK(err, "Couldn't add hexes to set.");
00437   time(&time2);
00438 
00439   std::string out_name;
00440   std::stringstream ss;
00441   if (type == 0) ss << "inside_";
00442   else if (type == 1) ss << "outside_";
00443   else if (type == 2) ss << "boundary_";
00444   ss << file_name;
00445   ss >> out_name;
00446   
00447   rval = moab_instance()->write_mesh(out_name.c_str(),
00448                                      (const moab::EntityHandle*) &set, 1);
00449   MBERRCHK(rval, mk_core()->moab_instance());
00450   
00451   std::cout << "Elements are exported." << std::endl;
00452   time(&time3);
00453 
00454   if (debug_ebmesh) {
00455     std::cout << "set_creation_time: "
00456               << difftime(time2, time1)
00457               << ", write_time: "
00458               << difftime(time3, time2)
00459               << std::endl;
00460   }
00461 }
00462 #endif
00463 
00464 EdgeStatus EBMesher::get_edge_status(const double dP, int& iSkip)
00465 {
00466   if (m_nStatus == INSIDE) { // previous inside
00467     if (dP < m_dSecondP) {
00468       m_nMove = 0;
00469       iSkip = m_iSecondP;
00470       return INSIDE;
00471     }
00472     else {
00473       if (is_shared_overlapped_surf(m_iInter - 1)) m_nMove = 1;
00474       else m_nMove = 2;
00475         
00476       // skip shared and overlapped interesections
00477       while (m_vIntersection[m_iInter].distance -
00478              m_vIntersection[m_iInter - 1].distance < 1e-7 &&
00479              (unsigned int) (m_iInter + 1) < m_vIntersection.size()) m_iInter++;        
00480       
00481       return BOUNDARY;
00482     }
00483   }
00484   else if (m_nStatus == OUTSIDE) { // previous outside
00485     if (dP < m_dFirstP) {
00486       m_nMove = 0;
00487       return OUTSIDE;
00488     }
00489     else {
00490       if (dP < m_dSecondP) m_nMove = 0;
00491       else if (is_shared_overlapped_surf(m_iInter - 1)) m_nMove = 1;
00492       else m_nMove = 2;
00493 
00494       // skip shared and overlapped interesections
00495       while (m_vIntersection[m_iInter].distance -
00496              m_vIntersection[m_iInter - 1].distance < 1e-7 &&
00497              (unsigned int) (m_iInter + 1) < m_vIntersection.size()) m_iInter++;
00498 
00499       return BOUNDARY;
00500     }
00501   }
00502   else if (m_nStatus == BOUNDARY) { // previous boundary
00503     if (dP < m_dFirstP) {
00504       m_nMove = 0;
00505       iSkip = m_iFirstP;
00506       return OUTSIDE;
00507     }
00508     else {
00509       if (dP < m_dSecondP) {
00510         m_nMove = 0;
00511         if (m_prevPnt < m_dFirstP) return BOUNDARY;
00512         else {
00513           iSkip = m_iSecondP;
00514           return INSIDE;
00515         }
00516       }
00517       else {
00518         if (is_shared_overlapped_surf(m_iInter - 1)) m_nMove = 1;
00519         else m_nMove = 2;
00520 
00521         // skip shared and overlapped interesections
00522         while (m_vIntersection[m_iInter].distance -
00523                m_vIntersection[m_iInter - 1].distance < 1e-7 &&
00524                (unsigned int) (m_iInter + 1) < m_vIntersection.size()) m_iInter++;
00525 
00526         if (m_prevPnt < m_dSecondP) return BOUNDARY;
00527         else return OUTSIDE;
00528       }
00529     }
00530   }
00531   else {
00532     std::cerr << "Couldn't get edge status." << std::endl;
00533     return INSIDE;
00534   }
00535 }
00536 
00537 bool EBMesher::set_neighbor_hex_status(int dir, int i, int j, int k)
00538 {
00539   int iElem;
00540   int otherDir1 = (dir + 1)%3;
00541   int otherDir2 = (dir + 2)%3;
00542 
00543   if (dir == 0) { // x coordinate ray
00544     m_iElem = j*m_nDiv[0]*m_nDiv[1] + i*m_nDiv[0] + k;
00545     if (!set_hex_status(m_iElem, m_nStatus, dir)) return false;
00546     iElem = m_iElem - m_nDiv[dir];
00547     if (!set_hex_status(iElem, m_nStatus, dir)) return false;
00548     iElem -= m_nDiv[dir]*m_nDiv[otherDir1];
00549     if (!set_hex_status(iElem, m_nStatus, dir)) return false;
00550     iElem += m_nDiv[dir];
00551     if (!set_hex_status(iElem, m_nStatus, dir)) return false;
00552   }
00553   else if (dir == 1) { // y coordinate ray
00554     m_iElem = i*m_nDiv[1]*m_nDiv[0] + k*m_nDiv[0] + j;
00555     if (!set_hex_status(m_iElem, m_nStatus, dir)) return false;
00556     iElem = m_iElem - 1;
00557     if (!set_hex_status(iElem, m_nStatus, dir)) return false;
00558     iElem -= m_nDiv[dir]*m_nDiv[otherDir2];
00559     if (!set_hex_status(iElem++, m_nStatus, dir)) return false;
00560     if (!set_hex_status(iElem, m_nStatus, dir)) return false;
00561   }
00562   else if (dir == 2) { // z coordinate ray
00563     m_iElem = k*m_nDiv[0]*m_nDiv[1] + j*m_nDiv[0] + i;
00564     if (!set_hex_status(m_iElem, m_nStatus, dir)) return false;
00565     iElem = m_iElem - 1;
00566     if (!set_hex_status(iElem, m_nStatus, dir)) return false;
00567     iElem -= m_nDiv[otherDir1];
00568     if (!set_hex_status(iElem++, m_nStatus, dir)) return false;
00569     if (!set_hex_status(iElem, m_nStatus, dir)) return false;
00570   }
00571 
00572   return true;
00573 }
00574 
00575 bool EBMesher::set_hex_status(int index, EdgeStatus value, int dir)
00576 {
00577   if (index < 0 || index > m_nHex - 1) {
00578     return false;
00579   }
00580 
00581   if (m_vnHexStatus[index] != 2) {
00582     if (value == INSIDE) {
00583       m_vnHexStatus[index] = 0;
00584     }
00585     else if (value == OUTSIDE) {
00586       m_vnHexStatus[index] = 1;
00587     }
00588     else if (value == BOUNDARY) {
00589       m_vnHexStatus[index] = 2;
00590     }
00591   }
00592 
00593   return true;
00594 }
00595 
00596 bool EBMesher::set_edge_status(int dir)
00597 {
00598   // set boundary cut information to edge
00599   std::vector<double> vdCutFraction;
00600   if (m_nMove == 0) vdCutFraction.push_back((m_curPnt - m_dFirstP)/m_dIntervalSize[dir] - 1.);
00601   else if (m_nMove == 1) vdCutFraction.push_back(1. - (m_curPnt - m_dSecondP)/m_dIntervalSize[dir]);
00602   else if (m_nMove == 2) {
00603     vdCutFraction.push_back(1. - (m_curPnt - m_dSecondP)/m_dIntervalSize[dir]);
00604     if (m_dFirstP < m_curPnt) {
00605       vdCutFraction.push_back((m_curPnt - m_dFirstP)/m_dIntervalSize[dir] - 1.);
00606     }
00607   }
00608 
00609   std::map<int, CutFraction>::iterator iter = m_mdCutFraction.find(m_iElem);
00610   if (iter == m_mdCutFraction.end()) { // not exist
00611     CutFraction cFraction(dir, vdCutFraction);
00612     m_mdCutFraction[m_iElem] = cFraction;
00613   }
00614   else { // exist
00615     iter->second.add(dir, vdCutFraction);
00616   }
00617 
00618   //m_nFraction += vdCutFraction.size();
00619 
00620   return true;
00621 }
00622 
00623 #ifdef HAVE_MOAB
00624 void EBMesher::set_division()
00625 {
00626   int i, j;
00627   moab::CartVect box_center, box_axis1, box_axis2, box_axis3,
00628     min_cart_box(HUGE_VAL, HUGE_VAL, HUGE_VAL),
00629     max_cart_box(0., 0., 0.);
00630   
00631   moab::ErrorCode rval = m_hObbTree->box(m_hTreeRoot, box_center.array(),
00632                                      box_axis1.array(), box_axis2.array(),
00633                                      box_axis3.array());
00634   MBERRCHK(rval, mk_core()->moab_instance());
00635 
00636   // cartesian box corners
00637   moab::CartVect corners[8] = {box_center + box_axis1 + box_axis2 + box_axis3,
00638                                box_center + box_axis1 + box_axis2 - box_axis3,
00639                                box_center + box_axis1 - box_axis2 + box_axis3,
00640                                box_center + box_axis1 - box_axis2 - box_axis3,
00641                                box_center - box_axis1 + box_axis2 + box_axis3,
00642                                box_center - box_axis1 + box_axis2 - box_axis3,
00643                                box_center - box_axis1 - box_axis2 + box_axis3,
00644                                box_center - box_axis1 - box_axis2 - box_axis3};
00645 
00646   // get the max, min cartesian box corners
00647   for (i = 0; i < 8; i++) {
00648     for (j = 0; j < 3; j++) {
00649       if (corners[i][j] < min_cart_box[j]) min_cart_box[j] = corners[i][j];
00650       if (corners[i][j] > max_cart_box[j]) max_cart_box[j] = corners[i][j];
00651     }
00652   }
00653   moab::CartVect length = max_cart_box - min_cart_box;
00654   
00655   // default value is adjusted to large geometry file
00656   // interval_size_estimate : 2*L*sqrt(2*PI*sqrt(2)/# of tris)
00657   if (m_dInputSize < 0.) {
00658     int n_tri;
00659     rval = moab_instance()->
00660       get_number_entities_by_dimension(reinterpret_cast<MBEntityHandle>(m_hRootSet),
00661                                        2, n_tri);
00662     MBERRCHK(rval, mk_core()->moab_instance());
00663     
00664     double box_length_ave = (length[0] + length[1] + length[2])/3.;
00665     m_dInputSize = 2.*box_length_ave*sqrt(8.886/n_tri);
00666   }
00667 
00668   for (i = 0; i < 3; i++) {
00669     m_nDiv[i] = length[i]/m_dInputSize;
00670     if (m_nDiv[i] < m_nAddLayer) m_nDiv[i] = m_nAddLayer; // make "m_nAddLayer" elements larger than bounding box
00671     m_dIntervalSize[i] = m_dInputSize;
00672     //if (m_nDiv[i]*.07 > m_nAddLayer) m_nDiv[i] += m_nDiv[i]*.07;
00673     //else m_nDiv[i] += m_nAddLayer;
00674     m_nDiv[i] += m_nAddLayer;
00675     m_nNode[i] = m_nDiv[i] + 1;
00676     m_origin_coords[i] = box_center[i] - .5*m_nDiv[i]*m_dIntervalSize[i];
00677   }
00678 
00679   m_nHex = m_nDiv[0]*m_nDiv[1]*m_nDiv[2];
00680 
00681   std::cout << "# of hex: " << m_nHex << ", interval size: "
00682             << m_dInputSize << std::endl;
00683 
00684   std::cout << "# of division: " << m_nDiv[0] << ","
00685             << m_nDiv[1] << "," << m_nDiv[2] << std::endl;
00686 }
00687 
00688 int EBMesher::set_division(double* min, double* max)
00689 {
00690   for (int i = 0; i < 3; i++) {
00691     m_dIntervalSize[i] = (max[i] - min[i])/m_nDiv[i];
00692     m_nNode[i] = m_nDiv[i] + 1;
00693     m_origin_coords[i] = min[i];
00694   }
00695 
00696   m_nHex = m_nDiv[0]*m_nDiv[1]*m_nDiv[2];
00697 
00698   std::cout << "# of hex: " << m_nHex << ", interval_size: "
00699             << m_dIntervalSize[0] << ", " << m_dIntervalSize[1] << ", "
00700             << m_dIntervalSize[2] << std::endl;
00701 
00702   std::cout << "# of division: " << m_nDiv[0] << ","
00703             << m_nDiv[1] << "," << m_nDiv[2] << std::endl;
00704 
00705   return iBase_SUCCESS;
00706 }
00707 
00708 int EBMesher::make_scd_hexes()
00709 {
00710   // create vertex and hex sequences
00711   int i;
00712   double max_coords[3];
00713   (void) max_coords;
00714   for (i = 0; i < 3; i++) {
00715     max_coords[i] = m_origin_coords[i] + m_nDiv[i]*m_dIntervalSize[i];
00716   }
00717 
00718   moab::HomCoord coord_min(0, 0, 0);
00719   moab::HomCoord coord_max(m_nDiv[0], m_nDiv[1], m_nDiv[2]);
00720   moab::EntitySequence* vertex_seq = NULL;
00721   moab::EntitySequence* cell_seq = NULL;
00722   moab::EntityHandle vs, cs;
00723   moab::Core *mbcore = dynamic_cast<moab::Core*>(moab_instance());
00724 
00725   moab::ErrorCode rval = mbcore->create_scd_sequence(coord_min, coord_max, MBVERTEX, 1, vs, vertex_seq);
00726   MBERRCHK(rval, mk_core()->moab_instance());
00727   
00728   mbcore->create_scd_sequence(coord_min, coord_max, MBHEX, 1, cs, cell_seq);
00729   MBERRCHK(rval, mk_core()->moab_instance());
00730 
00731   moab::HomCoord p2(coord_max.i(), coord_min.j(), coord_min.k());
00732   moab::HomCoord p3(coord_min.i(), coord_max.j(), coord_min.k()); 
00733   
00734   rval = mbcore->add_vsequence(vertex_seq, cell_seq, coord_min, coord_min,
00735                                         p2, p2, p3, p3);
00736   MBERRCHK(rval, mk_core()->moab_instance());
00737 
00738   int nTotNode = m_nNode[0]*m_nNode[1]*m_nNode[2];
00739   int ii, jj, kk;
00740   MBEntityHandle handle;
00741   double dumv[3];
00742   for (i = 0, handle = vs; i < nTotNode; i++, handle++) {
00743     ii = (i%(m_nNode[0]*m_nNode[1]))%m_nNode[0];
00744     jj = (i%(m_nNode[0]*m_nNode[1]))/m_nNode[0];
00745     kk = i/m_nNode[0]/m_nNode[1];
00746     dumv[0] = m_origin_coords[0] + ii*m_dIntervalSize[0];
00747     dumv[1] = m_origin_coords[1] + jj*m_dIntervalSize[1];
00748     dumv[2] = m_origin_coords[2] + kk*m_dIntervalSize[2];
00749     rval = moab_instance()->set_coords(&handle, 1, dumv);
00750     MBERRCHK(rval, mk_core()->moab_instance());
00751   }
00752 
00753   m_iStartHex = moab_instance()->id_from_handle(cs);
00754 
00755   return iBase_SUCCESS;
00756 }
00757 
00758 iBase_TagHandle EBMesher::get_tag(const char* name, int size,
00759                                      unsigned store, MBDataType type,
00760                                      const void* def_value,
00761                                      bool create_if_missing) 
00762 {
00763   MBTag retval = 0;
00764   /*moab::ErrorCode result = moab_instance()->tag_create(name, size, store, type,
00765                                                    retval, def_value,
00766                                                    create_if_missing);*/
00767   store = store | moab::MB_TAG_CREAT;
00768   if(!create_if_missing)
00769     store = store | moab::MB_TAG_EXCL;
00770   moab::ErrorCode result = moab_instance()->tag_get_handle(name, size, type, retval, store,
00771                                                       def_value);
00772   if (create_if_missing && MB_SUCCESS != result) {
00773     std::cerr << "Couldn't find nor create tag named " << name << std::endl;
00774   }
00775   
00776   return (iBase_TagHandle) retval;
00777 }
00778 
00779 iBase_TagHandle EBMesher::get_various_length_tag(const char* name,
00780                                                     unsigned store, MBDataType type)
00781 {
00782   MBTag retval = 0;
00783   store = store | moab::MB_TAG_VARLEN | moab::MB_TAG_CREAT;
00784   moab::ErrorCode result = moab_instance()->
00785     tag_get_handle( name, 1, type, retval, store);
00786   if (MB_SUCCESS != result) {
00787     std::cerr << "Couldn't find nor create tag named " << name << std::endl;
00788   }
00789   
00790   return (iBase_TagHandle) retval;
00791 }
00792 
00793 void EBMesher::set_tag_info()
00794 {
00795   // get all hexes
00796   int i, j, k;
00797   iBase_ErrorType err;
00798   std::vector<iBase_EntityHandle> hex_handles;
00799   err = mk_core()->imesh_instance()->getEntities(m_hRootSet, iBase_REGION,
00800                                                  iMesh_HEXAHEDRON, hex_handles);
00801   IBERRCHK(err, "Failed to get hexes.\n");
00802 
00803   err = mk_core()->imesh_instance()->setIntArrData(&hex_handles[0], m_nHex,
00804                                                    m_elemStatusTag,
00805                                                    &m_vnHexStatus[0]);
00806   IBERRCHK(err, "Failed to set hex element status data.");
00807 
00808   // set cut fraction info to boundary hexes
00809   int nBndrHex = m_mdCutFraction.size();
00810   std::vector<iBase_EntityHandle> hvBndrHex(nBndrHex);
00811   int* frac_size = new int[nBndrHex];
00812   int* frac_leng = new int[3*nBndrHex];
00813   int nFracSize, nTempSize, iHex, nTolFrac = 0;
00814   int nDoubleSize = sizeof(double);
00815   std::map<int, CutFraction>::iterator iter = m_mdCutFraction.begin();
00816   std::map<int, CutFraction>::iterator end_iter = m_mdCutFraction.end();
00817   for (i = 0; iter != end_iter; iter++, i++) {
00818     iHex = iter->first;
00819     hvBndrHex[i] = hex_handles[iHex];
00820 
00821     nFracSize = 0;
00822     for (j = 0; j < 3; j++) {
00823       nTempSize = iter->second.fraction[j].size();
00824       nFracSize += nTempSize;
00825       frac_leng[3*i + j] = nTempSize;
00826     }
00827     frac_size[i] = nDoubleSize*nFracSize; // sizeof(double)*
00828     nTolFrac += nFracSize;
00829   }
00830 
00831   int iFrac = 0;
00832   double* fractions = new double[nTolFrac];
00833   std::vector<const void*> frac_data_pointer(nBndrHex);
00834   iter = m_mdCutFraction.begin();
00835   for (i = 0; iter != end_iter; iter++, i++) {
00836     for (j = 0; j < 3; j++) {
00837       nFracSize = iter->second.fraction[j].size();
00838       frac_data_pointer[i] = &fractions[iFrac];
00839       for (k = 0; k < nFracSize; k++) {
00840         fractions[iFrac++] = iter->second.fraction[j][k];
00841       }
00842     }
00843   }
00844 
00845   err = mk_core()->imesh_instance()->setIntArrData(&hvBndrHex[0], nBndrHex,
00846                                                    m_edgeCutFracLengthTag,
00847                                                    frac_leng);
00848   IBERRCHK(err, "Failed to set cut fraction sizes to hex.");
00849 
00850   moab::ErrorCode rval = moab_instance()->tag_set_by_ptr(reinterpret_cast<MBTag> (m_edgeCutFracTag),
00851                                                    reinterpret_cast<moab::EntityHandle*> (&hvBndrHex[0]),
00852                                                    nBndrHex, &frac_data_pointer[0], frac_size);
00853   MBERRCHK(rval, mk_core()->moab_instance());
00854   
00855   delete [] frac_size;
00856   delete [] frac_leng;
00857   delete [] fractions;
00858 }
00859 
00860 void EBMesher::fire_rays(int dir)
00861 {
00862   // ray fire
00863   int i, j, k, l, index[3];
00864   double tolerance = 1e-12;
00865   double rayLength = m_nDiv[dir]*m_dIntervalSize[dir];
00866   int iNodeStart, iNodeEnd, nIntersect, nNodeSlice;
00867   double startPnt[3], endPnt[3];
00868   int otherDir1 = (dir + 1)%3;
00869   int otherDir2 = (dir + 2)%3;
00870  // harmless as this expression (does nothing) so that a compiler sees it is used.
00871   (void) iNodeEnd;
00872   (void) nNodeSlice;
00873 
00874   for (j = 1; j < m_nNode[otherDir2] - 1; j++) {
00875     for (i = 1; i < m_nNode[otherDir1] - 1; i++) {
00876 
00877       // get ray start and end points
00878       if (dir == 0) { // x coordinate ray
00879         iNodeStart = j*m_nNode[dir]*m_nNode[otherDir1] + i*m_nNode[dir];
00880         iNodeEnd = iNodeStart + m_nNode[dir] - 1;
00881         nNodeSlice = 1;
00882         index[0] = 0;
00883         index[1] = i;
00884         index[2] = j;
00885       }
00886       else if (dir == 1) { // y coordinate ray
00887         iNodeStart = i*m_nNode[otherDir2]*m_nNode[dir] + j;
00888         iNodeEnd = iNodeStart + m_nNode[otherDir2]*(m_nNode[dir] - 1);
00889         nNodeSlice = m_nNode[otherDir2];
00890         index[0] = j;
00891         index[1] = 0;
00892         index[2] = i;
00893       }
00894       else if (dir == 2) { // z coordinate ray
00895         iNodeStart = j*m_nNode[otherDir1] + i;
00896         iNodeEnd = iNodeStart + m_nNode[otherDir1]*m_nNode[otherDir2]*(m_nNode[dir] - 1);
00897         nNodeSlice = m_nNode[otherDir1]*m_nNode[otherDir2];
00898         index[0] = i;
00899         index[1] = j;
00900         index[2] = 0;
00901       }
00902       else IBERRCHK(iBase_FAILURE, "Ray direction should be 0 to 2.");
00903       
00904       for (l = 0; l < 3; l++) {
00905         if (l == dir) {
00906           startPnt[l] = m_origin_coords[l];
00907           endPnt[l] = m_origin_coords[l] + m_nDiv[dir]*m_dIntervalSize[l];
00908         }
00909         else {
00910           startPnt[l] = m_origin_coords[l] + index[l]*m_dIntervalSize[l];
00911           endPnt[l] = startPnt[l];
00912         }
00913       }
00914       
00915       k = 0;
00916       m_iInter = 0;
00917       if (!fire_ray(nIntersect, startPnt, endPnt, tolerance, dir, rayLength)) {
00918         IBERRCHK(iBase_FAILURE, "Couldn't fire ray.");
00919       }
00920       
00921       if (nIntersect > 0) {
00922         m_iFirstP = m_vIntersection[m_iInter].distance/m_dIntervalSize[dir];
00923         m_dFirstP = startPnt[dir] + m_vIntersection[m_iInter++].distance;
00924         m_iSecondP = m_vIntersection[m_iInter].distance/m_dIntervalSize[dir];
00925         m_dSecondP = startPnt[dir] + m_vIntersection[m_iInter++].distance;
00926 
00927         // set outside before the first hit
00928         for (k = 0; k < m_iFirstP; k++) {
00929           m_nStatus = OUTSIDE;
00930           
00931           if (!set_neighbor_hex_status(dir, i, j, k)) {
00932             IBERRCHK(iBase_FAILURE, "Couldn't set neighbor hex status.");
00933           }
00934         }
00935         
00936         for (; k < m_nNode[dir] - 1;) {
00937           int i_skip = 0;
00938           m_curPnt = startPnt[dir] + (k + 1)*m_dIntervalSize[dir];
00939           EdgeStatus preStat = m_nStatus;
00940           m_nStatus = get_edge_status(m_curPnt, i_skip);
00941           m_vnEdgeStatus[dir][i*m_nDiv[dir] + j*m_nDiv[dir]*m_nDiv[otherDir1] + k] = m_nStatus;
00942 
00943           // set status of all hexes sharing the edge
00944           if (!set_neighbor_hex_status(dir, i, j, k)) {
00945             IBERRCHK(iBase_FAILURE, "Couldn't set neighbor hex status.");
00946           }
00947 
00948           if (m_nMove > 0) {
00949             if (m_iInter < nIntersect) {
00950               if (!move_intersections(dir, nIntersect, startPnt)) {
00951                 IBERRCHK(iBase_FAILURE, "Couldn't move intersections.");
00952               }
00953             }
00954             else {
00955               m_nMove = 1;
00956               if (m_nStatus == BOUNDARY && !set_edge_status(dir)) {
00957                 IBERRCHK(iBase_FAILURE, "Couldn't set edge status.");
00958               }
00959               k++;
00960               break; // rest is all outside
00961             }
00962           }
00963           else if (m_nStatus == BOUNDARY && !set_edge_status(dir)) {
00964             IBERRCHK(iBase_FAILURE, "Couldn't set edge status.");
00965           }
00966           else if (m_nStatus == OUTSIDE && preStat == BOUNDARY) { // set outside until next hit
00967             k++;
00968             for (; k < i_skip; k++) {
00969               m_nStatus = OUTSIDE;
00970               if (!set_neighbor_hex_status(dir, i, j, k)) {
00971                 IBERRCHK(iBase_FAILURE, "Couldn't set neighbor hex status.");
00972               }
00973             }
00974           }
00975 
00976           // set cut-cell edge status
00977           if (i_skip > 0) {
00978             m_prevPnt = startPnt[dir] + i_skip*m_dIntervalSize[dir];
00979             k = i_skip;
00980           }
00981           else {
00982             m_prevPnt = m_curPnt;
00983             k++;
00984           }
00985         }
00986       }
00987         
00988       // the rest are all outside
00989       for (; k < m_nNode[dir] - 1; k++) {
00990         m_nStatus = OUTSIDE;
00991         if (!set_neighbor_hex_status(dir, i, j, k)) {
00992           IBERRCHK(iBase_FAILURE, "Couldn't set neighbor hex status.");
00993         }
00994       }
00995     }
00996   }
00997 }
00998 
00999 bool EBMesher::fire_ray(int& nIntersect, double startPnt[3],
01000                       double endPnt[3], double tol, int dir,
01001                       double rayLength)
01002 {
01003   m_vIntersection.clear();
01004   m_vhInterSurf.clear();
01005   m_vhInterFacet.clear();
01006   m_mhOverlappedSurf.clear();
01007   std::vector<double> temp_intersects;
01008   moab::ErrorCode rVal;
01009   if (m_bUseGeom) { // geometry input
01010     rVal = m_hObbTree->ray_intersect_sets(temp_intersects, m_vhInterSurf,
01011                                           m_vhInterFacet, m_hTreeRoot, tol,
01012                                           -1, startPnt, rayDir[dir], &rayLength);
01013   }
01014   else { // facet input
01015     std::vector<moab::EntityHandle> dum_facets_out;
01016     rVal = m_hObbTree->ray_intersect_triangles(temp_intersects, dum_facets_out,
01017                                                m_hTreeRoot, tol,
01018                                                startPnt, rayDir[dir], &rayLength);
01019   }
01020   
01021   nIntersect = temp_intersects.size();
01022   if (MB_SUCCESS != rVal) {
01023     std::cerr << "Failed : ray-triangle intersection." << std::endl;
01024     return false;
01025   }
01026   
01027   if (nIntersect > 0) {
01028     m_vIntersection.resize(nIntersect);
01029     
01030     for (int l = 0; l < nIntersect; l++) {
01031       IntersectDist temp_inter_dist(temp_intersects[l], l);
01032       m_vIntersection[l] = temp_inter_dist;
01033     }
01034     std::sort(m_vIntersection.begin(), m_vIntersection.end(), less_intersect);
01035 
01036     if (nIntersect > 1) {
01037       bool bMoveOnce;
01038       m_nIteration = 0;
01039       m_iOverlap = 0;
01040       
01041       if (m_bUseGeom) { // if there are geometry info
01042         remove_intersection_duplicates();
01043       }
01044       else if (is_ray_move_and_set_overlap_surf(bMoveOnce)) { // facet geom case
01045         if (!move_ray(nIntersect, startPnt, endPnt, tol, dir, bMoveOnce)) {
01046           std::cerr << "Number of Intersection between edges and ray should be even." << std::endl;
01047           return false;
01048         }
01049       }
01050       nIntersect = m_vIntersection.size();
01051     }
01052   }
01053   
01054   return true;
01055 }
01056 
01057 bool EBMesher::move_intersections(int n_dir, int n_inter, double start_pnt[3])
01058 {
01059   if (m_nMove > 0) {
01060     if (m_iInter < n_inter) {
01061       if (m_nMove == 1) {
01062         do {
01063           if (m_nStatus == BOUNDARY && !set_edge_status(n_dir)) return false;
01064           m_iFirstP = m_iSecondP;
01065           m_dFirstP = m_dSecondP;
01066           m_iSecondP = m_vIntersection[m_iInter].distance/m_dIntervalSize[n_dir];
01067           m_dSecondP = start_pnt[n_dir] + m_vIntersection[m_iInter++].distance;
01068         }
01069         while (m_dSecondP < m_curPnt && m_iInter < n_inter);
01070       }
01071       else if (m_nMove == 2) {
01072         do {
01073           m_iFirstP = m_vIntersection[m_iInter].distance/m_dIntervalSize[n_dir];
01074           m_dFirstP = start_pnt[n_dir] + m_vIntersection[m_iInter++].distance;
01075           if (m_nStatus == BOUNDARY && !set_edge_status(n_dir)) return false;
01076           if (m_iInter < n_inter) {
01077             m_iSecondP = m_vIntersection[m_iInter].distance/m_dIntervalSize[n_dir];
01078             m_dSecondP = start_pnt[n_dir] + m_vIntersection[m_iInter++].distance;
01079           }
01080           else {
01081             m_iSecondP = m_iFirstP;
01082             m_dSecondP = m_dFirstP;
01083           }
01084         }
01085         while (m_dSecondP < m_curPnt && m_iInter < n_inter);
01086       }
01087     }
01088   }
01089 
01090   return true;
01091 }
01092 
01093 bool EBMesher::is_shared_overlapped_surf(int index)
01094 {
01095   int nParent;
01096   iBase_ErrorType err;
01097   moab::EntityHandle hSurf;
01098   if (m_bUseGeom) {
01099     hSurf = m_vhInterSurf[m_vIntersection[index].index];
01100     err = mk_core()->imesh_instance()->getNumPrnt(reinterpret_cast<iBase_EntitySetHandle> (hSurf),
01101                                                   1, nParent);
01102     IBERRCHK(err, "Failed to get number of surface parents.\n");
01103 
01104     if (nParent > 1) return true;
01105   }
01106   else hSurf = m_vIntersection[index].index;
01107 
01108   return m_mhOverlappedSurf.count(hSurf) > 0;
01109 }
01110 
01111 void EBMesher::get_grid_and_edges_techX(double* boxMin, double* boxMax, int* nDiv,
01112                                       std::map< CutCellSurfEdgeKey, std::vector<double>, LessThan >& rmdCutCellSurfEdge,
01113                                       std::vector<int>& rvnInsideCell, bool isCornerExterior)
01114 {
01115   int i, j, err, ii, jj, kk, iHex;
01116   for (i = 0; i < 3; i++) {
01117     boxMin[i] = m_origin_coords[i];
01118     boxMax[i] = m_origin_coords[i] + m_dIntervalSize[i]*m_nDiv[i];
01119     nDiv[i] = m_nDiv[i];
01120   }
01121   
01122   // get all hexes
01123   std::vector<iBase_EntityHandle> hex_handles;
01124   err = mk_core()->imesh_instance()->getEntities(m_hRootSet, iBase_REGION,
01125                                                  iMesh_HEXAHEDRON, hex_handles);
01126   IBERRCHK(err, "Failed to get hexes.\n");
01127   
01128   // get hex status
01129   int hex_size = hex_handles.size();
01130   /*
01131   //int* hex_status = new int[hex_size];
01132   //int* hex_status;
01133   //std::vector<int> hex_status(hex_size);
01134   int temp = 0;
01135   int* hex_status = &temp;
01136   err = mk_core()->imesh_instance()->getIntArrData(&hex_handles[0], hex_size,
01137                                                    m_elemStatusTag, hex_status);
01138   */
01139   int error;
01140   int* hex_status = new int[hex_size];
01141   int hex_status_alloc = sizeof(int)*hex_size;
01142   int hex_status_size = 0;
01143   iMesh_getIntArrData(m_mesh, &hex_handles[0],
01144                       hex_size, m_elemStatusTag,
01145                       &hex_status, &hex_status_alloc,
01146                       &hex_status_size, &error);
01147   IBERRCHK(error, "Failed to get hex status.");
01148 
01149   // get inside and boundary hexes
01150   int nInside = 0;
01151   int nOutside = 0;
01152   int nBoundary = 0;
01153   rvnInsideCell.clear();
01154   for (i = 0; i < hex_size; i++) {
01155     if (hex_status[i] == 0) { // if inside
01156       iHex = moab_instance()->id_from_handle(reinterpret_cast<moab::EntityHandle>
01157                                              (hex_handles[i])) - m_iStartHex;
01158       rvnInsideCell.push_back((iHex%(m_nDiv[0]*m_nDiv[1]))%m_nDiv[0]);
01159       rvnInsideCell.push_back((iHex%(m_nDiv[0]*m_nDiv[1]))/m_nDiv[0]);
01160       rvnInsideCell.push_back(iHex/m_nDiv[0]/m_nDiv[1]);
01161       nInside++;
01162     }
01163     else if (hex_status[i] == 1) nOutside++;
01164     else if (hex_status[i] == 2) nBoundary++;
01165     else IBERRCHK(err, "Element status should be one of inside/outside/boundary."); 
01166   }
01167   std::cout << "# of inside, outside, boundary elem: " << nInside
01168             << ", " << nOutside << ", " << nBoundary << std::endl;
01169   delete [] hex_status;
01170 
01171   // get cut-cell fractions
01172   double dFrac[4];
01173   std::map<int, CutFraction>::iterator iter = m_mdCutFraction.begin();
01174   std::map<int, CutFraction>::iterator end_iter = m_mdCutFraction.end();
01175   
01176   for (; iter != end_iter; iter++) { // for each cut-cell
01177     // get i, j, k index from handle
01178     iHex = iter->first;
01179     ii = (iHex%(m_nDiv[0]*m_nDiv[1]))%m_nDiv[0];
01180     jj = (iHex%(m_nDiv[0]*m_nDiv[1]))/m_nDiv[0];
01181     kk = iHex/m_nDiv[0]/m_nDiv[1];
01182 
01183     // surface 1
01184     CutFraction cutFrac = iter->second;
01185     if (cutFrac.fraction[1].size() > 0) {
01186       dFrac[0] = cutFrac.fraction[1][0];
01187       if (dFrac[0] < 0.) dFrac[0] *= -1.;
01188     }
01189     else dFrac[0] = -1.;
01190     if (cutFrac.fraction[2].size() > 0) {
01191       dFrac[3] = cutFrac.fraction[2][0];
01192       if (dFrac[3] < 0.) dFrac[3] *= -1.;
01193     }
01194     else dFrac[3] = -1.;
01195     dFrac[1] = get_edge_fraction(iHex + m_nDiv[0], 2);
01196     dFrac[2] = get_edge_fraction(iHex + m_nDiv[0]*m_nDiv[1], 1);
01197     
01198     if (dFrac[0] > 0. || dFrac[1] > 0. || dFrac[2] > 0. || dFrac[3] > 0.) { // if surface is cut
01199       CutCellSurfEdgeKey surfKey(ii, jj, kk, 0);
01200       std::vector<double> edges;
01201       if (dFrac[0] < 0.) dFrac[0] = get_uncut_edge_fraction(ii, jj, kk, 1);
01202       if (dFrac[1] < 0.) dFrac[1] = get_uncut_edge_fraction(ii, jj + 1, kk, 2);
01203       if (dFrac[2] < 0.) dFrac[2] = get_uncut_edge_fraction(ii, jj, kk + 1, 1);
01204       if (dFrac[3] < 0.) dFrac[3] = get_uncut_edge_fraction(ii, jj, kk, 2);
01205       for (j = 0; j < 4; j++) edges.push_back(dFrac[j]);
01206       rmdCutCellSurfEdge[surfKey] = edges;
01207     }
01208 
01209     // surface 2
01210     cutFrac = iter->second;
01211     if (cutFrac.fraction[0].size() > 0) {
01212       dFrac[0] = cutFrac.fraction[0][0];
01213       if (dFrac[0] < 0.) dFrac[0] *= -1.;
01214     }
01215     else dFrac[0] = -1.;
01216     if (cutFrac.fraction[1].size() > 0) {
01217       dFrac[3] = cutFrac.fraction[1][0];
01218       if (dFrac[3] < 0.) dFrac[3] *= -1.;
01219     }
01220     else dFrac[3] = -1.;
01221     dFrac[1] = get_edge_fraction(iHex + 1, 2);
01222     dFrac[2] = get_edge_fraction(iHex + m_nDiv[0]*m_nDiv[1], 0);
01223     
01224     if (dFrac[0] > 0. || dFrac[1] > 0. || dFrac[2] > 0. || dFrac[3] > 0.) { // if surface is cut
01225       CutCellSurfEdgeKey surfKey(ii, jj, kk, 1);
01226       std::vector<double> edges;
01227       if (dFrac[0] < 0.) dFrac[0] = get_uncut_edge_fraction(ii, jj, kk, 0);
01228       if (dFrac[1] < 0.) dFrac[1] = get_uncut_edge_fraction(ii + 1, jj, kk, 2);
01229       if (dFrac[2] < 0.) dFrac[2] = get_uncut_edge_fraction(ii, jj, kk + 1, 0);
01230       if (dFrac[3] < 0.) dFrac[3] = get_uncut_edge_fraction(ii, jj, kk, 2);
01231       for (j = 0; j < 4; j++) edges.push_back(dFrac[j]);
01232       rmdCutCellSurfEdge[surfKey] = edges;
01233     }
01234     
01235     // surface 3
01236     cutFrac = iter->second;
01237     if (cutFrac.fraction[0].size() > 0) {
01238       dFrac[0] = cutFrac.fraction[0][0];
01239       if (dFrac[0] < 0.) dFrac[0] *= -1.;
01240     }
01241     else dFrac[0] = -1.;
01242     if (cutFrac.fraction[1].size() > 0) {
01243       dFrac[3] = cutFrac.fraction[1][0];
01244       if (dFrac[3] < 0.) dFrac[3] *= -1.;
01245     }
01246     else dFrac[3] = -1.;
01247     dFrac[1] = get_edge_fraction(iHex + 1, 1);
01248     dFrac[2] = get_edge_fraction(iHex + m_nDiv[0], 0);
01249 
01250     if (dFrac[0] > 0. || dFrac[1] > 0. || dFrac[2] > 0. || dFrac[3] > 0.) { // if surface is cut
01251       CutCellSurfEdgeKey surfKey(ii, jj, kk, 2);
01252       std::vector<double> edges;
01253       if (dFrac[0] < 0.) dFrac[0] = get_uncut_edge_fraction(ii, jj, kk, 0);
01254       if (dFrac[1] < 0.) dFrac[1] = get_uncut_edge_fraction(ii + 1, jj, kk, 1);
01255       if (dFrac[2] < 0.) dFrac[2] = get_uncut_edge_fraction(ii, jj + 1, kk, 0);
01256       if (dFrac[3] < 0.) dFrac[3] = get_uncut_edge_fraction(ii, jj, kk, 1);
01257       for (j = 0; j < 4; j++) edges.push_back(dFrac[j]);
01258       rmdCutCellSurfEdge[surfKey] = edges;
01259     }
01260   }
01261   
01262   if (debug_ebmesh) export_fraction_edges(rmdCutCellSurfEdge);
01263 }
01264 
01265 bool EBMesher::get_grid_and_edges(double* boxMin, double* boxMax, int* nDiv,
01266                                      std::map< CutCellSurfEdgeKey, std::vector<double>, LessThan >& rmdCutCellEdge,
01267                                      std::vector<int>& rvnInsideCell, bool isCornerExterior)
01268 {
01269   int i, ii, jj, kk, iHex;
01270   for (i = 0; i < 3; i++) {
01271     boxMin[i] = m_origin_coords[i];
01272     boxMax[i] = m_origin_coords[i] + m_dIntervalSize[i]*m_nDiv[i];
01273     nDiv[i] = m_nDiv[i];
01274   }
01275   
01276   if (!get_inside_hex(rvnInsideCell)) return false;
01277 
01278   // get cut-cell fractions
01279   std::map<int, CutFraction>::iterator iter = m_mdCutFraction.begin();
01280   std::map<int, CutFraction>::iterator end_iter = m_mdCutFraction.end();
01281   
01282   for (; iter != end_iter; iter++) { // for each cut-cell
01283     // get i, j, k index from handle
01284     iHex = iter->first;
01285     ii = (iHex%(m_nDiv[0]*m_nDiv[1]))%m_nDiv[0];
01286     jj = (iHex%(m_nDiv[0]*m_nDiv[1]))/m_nDiv[0];
01287     kk = iHex/m_nDiv[0]/m_nDiv[1];
01288 
01289     for (i = 0; i < 3; i++) {
01290       std::vector<double> fractions(iter->second.fraction[i]);
01291       CutCellSurfEdgeKey edgeKey(ii, jj, kk, i);
01292       rmdCutCellEdge[edgeKey] = fractions;
01293     }
01294   }
01295 
01296   if (debug_ebmesh) return export_fraction_points(rmdCutCellEdge);
01297  
01298   return true;
01299 }
01300 
01301 bool EBMesher::get_inside_hex(std::vector<int>& rvnInsideCell)
01302 {
01303   int i, err, iHex;
01304   
01305   // get all hexes
01306   std::vector<iBase_EntityHandle> hex_handles;
01307   err = mk_core()->imesh_instance()->getEntities(m_hRootSet, iBase_REGION,
01308                                                  iMesh_HEXAHEDRON, hex_handles);
01309   IBERRCHK(err, "Failed to get hexes.\n");
01310   
01311   // get hex status
01312   int hex_size = hex_handles.size();
01313   /*
01314   //int* hex_status = new int[hex_size];
01315   //int* hex_status;
01316   std::vector<int> hex_status(hex_size);
01317   err = mk_core()->imesh_instance()->getIntArrData(&hex_handles[0], hex_size,
01318                                                    m_elemStatusTag, &hex_status[0]);
01319   */
01320   int error;
01321   int* hex_status = new int[hex_size];
01322   int hex_status_alloc = sizeof(int)*hex_size;
01323   int hex_status_size = 0;
01324   iMesh_getIntArrData(m_mesh, &hex_handles[0],
01325                       hex_size, m_elemStatusTag,
01326                       &hex_status, &hex_status_alloc,
01327                       &hex_status_size, &error);
01328   ERRORRF("Failed to get hex status.\n");
01329 
01330   // get inside and boundary hexes
01331   int nInside = 0;
01332   int nOutside = 0;
01333   int nBoundary = 0;
01334   rvnInsideCell.clear();
01335   for (i = 0; i < hex_size; i++) {
01336     if (hex_status[i] == 0) { // if inside
01337       iHex = moab_instance()->id_from_handle(reinterpret_cast<moab::EntityHandle>
01338                                              (hex_handles[i])) - m_iStartHex;
01339       rvnInsideCell.push_back((iHex%(m_nDiv[0]*m_nDiv[1]))%m_nDiv[0]);
01340       rvnInsideCell.push_back((iHex%(m_nDiv[0]*m_nDiv[1]))/m_nDiv[0]);
01341       rvnInsideCell.push_back(iHex/m_nDiv[0]/m_nDiv[1]);
01342       nInside++;
01343     }
01344     else if (hex_status[i] == 1) nOutside++;
01345     else if (hex_status[i] == 2) nBoundary++;
01346     else ERRORRF("Element status should be one of inside/outside/boundary.\n"); 
01347   }
01348   std::cout << "# of inside, outside, boundary elem: " << nInside
01349             << ", " << nOutside << ", " << nBoundary << std::endl;
01350 
01351   delete [] hex_status;
01352   return true;
01353 }
01354 
01355 bool EBMesher::export_fraction_edges(std::map< CutCellSurfEdgeKey, std::vector<double>, LessThan >& mdCutCellSurfEdge)
01356 {
01357   // export fractions as edge
01358   double curPnt[3], ePnt[6];
01359   std::vector<iBase_EntityHandle> edge_handles;
01360   std::map< CutCellSurfEdgeKey, std::vector<double>, LessThan >::iterator itr = mdCutCellSurfEdge.begin();
01361   std::map< CutCellSurfEdgeKey, std::vector<double>, LessThan >::iterator e_itr = mdCutCellSurfEdge.end();
01362   for (; itr != e_itr; itr++) {
01363     curPnt[0] = m_origin_coords[0] + itr->first.i*m_dIntervalSize[0];
01364     curPnt[1] = m_origin_coords[1] + itr->first.j*m_dIntervalSize[1];
01365     curPnt[2] = m_origin_coords[2] + itr->first.k*m_dIntervalSize[2];
01366     std::vector<double> edges = itr->second;
01367     
01368     if (itr->first.l == 0) {
01369       if (edges[0] > 0. && edges[0] < 1.) {
01370         ePnt[0] = curPnt[0];
01371         ePnt[1] = curPnt[1];
01372         ePnt[2] = curPnt[2];
01373         ePnt[3] = ePnt[0];
01374         ePnt[4] = ePnt[1] + edges[0]*m_dIntervalSize[1];
01375         ePnt[5] = ePnt[2];
01376         if (!make_edge(ePnt, edge_handles)) return false;
01377       }
01378       if (edges[1] > 0. && edges[1] < 1.) {
01379         ePnt[0] = curPnt[0];
01380         ePnt[1] = curPnt[1] + m_dIntervalSize[1];
01381         ePnt[2] = curPnt[2];
01382         ePnt[3] = ePnt[0];
01383         ePnt[4] = ePnt[1];
01384         ePnt[5] = ePnt[2] + edges[1]*m_dIntervalSize[2];
01385         if (!make_edge(ePnt, edge_handles)) return false;
01386       }
01387       if (edges[2] > 0. && edges[2] < 1.) {
01388         ePnt[0] = curPnt[0];
01389         ePnt[1] = curPnt[1];
01390         ePnt[2] = curPnt[2] + m_dIntervalSize[2];
01391         ePnt[3] = ePnt[0];
01392         ePnt[4] = ePnt[1] + edges[2]*m_dIntervalSize[1];
01393         ePnt[5] = ePnt[2];
01394         if (!make_edge(ePnt, edge_handles)) return false;
01395       }
01396       if (edges[3] > 0. && edges[3] < 1.) {
01397         ePnt[0] = curPnt[0];
01398         ePnt[1] = curPnt[1];
01399         ePnt[2] = curPnt[2];
01400         ePnt[3] = ePnt[0];
01401         ePnt[4] = ePnt[1];
01402         ePnt[5] = ePnt[2] + edges[3]*m_dIntervalSize[2];
01403         if (!make_edge(ePnt, edge_handles)) return false;
01404       }
01405     }
01406     if (itr->first.l == 1) {
01407       if (edges[0] > 0. && edges[0] < 1.) {
01408         ePnt[0] = curPnt[0];
01409         ePnt[1] = curPnt[1];
01410         ePnt[2] = curPnt[2];
01411         ePnt[3] = ePnt[0] + edges[0]*m_dIntervalSize[0];
01412         ePnt[4] = ePnt[1];
01413         ePnt[5] = ePnt[2];
01414         if (!make_edge(ePnt, edge_handles)) return false;
01415       }
01416       if (edges[1] > 0. && edges[1] < 1.) {
01417         ePnt[0] = curPnt[0] + m_dIntervalSize[0];
01418         ePnt[1] = curPnt[1];
01419         ePnt[2] = curPnt[2];
01420         ePnt[3] = ePnt[0];
01421         ePnt[4] = ePnt[1];
01422         ePnt[5] = ePnt[2] + edges[1]*m_dIntervalSize[2];
01423         if (!make_edge(ePnt, edge_handles)) return false;
01424       }
01425       if (edges[2] > 0. && edges[2] < 1.) {
01426         ePnt[0] = curPnt[0];
01427         ePnt[1] = curPnt[1];
01428         ePnt[2] = curPnt[2] + m_dIntervalSize[2];
01429         ePnt[3] = ePnt[0] + edges[2]*m_dIntervalSize[0];
01430         ePnt[4] = ePnt[1];
01431         ePnt[5] = ePnt[2];
01432         if (!make_edge(ePnt, edge_handles)) return false;
01433       }
01434       if (edges[3] > 0. && edges[3] < 1.) {
01435         ePnt[0] = curPnt[0];
01436         ePnt[1] = curPnt[1];
01437         ePnt[2] = curPnt[2];
01438         ePnt[3] = ePnt[0];
01439         ePnt[4] = ePnt[1];
01440         ePnt[5] = ePnt[2] + edges[3]*m_dIntervalSize[2];
01441         if (!make_edge(ePnt, edge_handles)) return false;
01442       }
01443     }
01444     if (itr->first.l == 2) {
01445       if (edges[0] > 0. && edges[0] < 1.) {
01446         ePnt[0] = curPnt[0];
01447         ePnt[1] = curPnt[1];
01448         ePnt[2] = curPnt[2];
01449         ePnt[3] = ePnt[0] + edges[0]*m_dIntervalSize[0];
01450         ePnt[4] = ePnt[1];
01451         ePnt[5] = ePnt[2];
01452         if (!make_edge(ePnt, edge_handles)) return false;
01453       }
01454       if (edges[1] > 0. && edges[1] < 1.) {
01455         ePnt[0] = curPnt[0] + m_dIntervalSize[0];
01456         ePnt[1] = curPnt[1];
01457         ePnt[2] = curPnt[2];
01458         ePnt[3] = ePnt[0];
01459         ePnt[4] = ePnt[1] + edges[1]*m_dIntervalSize[1];
01460         ePnt[5] = ePnt[2];
01461         if (!make_edge(ePnt, edge_handles)) return false;
01462       }
01463       if (edges[2] > 0. && edges[2] < 1.) {
01464         ePnt[0] = curPnt[0];
01465         ePnt[1] = curPnt[1] + m_dIntervalSize[2];
01466         ePnt[2] = curPnt[2];
01467         ePnt[3] = ePnt[0] + edges[2]*m_dIntervalSize[0];
01468         ePnt[4] = ePnt[1];
01469         ePnt[5] = ePnt[2];
01470         if (!make_edge(ePnt, edge_handles)) return false;
01471       }
01472       if (edges[3] > 0. && edges[3] < 1.) {
01473         ePnt[0] = curPnt[0];
01474         ePnt[1] = curPnt[1];
01475         ePnt[2] = curPnt[2];
01476         ePnt[3] = ePnt[0];
01477         ePnt[4] = ePnt[1] + edges[3]*m_dIntervalSize[1];
01478         ePnt[5] = ePnt[2];
01479         if (!make_edge(ePnt, edge_handles)) return false;
01480       }
01481     }
01482   }
01483 
01484   int is_list = 1;
01485   iBase_EntitySetHandle set;
01486   iBase_ErrorType err;
01487   err = mk_core()->imesh_instance()->createEntSet(is_list, set);
01488   IBERRCHK(err, "Couldn't create set.");
01489   
01490   err = mk_core()->imesh_instance()->addEntArrToSet(&edge_handles[0],
01491                                                     edge_handles.size(), set);
01492   IBERRCHK(err, "Couldn't add edges to set.");
01493   
01494   moab::ErrorCode rval = moab_instance()->write_mesh("edges.vtk",
01495                                                      (const moab::EntityHandle*) &set, 1);
01496   MBERRCHK(rval, mk_core()->moab_instance());
01497 
01498   return true;
01499 }
01500 
01501 bool EBMesher::export_fraction_points(std::map< CutCellSurfEdgeKey, std::vector<double>, LessThan >& mdCutCellEdge)
01502 {
01503   // export fractions as edge
01504   int i, j, dir, nFrc;
01505   iBase_ErrorType err;
01506   double curPnt[3], fracPnt[3], frac;
01507   iBase_EntityHandle v_handle;
01508   std::vector<iBase_EntityHandle> vertex_handles;
01509   std::map< CutCellSurfEdgeKey, std::vector<double>, LessThan >::iterator itr = mdCutCellEdge.begin();
01510   std::map< CutCellSurfEdgeKey, std::vector<double>, LessThan >::iterator e_itr = mdCutCellEdge.end();
01511   for (; itr != e_itr; itr++) {
01512     curPnt[0] = m_origin_coords[0] + itr->first.i*m_dIntervalSize[0];
01513     curPnt[1] = m_origin_coords[1] + itr->first.j*m_dIntervalSize[1];
01514     curPnt[2] = m_origin_coords[2] + itr->first.k*m_dIntervalSize[2];
01515     dir = itr->first.l;
01516     nFrc = itr->second.size();
01517     
01518     for (i = 0; i < nFrc; i++) {
01519       frac = itr->second[i];
01520       if (frac > 0. && frac < 1.) {
01521         for (j = 0; j < 3; j++) {
01522           if (j == dir) fracPnt[j] = curPnt[j] + frac*m_dIntervalSize[j];
01523           else fracPnt[j] = curPnt[j];
01524         }
01525         err = mk_core()->imesh_instance()->createVtx(fracPnt[0], fracPnt[1],
01526                                                      fracPnt[2], v_handle);
01527         IBERRCHK(err, "Couldn't create vertex.");
01528         vertex_handles.push_back(v_handle);
01529       }
01530     }
01531   }
01532     
01533   int is_list = 1;
01534   moab::ErrorCode result;
01535   iBase_EntitySetHandle set;
01536   err = mk_core()->imesh_instance()->createEntSet(is_list, set);
01537   IBERRCHK(err, "Couldn't create set.");
01538   
01539   err = mk_core()->imesh_instance()->addEntArrToSet(&vertex_handles[0],
01540                                                     vertex_handles.size(), set);
01541   IBERRCHK(err, "Couldn't add vertices to set.");
01542   
01543   result = moab_instance()->write_mesh("frac_vertices.vtk",
01544                                        (const moab::EntityHandle*) &set, 1);
01545   if (MB_SUCCESS != result) {
01546     std::cerr << "Failed to write fraction vertices." << std::endl;
01547     return false;
01548   }
01549 
01550   return true;
01551 }
01552 
01553 bool EBMesher::make_edge(double ePnt[6], std::vector<iBase_EntityHandle>& edge_handles)
01554 {
01555   iBase_ErrorType err;
01556   iBase_EntityHandle vertex_handle[2], edge_handle;
01557   iBase_EntityHandle* pVertexHandle = &vertex_handle[0];
01558   err = mk_core()->imesh_instance()->createVtxArr(2, iBase_INTERLEAVED,
01559                                                   ePnt, pVertexHandle);
01560   IBERRCHK(err, "Failed to create vertices.\n");
01561 
01562   err = mk_core()->imesh_instance()->createEnt(iMesh_LINE_SEGMENT,
01563                                                &vertex_handle[0], 2,
01564                                                edge_handle);
01565   IBERRCHK(err, "Failed to create edge.\n");
01566 
01567   edge_handles.push_back(edge_handle);
01568 
01569   return true;
01570 }
01571 
01572 double EBMesher::get_edge_fraction(int idHex, int dir)
01573 {
01574   std::map<int, CutFraction>::iterator end_iter = m_mdCutFraction.end();
01575   std::map<int, CutFraction>::iterator iter = m_mdCutFraction.find(idHex);
01576   if (iter != end_iter && iter->second.fraction[dir].size() > 0) {
01577     double frac = iter->second.fraction[dir][0];
01578     if (frac < 0.) frac *= -1.;
01579     return frac;
01580   }
01581   else return -1.;
01582 }
01583 #endif
01584 
01585 double EBMesher::get_uncut_edge_fraction(int i, int j, int k, int dir)
01586 {
01587   int iEdge;
01588 
01589   if (dir == 0) {
01590     if (j == m_nDiv[1] || k == m_nDiv[2]) return 0.; // return outside
01591     iEdge = k*m_nDiv[0]*m_nDiv[1] + j*m_nDiv[0] + i;
01592   }
01593   else if (dir == 1) {
01594     if (i == m_nDiv[0] || k == m_nDiv[2]) return 0.; // return outside
01595     iEdge = i*m_nDiv[1]*m_nDiv[2] + k*m_nDiv[1] + j;
01596   }
01597   else if (dir == 2) {
01598     if (i == m_nDiv[0] || j == m_nDiv[1]) return 0.; // return outside
01599     iEdge = j*m_nDiv[0]*m_nDiv[2] + i*m_nDiv[2] + k;
01600   }
01601   else return -1.;
01602 
01603   EdgeStatus edgeStatus = m_vnEdgeStatus[dir][iEdge];
01604   if (edgeStatus == INSIDE) return 1.;
01605   else if (edgeStatus == OUTSIDE) return 0.;
01606   else return -1.;
01607 }
01608 
01609 #ifdef HAVE_MOAB
01610 bool EBMesher::move_ray(int& nIntersect, double* startPnt, double* endPnt,
01611                       double tol, int dir, bool bSpecialCase)
01612 {
01613   //int i, nIteration;
01614   int i;
01615   bool bMove = true;
01616 
01617   if (bSpecialCase) m_iOverlap = 0;
01618 
01619   while (bMove) {
01620     if (m_nIteration > 10) {
01621       if (bSpecialCase) return true; // special case
01622       else if (m_bUseGeom) { // shared/overlapped, faceting case
01623         m_mhOverlappedSurf[m_iOverlap] = 0;
01624         m_mhOverlappedSurf[m_iOverlap + 1] = 0;
01625         return true;
01626       }
01627       else {
01628         return false;
01629       }
01630     }
01631 
01632     for (i = 0; i < 3; i++) {
01633       if (i != dir) {
01634         startPnt[i] += tol;
01635         endPnt[i] += tol;
01636       }
01637     }
01638 
01639     MBCartVect ray(endPnt[0] - startPnt[0], endPnt[1] - startPnt[1], endPnt[2] - startPnt[2]);
01640     double rayLength = ray.length();
01641     moab::ErrorCode rVal;
01642     ray.normalize();
01643     m_vIntersection.clear();
01644     m_vhInterSurf.clear();
01645     m_vhInterFacet.clear();
01646     
01647     std::vector<double> temp_intersects;
01648     if (m_bUseGeom) {
01649       rVal = m_hObbTree->ray_intersect_sets(temp_intersects, m_vhInterSurf,
01650                                             m_vhInterFacet, m_hTreeRoot, tol,
01651                                             -1, startPnt, ray.array(), &rayLength);
01652     }
01653     else { // facet input
01654       std::vector<moab::EntityHandle> dum_facets_out;
01655       rVal = m_hObbTree->ray_intersect_triangles(temp_intersects, dum_facets_out,
01656                                                  m_hTreeRoot, tol,
01657                                                  startPnt, ray.array(), &rayLength);
01658       m_vhInterSurf.resize(temp_intersects.size());
01659     }
01660 
01661     if (MB_SUCCESS != rVal) {
01662       std::cerr << "Failed : ray-triangle intersection." << std::endl;
01663       return false;
01664     }
01665 
01666     nIntersect = temp_intersects.size();
01667     m_vIntersection.resize(nIntersect);
01668     for (i = 0; i < nIntersect; i++) {
01669       IntersectDist temp_inter_dist(temp_intersects[i], i);
01670       m_vIntersection[i] = temp_inter_dist;
01671     }
01672     std::sort(m_vIntersection.begin(), m_vIntersection.end(), less_intersect);
01673     bMove = is_ray_move_and_set_overlap_surf(bSpecialCase);
01674     m_nIteration++;
01675   }
01676 
01677   std::cout << "ray is moved successfully." << std::endl;
01678 
01679   return true;
01680 }
01681 #endif
01682 
01683 bool EBMesher::is_ray_move_and_set_overlap_surf(bool& bSpecialCase)
01684 {
01685   int nInter = m_vIntersection.size() - 1;
01686 
01687   while (m_iOverlap < nInter) {
01688     if (m_vIntersection[m_iOverlap + 1].distance - m_vIntersection[m_iOverlap].distance < 1e-7) {
01689       if (m_bUseGeom) {
01690         moab::EntityHandle h1 = m_vhInterSurf[m_vIntersection[m_iOverlap].index];
01691         moab::EntityHandle h2 = m_vhInterSurf[m_vIntersection[m_iOverlap + 1].index];
01692         
01693         if (h1 == h2) { // remove too close case
01694           bSpecialCase = false;
01695           return true;
01696         }
01697         else if (m_nIteration < 10) { // when ray intesect shared edge by 2 triangles
01698           bSpecialCase = true;
01699           return true;
01700         }
01701         else { // overlapped surfaces
01702           m_mhOverlappedSurf[h1] = 0;
01703           m_mhOverlappedSurf[h2] = 0;
01704           m_nIteration = 0;
01705           m_iOverlap++;
01706         }
01707       }
01708       else {
01709         if (m_nIteration < 10) { // when ray intesect shared edge by 2 triangles
01710           bSpecialCase = true;
01711           return true;
01712         }
01713         else { // overlapped surfaces
01714           //bSpecialCase = false;
01715           //m_nIteration = 0;
01716           //m_iOverlap++;
01717           m_vIntersection.erase(m_vIntersection.begin() + m_iOverlap + 1);
01718           nInter = m_vIntersection.size();
01719           m_vhInterSurf.resize(nInter);
01720           //m_nIteration = 0;
01721         }
01722       }
01723     }
01724     else m_iOverlap++;
01725   }
01726 
01727   return false;
01728 }
01729 
01730 void EBMesher::remove_intersection_duplicates()
01731 {
01732   int ind = 0;
01733   int nInter = m_vIntersection.size() - 1;
01734 
01735   while (ind < nInter) {
01736     if (m_vIntersection[ind + 1].distance - m_vIntersection[ind].distance < 1e-7) {
01737       moab::EntityHandle h1 = m_vhInterSurf[m_vIntersection[ind].index];
01738       moab::EntityHandle h2 = m_vhInterSurf[m_vIntersection[ind + 1].index];
01739       
01740       if (h1 != h2) { // overlapped/shared surfaces
01741         std::vector<iBase_EntitySetHandle> parents_out1, parents_out2;
01742         int err = mk_core()->imesh_instance()->getPrnts(reinterpret_cast<iBase_EntitySetHandle> (h1), 1, parents_out1);
01743         IBERRCHK(err, "Failed to get number of surface parents.\n");
01744         err = mk_core()->imesh_instance()->getPrnts(reinterpret_cast<iBase_EntitySetHandle> (h2), 1, parents_out2);
01745         IBERRCHK(err, "Failed to get number of surface parents.\n");
01746         if (parents_out1.size() == 1 && parents_out2.size() == 1) {
01747           if (parents_out1[0] != parents_out2[0]) { // parent volues are also different
01748             m_mhOverlappedSurf[h1] = 0;
01749             m_mhOverlappedSurf[h2] = 0;
01750           }
01751         }
01752       }
01753       m_vIntersection.erase(m_vIntersection.begin() + ind + 1);
01754       nInter--;
01755     }
01756     else ind++;
01757   }
01758 }
01759 
01760 bool EBMesher::get_volume_fraction(int vol_frac_div)
01761 {
01762   std::cout << "starting get_volume_fraction." << std::endl;
01763   int i, j, k, l, n, iHex, dir, nIntersect, rayIndex[3], index[3],
01764     otherDir1, otherDir2, err, nParent;
01765   (void) otherDir1;
01766   (void) otherDir2;
01767   double tolerance = 1e-12, dDistance, elem_origin[3],
01768     elem_interval_size[3], startPnt[3], endPnt[3], rayMaxEnd[3];
01769   moab::ErrorCode rval;
01770   bool bOverlapSecond, bClosed;
01771   std::vector<iBase_EntityHandle> edge_handles;
01772 
01773   double dTotEdgeElem = 0.;
01774   for (i = 0; i < 3; i++) {
01775     rayMaxEnd[i] = m_origin_coords[i] + m_nDiv[i]*m_dIntervalSize[i];
01776     dTotEdgeElem += m_dIntervalSize[i]*(vol_frac_div + 1)*(vol_frac_div + 1);
01777   }
01778 
01779   // get all hexes
01780   std::vector<iBase_EntityHandle> hex_handles;
01781   err = mk_core()->imesh_instance()->getEntities(m_hRootSet, iBase_REGION,
01782                                                  iMesh_HEXAHEDRON, hex_handles);
01783   IBERRCHK(err, "Failed to get hexes.\n");
01784 
01785   int hex_size = hex_handles.size();
01786   /*
01787   std::vector<int> hex_status(hex_size);
01788   //int* hex_status = NULL;
01789   err = mk_core()->imesh_instance()->getIntArrData(&hex_handles[0], hex_size,
01790                                                    m_elemStatusTag, &hex_status[0]);
01791   */
01792   int error;
01793   std::vector<int> frac_length;
01794   int* hex_status = new int[hex_size];
01795   int hex_status_alloc = sizeof(int)*hex_size;
01796   int hex_status_size = 0;
01797   iMesh_getIntArrData(m_mesh, &hex_handles[0],
01798                       hex_size, m_elemStatusTag,
01799                       &hex_status, &hex_status_alloc,
01800                       &hex_status_size, &error);
01801   ERRORRF("Failed to get hex status.\n");
01802 
01803   for (n = 0; n < hex_size; n++) {
01804     if (hex_status[n] == 2) { // just boundary
01805       std::map<moab::EntityHandle, VolFrac> vol_fraction;
01806       std::map<moab::EntityHandle, VolFrac>::iterator vf_iter;
01807       std::map<moab::EntityHandle, VolFrac>::iterator vf_end_iter;
01808       iHex = moab_instance()->id_from_handle(reinterpret_cast<moab::EntityHandle>
01809                                              (hex_handles[n])) - m_iStartHex;
01810       index[0] = (iHex%(m_nDiv[0]*m_nDiv[1]))%m_nDiv[0];
01811       index[1] = (iHex%(m_nDiv[0]*m_nDiv[1]))/m_nDiv[0];
01812       index[2] = iHex/m_nDiv[0]/m_nDiv[1];
01813       
01814       for (i = 0; i < 3; i++) {
01815         elem_origin[i] = m_origin_coords[i] + index[i]*m_dIntervalSize[i];
01816         elem_interval_size[i] = m_dIntervalSize[i]/vol_frac_div;
01817       }
01818       
01819       for (dir = 0; dir < 3; dir++) { // x, y, z directions
01820         otherDir1 = (dir + 1)%3;
01821         otherDir2 = (dir + 2)%3;
01822         
01823         for (j = 0; j < vol_frac_div + 1; j++) {
01824           for (i = 0; i < vol_frac_div + 1; i++) {
01825             // get ray start and end points
01826             if (dir == 0) { // x coordinate ray
01827               rayIndex[0] = 0;
01828               rayIndex[1] = i;
01829               rayIndex[2] = j;
01830             }
01831             else if (dir == 1) { // y coordinate ray
01832               rayIndex[0] = j;
01833               rayIndex[1] = 0;
01834               rayIndex[2] = i;
01835             }
01836             else if (dir == 2) { // z coordinate ray
01837               rayIndex[0] = i;
01838               rayIndex[1] = j;
01839               rayIndex[2] = 0;
01840             }
01841             else IBERRCHK(iBase_FAILURE, "Ray direction should be from 0 to 2.");
01842             
01843             for (k = 0; k < 3; k++) {
01844               if (k == dir) {
01845                 startPnt[k] = elem_origin[k];
01846                 endPnt[k] = startPnt[k] + m_dIntervalSize[k];
01847               }
01848               else {
01849                 startPnt[k] = elem_origin[k] + rayIndex[k]*elem_interval_size[k];
01850                 endPnt[k] = startPnt[k];
01851               }
01852             }
01853             
01854             // ray-tracing
01855             if (!fire_ray(nIntersect, startPnt, endPnt,
01856                           tolerance, dir, m_dIntervalSize[dir])) return iBase_FAILURE;
01857             
01858             if (nIntersect > 0) { // ray is intersected
01859               bOverlapSecond = false;
01860               bClosed = true;
01861               for (k = 0; k < nIntersect; k++) {
01862                 std::vector<moab::EntityHandle> parents;
01863                 //MBRange parents;
01864                 rval = moab_instance()->get_parent_meshsets(m_vhInterSurf[m_vIntersection[k].index],
01865                                                             parents);
01866                 if (rval != MB_SUCCESS) {
01867                   std::cerr << "Couldn't get parents." << std::endl;
01868                   return false;
01869                 }
01870 
01871                 nParent = parents.size();
01872                 dDistance = m_vIntersection[k].distance;
01873                 
01874                 if (is_shared_overlapped_surf(k)) {
01875                   if (nParent == 2) { // shared surface
01876                     for (l = 0; l < 2; l++) {
01877                       if (l == 1) {
01878                         dDistance *= -1.;
01879                         bClosed = false;
01880                       }
01881                       else bClosed = true;
01882 
01883                       vf_iter = vol_fraction.find(parents[l]);
01884                       if (vf_iter == vol_fraction.end()) {
01885                         VolFrac temp_vf(dDistance, bClosed);
01886                         vol_fraction[parents[l]] = temp_vf;
01887                         //std::cout << "iHex=" << iHex << ", vh="
01888                         //        << parents[l] << ", dir=" << dir << ", dDistance1="
01889                         //        << dDistance << ", vol="
01890                         //        << temp_vf.vol << std::endl;
01891                       }
01892                       else {
01893                         vf_iter->second.vol += dDistance;
01894                         vf_iter->second.closed = bClosed;
01895                         //std::cout << "iHex=" << iHex << ", vh="
01896                         //        << vf_iter->first << ", dir=" << dir << ", dDistance1="
01897                         //                         << dDistance << ", vol="
01898                         //        << vf_iter->second.vol << std::endl;
01899                       }
01900                     }
01901                   }
01902                   else if (nParent == 1) { // overlapped surface
01903                     if (bOverlapSecond) { // second intersection
01904                       /*
01905                       for (int m = 0; m < 3; m++) {
01906                         ePnt[m] = startPnt[m];
01907                       }
01908                       ePnt[dir] += dDistance;
01909                       */
01910                       dDistance *= -1.;
01911                       bClosed = false;
01912                       bOverlapSecond = false;
01913                     }
01914                     else {
01915                       /*
01916                       // make edge
01917                       for (int m = 0; m < 3; m++) {
01918                         if (bClosed) ePnt[m] = startPnt[m];
01919                         ePnt[m + 3] = ePnt[m];
01920                       }
01921                       ePnt[dir + 3] += dDistance;
01922                       if (!make_edge(ePnt, edge_handles)) return iBase_FAILURE;
01923                       */
01924                       bOverlapSecond = true;// first intersection
01925                       bClosed = true;
01926                     }
01927                     
01928                     vf_iter = vol_fraction.find(parents[0]);
01929                     if (vf_iter == vol_fraction.end()) {
01930                       VolFrac temp_vf(dDistance, bClosed);
01931                       vol_fraction[parents[0]] = temp_vf;
01932                       //std::cout << "iHex=" << iHex << ", vh="
01933                       //        << parents[0] << ", dDistance2="
01934                       //        << dDistance << ", vol="
01935                       //        << temp_vf.vol << std::endl;
01936                     }
01937                     else {
01938                       vf_iter->second.vol += dDistance;
01939                       vf_iter->second.closed = bClosed;
01940                       //std::cout << "iHex=" << iHex << ", vh="
01941                       //        << vf_iter->first << ", dir=" << dir << ", dDistance2="
01942                       //        << dDistance << ", vol="
01943                       //        << vf_iter->second.vol << std::endl;
01944                     }
01945                   }
01946                   else return iBase_FAILURE;
01947                 }
01948                 else { // normal case
01949                   if (nParent != 1) return iBase_FAILURE;
01950 
01951                   if (!is_same_direct_to_ray(k, dir)) {
01952                     dDistance *= -1.; // outside
01953                     bClosed = false;
01954                   }
01955                   else bClosed = true;
01956                   
01957                   vf_iter = vol_fraction.find(parents[0]);
01958                   if (vf_iter == vol_fraction.end()) {
01959                     VolFrac temp_vf(dDistance, bClosed);
01960                     vol_fraction[parents[0]] = temp_vf;
01961                     //std::cout << "iHex=" << iHex << ", vh="
01962                     //        << parents[0] << ", dir=" << dir << ", dDistance3="
01963                     //        << dDistance << ", vol="
01964                     //        << temp_vf.vol << std::endl;
01965                   }
01966                   else {
01967                     vf_iter->second.vol += dDistance;
01968                     vf_iter->second.closed = bClosed;
01969                     //std::cout << "iHex=" << iHex << ", vh="
01970                     //        << vf_iter->first << ", dir=" << dir << ", dDistance3="
01971                     //        << dDistance << ", vol="
01972                     //        << vf_iter->second.vol << std::endl;
01973                   }
01974                 }
01975               }
01976 
01977               // if fraction is not closed, add interval size to close
01978               vf_iter = vol_fraction.begin();
01979               vf_end_iter = vol_fraction.end();
01980               for (; vf_iter != vf_end_iter; vf_iter++) {
01981                 if (!vf_iter->second.closed) {
01982                   vf_iter->second.vol += m_dIntervalSize[dir];
01983                   vf_iter->second.closed = true;
01984                   /*
01985                   for (int m = 0; m < 3; m++) {
01986                     ePnt[m + 3] = startPnt[m];
01987                   }
01988                   ePnt[dir + 3] += m_dIntervalSize[dir];
01989                   if (!make_edge(ePnt, edge_handles)) return iBase_FAILURE;
01990                   */
01991                   //std::cout << "iHex=" << iHex << ", vh="
01992                   //        << vf_iter->first << ", dir=" << dir << ", dDistance4="
01993                   //        << m_dIntervalSize[dir] << ", vol="
01994                   //        << vf_iter->second.vol << std::endl;
01995                 }
01996               }
01997             }
01998             else { // decide if it is fully inside
01999               if (!fire_ray(nIntersect, startPnt, rayMaxEnd,
02000                             tolerance, dir, m_nDiv[dir]*m_dIntervalSize[dir])) return iBase_FAILURE;
02001               
02002               if (nIntersect > 0) { // fully inside
02003                 if (is_shared_overlapped_surf(0) || // shared or overlapped
02004                     is_same_direct_to_ray(0, dir)) { // other inside case
02005                   MBRange parents;
02006                   rval = moab_instance()->get_parent_meshsets(m_vhInterSurf[m_vIntersection[0].index],
02007                                                               parents);
02008                   if (rval != MB_SUCCESS) {
02009                     std::cerr << "Couldn't get parents." << std::endl;
02010                     return false;
02011                   }
02012 
02013                   moab::EntityHandle parent_entity = parents.pop_front();
02014                   vf_iter = vol_fraction.find(parent_entity);
02015                   if (vf_iter == vf_end_iter) {
02016                     VolFrac temp_vf(m_dIntervalSize[dir], true);
02017                     vol_fraction[parent_entity] = temp_vf;
02018                     //std::cout << "iHex=" << iHex << ", vh="
02019                     //        << parents[0] << ", dir=" << dir << ", dDistance5="
02020                     //                             << dDistance << ", vol="
02021                     //        << temp_vf.vol << std::endl;
02022                   }
02023                   else {
02024                     vf_iter->second.vol += m_dIntervalSize[dir];
02025                     vf_iter->second.closed = bClosed;
02026                     //std::cout << "iHex=" << iHex << ", vh="
02027                     //        << vf_iter->first << ", dir=" << dir << ", dDistance5="
02028                     //                         << dDistance << ", vol="
02029                     //        << vf_iter->second.vol << std::endl;
02030                   }
02031                 }
02032               }
02033             }
02034           }
02035         }
02036       }
02037 
02038       int vol_frac_length = vol_fraction.size();
02039       std::vector<int> vol_frac_id(vol_frac_length);
02040       std::vector<double> vol_frac(vol_frac_length);
02041       int vol_frac_id_size = vol_frac_length*sizeof(int);
02042       int vol_frac_size = vol_frac_length*sizeof(double);
02043       vf_iter = vol_fraction.begin();
02044       vf_end_iter = vol_fraction.end();
02045       for (int m = 0; vf_iter != vf_end_iter; vf_iter++, m++) {
02046         vol_frac_id[m] = vf_iter->first;
02047         vol_frac[m] = vf_iter->second.vol/dTotEdgeElem;
02048         //std::cout << "iHex=" << iHex << ", i=" << index[0]
02049         //        << ", j=" << index[1] << ", k=" << index[2]
02050         //        << ", vol_handle=" << vf_iter->first
02051         //        << ", vol=" << vf_iter->second.vol
02052         //        << ", vol_fraction=" << vf_iter->second.vol/dTotEdgeElem
02053         //        << std::endl;
02054       }
02055       const void* vol_frac_ids = &vol_frac_id[0];
02056       const void* vol_fracs = &vol_frac[0];
02057 
02058       // set volume fraction information as tag
02059       rval = moab_instance()->tag_set_data(reinterpret_cast<MBTag> (m_volFracLengthTag),
02060                                            reinterpret_cast<moab::EntityHandle*> (&hex_handles[n]),
02061                                            1, &vol_frac_length);
02062       MBERRCHK(rval, mk_core()->moab_instance());
02063 
02064       rval = moab_instance()->tag_set_by_ptr(reinterpret_cast<MBTag> (m_volFracHandleTag),
02065                                            reinterpret_cast<moab::EntityHandle*> (&hex_handles[n]),
02066                                            1, &vol_frac_ids, &vol_frac_id_size);
02067       MBERRCHK(rval, mk_core()->moab_instance());
02068 
02069       rval = moab_instance()->tag_set_by_ptr(reinterpret_cast<MBTag> (m_volFracTag),
02070                                            reinterpret_cast<moab::EntityHandle*> (&hex_handles[n]),
02071                                            1, &vol_fracs, &vol_frac_size);
02072       MBERRCHK(rval, mk_core()->moab_instance());
02073 
02074       if (debug_ebmesh) {
02075         for (int v = 0; v < vol_frac_length; v++) {
02076           std::cout << "#_boundary_hex_handles=" << hex_handles[n]
02077                     << ",vol_frac_handle[" << v << "]=" << vol_frac_id[v]
02078                     << ",vol_fracs[" << v << "]=" << vol_frac[v]
02079                     << std::endl;
02080         }
02081       }
02082     }
02083   }  
02084 
02085   std::cout << "end get_volume_fraction." << std::endl;
02086   delete [] hex_status;
02087 
02088   return true;
02089 }
02090 
02091 #ifdef HAVE_MOAB
02092 bool EBMesher::is_same_direct_to_ray(int i, int dir)
02093 {
02094   MBCartVect coords[3], normal(0.0), ray_dir(rayDir[dir]);
02095   const moab::EntityHandle *conn;
02096   int len;
02097 
02098   // get triangle normal vector
02099   moab::ErrorCode rval = moab_instance()->get_connectivity(m_vhInterFacet[m_vIntersection[i].index],
02100                                                            conn, len);
02101   assert(MB_SUCCESS == rval && 3 == len);
02102   
02103   rval = moab_instance()->get_coords(conn, 3, coords[0].array());
02104   assert(MB_SUCCESS == rval);
02105 
02106   coords[1] -= coords[0];
02107   coords[2] -= coords[0];
02108   normal += coords[1] * coords[2];
02109   normal.normalize();
02110 
02111   return angle(normal, ray_dir) < .5*PI;
02112 }
02113 
02114 void EBMesher::set_obb_tree_box_dimension()
02115 {
02116   std::cout << "starting to construct obb tree." << std::endl;
02117   moab::ErrorCode rval = m_GeomTopoTool->construct_obb_trees(m_bUseWholeGeom);
02118   MBERRCHK(rval, mk_core()->moab_instance());
02119 
02120   m_hObbTree = m_GeomTopoTool->obb_tree();
02121   m_hTreeRoot = m_GeomTopoTool->get_one_vol_root();
02122 
02123   moab::CartVect box_center, box_axis1, box_axis2, box_axis3;
02124   for (int i = 0; i < 3; i++) {
02125     m_minCoord[i] = HUGE_VAL;
02126     m_maxCoord[i] = 0.;
02127   }
02128   rval = m_hObbTree->box(m_hTreeRoot, box_center.array(),
02129                          box_axis1.array(), box_axis2.array(),
02130                          box_axis3.array());
02131   MBERRCHK(rval, mk_core()->moab_instance());
02132   
02133   // cartesian box corners
02134   moab::CartVect corners[8] = {box_center + box_axis1 + box_axis2 + box_axis3,
02135                                box_center + box_axis1 + box_axis2 - box_axis3,
02136                                box_center + box_axis1 - box_axis2 + box_axis3,
02137                                box_center + box_axis1 - box_axis2 - box_axis3,
02138                                box_center - box_axis1 + box_axis2 + box_axis3,
02139                                box_center - box_axis1 + box_axis2 - box_axis3,
02140                                box_center - box_axis1 - box_axis2 + box_axis3,
02141                                box_center - box_axis1 - box_axis2 - box_axis3};
02142   
02143   // get the max, min cartesian box corners
02144   for (int i = 0; i < 8; i++) {
02145     for (int j = 0; j < 3; j++) {
02146       if (corners[i][j] < m_minCoord[j]) m_minCoord[j] = corners[i][j];
02147       if (corners[i][j] > m_maxCoord[j]) m_maxCoord[j] = corners[i][j];
02148     }
02149   }
02150   std::cout << "finished to construct obb tree." << std::endl;
02151 }
02152 #endif
02153 } // namespace MeshKit
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines