From cfc267eef990db45824ed8d1a3a05bf2de61b949 Mon Sep 17 00:00:00 2001 From: Jean-Francois Remacle <jean-francois.remacle@uclouvain.be> Date: Fri, 22 Nov 2013 19:18:33 +0000 Subject: [PATCH] oops again --- Mesh/filterElements.cpp | 223 ++++++++++++++++++++++++++++++++++++++++ Mesh/filterElements.h | 23 +++++ 2 files changed, 246 insertions(+) create mode 100644 Mesh/filterElements.cpp create mode 100644 Mesh/filterElements.h diff --git a/Mesh/filterElements.cpp b/Mesh/filterElements.cpp new file mode 100644 index 0000000000..f6f8473312 --- /dev/null +++ b/Mesh/filterElements.cpp @@ -0,0 +1,223 @@ +#include <algorithm> +#include <vector> +#include <set> +#include "GmshDefines.h" +#include "filterElements.h" +#include "fullMatrix.h" +#include "GaussIntegration.h" +#include "MElement.h" +#include "MTriangle.h" +#include "MQuadrangle.h" +#include "MPrism.h" +#include "MHexahedron.h" +#if defined(HAVE_RTREE) +#include "rtree.h" +void MElementBB(void *a, double *min, double *max); +int MElementInEle(void *a, double *x); + +struct MElement_Wrapper +{ + bool _overlap; + MElement *_e; + std::vector<MElement*> _notOverlap; + MElement_Wrapper (MElement *e, std::vector<MElement*> notOverlap) + : _overlap(false), _e(e), _notOverlap(notOverlap) + { + std::sort(_notOverlap.begin(),_notOverlap.end()); + } +}; + +static bool inBB (double *mi, double *ma, double *x){ + if (x[0] < mi[0])return false; + if (x[1] < mi[1])return false; + if (x[2] < mi[2])return false; + if (x[0] > ma[0])return false; + if (x[1] > ma[1])return false; + if (x[2] > ma[2])return false; + return true; +} + +bool rtree_callback(MElement *e1,void* pe2){ + MElement_Wrapper *wrapper = static_cast<MElement_Wrapper*>(pe2); + MElement *e2 = wrapper->_e; + + if (std::binary_search(wrapper->_notOverlap.begin(),wrapper->_notOverlap.end(),e1))return true; + + + for (int i=0;i<e1->getNumVertices();i++){ + for (int j=0;j<e2->getNumVertices();j++){ + if(e1->getVertex(i) == e2->getVertex(j))return true; + } + } + + double min2[3],max2[3]; + MElementBB(e2,min2,max2); + + for (int i=0;i<e1->getNumVertices();i++){ + SPoint3 xyz (e1->getVertex(i)->x(),e1->getVertex(i)->y(),e1->getVertex(i)->z()); + if (inBB (min2,max2,xyz)){ + if (MElementInEle(e2,xyz)){ + wrapper->_overlap = true; + return false; + } + } + } + + double min1[3],max1[3]; + MElementBB(e1,min1,max1); + for (int i=0;i<e2->getNumVertices();i++){ + SPoint3 xyz (e2->getVertex(i)->x(),e2->getVertex(i)->y(),e2->getVertex(i)->z()); + if (inBB(min1,max1,xyz)){ + if (MElementInEle(e1,xyz)){ + wrapper->_overlap = true; + return false; + } + } + } + + return false; + + fullMatrix<double> pts1,pts2; + fullVector<double> weights; + + gaussIntegration::get (e1->getType(),1,pts1,weights); + gaussIntegration::get (e2->getType(),1,pts2,weights); + + for (int i=0;i<pts1.size1();i++){ + double u = pts1(i,0); + double v = pts1(i,1); + double w = pts1(i,2); + SPoint3 xyz; + e1->pnt(u,v,w,xyz); + if (inBB(min2,max2,xyz)){ + if (MElementInEle(e2,xyz)){ + wrapper->_overlap = true; + return false; + } + } + } + for (int i=0;i<pts2.size1();i++){ + double u = pts2(i,0); + double v = pts2(i,1); + double w = pts2(i,2); + SPoint3 xyz; + e2->pnt(u,v,w,xyz); + if (inBB(min1,max1,xyz)){ + if (MElementInEle(e1,xyz)){ + wrapper->_overlap = true; + return false; + } + } + } + return true; +} + +struct Less_Partition : public std::binary_function<MElement*, MElement*, bool> { + bool operator()(const MElement *f1, const MElement *f2) const + { + return f1->getPartition() < f2->getPartition() ; + } +}; + +void filterColumns(std::vector<MElement*> &elem, + std::map<MElement*,std::vector<MElement*> > &_elemColumns) +{ + std::sort(elem.begin(),elem.end()); + std::vector<MElement*> toKeep; + for (std::map<MElement*,std::vector<MElement*> >::iterator it = _elemColumns.begin(); + it !=_elemColumns.end() ; ++it){ + const std::vector<MElement*> &c = it->second; + unsigned int MAX = c.size() - 1; + for (unsigned int i=0;i<c.size(); i++){ + if (!std::binary_search(elem.begin(),elem.end(),c[i])){ + MAX = i - 1; + break; + } + } + // printf("MAX = %d c = %d\n",MAX,c.size()); + for (unsigned int i=0;i<MAX;i++){ + toKeep.push_back(c[i]); + } + for (unsigned int i=MAX;i<c.size();i++){ + /// FIXME !!! + // delete c[i]; + } + } + printf("%d --> %d\n",elem.size(),toKeep.size()); + elem = toKeep; +} + + +void filterOverlappingElements (std::vector<MTriangle*> &blTris, + std::vector<MQuadrangle*>&blQuads, + std::map<MElement*,std::vector<MElement*> > &_elemColumns, + std::map<MElement*,MElement*> &_toFirst) +{ + std::vector<MElement*> vvv; + vvv.insert(vvv.begin(),blTris.begin(),blTris.end()); + vvv.insert(vvv.begin(),blQuads.begin(),blQuads.end()); + Less_Partition lp; + std::sort(vvv.begin(),vvv.end(), lp); + filterOverlappingElements (vvv,_elemColumns,_toFirst); + filterColumns (vvv,_elemColumns); + blTris.clear(); + blQuads.clear(); + for (unsigned int i=0;i<vvv.size();i++){ + if (vvv[i]->getType() == TYPE_TRI)blTris.push_back((MTriangle*)vvv[i]); + else if (vvv[i]->getType() == TYPE_QUA)blQuads.push_back((MQuadrangle*)vvv[i]); + } +} + +void filterOverlappingElements (std::vector<MPrism*> &blPrisms, + std::vector<MHexahedron*>&blHexes, + std::map<MElement*,std::vector<MElement*> > &_elemColumns, + std::map<MElement*,MElement*> &_toFirst) +{ + printf("filtering !!\n"); + std::vector<MElement*> vvv; + vvv.insert(vvv.begin(),blPrisms.begin(),blPrisms.end()); + vvv.insert(vvv.begin(),blHexes.begin(),blHexes.end()); + Less_Partition lp; + std::sort(vvv.begin(),vvv.end(), lp); + filterOverlappingElements (vvv,_elemColumns,_toFirst); + filterColumns (vvv,_elemColumns); + blPrisms.clear(); + blHexes.clear(); + for (unsigned int i=0;i<vvv.size();i++){ + if (vvv[i]->getType() == TYPE_PRI)blPrisms.push_back((MPrism*)vvv[i]); + else if (vvv[i]->getType() == TYPE_HEX)blHexes.push_back((MHexahedron*)vvv[i]); + } +} + + +void filterOverlappingElements (std::vector<MElement*> &els, + std::map<MElement*,std::vector<MElement*> > &_elemColumns, + std::map<MElement*,MElement*> &_toFirst ) +{ + std::vector<MElement*> newEls; + RTree<MElement*,double,3,double> rtree; + for (unsigned int i=0;i<els.size();i++){ + MElement *e = els[i]; + double _min[3],_max[3]; + MElementBB(e,_min,_max); + MElement *first = _toFirst[e]; + MElement_Wrapper w(e,_elemColumns[first]); + rtree.Search(_min,_max,rtree_callback,&w); + if (w._overlap){ + delete e; + } + else { + rtree.Insert(_min,_max,e); + newEls.push_back(e); + } + } + els = newEls; +} +#else +void filterOverlappingElements (std::vector<MElement*> &els, + std::map<MElement*,std::vector<MElement*> > &_elemColumns, + std::map<MElement*,MElement*> &_toFirst ) +{ + Msg::Error("full boundary layer capabilities are only available whilst compiling GMSH together with a RTREE library"); +} +#endif diff --git a/Mesh/filterElements.h b/Mesh/filterElements.h new file mode 100644 index 0000000000..f046b37d63 --- /dev/null +++ b/Mesh/filterElements.h @@ -0,0 +1,23 @@ +#ifndef _FILTER_OVERLAPPING_ELEMENTS_ +#define _FILTER_OVERLAPPING_ELEMENTS_ +#include <map> +#include <vector> +class MElement; +class MPrism; +class MHexahedron; +class MTriangle; +class MQuadrangle; +void filterOverlappingElements (std::vector<MElement*> &, + std::map<MElement*,std::vector<MElement*> > &_elemColumns, + std::map<MElement*,MElement*> &_toFirst); +void filterOverlappingElements (std::vector<MPrism*> &blPrisms, + std::vector<MHexahedron*>&blHexes, + std::map<MElement*,std::vector<MElement*> > &_elemColumns, + std::map<MElement*,MElement*> &_toFirst); +void filterOverlappingElements (std::vector<MTriangle*> &blTris, + std::vector<MQuadrangle*>&blQuads, + std::map<MElement*,std::vector<MElement*> > &_elemColumns, + std::map<MElement*,MElement*> &_toFirst); +void filterColumns(std::vector<MElement*> &elem, + std::map<MElement*,std::vector<MElement*> > &_elemColumns); +#endif -- GitLab