moab
moab::MergeMesh Class Reference

#include <MergeMesh.hpp>

List of all members.

Public Member Functions

 MergeMesh (moab::Interface *mbImpl, bool printErrorIn=true)
virtual ~MergeMesh ()
moab::ErrorCode merge_entities (moab::EntityHandle *elems, int elems_size, const double merge_tol, const int do_merge=true, const int update_sets=false, moab::Tag merge_tag=0, bool do_higher_dim=true)
moab::ErrorCode merge_entities (moab::Range &elems, const double merge_tol, const int do_merge=true, const int update_sets=false, moab::Tag merge_tag=0, bool do_higher_dim=true)
moab::ErrorCode merge_higher_dimensions (moab::Range &elems)
moab::ErrorCode perform_merge (moab::Tag merged_to)

Private Member Functions

moab::ErrorCode find_merged_to (moab::EntityHandle &tree_root, moab::AdaptiveKDTree &tree, moab::Tag merged_to)

Private Attributes

double mergeTol
double mergeTolSq
moab::Tag mergeTag
moab::InterfacembImpl
moab::Tag mbMergeTag
moab::Range deadEnts
bool printError

Detailed Description

Definition at line 11 of file MergeMesh.hpp.


Constructor & Destructor Documentation

moab::MergeMesh::MergeMesh ( moab::Interface mbImpl,
bool  printErrorIn = true 
) [inline]

Definition at line 69 of file MergeMesh.hpp.

    : mbImpl(impl), printError(printErrorIn)
{
}
moab::MergeMesh::~MergeMesh ( ) [inline, virtual]

Definition at line 74 of file MergeMesh.hpp.


Member Function Documentation

Definition at line 127 of file MergeMesh.cpp.

{
  moab::AdaptiveKDTreeIter iter;
  
  // evaluate vertices in this leaf
  moab::Range leaf_range, leaf_range2;
  std::vector<moab::EntityHandle> sorted_leaves;
  std::vector<double> coords;
  std::vector<moab::EntityHandle> merge_tag_val, leaves_out;
  
  moab::ErrorCode result = tree.get_tree_iterator(tree_root, iter);
  if (moab::MB_SUCCESS != result) return result;
  while (result == moab::MB_SUCCESS) {
    sorted_leaves.push_back( iter.handle() );
    result = iter.step();
  }
  if (result != moab::MB_ENTITY_NOT_FOUND)
    return result;
  std::sort( sorted_leaves.begin(), sorted_leaves.end() );
  
  std::vector<moab::EntityHandle>::iterator it;
  for (it = sorted_leaves.begin(); it != sorted_leaves.end(); ++it) {

    leaf_range.clear();
    result = mbImpl->get_entities_by_handle(*it, leaf_range);
    if (moab::MB_SUCCESS != result) return result;
    coords.resize(3*leaf_range.size());
    merge_tag_val.resize(leaf_range.size());
    result = mbImpl->get_coords(leaf_range, &coords[0]);
    if (moab::MB_SUCCESS != result) return result;
    result = mbImpl->tag_get_data(merge_tag, leaf_range, &merge_tag_val[0]);
    if (moab::MB_SUCCESS != result) return result;
    moab::Range::iterator rit;
    unsigned int i;
    bool inleaf_merged, outleaf_merged = false;
    unsigned int lr_size = leaf_range.size();
    
    for (i = 0, rit = leaf_range.begin(); i != lr_size; rit++, i++) {
      if (0 != merge_tag_val[i]) continue;
      moab::CartVect from(&coords[3*i]);
      inleaf_merged = false;

      // check close-by leaves too
      leaves_out.clear();
      result = tree.distance_search(from.array(), mergeTol,
                                    leaves_out, mergeTol, 1.0e-6, NULL, NULL, &tree_root);
      leaf_range2.clear();
      for (std::vector<moab::EntityHandle>::iterator vit = leaves_out.begin();
           vit != leaves_out.end(); vit++) {
        if (*vit > *it) { // if we haven't visited this leaf yet in the outer loop
          result = mbImpl->get_entities_by_handle(*vit, leaf_range2, moab::Interface::UNION);
          if (moab::MB_SUCCESS != result) return result;
        }
      }
      if (!leaf_range2.empty()) {
        coords.resize(3*(lr_size+leaf_range2.size()));
        merge_tag_val.resize(lr_size+leaf_range2.size());
        result = mbImpl->get_coords(leaf_range2, &coords[3*lr_size]);
        if (moab::MB_SUCCESS != result) return result;
        result = mbImpl->tag_get_data(merge_tag, leaf_range2, &merge_tag_val[lr_size]);
        if (moab::MB_SUCCESS != result) return result;
        outleaf_merged = false;
      }

      // check other verts in this leaf
      for (unsigned int j = i+1; j < merge_tag_val.size(); j++) {
        moab::EntityHandle to_ent = j >= lr_size ? leaf_range2[j-lr_size] : 
      leaf_range[j];
        
        if (*rit == to_ent) continue;
        
        if ((from - moab::CartVect(&coords[3*j])).length_squared() < mergeTolSq) {
          merge_tag_val[j] = *rit;
          if (j < lr_size){
        inleaf_merged = true;}
          else{
        outleaf_merged = true;}
          deadEnts.insert(to_ent);
        }

      }
      if (outleaf_merged) {
    result = mbImpl->tag_set_data(merge_tag, leaf_range2, &merge_tag_val[leaf_range.size()]);
        if (moab::MB_SUCCESS != result) return result;
    outleaf_merged = false;
      }
      if (inleaf_merged) {
    result = mbImpl->tag_set_data(merge_tag, leaf_range, &merge_tag_val[0]);
    if (moab::MB_SUCCESS != result) return result;
      }

    }
  }
  return moab::MB_SUCCESS;
}
moab::ErrorCode moab::MergeMesh::merge_entities ( moab::EntityHandle elems,
int  elems_size,
const double  merge_tol,
const int  do_merge = true,
const int  update_sets = false,
moab::Tag  merge_tag = 0,
bool  do_higher_dim = true 
)

