LCOV - code coverage report
Current view: top level - algs - MergeMesh.cpp (source / functions) Hit Total Coverage
Test: coverage_sk.info Lines: 138 154 89.6 %
Date: 2020-07-01 15:24:36 Functions: 12 14 85.7 %
Branches: 163 312 52.2 %

           Branch data     Line data    Source code
       1                 :            : #include "meshkit/MergeMesh.hpp"
       2                 :            : 
       3                 :            : #include <algorithm>
       4                 :            : #include <cstdlib>
       5                 :            : #include <cstring>
       6                 :            : #include <functional>
       7                 :            : #include <string>
       8                 :            : #include <vector>
       9                 :            : #include <cassert>
      10                 :            : #include <iostream>
      11                 :            : 
      12                 :            : #include "moab/Skinner.hpp"
      13                 :            : #include "moab/AdaptiveKDTree.hpp"
      14                 :            : #include "moab/Range.hpp"
      15                 :            : #include "moab/CartVect.hpp"
      16                 :            : 
      17                 :            : namespace MeshKit
      18                 :            : {
      19                 :            :   // static registration of this  mesh scheme
      20                 :            :   moab::EntityType MergeMesh_tps[] = { moab::MBVERTEX,
      21                 :            :                                        moab::MBEDGE,
      22                 :            :                                        moab::MBTRI,
      23                 :            :                                        moab::MBHEX,
      24                 :            :                                        moab::MBMAXTYPE};
      25                 :            : 
      26                 :         40 :   const moab::EntityType* MergeMesh::output_types()
      27                 :         40 :   { return MergeMesh_tps; }
      28                 :            :   
      29                 :          1 :   MergeMesh::MergeMesh(MKCore *mkcore, const MEntVector &me_vec)
      30                 :            :     : MeshScheme(mkcore, me_vec),
      31 [ +  - ][ +  - ]:          1 :       imeshImpl(mkcore->imesh_instance()), mbImpl (mkcore->moab_instance())
                 [ +  - ]
      32                 :            :   {
      33                 :          1 :     mergeTol = 1e-4;
      34                 :          1 :     updateSets = 0;
      35                 :          1 :     doMerge = 1;
      36                 :          1 :     mergeTag = NULL;
      37                 :          1 :   }
      38                 :            : 
      39                 :          3 :   MergeMesh::~MergeMesh()
      40                 :            :   {
      41         [ +  - ]:          1 :     if (mbMergeTag) mbImpl->tag_delete(mbMergeTag);
      42         [ -  + ]:          2 :   }
      43                 :            : 
      44                 :          0 :   bool MergeMesh::add_modelent(ModelEnt *model_ent)
      45                 :            :   {
      46                 :          0 :     return MeshOp::add_modelent(model_ent);
      47                 :            :   }
      48                 :            : 
      49                 :          1 :   void MergeMesh::set_merge_params(double merge_tol, int updatesets,
      50                 :            :                                    int domerge, iBase_TagHandle merge_tag)
      51                 :            :   {
      52                 :          1 :     mergeTol = merge_tol;
      53                 :          1 :     updateSets = updatesets;
      54                 :          1 :     doMerge = domerge;
      55                 :          1 :     mergeTag = merge_tag;
      56                 :          1 :   }
      57                 :            : 
      58                 :          1 :   void MergeMesh::setup_this()
      59                 :            :   {
      60                 :          1 :     std::cout << "IN SETUPTHIS MERGEMESH " << std::endl;
      61                 :            : 
      62                 :          1 :   }
      63                 :            : 
      64                 :          1 :   void MergeMesh::execute_this()
      65                 :            :   {
      66 [ +  - ][ +  - ]:          1 :     std::cout << "IN EXTHIS MERGEMESH " << std::endl;
      67                 :            : 
      68         [ +  - ]:          1 :     std::vector<iBase_EntityHandle> ents(mentSelection.size());
      69                 :          1 :     int dim = 3;
      70   [ #  #  +  - ]:          2 :     for (MEntSelection::iterator mit = mentSelection.begin();
                 [ -  + ]
      71                 :          1 :          mit != mentSelection.end(); mit++) {
      72         [ #  # ]:          0 :       ModelEnt *me = mit->first;
      73         [ #  # ]:          0 :       dim  = me->dimension();
      74                 :            :     }
      75                 :            : 
      76         [ +  - ]:          1 :     if(dim == 3){
      77                 :            :       imeshImpl->getEntities(0, iBase_REGION, iMesh_ALL_TOPOLOGIES,
      78         [ +  - ]:          1 :                              ents);
      79                 :            :     }
      80         [ #  # ]:          0 :     else if (dim == 2){
      81                 :            :       imeshImpl->getEntities(0, iBase_FACE, iMesh_ALL_TOPOLOGIES,
      82         [ #  # ]:          0 :                              ents);
      83                 :            :     }
      84         [ +  - ]:          1 :     merge_entities(&ents[0], ents.size(), mergeTol, doMerge, updateSets,
      85         [ +  - ]:          1 :                    mergeTag);
      86                 :          1 :   }
      87                 :            : 
      88                 :          1 :   void MergeMesh::merge_entities(iBase_EntityHandle *elems,
      89                 :            :                                  int elems_size,
      90                 :            :                                  const double merge_tol,
      91                 :            :                                  const int do_merge,
      92                 :            :                                  const int update_sets,
      93                 :            :                                  iBase_TagHandle merge_tag)  
      94                 :            :   {
      95                 :          1 :     mergeTol = merge_tol;
      96                 :          1 :     mergeTolSq = merge_tol*merge_tol;
      97                 :            :   
      98         [ +  - ]:          1 :     moab::Range tmp_elems;
      99         [ +  - ]:          1 :     tmp_elems.insert((moab::EntityHandle*)elems, (moab::EntityHandle*)elems + elems_size);
     100                 :            :     moab::ErrorCode result = merge_entities(tmp_elems, do_merge, update_sets,
     101         [ +  - ]:          1 :                                         (moab::Tag)merge_tag);
     102         [ -  + ]:          1 :     if (moab::MB_SUCCESS != result)
     103                 :          1 :       exit(0);
     104                 :          1 :   }
     105                 :            : 
     106                 :          0 :   void MergeMesh::perform_merge(iBase_TagHandle merge_tag) 
     107                 :            :   {
     108                 :            :     // put into a range
     109                 :          0 :     moab::ErrorCode result = perform_merge((moab::Tag) merge_tag);
     110         [ #  # ]:          0 :     if (moab::MB_SUCCESS != result)
     111                 :          0 :       exit(0);
     112                 :          0 :   }
     113                 :            : 
     114                 :          1 :   moab::ErrorCode MergeMesh::merge_entities(moab::Range &elems,
     115                 :            :                                         const int do_merge,
     116                 :            :                                         const int update_sets,
     117                 :            :                                         moab::Tag merge_tag) 
     118                 :            :   {
     119                 :            :     // get the skin of the entities
     120         [ +  - ]:          1 :     moab::Skinner skinner(mbImpl);
     121         [ +  - ]:          2 :     moab::Range skin_range;
     122         [ +  - ]:          1 :     moab::ErrorCode result = skinner.find_skin(0, elems, 0, skin_range);
     123         [ -  + ]:          1 :     if (moab::MB_SUCCESS != result) return result;
     124                 :            : 
     125                 :            :     // create a tag to mark merged-to entity; reuse tree_root
     126                 :          1 :     moab::EntityHandle tree_root = 0;
     127         [ +  - ]:          1 :     if (0 == merge_tag) {
     128                 :            :       //result = mbImpl->tag_create("__merge_tag", sizeof(moab::EntityHandle), 
     129                 :            :       //                            MB_TAG_DENSE, MB_TYPE_HANDLE,
     130                 :            :       //                            mbMergeTag, &tree_root);
     131                 :            :       result = mbImpl->tag_get_handle("__merge_tag", 1, moab::MB_TYPE_HANDLE,
     132                 :            :                                       mbMergeTag, moab::MB_TAG_DENSE|moab::MB_TAG_CREAT,
     133         [ +  - ]:          1 :                                       &tree_root);
     134         [ -  + ]:          1 :       if (moab::MB_SUCCESS != result) return result;
     135                 :            :     }
     136                 :          0 :     else mbMergeTag = merge_tag;
     137                 :            :   
     138                 :            :     // build a kd tree with the vertices
     139         [ +  - ]:          2 :     moab::AdaptiveKDTree kd(mbImpl);
     140         [ +  - ]:          1 :     result = kd.build_tree(skin_range, &tree_root);
     141         [ -  + ]:          1 :     if (moab::MB_SUCCESS != result) return result;
     142                 :            : 
     143                 :            :     // find matching vertices, mark them
     144         [ +  - ]:          1 :     result = find_merged_to(kd, tree_root, mbMergeTag);
     145         [ -  + ]:          1 :     if (moab::MB_SUCCESS != result) return result;
     146                 :            :   
     147                 :            :     // merge them if requested
     148         [ +  - ]:          1 :     if (do_merge) {
     149         [ +  - ]:          1 :       result = perform_merge(mbMergeTag);
     150         [ -  + ]:          1 :       if (moab::MB_SUCCESS != result) return result;
     151                 :            :     }
     152                 :            :   
     153                 :          2 :     return moab::MB_SUCCESS;
     154                 :            :   }
     155                 :            : 
     156                 :          1 :   moab::ErrorCode MergeMesh::perform_merge(moab::Tag merge_tag) 
     157                 :            :   {
     158 [ +  - ][ -  + ]:          1 :     if (deadEnts.size()==0){
     159 [ #  # ][ #  # ]:          0 :       std::cout << "\nWarning: Geometries don't have a common face; Nothing to merge" << std::endl;
     160                 :          0 :       return moab::MB_SUCCESS; //nothing to merge carry on with the program
     161                 :            :     }
     162 [ +  - ][ +  - ]:          1 :     if (mbImpl->type_from_handle(*deadEnts.rbegin()) != moab::MBVERTEX)
         [ +  - ][ -  + ]
     163                 :          0 :       return moab::MB_FAILURE;
     164                 :            :   
     165 [ +  - ][ +  - ]:          1 :     std::vector<moab::EntityHandle> merge_tag_val(deadEnts.size());
     166 [ +  - ][ +  - ]:          1 :     moab::ErrorCode result = mbImpl->tag_get_data(merge_tag, deadEnts, &merge_tag_val[0]);
     167         [ -  + ]:          1 :     if (moab::MB_SUCCESS != result) return result;
     168                 :            :   
     169         [ +  - ]:          1 :     moab::Range::iterator rit;
     170                 :            :     unsigned int i;
     171 [ +  - ][ +  - ]:         10 :     for (rit = deadEnts.begin(), i = 0; rit != deadEnts.end(); rit++, i++) {
         [ +  - ][ +  - ]
                 [ +  + ]
     172 [ +  - ][ -  + ]:          9 :       assert(merge_tag_val[i]);
     173 [ +  - ][ +  - ]:          9 :       result = mbImpl->merge_entities(merge_tag_val[i], *rit, false, false);
                 [ +  - ]
     174         [ -  + ]:          9 :       if (moab::MB_SUCCESS != result) return result;
     175                 :            :     }
     176                 :            :   
     177         [ +  - ]:          1 :     return mbImpl->delete_entities(deadEnts);
     178                 :            :   }
     179                 :            : 
     180                 :          1 :   moab::ErrorCode MergeMesh::find_merged_to(moab::AdaptiveKDTree & tree, moab::EntityHandle &tree_root, moab::Tag merge_tag)
     181                 :            :   {
     182         [ +  - ]:          1 :     moab::AdaptiveKDTreeIter iter;
     183                 :            :     //moab::AdaptiveKDTree tree(mbImpl);
     184                 :            :   
     185                 :            :     // evaluate vertices in this leaf
     186 [ +  - ][ +  - ]:          2 :     moab::Range leaf_range, leaf_range2;
     187         [ +  - ]:          2 :     std::vector<moab::EntityHandle> sorted_leaves;
     188         [ +  - ]:          2 :     std::vector<double> coords;
     189 [ +  - ][ +  - ]:          2 :     std::vector<moab::EntityHandle> merge_tag_val, leaves_out;
     190                 :            :   
     191         [ +  - ]:          1 :     moab::ErrorCode result = tree.get_tree_iterator(tree_root, iter);
     192         [ -  + ]:          1 :     if (moab::MB_SUCCESS != result) return result;
     193         [ +  + ]:         17 :     while (result == moab::MB_SUCCESS) {
     194 [ +  - ][ +  - ]:         16 :       sorted_leaves.push_back( iter.handle() );
     195         [ +  - ]:         16 :       result = iter.step();
     196                 :            :     }
     197         [ -  + ]:          1 :     if (result != moab::MB_ENTITY_NOT_FOUND)
     198                 :          0 :       return result;
     199         [ +  - ]:          1 :     std::sort( sorted_leaves.begin(), sorted_leaves.end() );
     200                 :            :   
     201                 :          1 :     std::vector<moab::EntityHandle>::iterator it;
     202 [ +  - ][ +  - ]:         17 :     for (it = sorted_leaves.begin(); it != sorted_leaves.end(); ++it) {
                 [ +  + ]
     203                 :            : 
     204         [ +  - ]:         16 :       leaf_range.clear();
     205 [ +  - ][ +  - ]:         16 :       result = mbImpl->get_entities_by_handle(*it, leaf_range);
     206         [ -  + ]:         16 :       if (moab::MB_SUCCESS != result) return result;
     207 [ +  - ][ +  - ]:         16 :       coords.resize(3*leaf_range.size());
     208 [ +  - ][ +  - ]:         16 :       merge_tag_val.resize(leaf_range.size());
     209 [ +  - ][ +  - ]:         16 :       result = mbImpl->get_coords(leaf_range, &coords[0]);
     210         [ -  + ]:         16 :       if (moab::MB_SUCCESS != result) return result;
     211 [ +  - ][ +  - ]:         16 :       result = mbImpl->tag_get_data(merge_tag, leaf_range, &merge_tag_val[0]);
     212         [ -  + ]:         16 :       if (moab::MB_SUCCESS != result) return result;
     213         [ +  - ]:         16 :       moab::Range::iterator rit;
     214                 :            :       unsigned int i;
     215                 :         16 :       bool inleaf_merged, outleaf_merged = false;
     216         [ +  - ]:         16 :       unsigned int lr_size = leaf_range.size();
     217                 :            :     
     218 [ +  - ][ +  - ]:        160 :       for (i = 0, rit = leaf_range.begin(); i != lr_size; rit++, i++) {
                 [ +  + ]
     219 [ +  - ][ +  + ]:        144 :         if (0 != merge_tag_val[i]) continue;
     220 [ +  - ][ +  - ]:        112 :         moab::CartVect from(&coords[3*i]);
     221                 :        112 :         inleaf_merged = false;
     222                 :            : 
     223                 :            :         // check close-by leaves too
     224                 :        112 :         leaves_out.clear();
     225         [ +  - ]:        112 :         result = tree.distance_search( from.array(), mergeTol,
     226         [ +  - ]:        112 :                                              leaves_out);
     227         [ +  - ]:        112 :         leaf_range2.clear();
     228   [ +  -  +  - ]:        976 :         for (std::vector<moab::EntityHandle>::iterator vit = leaves_out.begin();
                 [ +  + ]
     229                 :        488 :              vit != leaves_out.end(); vit++) {
     230 [ +  - ][ +  - ]:        376 :           if (*vit > *it) { // if we haven't visited this leaf yet in the outer loop
                 [ +  + ]
     231 [ +  - ][ +  - ]:        132 :             result = mbImpl->get_entities_by_handle(*vit, leaf_range2, moab::Interface::UNION);
     232         [ -  + ]:        132 :             if (moab::MB_SUCCESS != result) return result;
     233                 :            :           }
     234                 :            :         }
     235 [ +  - ][ +  + ]:        112 :         if (!leaf_range2.empty()) {
     236 [ +  - ][ +  - ]:         69 :           coords.resize(3*(lr_size+leaf_range2.size()));
     237 [ +  - ][ +  - ]:         69 :           merge_tag_val.resize(lr_size+leaf_range2.size());
     238 [ +  - ][ +  - ]:         69 :           result = mbImpl->get_coords(leaf_range2, &coords[3*lr_size]);
     239         [ -  + ]:         69 :           if (moab::MB_SUCCESS != result) return result;
     240 [ +  - ][ +  - ]:         69 :           result = mbImpl->tag_get_data(merge_tag, leaf_range2, &merge_tag_val[lr_size]);
     241         [ -  + ]:         69 :           if (moab::MB_SUCCESS != result) return result;
     242                 :         69 :           outleaf_merged = false;
     243                 :            :         }
     244                 :            : 
     245                 :            :         // check other verts in this leaf
     246         [ +  + ]:       1809 :         for (unsigned int j = i+1; j < merge_tag_val.size(); j++) {
     247                 :       1160 :           moab::EntityHandle to_ent = j >= lr_size ? leaf_range2[j-lr_size] : 
     248 [ +  + ][ +  - ]:       1697 :             leaf_range[j];
                 [ +  - ]
     249                 :            :         
     250 [ +  - ][ +  + ]:       1697 :           if (*rit == to_ent) continue;
     251                 :            :         
     252 [ +  - ][ +  - ]:       1628 :           if ((from - moab::CartVect(&coords[3*j])).length_squared() < mergeTolSq) {
         [ +  - ][ +  - ]
                 [ +  + ]
     253 [ +  - ][ +  - ]:         55 :             merge_tag_val[j] = *rit;
     254         [ +  + ]:         55 :             if (j < lr_size){
     255                 :         32 :               inleaf_merged = true;}
     256                 :            :             else{
     257                 :         23 :               outleaf_merged = true;}
     258                 :            : 
     259         [ +  - ]:         55 :             deadEnts.insert(to_ent);
     260                 :            :           }
     261                 :            : 
     262                 :            :         }
     263         [ +  + ]:        112 :         if (outleaf_merged) {
     264 [ +  - ][ +  - ]:         23 :           result = mbImpl->tag_set_data(merge_tag, leaf_range2, &merge_tag_val[leaf_range.size()]);
                 [ +  - ]
     265         [ -  + ]:         23 :           if (moab::MB_SUCCESS != result) return result;
     266                 :         23 :           outleaf_merged = false;
     267                 :            :         }
     268         [ +  + ]:        112 :         if (inleaf_merged) {
     269 [ +  - ][ +  - ]:         32 :           result = mbImpl->tag_set_data(merge_tag, leaf_range, &merge_tag_val[0]);
     270         [ -  + ]:        112 :           if (moab::MB_SUCCESS != result) return result;
     271                 :            :         }
     272                 :            : 
     273                 :            :       }
     274                 :            :     }
     275                 :          2 :     return moab::MB_SUCCESS;
     276                 :            :   }
     277 [ +  - ][ +  - ]:        156 : }

Generated by: LCOV version 1.11