MeshKit
1.0
|
00001 #include "meshkit/MergeMesh.hpp" 00002 00003 #include <algorithm> 00004 #include <cstdlib> 00005 #include <cstring> 00006 #include <functional> 00007 #include <string> 00008 #include <vector> 00009 #include <cassert> 00010 #include <iostream> 00011 00012 #ifdef HAVE_MOAB 00013 #include "MBSkinner.hpp" 00014 #include "MBAdaptiveKDTree.hpp" 00015 #include "MBRange.hpp" 00016 #include "MBCartVect.hpp" 00017 #endif 00018 00019 namespace MeshKit 00020 { 00021 // static registration of this mesh scheme 00022 moab::EntityType MergeMesh_tps[] = { moab::MBVERTEX, 00023 moab::MBEDGE, 00024 moab::MBTRI, 00025 moab::MBHEX, 00026 moab::MBMAXTYPE}; 00027 00028 const moab::EntityType* MergeMesh::output_types() 00029 { return MergeMesh_tps; } 00030 00031 MergeMesh::MergeMesh(MKCore *mkcore, const MEntVector &me_vec) 00032 : MeshScheme(mkcore, me_vec), 00033 imeshImpl(mkcore->imesh_instance()), mbImpl (mkcore->moab_instance()) 00034 { 00035 mergeTol = 1e-4; 00036 updateSets = 0; 00037 doMerge = 1; 00038 mergeTag = NULL; 00039 } 00040 00041 MergeMesh::~MergeMesh() 00042 { 00043 #ifdef HAVE_MOAB 00044 if (mbMergeTag) mbImpl->tag_delete(mbMergeTag); 00045 #endif 00046 } 00047 00048 bool MergeMesh::add_modelent(ModelEnt *model_ent) 00049 { 00050 return MeshOp::add_modelent(model_ent); 00051 } 00052 00053 void MergeMesh::set_merge_params(double merge_tol, int updatesets, 00054 int domerge, iBase_TagHandle merge_tag) 00055 { 00056 mergeTol = merge_tol; 00057 updateSets = updatesets; 00058 doMerge = domerge; 00059 mergeTag = merge_tag; 00060 } 00061 00062 void MergeMesh::setup_this() 00063 { 00064 std::cout << "IN SETUPTHIS MERGEMESH " << std::endl; 00065 00066 } 00067 00068 void MergeMesh::execute_this() 00069 { 00070 std::cout << "IN EXTHIS MERGEMESH " << std::endl; 00071 00072 std::vector<iBase_EntityHandle> ents(mentSelection.size()); 00073 int dim; 00074 for (MEntSelection::iterator mit = mentSelection.begin(); 00075 mit != mentSelection.end(); mit++) { 00076 ModelEnt *me = mit->first; 00077 dim = me->dimension(); 00078 } 00079 00080 if(dim == 3){ 00081 imeshImpl->getEntities(0, iBase_REGION, iMesh_ALL_TOPOLOGIES, 00082 ents); 00083 } 00084 else if (dim == 2){ 00085 imeshImpl->getEntities(0, iBase_FACE, iMesh_ALL_TOPOLOGIES, 00086 ents); 00087 } 00088 merge_entities(&ents[0], ents.size(), mergeTol, doMerge, updateSets, 00089 mergeTag); 00090 } 00091 00092 void MergeMesh::merge_entities(iBase_EntityHandle *elems, 00093 int elems_size, 00094 const double merge_tol, 00095 const int do_merge, 00096 const int update_sets, 00097 iBase_TagHandle merge_tag) 00098 { 00099 mergeTol = merge_tol; 00100 mergeTolSq = merge_tol*merge_tol; 00101 00102 #ifdef HAVE_MOAB 00103 MBRange tmp_elems; 00104 tmp_elems.insert((MBEntityHandle*)elems, (MBEntityHandle*)elems + elems_size); 00105 MBErrorCode result = merge_entities(tmp_elems, do_merge, update_sets, 00106 (MBTag)merge_tag); 00107 if (result != MB_SUCCESS) 00108 throw MKException(iBase_FAILURE, ""); 00109 #else 00110 throw MKException(iBase_NOT_SUPPORTED, ""); 00111 #endif 00112 } 00113 00114 void MergeMesh::perform_merge(iBase_TagHandle merge_tag) 00115 { 00116 #ifdef HAVE_MOAB 00117 // put into a range 00118 MBErrorCode result = perform_merge((MBTag) merge_tag); 00119 if (result != MB_SUCCESS) 00120 throw MKException(iBase_FAILURE, ""); 00121 #else 00122 throw MKException(iBase_NOT_SUPPORTED, ""); 00123 #endif 00124 } 00125 00126 #ifdef HAVE_MOAB 00127 MBErrorCode MergeMesh::merge_entities(MBRange &elems, 00128 const int do_merge, 00129 const int update_sets, 00130 MBTag merge_tag) 00131 { 00132 // get the skin of the entities 00133 MBSkinner skinner(mbImpl); 00134 MBRange skin_range; 00135 MBErrorCode result = skinner.find_skin(0, elems, 0, skin_range); 00136 if (MB_SUCCESS != result) return result; 00137 00138 // create a tag to mark merged-to entity; reuse tree_root 00139 MBEntityHandle tree_root = 0; 00140 if (0 == merge_tag) { 00141 //result = mbImpl->tag_create("__merge_tag", sizeof(MBEntityHandle), 00142 // MB_TAG_DENSE, MB_TYPE_HANDLE, 00143 // mbMergeTag, &tree_root); 00144 result = mbImpl->tag_get_handle("__merge_tag", 1, MB_TYPE_HANDLE, 00145 mbMergeTag, MB_TAG_DENSE|MB_TAG_CREAT, 00146 &tree_root); 00147 if (MB_SUCCESS != result) return result; 00148 } 00149 else mbMergeTag = merge_tag; 00150 00151 // build a kd tree with the vertices 00152 MBAdaptiveKDTree kd(mbImpl); 00153 result = kd.build_tree(skin_range, &tree_root); 00154 if (MB_SUCCESS != result) return result; 00155 00156 // find matching vertices, mark them 00157 result = find_merged_to(kd, tree_root, mbMergeTag); 00158 if (MB_SUCCESS != result) return result; 00159 00160 // merge them if requested 00161 if (do_merge) { 00162 result = perform_merge(mbMergeTag); 00163 if (MB_SUCCESS != result) return result; 00164 } 00165 00166 return MB_SUCCESS; 00167 } 00168 00169 MBErrorCode MergeMesh::perform_merge(MBTag merge_tag) 00170 { 00171 if (deadEnts.size()==0){ 00172 std::cout << "\nWarning: Geometries don't have a common face; Nothing to merge" << std::endl; 00173 return MB_SUCCESS; //nothing to merge carry on with the program 00174 } 00175 if (mbImpl->type_from_handle(*deadEnts.rbegin()) != MBVERTEX) 00176 return MB_FAILURE; 00177 00178 std::vector<MBEntityHandle> merge_tag_val(deadEnts.size()); 00179 MBErrorCode result = mbImpl->tag_get_data(merge_tag, deadEnts, &merge_tag_val[0]); 00180 if (MB_SUCCESS != result) return result; 00181 00182 MBRange::iterator rit; 00183 unsigned int i; 00184 for (rit = deadEnts.begin(), i = 0; rit != deadEnts.end(); rit++, i++) { 00185 assert(merge_tag_val[i]); 00186 result = mbImpl->merge_entities(merge_tag_val[i], *rit, false, false); 00187 if (MB_SUCCESS != result) return result; 00188 } 00189 00190 return mbImpl->delete_entities(deadEnts); 00191 } 00192 00193 MBErrorCode MergeMesh::find_merged_to(MBAdaptiveKDTree & tree, MBEntityHandle &tree_root, MBTag merge_tag) 00194 { 00195 MBAdaptiveKDTreeIter iter; 00196 //MBAdaptiveKDTree tree(mbImpl); 00197 00198 // evaluate vertices in this leaf 00199 MBRange leaf_range, leaf_range2; 00200 std::vector<MBEntityHandle> sorted_leaves; 00201 std::vector<double> coords; 00202 std::vector<MBEntityHandle> merge_tag_val, leaves_out; 00203 00204 MBErrorCode result = tree.get_tree_iterator(tree_root, iter); 00205 if (MB_SUCCESS != result) return result; 00206 while (result == MB_SUCCESS) { 00207 sorted_leaves.push_back( iter.handle() ); 00208 result = iter.step(); 00209 } 00210 if (result != MB_ENTITY_NOT_FOUND) 00211 return result; 00212 std::sort( sorted_leaves.begin(), sorted_leaves.end() ); 00213 00214 std::vector<MBEntityHandle>::iterator it; 00215 for (it = sorted_leaves.begin(); it != sorted_leaves.end(); ++it) { 00216 00217 leaf_range.clear(); 00218 result = mbImpl->get_entities_by_handle(*it, leaf_range); 00219 if (MB_SUCCESS != result) return result; 00220 coords.resize(3*leaf_range.size()); 00221 merge_tag_val.resize(leaf_range.size()); 00222 result = mbImpl->get_coords(leaf_range, &coords[0]); 00223 if (MB_SUCCESS != result) return result; 00224 result = mbImpl->tag_get_data(merge_tag, leaf_range, &merge_tag_val[0]); 00225 if (MB_SUCCESS != result) return result; 00226 MBRange::iterator rit; 00227 unsigned int i; 00228 bool inleaf_merged, outleaf_merged = false; 00229 unsigned int lr_size = leaf_range.size(); 00230 00231 for (i = 0, rit = leaf_range.begin(); i != lr_size; rit++, i++) { 00232 if (0 != merge_tag_val[i]) continue; 00233 MBCartVect from(&coords[3*i]); 00234 inleaf_merged = false; 00235 00236 // check close-by leaves too 00237 leaves_out.clear(); 00238 result = tree.distance_search( from.array(), mergeTol, 00239 leaves_out); 00240 leaf_range2.clear(); 00241 for (std::vector<MBEntityHandle>::iterator vit = leaves_out.begin(); 00242 vit != leaves_out.end(); vit++) { 00243 if (*vit > *it) { // if we haven't visited this leaf yet in the outer loop 00244 result = mbImpl->get_entities_by_handle(*vit, leaf_range2, MBInterface::UNION); 00245 if (MB_SUCCESS != result) return result; 00246 } 00247 } 00248 if (!leaf_range2.empty()) { 00249 coords.resize(3*(lr_size+leaf_range2.size())); 00250 merge_tag_val.resize(lr_size+leaf_range2.size()); 00251 result = mbImpl->get_coords(leaf_range2, &coords[3*lr_size]); 00252 if (MB_SUCCESS != result) return result; 00253 result = mbImpl->tag_get_data(merge_tag, leaf_range2, &merge_tag_val[lr_size]); 00254 if (MB_SUCCESS != result) return result; 00255 outleaf_merged = false; 00256 } 00257 00258 // check other verts in this leaf 00259 for (unsigned int j = i+1; j < merge_tag_val.size(); j++) { 00260 MBEntityHandle to_ent = j >= lr_size ? leaf_range2[j-lr_size] : 00261 leaf_range[j]; 00262 00263 if (*rit == to_ent) continue; 00264 00265 if ((from - MBCartVect(&coords[3*j])).length_squared() < mergeTolSq) { 00266 merge_tag_val[j] = *rit; 00267 if (j < lr_size){ 00268 inleaf_merged = true;} 00269 else{ 00270 outleaf_merged = true;} 00271 00272 deadEnts.insert(to_ent); 00273 } 00274 00275 } 00276 if (outleaf_merged) { 00277 result = mbImpl->tag_set_data(merge_tag, leaf_range2, &merge_tag_val[leaf_range.size()]); 00278 if (MB_SUCCESS != result) return result; 00279 outleaf_merged = false; 00280 } 00281 if (inleaf_merged) { 00282 result = mbImpl->tag_set_data(merge_tag, leaf_range, &merge_tag_val[0]); 00283 if (MB_SUCCESS != result) return result; 00284 } 00285 00286 } 00287 } 00288 return MB_SUCCESS; 00289 } 00290 00291 #endif // ifdef MOAB 00292 }