Definition at line 18 of file MergeMesh.cpp.

{
  mergeTol = merge_tol;
  mergeTolSq = merge_tol*merge_tol;
  moab::Range tmp_elems;
  tmp_elems.insert( elems, elems + elems_size);
  moab::ErrorCode result = merge_entities(tmp_elems, merge_tol, do_merge, update_sets,
                      (moab::Tag)merge_tag, do_higher_dim);

  return result;
}
moab::ErrorCode moab::MergeMesh::merge_entities ( moab::Range elems,
const double  merge_tol,
const int  do_merge = true,
const int  update_sets = false,
moab::Tag  merge_tag = 0,
bool  do_higher_dim = true 
)

Definition at line 46 of file MergeMesh.cpp.

{
  //If merge_higher_dim is true, do_merge must also be true
  if(merge_higher_dim && !do_merge){
    return moab::MB_FAILURE;
  }

  mergeTol = merge_tol;
  mergeTolSq = merge_tol*merge_tol;

  // get the skin of the entities
  moab::Skinner skinner(mbImpl);
  moab::Range skin_range;
  moab::ErrorCode result = skinner.find_skin(0, elems, 0, skin_range, false, false);
  if (moab::MB_SUCCESS != result) return result;

  // create a tag to mark merged-to entity; reuse tree_root
  moab::EntityHandle tree_root = 0;
  if (0 == merge_tag) {
    result = mbImpl->tag_get_handle("__merge_tag", 1, moab::MB_TYPE_HANDLE, 
                                    mbMergeTag, 
                                    moab::MB_TAG_DENSE|moab::MB_TAG_EXCL,
                                    &tree_root);
    if (moab::MB_SUCCESS != result) return result;
  }
  else mbMergeTag = merge_tag;
  
  // build a kd tree with the vertices
  moab::AdaptiveKDTree kd(mbImpl);
  result = kd.build_tree(skin_range, &tree_root);
  if (moab::MB_SUCCESS != result) return result;

  // find matching vertices, mark them
  result = find_merged_to(tree_root, kd, mbMergeTag);
  if (moab::MB_SUCCESS != result) return result;

  // merge them if requested
  if (do_merge) {
    result = perform_merge(mbMergeTag);
    if (moab::MB_SUCCESS != result) return result;
  }

  if(merge_higher_dim && deadEnts.size() != 0){
    result = merge_higher_dimensions(elems);
    if(moab::MB_SUCCESS != result) return result;
  }
  
  return moab::MB_SUCCESS;
}

