diff --git a/Geo/GModel.cpp b/Geo/GModel.cpp index 4157e80cfda8c2bf2498598a9af7d9a295b1220c..95f0fa35ce593ee6b59cea4b8099acc16e6e946c 100644 --- a/Geo/GModel.cpp +++ b/Geo/GModel.cpp @@ -1268,6 +1268,14 @@ void GModel::_storeElementsInEntities(std::map< int, std::vector<MElement* > >& } } +void GModel::_storeParentsInSubElements(std::map<int, std::vector<MElement*> > &map) +{ + std::map<int, std::vector<MElement*> >::const_iterator it; + for(it = map.begin(); it != map.end(); ++it) + for (int i=0; i<it->second.size(); ++i) + it->second[i]->updateParent(this); +} + template<class T> static void _associateEntityWithElementVertices(GEntity *ge, std::vector<T*> &elements, bool force=false) diff --git a/Geo/GModel.h b/Geo/GModel.h index 9beb563afedc1cbc43fa1637d4408dddde11383b..96722dde8d249c3394d1bef3f0cbbf64b425bf92 100644 --- a/Geo/GModel.h +++ b/Geo/GModel.h @@ -119,6 +119,9 @@ class GModel // the fly if needed void _storeElementsInEntities(std::map<int, std::vector<MElement*> > &map); + // store the parent's pointer back into MSubElements (replacing numeric id) + void _storeParentsInSubElements(std::map< int, std::vector<MElement* > >& map); + // Discrete Entities have to have their mesh moved to a geometry container void _createGeometryOfDiscreteEntities(bool force=false); diff --git a/Geo/GModelIO_MSH.cpp b/Geo/GModelIO_MSH.cpp index 4c986a60a48c28d16c47a79612f1e42f9e799b72..7cf835757f5ddbde1facf2e039cbec8e425bd308 100644 --- a/Geo/GModelIO_MSH.cpp +++ b/Geo/GModelIO_MSH.cpp @@ -354,6 +354,7 @@ int GModel::readMSH(const std::string &name) _vertexMapCache.clear(); } } + // $Elements section else if(!strncmp(&str[1], "Elements", 8)) { if(!fgets(str, sizeof(str), fp)){ fclose(fp); return 0; } @@ -439,7 +440,7 @@ int GModel::readMSH(const std::string &name) // entity does not exist, create a new (discrete) one. for(int i = 0; i < (int)(sizeof(elements) / sizeof(elements[0])); i++) _storeElementsInEntities(elements[i]); - + // associate the correct geometrical entity with each mesh vertex _associateEntityWithMeshVertices(); @@ -451,6 +452,9 @@ int GModel::readMSH(const std::string &name) _createGeometryOfDiscreteEntities() ; + for(int i = 0; i < (int)(sizeof(elements) / sizeof(elements[0])); i++) + _storeParentsInSubElements(elements[i]); + fclose(fp); return postpro ? 2 : 1; diff --git a/Geo/GModelIO_MSH2.cpp b/Geo/GModelIO_MSH2.cpp index 5304577b48bf91f2c9d193fcf06911b9ea8046e7..322c7520a380b118bde62c61e11cbe80cfc7ce65 100644 --- a/Geo/GModelIO_MSH2.cpp +++ b/Geo/GModelIO_MSH2.cpp @@ -73,7 +73,7 @@ static MElement *createElementMSH2(GModel *m, int num, int typeMSH, int physical } MElementFactory factory; - MElement *e = factory.create(typeMSH, v, num, part, owner, parent, d1, d2); + MElement *e = factory.create(typeMSH, v, num, part, owner, 0, parent, d1, d2); if(!e){ Msg::Error("Unknown type of element %d", typeMSH); diff --git a/Geo/MElement.cpp b/Geo/MElement.cpp index 352467f3b776ba290211b805b7b37ab09f4ae7b4..e50141e44f52de1ca24223d9954e61eb15d40e16 100644 --- a/Geo/MElement.cpp +++ b/Geo/MElement.cpp @@ -1627,7 +1627,7 @@ MElement *MElement::copy(std::map<int, MVertex*> &vertexMap, } MElementFactory f; - MElement *newEl = f.create(eType, vmv, getNum(), _partition, ownsParent(), parent); + MElement *newEl = f.create(eType, vmv, getNum(), _partition, ownsParent(), 0, parent); for(int i = 0; i < 2; i++) { MElement *dom = getDomain(i); @@ -1646,7 +1646,8 @@ MElement *MElement::copy(std::map<int, MVertex*> &vertexMap, } MElement *MElementFactory::create(int type, std::vector<MVertex*> &v, - int num, int part, bool owner, MElement *parent, + int num, int part, bool owner, + int parent, MElement* parent_ptr, MElement *d1, MElement *d2) { switch (type) { @@ -1662,7 +1663,7 @@ MElement *MElementFactory::create(int type, std::vector<MVertex*> &v, case MSH_LIN_10: return new MLineN(v, num, part); case MSH_LIN_11: return new MLineN(v, num, part); case MSH_LIN_B: return new MLineBorder(v, num, part, d1, d2); - case MSH_LIN_C: return new MLineChild(v, num, part, owner, parent); + case MSH_LIN_C: return new MLineChild(v, num, part, owner, parent_ptr); case MSH_TRI_3: return new MTriangle(v, num, part); case MSH_TRI_6: return new MTriangle6(v, num, part); case MSH_TRI_10: return new MTriangleN(v, 3, num, part); @@ -1701,7 +1702,7 @@ MElement *MElementFactory::create(int type, std::vector<MVertex*> &v, case MSH_QUA_32: return new MQuadrangleN(v, 8, num, part); case MSH_QUA_36I: return new MQuadrangleN(v, 9, num, part); case MSH_QUA_40: return new MQuadrangleN(v,10, num, part); - case MSH_POLYG_: return new MPolygon(v, num, part, owner, parent); + case MSH_POLYG_: return new MPolygon(v, num, part, owner, parent_ptr); case MSH_POLYG_B: return new MPolygonBorder(v, num, part, d1, d2); case MSH_TET_4: return new MTetrahedron(v, num, part); case MSH_TET_10: return new MTetrahedron10(v, num, part); @@ -1742,7 +1743,7 @@ MElement *MElementFactory::create(int type, std::vector<MVertex*> &v, case MSH_TET_46: return new MTetrahedronN(v, 8, num, part); case MSH_TET_52: return new MTetrahedronN(v, 9, num, part); case MSH_TET_58: return new MTetrahedronN(v, 10, num, part); - case MSH_POLYH_: return new MPolyhedron(v, num, part, owner, parent); + case MSH_POLYH_: return new MPolyhedron(v, num, part, owner, parent_ptr); case MSH_HEX_32: return new MHexahedronN(v, 3, num, part); case MSH_HEX_64: return new MHexahedronN(v, 3, num, part); case MSH_HEX_125: return new MHexahedronN(v, 4, num, part); @@ -1751,10 +1752,14 @@ MElement *MElementFactory::create(int type, std::vector<MVertex*> &v, case MSH_HEX_512: return new MHexahedronN(v, 7, num, part); case MSH_HEX_729: return new MHexahedronN(v, 8, num, part); case MSH_HEX_1000:return new MHexahedronN(v, 9, num, part); - case MSH_PNT_SUB: return new MSubPoint(v, num, part, owner, parent); - case MSH_LIN_SUB: return new MSubLine(v, num, part, owner, parent); - case MSH_TRI_SUB: return new MSubTriangle(v, num, part, owner, parent); - case MSH_TET_SUB: return new MSubTetrahedron(v, num, part, owner, parent); + case MSH_PNT_SUB: return (parent_ptr) ? new MSubPoint(v, num, part, owner, parent_ptr) + : new MSubPoint(v, num, part, owner, parent); + case MSH_LIN_SUB: return (parent_ptr) ? new MSubLine(v, num, part, owner, parent_ptr) + : new MSubLine(v, num, part, owner, parent); + case MSH_TRI_SUB: return (parent_ptr) ? new MSubTriangle(v, num, part, owner, parent_ptr) + : new MSubTriangle(v, num, part, owner, parent); + case MSH_TET_SUB: return (parent_ptr) ? new MSubTetrahedron(v, num, part, owner, parent_ptr) + : new MSubTetrahedron(v, num, part, owner, parent); case MSH_PYR_5: return new MPyramid(v, num, part); case MSH_PYR_13: return new MPyramidN(v, 2, num, part); case MSH_PYR_14: return new MPyramidN(v, 2, num, part); @@ -1805,10 +1810,10 @@ MElement *MElementFactory::create(int num, int type, const std::vector<int> &dat int part = 0; int startPartitions = startVertices + numVertices; - MElement *parent = 0; + int parent = 0; if((type == MSH_PNT_SUB || type == MSH_LIN_SUB || type == MSH_TRI_SUB || type == MSH_TET_SUB)){ - parent = model->getMeshElementByTag(data[startPartitions]); + parent = data[startPartitions]; startPartitions += 1; } diff --git a/Geo/MElement.h b/Geo/MElement.h index fda1ade945ebb1b1e218683571332657ebf71056..7aff9cc4dc4bff9cfa5d0cd8933194408deffde2 100644 --- a/Geo/MElement.h +++ b/Geo/MElement.h @@ -174,6 +174,7 @@ class MElement // get and set parent and children for hierarchial grids virtual MElement *getParent() const { return NULL; } virtual void setParent(MElement *p, bool owner = false) {} + virtual void updateParent(GModel *gm) {} // used only for reading msh files virtual int getNumChildren() const { return 0; } virtual MElement *getChild(int i) const { return NULL; } virtual bool ownsParent() const { return false; } @@ -402,8 +403,8 @@ class MElement class MElementFactory{ public: - MElement *create(int type, std::vector<MVertex*> &v, int num=0, int part=0, - bool owner=false, MElement *parent=0, MElement *d1=0, MElement *d2=0); + MElement *create(int type, std::vector< MVertex* > &v, int num=0, int part=0, + bool owner=false, int parent=0, MElement *parent_ptr=NULL, MElement *d1 = 0, MElement *d2 = 0); MElement *create(int num, int type, const std::vector<int> &data, GModel *model); }; diff --git a/Geo/MSubElement.cpp b/Geo/MSubElement.cpp index 737251e3718488f4661eb1be841ecaa9250f318e..4526678a8e97e008d20bbc3b9ca73e5c33465166 100644 --- a/Geo/MSubElement.cpp +++ b/Geo/MSubElement.cpp @@ -8,6 +8,7 @@ #include "MSubElement.h" #include "Numeric.h" +#include "GModel.h" // MSubTetrahedron @@ -17,6 +18,11 @@ MSubTetrahedron::~MSubTetrahedron() if(_base) delete _base; } +void MSubTetrahedron::updateParent(GModel *gm) +{ + _orig=gm->getMeshElementByTag(_orig_N); +} + const nodalBasis* MSubTetrahedron::getFunctionSpace(int order, bool serendip) const { if(_orig) return _orig->getFunctionSpace(order, serendip); @@ -209,6 +215,12 @@ MSubTriangle::~MSubTriangle() if(_base) delete _base; } +void MSubTriangle::updateParent(GModel *gm) +{ + _orig=gm->getMeshElementByTag(_orig_N); +} + + const nodalBasis* MSubTriangle::getFunctionSpace(int order, bool serendip) const { if(_orig) return _orig->getFunctionSpace(order, serendip); @@ -447,6 +459,11 @@ MSubLine::~MSubLine() if(_base) delete _base; } +void MSubLine::updateParent(GModel *gm) +{ + _orig=gm->getMeshElementByTag(_orig_N); +} + const nodalBasis* MSubLine::getFunctionSpace(int order, bool serendip) const { if(_orig) return _orig->getFunctionSpace(order, serendip); @@ -676,6 +693,11 @@ MSubPoint::~MSubPoint() if(_base) delete _base; } +void MSubPoint::updateParent(GModel *gm) +{ + _orig=gm->getMeshElementByTag(_orig_N); +} + const nodalBasis* MSubPoint::getFunctionSpace(int order, bool serendip) const { if(_orig) return _orig->getFunctionSpace(order, serendip); diff --git a/Geo/MSubElement.h b/Geo/MSubElement.h index f54dae3f37aab01cf1bdc9de1c1f6e0f9b2398d6..82c17dc6e56df9850632948eda306aa26fa62b45 100644 --- a/Geo/MSubElement.h +++ b/Geo/MSubElement.h @@ -19,16 +19,26 @@ // A sub tetrahedron, contained in another element class MSubTetrahedron : public MTetrahedron { + friend class MElementFactory; + friend class GModel; protected: bool _owner; - MElement* _orig; - std::vector<MElement*> _parents; + union + { + MElement* _orig; // pointer to parent + int _orig_N ; // element number of parent (only used while reading file...) + }; + std::vector<MElement*> _parents; // not used in msh 3 file format mutable MElement* _base; int _pOrder; int _npts; IntPt *_pts; + MSubTetrahedron(std::vector<MVertex*> v, int num, int part, bool owner, int orig) + : MTetrahedron(v, num, part), _owner(owner), _orig_N(orig), _base(0), _pOrder(-1), _npts(0), _pts(0) {} + virtual void updateParent(GModel *gm); // NEVER ever use this ! (except for reading msh files !) + public: MSubTetrahedron(MVertex *v0, MVertex *v1, MVertex *v2, MVertex *v3, int num=0, int part=0, bool owner=false, MElement* orig=NULL) @@ -77,16 +87,25 @@ class MSubTetrahedron : public MTetrahedron // A sub triangle, contained in another element class MSubTriangle : public MTriangle { + friend class MElementFactory; + friend class GModel; protected: bool _owner; - MElement* _orig; - std::vector<MElement*> _parents; + union + { + MElement* _orig; // pointer to parent + int _orig_N ; // element number of parent (only used while reading file...) + }; + std::vector<MElement*> _parents; // not used in msh 3 file format mutable MElement* _base; int _pOrder; int _npts; IntPt *_pts; - + + MSubTriangle(std::vector<MVertex*> v, int num, int part, bool owner, int orig) + : MTriangle(v, num, part), _owner(owner), _orig_N(orig), _base(0), _pOrder(-1), _npts(0), _pts(0) {} + virtual void updateParent(GModel *gm); // NEVER ever use this ! (except for reading msh files !) public: MSubTriangle(MVertex *v0, MVertex *v1, MVertex *v2, int num=0, int part=0, bool owner=false, MElement* orig=NULL) @@ -135,16 +154,25 @@ class MSubTriangle : public MTriangle // A sub line, contained in another element class MSubLine : public MLine { + friend class MElementFactory; + friend class GModel; protected: bool _owner; - MElement* _orig; - std::vector<MElement*> _parents; + union + { + MElement* _orig; // pointer to parent + int _orig_N ; // element number of parent (only used while reading file...) + }; + std::vector<MElement*> _parents; // not used in msh 3 file format mutable MElement* _base; int _pOrder; int _npts; IntPt *_pts; - + + MSubLine(std::vector<MVertex*> v, int num, int part, bool owner, int orig) + : MLine(v, num, part), _owner(owner), _orig_N(orig), _base(0), _pOrder(-1), _npts(0), _pts(0) {} + virtual void updateParent(GModel *gm); // NEVER ever use this ! (except for reading msh files !) public: MSubLine(MVertex *v0, MVertex *v1, int num=0, int part=0, bool owner=false, MElement* orig=NULL) @@ -193,16 +221,25 @@ class MSubLine : public MLine // A sub point, contained in another element class MSubPoint : public MPoint { + friend class MElementFactory; + friend class GModel; protected: bool _owner; - MElement* _orig; - std::vector<MElement*> _parents; + union + { + MElement* _orig; // pointer to parent + int _orig_N ; // element number of parent (only used while reading file...) + }; + std::vector<MElement*> _parents; // not used in msh 3 file format mutable MElement* _base; int _pOrder; int _npts; IntPt *_pts; - + + MSubPoint(std::vector<MVertex*> v, int num, int part, bool owner, int orig) + : MPoint(v, num, part), _owner(owner), _orig_N(orig), _base(0), _pOrder(-1), _npts(0), _pts(0) {} + virtual void updateParent(GModel *gm); // NEVER ever use this ! (except for reading msh files !) public: MSubPoint(MVertex *v0, int num=0, int part=0, bool owner=false, MElement* orig=NULL)