]> SALOME platform Git repositories - tools/medcoupling.git/commitdiff
Salome HOME
IntersectMesh with quadratic elements
authorageay <ageay>
Mon, 13 Feb 2012 16:10:19 +0000 (16:10 +0000)
committerageay <ageay>
Mon, 13 Feb 2012 16:10:19 +0000 (16:10 +0000)
src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdge.hxx
src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeArcCircle.cxx
src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DElementaryEdge.cxx
src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DElementaryEdge.hxx
src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DQuadraticPolygon.cxx
src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DQuadraticPolygon.hxx
src/MEDCoupling/MEDCouplingUMesh.cxx
src/MEDCoupling/MEDCouplingUMesh.hxx
src/MEDLoader/MEDFileMesh.cxx
src/MEDLoader/MEDFileMesh.hxx
src/MEDLoader/Swig/MEDLoader.i

index e712a0d0de6760c7b32fb2cd9a91bf5a132c6829..cdd81b2c26798ee4bb1863b66b7afb9477339620 100644 (file)
@@ -261,7 +261,8 @@ namespace INTERP_KERNEL
                                    std::vector<int>& edgesThis, std::vector<double>& addCoo, std::map<INTERP_KERNEL::Node *,int> mapAddCoo) const = 0;
     virtual void fillGlobalInfoAbs2(const std::map<INTERP_KERNEL::Node *,int>& mapThis, const std::map<INTERP_KERNEL::Node *,int>& mapOther, int offset1, int offset2, double fact, double baryX, double baryY,
                                     std::vector<int>& edgesOther, std::vector<double>& addCoo, std::map<INTERP_KERNEL::Node *,int>& mapAddCoo) const = 0;
-    virtual void sortIdsAbs(const std::vector<INTERP_KERNEL::Node *>& addNodes, const std::map<INTERP_KERNEL::Node *, int>& mapp1, const std::map<INTERP_KERNEL::Node *, int>& mapp2, std::vector<int>& edgesThis) = 0; 
+    virtual void sortIdsAbs(const std::vector<INTERP_KERNEL::Node *>& addNodes, const std::map<INTERP_KERNEL::Node *, int>& mapp1, const std::map<INTERP_KERNEL::Node *, int>& mapp2, std::vector<int>& edgesThis) = 0;
+    virtual Edge *buildEdgeLyingOnMe(Node *start, Node *end, bool direction=true) const = 0;
   protected:
     Edge():_cnt(1),_loc(FULL_UNKNOWN),_start(0),_end(0) { }
     virtual ~Edge();
@@ -271,7 +272,6 @@ namespace INTERP_KERNEL
     //! The code 'code' is built by method combineCodes
     static bool SplitOverlappedEdges(const Edge *e1, const Edge *e2, Node *nS, Node *nE, bool direction, int code,
                                      ComposedEdge& outVal1, ComposedEdge& outVal2);
-    virtual Edge *buildEdgeLyingOnMe(Node *start, Node *end, bool direction=true) const = 0;
   protected:
     mutable unsigned char _cnt;
     mutable TypeOfEdgeLocInPolygon _loc;
index b9a8f0cddf01a5a47218bf299145d36cd9793cf8..640f5b122d4b071767cc165e6d1583accb70b2b7 100644 (file)
@@ -497,18 +497,18 @@ void EdgeArcCircle::dumpInXfigFile(std::ostream& stream, bool direction, int res
   stream << "5 1 0 1 ";
   fillXfigStreamForLoc(stream);
   stream << " 7 50 -1 -1 0.000 0 ";
-  if( (direction && _angle>=0) || (!direction && _angle<0))
+  if( (direction && (-_angle)>=0) || (!direction && (-_angle)<0))
     stream << '0';//'0'
   else
     stream << '1';//'1'
-  stream << " 0 0 ";
+  stream << " 1 0 ";
   stream << box.fitXForXFigD(_center[0],resolution) << " " << box.fitYForXFigD(_center[1],resolution) << " ";
   direction?_start->dumpInXfigFile(stream,resolution,box):_end->dumpInXfigFile(stream,resolution,box);
   Node *middle=buildRepresentantOfMySelf();
   middle->dumpInXfigFile(stream,resolution,box);
   middle->decrRef();
   direction?_end->dumpInXfigFile(stream,resolution,box):_start->dumpInXfigFile(stream,resolution,box);
-  stream << std::endl;
+  stream << std::endl << "1 1 2.00 120.00 180.00" << std::endl;
 }
 
 void EdgeArcCircle::update(Node *m)
index 0294997f28ac59fe49344efb9df7d752ea1bf24a..59100475a5a8a6a210cdc2c070cc18cbefd22300 100644 (file)
@@ -224,7 +224,7 @@ void ElementaryEdge::fillGlobalInfoAbs2(const std::map<INTERP_KERNEL::Node *,int
  * This method builds from descending conn of a quadratic polygon stored in crude mode (MEDCoupling). Descending conn is in FORTRAN relative mode in order to give the
  * orientation of edge. Called by QuadraticPolygon::buildFromCrudeDataArray.
  */
-ElementaryEdge *ElementaryEdge::BuildEdgeFromCrudeDataArray(bool isQuad, bool direction, INTERP_KERNEL::Node *start, INTERP_KERNEL::Node *end)
+ElementaryEdge *ElementaryEdge::BuildEdgeFromCrudeDataArray(bool direction, INTERP_KERNEL::Node *start, INTERP_KERNEL::Node *end)
 {
   Edge *ptr=Edge::BuildEdgeFrom(start,end);
   return new ElementaryEdge(ptr,direction);
index ef30386c64a3ff2ef941c3969e9e40066245bf80..4547917befa953352641ce9f501255012b8361ae 100644 (file)
@@ -70,7 +70,7 @@ namespace INTERP_KERNEL
                            std::vector<int>& edgesThis, std::vector<double>& addCoo, std::map<INTERP_KERNEL::Node *,int> mapAddCoo) const;
     void fillGlobalInfoAbs2(const std::map<INTERP_KERNEL::Node *,int>& mapThis, const std::map<INTERP_KERNEL::Node *,int>& mapOther, int offset1, int offset2, double fact, double baryX, double baryY,
                             std::vector<int>& edgesOther, std::vector<double>& addCoo, std::map<INTERP_KERNEL::Node *,int>& mapAddCoo) const;
-    static ElementaryEdge *BuildEdgeFromCrudeDataArray(bool isQuad, bool direction, INTERP_KERNEL::Node *start, INTERP_KERNEL::Node *end);
+    static ElementaryEdge *BuildEdgeFromCrudeDataArray(bool direction, INTERP_KERNEL::Node *start, INTERP_KERNEL::Node *end);
   private:
     bool _direction;
     Edge *_ptr;
index 178a184ac0aeb7efb9c59e97f51155ed3bc23aa0..1a96efa8e85d3ac0ca245f627037805f32a7e408 100644 (file)
@@ -292,21 +292,73 @@ void QuadraticPolygon::splitAbs(QuadraticPolygon& other, const std::map<INTERP_K
  * This method builds from descending conn of a quadratic polygon stored in crude mode (MEDCoupling). Descending conn is in FORTRAN relative mode in order to give the
  * orientation of edge.
  */
-void QuadraticPolygon::buildFromCrudeDataArray(const std::map<int,INTERP_KERNEL::Node *>& mapp, bool isQuad, const int *descBg, const int *descEnd, const std::vector<std::vector<int> >& intersectEdges)
+void QuadraticPolygon::buildFromCrudeDataArray(const std::map<int,INTERP_KERNEL::Node *>& mapp, bool isQuad, const int *nodalBg, const double *coords,
+                                               const int *descBg, const int *descEnd, const std::vector<std::vector<int> >& intersectEdges)
 {
-  std::size_t nbOfSeg=std::distance(descBg,descEnd);
-  for(std::size_t i=0;i<nbOfSeg;i++)
+  if(!isQuad)
     {
-      bool direct=descBg[i]>0;
-      int edgeId=abs(descBg[i])-1;
-      const std::vector<int>& subEdge=intersectEdges[edgeId];
-      std::size_t nbOfSubEdges=subEdge.size()/2;
-      for(std::size_t j=0;j<nbOfSubEdges;j++)
+      std::size_t nbOfSeg=std::distance(descBg,descEnd);
+      for(std::size_t i=0;i<nbOfSeg;i++)
+        {
+          bool direct=descBg[i]>0;
+          int edgeId=abs(descBg[i])-1;
+          const std::vector<int>& subEdge=intersectEdges[edgeId];
+          std::size_t nbOfSubEdges=subEdge.size()/2;
+          for(std::size_t j=0;j<nbOfSubEdges;j++)
+            {
+              Node *start=(*mapp.find(direct?subEdge[2*j]:subEdge[2*nbOfSubEdges-2*j-1])).second;
+              Node *end=(*mapp.find(direct?subEdge[2*j+1]:subEdge[2*nbOfSubEdges-2*j-2])).second;
+              ElementaryEdge *e=ElementaryEdge::BuildEdgeFromCrudeDataArray(true,start,end);
+              pushBack(e);
+            }
+        }
+    }
+  else
+    {
+      std::size_t nbOfSeg=std::distance(descBg,descEnd);
+      for(std::size_t i=0;i<nbOfSeg;i++)
         {
-          Node *start=(*mapp.find(direct?subEdge[2*j]:subEdge[2*nbOfSubEdges-2*j-1])).second;
-          Node *end=(*mapp.find(direct?subEdge[2*j+1]:subEdge[2*nbOfSubEdges-2*j-2])).second;
-          ElementaryEdge *e=ElementaryEdge::BuildEdgeFromCrudeDataArray(isQuad,true,start,end);
-          pushBack(e);
+          const double *st=coords+2*(nodalBg[i]); 
+          INTERP_KERNEL::Node *st0=new INTERP_KERNEL::Node(st[0],st[1]);
+          const double *endd=coords+2*(nodalBg[(i+1)%nbOfSeg]);
+          INTERP_KERNEL::Node *endd0=new INTERP_KERNEL::Node(endd[0],endd[1]);
+          const double *middle=coords+2*(nodalBg[i+nbOfSeg]);
+          INTERP_KERNEL::Node *middle0=new INTERP_KERNEL::Node(middle[0],middle[1]);
+          EdgeLin *e1,*e2;
+          e1=new EdgeLin(st0,middle0);
+          e2=new EdgeLin(middle0,endd0);
+          SegSegIntersector inters(*e1,*e2);
+          bool colinearity=inters.areColinears();
+          delete e1; delete e2;
+          //
+          bool direct=descBg[i]>0;
+          int edgeId=abs(descBg[i])-1;
+          const std::vector<int>& subEdge=intersectEdges[edgeId];
+          std::size_t nbOfSubEdges=subEdge.size()/2;
+          if(colinearity)
+            {   
+              for(std::size_t j=0;j<nbOfSubEdges;j++)
+                {
+                  Node *start=(*mapp.find(direct?subEdge[2*j]:subEdge[2*nbOfSubEdges-2*j-1])).second;
+                  Node *end=(*mapp.find(direct?subEdge[2*j+1]:subEdge[2*nbOfSubEdges-2*j-2])).second;
+                  ElementaryEdge *e=ElementaryEdge::BuildEdgeFromCrudeDataArray(true,start,end);
+                  pushBack(e);
+                }
+            }
+          else
+            {
+              Edge *e=new EdgeArcCircle(st0,middle0,endd0,direct);
+              for(std::size_t j=0;j<nbOfSubEdges;j++)
+                {
+                  Node *start=(*mapp.find(direct?subEdge[2*j]:subEdge[2*nbOfSubEdges-2*j-1])).second;
+                  Node *end=(*mapp.find(direct?subEdge[2*j+1]:subEdge[2*nbOfSubEdges-2*j-2])).second;
+                  Edge *ee=e->buildEdgeLyingOnMe(start,end);
+                  ElementaryEdge *eee=new ElementaryEdge(ee,true);
+                  pushBack(eee);
+                }
+              e->decrRef();
+            }
+          st0->decrRef(); endd0->decrRef(); middle0->decrRef();
         }
     }
 }
@@ -350,7 +402,7 @@ void QuadraticPolygon::buildFromCrudeDataArray2(const std::map<int,INTERP_KERNEL
             {
               Node *start=(*mapp.find(direct?subEdge[2*j]:subEdge[2*nbOfSubEdges-2*j-1])).second;
               Node *end=(*mapp.find(direct?subEdge[2*j+1]:subEdge[2*nbOfSubEdges-2*j-2])).second;
-              ElementaryEdge *e=ElementaryEdge::BuildEdgeFromCrudeDataArray(isQuad,true,start,end);
+              ElementaryEdge *e=ElementaryEdge::BuildEdgeFromCrudeDataArray(true,start,end);
               pushBack(e);
             }
         }
@@ -377,7 +429,7 @@ void QuadraticPolygon::buildFromCrudeDataArray2(const std::map<int,INTERP_KERNEL
                 {//the current subedge of edge 'edgeId' of pol2 is not a part of the colinear edge 'idIn1' of pol1 -> build new Edge instance
                   Node *start=(*mapp.find(idBg)).second;
                   Node *end=(*mapp.find(idEnd)).second;
-                  ElementaryEdge *e=ElementaryEdge::BuildEdgeFromCrudeDataArray(isQuad,true,start,end);
+                  ElementaryEdge *e=ElementaryEdge::BuildEdgeFromCrudeDataArray(true,start,end);
                   pushBack(e);
                 }
               else
index 8ccbde27f2d43bc3e2fd38ffb919524732e9544a..bab62ab32b44eba4ad43d242638613bc0c0b046c 100644 (file)
@@ -56,7 +56,8 @@ namespace INTERP_KERNEL
     double intersectWithAbs(QuadraticPolygon& other, double* barycenter);
     void splitAbs(QuadraticPolygon& other, const std::map<INTERP_KERNEL::Node *,int>& mapThis, const std::map<INTERP_KERNEL::Node *,int>& mapOther, int offset1, int offset2, const std::vector<int>& otherEdgeIds,
                   std::vector<int>& edgesThis, int cellIdThis, std::vector< std::vector<int> >& edgesInOtherColinearWithThis, std::vector< std::vector<int> >& subDivOther, std::vector<double>& addCoo);
-    void buildFromCrudeDataArray(const std::map<int,INTERP_KERNEL::Node *>& mapp, bool isQuad, const int *descBg, const int *descEnd, const std::vector<std::vector<int> >& intersectEdges);
+    void buildFromCrudeDataArray(const std::map<int,INTERP_KERNEL::Node *>& mapp, bool isQuad, const int *nodalBg, const double *coords,
+                                 const int *descBg, const int *descEnd, const std::vector<std::vector<int> >& intersectEdges);
     void buildFromCrudeDataArray2(const std::map<int,INTERP_KERNEL::Node *>& mapp, bool isQuad, const int *descBg, const int *descEnd, const std::vector<std::vector<int> >& intersectEdges,
                                   const INTERP_KERNEL::QuadraticPolygon& pol1, const int *descBg1, const int *descEnd1, const std::vector<std::vector<int> >& intersectEdges1,
                                   const std::vector< std::vector<int> >& colinear1);
index 7e920f6ad7e8f204b3ad69c504269b57cdd36e10..9a517ec518834a3b524f40a61de09af54694225c 100644 (file)
@@ -2527,7 +2527,15 @@ namespace ParaMEDMEM
         }
       case INTERP_KERNEL::NORM_SEG3:
         {
-          ret=new INTERP_KERNEL::EdgeArcCircle(mapp2[bg[0]],mapp2[bg[2]],mapp2[bg[1]]);
+          INTERP_KERNEL::EdgeLin * e1=new INTERP_KERNEL::EdgeLin(mapp2[bg[0]],mapp2[bg[2]]);
+          INTERP_KERNEL::EdgeLin *e2=new INTERP_KERNEL::EdgeLin(mapp2[bg[2]],mapp2[bg[1]]);
+          INTERP_KERNEL::SegSegIntersector inters(*e1,*e2);
+          bool colinearity=inters.areColinears();
+          delete e1; delete e2;
+          if(colinearity)
+            ret=new INTERP_KERNEL::EdgeLin(mapp2[bg[0]],mapp2[bg[1]]);
+          else
+            ret=new INTERP_KERNEL::EdgeArcCircle(mapp2[bg[0]],mapp2[bg[2]],mapp2[bg[1]]);
           break;
         }
       default:
@@ -4825,12 +4833,11 @@ MEDCouplingUMesh *MEDCouplingUMesh::Intersect2DMeshes(const MEDCouplingUMesh *m1
   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> dd5(m1Desc),dd6(m2Desc);
   std::vector< std::vector<int> > intersectEdge2;
   BuildIntersectEdges(m1Desc,m2Desc,addCoo,subDiv2,intersectEdge2);
-  std::vector<bool> b1=m1Desc->getQuadraticStatus();
   std::vector<bool> b2=m1Desc->getQuadraticStatus();
   subDiv2.clear(); dd5=0; dd6=0;
   std::vector<int> cr,crI;
   std::vector<int> cNb1,cNb2;
-  BuildIntersecting2DCellsFromEdges(eps,m1,b1,desc1->getConstPointer(),descIndx1->getConstPointer(),intersectEdge1,colinear2,m2,b2,desc2->getConstPointer(),descIndx2->getConstPointer(),intersectEdge2,addCoo,
+  BuildIntersecting2DCellsFromEdges(eps,m1,desc1->getConstPointer(),descIndx1->getConstPointer(),intersectEdge1,colinear2,m2,b2,desc2->getConstPointer(),descIndx2->getConstPointer(),intersectEdge2,addCoo,
                                     /* outputs -> */cr,crI,cNb1,cNb2);
   //
   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> addCooDa=DataArrayDouble::New();
@@ -4852,7 +4859,7 @@ MEDCouplingUMesh *MEDCouplingUMesh::Intersect2DMeshes(const MEDCouplingUMesh *m1
 
 /// @endcond
 
-void MEDCouplingUMesh::BuildIntersecting2DCellsFromEdges(double eps, const MEDCouplingUMesh *m1, const std::vector<bool>& b1, const int *desc1, const int *descIndx1,
+void MEDCouplingUMesh::BuildIntersecting2DCellsFromEdges(double eps, const MEDCouplingUMesh *m1, const int *desc1, const int *descIndx1,
                                                          const std::vector<std::vector<int> >& intesctEdges1, const std::vector< std::vector<int> >& colinear2,
                                                          const MEDCouplingUMesh *m2, const std::vector<bool>& b2, const int *desc2, const int *descIndx2, const std::vector<std::vector<int> >& intesctEdges2,
                                                          const std::vector<double>& addCoords,
@@ -4861,6 +4868,8 @@ void MEDCouplingUMesh::BuildIntersecting2DCellsFromEdges(double eps, const MEDCo
   static const int SPACEDIM=2;
   std::vector<double> bbox1,bbox2;
   const double *coo1=m1->getCoords()->getConstPointer();
+  const int *conn1=m1->getNodalConnectivity()->getConstPointer();
+  const int *connI1=m1->getNodalConnectivityIndex()->getConstPointer();
   int offset1=m1->getNumberOfNodes();
   const double *coo2=m2->getCoords()->getConstPointer();
   int offset2=offset1+m2->getNumberOfNodes();
@@ -4876,8 +4885,11 @@ void MEDCouplingUMesh::BuildIntersecting2DCellsFromEdges(double eps, const MEDCo
       std::map<INTERP_KERNEL::Node *,int> mapp;
       std::map<int,INTERP_KERNEL::Node *> mappRev;
       INTERP_KERNEL::QuadraticPolygon pol1;
+      INTERP_KERNEL::NormalizedCellType typ=(INTERP_KERNEL::NormalizedCellType)conn1[connI1[i]];
+      const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(typ);
       MEDCouplingUMeshBuildQPFromMesh3(coo1,offset1,coo2,offset2,addCoords,desc1+descIndx1[i],desc1+descIndx1[i+1],intesctEdges1,/* output */mapp,mappRev);
-      pol1.buildFromCrudeDataArray(mappRev,b1[i],desc1+descIndx1[i],desc1+descIndx1[i+1],intesctEdges1);
+      pol1.buildFromCrudeDataArray(mappRev,cm.isQuadratic(),conn1+connI1[i]+1,coo1,
+                                   desc1+descIndx1[i],desc1+descIndx1[i+1],intesctEdges1);
       std::vector<int> crTmp,crITmp;
       crITmp.push_back(crI.back());
       for(std::vector<int>::const_iterator it2=candidates2.begin();it2!=candidates2.end();it2++)
index d9aec073c25cc6daad30c8e263501c7241d9a2f9..dc84121d8328d0bab0c1f4c60a7492cd2a2057f7 100644 (file)
@@ -220,7 +220,7 @@ namespace ParaMEDMEM
                                             MEDCouplingUMesh *& m2Desc, DataArrayInt *&desc2, DataArrayInt *&descIndx2, DataArrayInt *&revDesc2, DataArrayInt *&revDescIndx2,
                                             std::vector<double>& addCoo) throw(INTERP_KERNEL::Exception);
     static void BuildIntersectEdges(const MEDCouplingUMesh *m1, const MEDCouplingUMesh *m2, const std::vector<double>& addCoo, const std::vector< std::vector<int> >& subDiv, std::vector< std::vector<int> >& intersectEdge) throw(INTERP_KERNEL::Exception);
-    static void BuildIntersecting2DCellsFromEdges(double eps, const MEDCouplingUMesh *m1, const std::vector<bool>& b1, const int *desc1, const int *descIndx1, const std::vector<std::vector<int> >& intesctEdges1, const std::vector< std::vector<int> >& colinear2,
+    static void BuildIntersecting2DCellsFromEdges(double eps, const MEDCouplingUMesh *m1, const int *desc1, const int *descIndx1, const std::vector<std::vector<int> >& intesctEdges1, const std::vector< std::vector<int> >& colinear2,
                                                   const MEDCouplingUMesh *m2, const std::vector<bool>& b2, const int *desc2, const int *descIndx2, const std::vector<std::vector<int> >& intesctEdges2,
                                                   const std::vector<double>& addCoords,
                                                   std::vector<int>& cr, std::vector<int>& crI, std::vector<int>& cNb1, std::vector<int>& cNb2);
index f0b4c07695f0a714a5f00b04ff8a761228009b4d..cd2284a5a56390adeb839ec8727d05944d844f15 100644 (file)
@@ -1166,6 +1166,14 @@ int MEDFileUMesh::getMeshDimension() const throw(INTERP_KERNEL::Exception)
   throw INTERP_KERNEL::Exception("MEDFileUMesh::getMeshDimension : impossible to find a mesh dimension !");
 }
 
+int MEDFileUMesh::getSpaceDimension() const throw(INTERP_KERNEL::Exception)
+{
+  const DataArrayDouble *coo=_coords;
+  if(!coo)
+    throw INTERP_KERNEL::Exception(" MEDFileUMesh::getSpaceDimension : no coords set !");
+  return coo->getNumberOfComponents();
+}
+
 std::string MEDFileUMesh::simpleRepr() const
 {
   std::ostringstream oss;
index 013fcb2b7314a018560fe57c44041e70ea256315..8aa496ecf285df01da39d181270b4eec252eef0d 100644 (file)
@@ -142,6 +142,7 @@ namespace ParaMEDMEM
     //
     void write(const char *fileName, int mode) const throw(INTERP_KERNEL::Exception);
     int getMeshDimension() const throw(INTERP_KERNEL::Exception);
+    int getSpaceDimension() const throw(INTERP_KERNEL::Exception);
     std::string simpleRepr() const;
     std::string advancedRepr() const;
     int getSizeAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception);
index ec3ab77a08f40400a2eeea2c71de48d177ba7736..b10981ab56f5a4aa09f404fb2423ba9775490b95 100644 (file)
@@ -458,6 +458,7 @@ namespace ParaMEDMEM
     static MEDFileUMesh *New(const char *fileName) throw(INTERP_KERNEL::Exception);
     static MEDFileUMesh *New();
     ~MEDFileUMesh();
+    int getSpaceDimension() const throw(INTERP_KERNEL::Exception);
     //
     std::vector<int> getGrpNonEmptyLevels(const char *grp) const throw(INTERP_KERNEL::Exception);
     std::vector<int> getGrpNonEmptyLevelsExt(const char *grp) const throw(INTERP_KERNEL::Exception);