Definition at line 227 of file MergeMesh.cpp.

{ 
  Range skinEnts, adj, matches, moreDeadEnts;  moab::ErrorCode result;
  moab::Skinner skinner(mbImpl);
  //Go through each dimension
  for(int dim = 1; dim <3; dim++){
    skinEnts.clear();
    moreDeadEnts.clear();
    result = skinner.find_skin(0, elems, dim, skinEnts, false, false);
    //Go through each skin entity and see if it shares adjacancies with another entity
    for(moab::Range::iterator skinIt = skinEnts.begin(); skinIt != skinEnts.end(); skinIt++){
      adj.clear();
      //Get the adjacencies 1 dimension lower
      result = mbImpl->get_adjacencies(&(*skinIt), 1, dim-1, false, adj);
      if(result != moab::MB_SUCCESS) return result;
      //See what other entities share these adjacencies
      matches.clear();
      result = mbImpl->get_adjacencies(adj, dim, false, matches, moab::Interface::INTERSECT);
      if(result != moab::MB_SUCCESS) return result;
      //If there is more than one entity, then we have some to merge and erase
      if(matches.size() > 1){
    for(moab::Range::iterator matchIt = matches.begin(); matchIt != matches.end(); matchIt++){
      if(*matchIt != *skinIt){
        moreDeadEnts.insert(*matchIt);
        result = mbImpl->merge_entities(*skinIt, *matchIt, false, false);
        if(result != moab::MB_SUCCESS) return result;
        skinEnts.erase(*matchIt);
      }
    }
      }      
    }
    //Delete the entities
    result = mbImpl->delete_entities(moreDeadEnts);
    if(result != moab::MB_SUCCESS)return result;
  }
  return moab::MB_SUCCESS;
}

Definition at line 101 of file MergeMesh.cpp.

{
  moab::ErrorCode result;
  if (deadEnts.size()==0){
    if(printError)std::cout << "\nWarning: Geometries don't have a common face; Nothing to merge" << std::endl;
    return moab::MB_SUCCESS; //nothing to merge carry on with the program
  }
  if  (mbImpl->type_from_handle(*deadEnts.rbegin()) != moab::MBVERTEX) 
    return moab::MB_FAILURE;
  std::vector<moab::EntityHandle> merge_tag_val(deadEnts.size());
  result = mbImpl->tag_get_data(merge_tag, deadEnts, &merge_tag_val[0]);
  if (moab::MB_SUCCESS != result) return result;
  
  moab::Range::iterator rit;
  unsigned int i;
  for (rit = deadEnts.begin(), i = 0; rit != deadEnts.end(); rit++, i++) {
    assert(merge_tag_val[i]);
    result = mbImpl->merge_entities(merge_tag_val[i], *rit, false, false);
    if (moab::MB_SUCCESS != result) {
      return result;
    }
  }
  result = mbImpl->delete_entities(deadEnts);
  return result;
}

Member Data Documentation

Definition at line 63 of file MergeMesh.hpp.

Definition at line 57 of file MergeMesh.hpp.

Definition at line 60 of file MergeMesh.hpp.

Definition at line 49 of file MergeMesh.hpp.

double moab::MergeMesh::mergeTol [private]

Definition at line 47 of file MergeMesh.hpp.

double moab::MergeMesh::mergeTolSq [private]

Definition at line 47 of file MergeMesh.hpp.

Definition at line 66 of file MergeMesh.hpp.


The documentation for this class was generated from the following files:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines