]> SALOME platform Git repositories - tools/medcoupling.git/commitdiff
Salome HOME
Partitionnizer of meshes.
authorageay <ageay>
Fri, 14 Oct 2011 10:33:49 +0000 (10:33 +0000)
committerageay <ageay>
Fri, 14 Oct 2011 10:33:49 +0000 (10:33 +0000)
23 files changed:
src/INTERP_KERNEL/Bases/NormalizedUnstructuredMesh.hxx
src/INTERP_KERNEL/CellModel.cxx
src/INTERP_KERNEL/CellModel.hxx
src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DComposedEdge.cxx
src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DComposedEdge.hxx
src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdge.cxx
src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdge.hxx
src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdge.txx
src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeArcCircle.cxx
src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeArcCircle.hxx
src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeLin.cxx
src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeLin.hxx
src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DElementaryEdge.cxx
src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DElementaryEdge.hxx
src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DNode.cxx
src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DNode.hxx
src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DQuadraticPolygon.cxx
src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DQuadraticPolygon.hxx
src/INTERP_KERNEL/InterpKernelCellSimplify.cxx
src/INTERP_KERNEL/InterpKernelCellSimplify.hxx
src/MEDCoupling/MEDCouplingUMesh.cxx
src/MEDCoupling/MEDCouplingUMesh.hxx
src/MEDCoupling_Swig/MEDCoupling.i

index 1a8101da6008671e43c6520ed560869af28e70ce..a5520aeb32a834416ef239d96fb8bf4dc2eda933 100644 (file)
@@ -39,6 +39,7 @@ namespace INTERP_KERNEL
       NORM_POLYGON =  5,
       NORM_TRI6    =  6,
       NORM_QUAD8   =  8,
+      NORM_QPOLYG  =  32,
       //
       NORM_TETRA4  = 14,
       NORM_PYRA5   = 15,
@@ -51,7 +52,7 @@ namespace INTERP_KERNEL
       NORM_HEXA20  = 30,
       NORM_POLYHED = 31,
       NORM_ERROR   = 40,
-      NORM_MAXTYPE = 31 // = NORM_POLYHED
+      NORM_MAXTYPE = 32
     } NormalizedCellType;
 
   class GenericMesh
index 4def4b4a69a787c3c402650ca14aed1eab432224..f9199b56f236ed22b145feeb6306731a8de8d560 100644 (file)
@@ -23,6 +23,7 @@
 
 #include <algorithm>
 #include <sstream>
+#include <vector>
 #include <limits>
 
 namespace INTERP_KERNEL
@@ -33,7 +34,7 @@ namespace INTERP_KERNEL
                                             "NORM_PYRA5", "NORM_PENTA6", "", "NORM_HEXA8", "",//15->19
                                             "NORM_TETRA10", "", "NORM_HEXGP12", "NORM_PYRA13", "",//20->24
                                             "NORM_PENTA15", "", "", "", "",//25->29
-                                            "NORM_HEXA20", "NORM_POLYHED", "", "", "",//30->34
+                                            "NORM_HEXA20", "NORM_POLYHED", "NORM_QPOLYG", "", "",//30->34
                                             "", "", "", "", "",//35->39
                                             "NORM_ERROR"};
 
@@ -96,6 +97,7 @@ namespace INTERP_KERNEL
     _map_of_unique_instance.insert(std::make_pair(NORM_HEXA20,CellModel(NORM_HEXA20)));
     _map_of_unique_instance.insert(std::make_pair(NORM_POLYGON,CellModel(NORM_POLYGON)));
     _map_of_unique_instance.insert(std::make_pair(NORM_POLYHED,CellModel(NORM_POLYHED)));
+    _map_of_unique_instance.insert(std::make_pair(NORM_QPOLYG,CellModel(NORM_QPOLYG)));
   }
 
   CellModel::CellModel(NormalizedCellType type):_type(type)
@@ -274,6 +276,11 @@ namespace INTERP_KERNEL
           _nb_of_pts=0; _nb_of_sons=0; _dim=3; _dyn=true; _is_simplex=false;
         }
         break;
+      case NORM_QPOLYG:
+        {
+          _nb_of_pts=0; _nb_of_sons=0; _dim=2; _dyn=true; _is_simplex=false;
+        }
+        break;
       case NORM_ERROR:
         {
           _nb_of_pts=std::numeric_limits<unsigned>::max(); _nb_of_sons=std::numeric_limits<unsigned>::max(); _dim=std::numeric_limits<unsigned>::max();
@@ -289,8 +296,13 @@ namespace INTERP_KERNEL
   {
     if(!isDynamic())
       return getNumberOfSons();
-    if(_dim==2)//polygon
-      return lgth;
+    if(_dim==2)
+      {
+        if(_type==NORM_POLYGON)
+          return lgth;
+        else
+          return lgth/2;
+      }
     else
       return std::count(conn,conn+lgth,-1)+1;
   }
@@ -302,8 +314,13 @@ namespace INTERP_KERNEL
   {
     if(!isDynamic())
       return getSonType(sonId);
-    if(_dim==2)//polygon
-      return NORM_SEG2;
+    if(_dim==2)
+      {
+        if(_type==NORM_POLYGON)
+          return NORM_SEG2;
+        else
+          return NORM_SEG3;
+      }
     //polyedron
     return NORM_POLYGON;
   }
@@ -329,9 +346,19 @@ namespace INTERP_KERNEL
       {
         if(_dim==2)//polygon
           {
-            sonNodalConn[0]=nodalConn[sonId];
-            sonNodalConn[1]=nodalConn[(sonId+1)%lgth];
-            return 2;
+            if(_type==NORM_POLYGON)
+              {
+                sonNodalConn[0]=nodalConn[sonId];
+                sonNodalConn[1]=nodalConn[(sonId+1)%lgth];
+                return 2;
+              }
+            else
+              {
+                sonNodalConn[0]=nodalConn[sonId];
+                sonNodalConn[1]=nodalConn[(sonId+1)%lgth];
+                sonNodalConn[2]=nodalConn[sonId+lgth];
+                return 3;
+              }
           }
         else
           {//polyedron
@@ -361,7 +388,10 @@ namespace INTERP_KERNEL
 
     if(_dim==2)//polygon
       {
-        return 2;
+        if(_type==NORM_POLYGON)
+          return 2;
+        else
+          return 3;
       }
     else
       {//polyedron
@@ -376,4 +406,63 @@ namespace INTERP_KERNEL
       }
   }
 
+  /*!
+   * This method retrieves if cell1 represented by 'conn1' and cell2 represented by 'conn2'
+   * are equivalent by a permutation or not. This method expects to work on 1D or 2D (only mesh dimension where it is possible to have a spaceDim) strictly higher than meshDim.
+   * If not an exception will be thrown.
+   * @return True if two cells have same orientation, false if not.
+   */
+  bool CellModel::getOrientationStatus(unsigned lgth, const int *conn1, const int *conn2) const
+  {
+    if(_dim!=1 && _dim!=2)
+      throw INTERP_KERNEL::Exception("CellModel::getOrientationStatus : invalid dimension ! Must be 1 or 2 !");
+    if(!_quadratic)
+      {
+        std::vector<int> tmp(2*lgth);
+        std::vector<int>::iterator it=std::copy(conn1,conn1+lgth,tmp.begin());
+        std::copy(conn1,conn1+lgth,it);
+        it=std::find_first_of(tmp.begin(),tmp.end(),conn2,conn2+lgth);
+        return it!=tmp.end();
+      }
+    else
+      {
+        if(_dim!=1)
+          {
+            std::vector<int> tmp(lgth);
+            std::vector<int>::iterator it=std::copy(conn1,conn1+lgth/2,tmp.begin());
+            std::copy(conn1,conn1+lgth/2,it);
+            it=std::find_first_of(tmp.begin(),tmp.end(),conn2,conn2+lgth/2);
+            int d=std::distance(tmp.begin(),it);
+            if(it==tmp.end())
+              return false;
+            it=std::copy(conn1+lgth/2,conn1+lgth,tmp.begin());
+            std::copy(conn1+lgth/2,conn1+lgth,it);
+            it=std::find_first_of(tmp.begin(),tmp.end(),conn2,conn2+lgth);
+            if(it==tmp.end())
+              return false;
+            int d2=std::distance(tmp.begin(),it);
+            return d==d2;
+          }
+        else
+          {
+            int p=(lgth+1)/2;
+            std::vector<int> tmp(2*p);
+            std::vector<int>::iterator it=std::copy(conn1,conn1+p,tmp.begin());
+            std::copy(conn1,conn1+p,it);
+            it=std::find_first_of(tmp.begin(),tmp.end(),conn2,conn2+p);
+            int d=std::distance(tmp.begin(),it);
+            if(it==tmp.end())
+              return false;
+            tmp.resize(2*p-2);
+            it=std::copy(conn1+p,conn1+lgth,tmp.begin());
+            std::copy(conn1+p,conn1+lgth,it);
+            it=std::find_first_of(tmp.begin(),tmp.end(),conn2+p,conn2+lgth);
+            if(it==tmp.end())
+              return false;
+            int d2=std::distance(tmp.begin(),it);
+            return d==d2;
+          }
+      }
+  }
+
 }
index 8c4b7d2360240b8813ff8426bad47a10dbb2dcae..4a07066461cc47003a157062631d6537b31b788f 100644 (file)
@@ -50,6 +50,7 @@ namespace INTERP_KERNEL
     INTERPKERNEL_EXPORT bool isSimplex() const { return _is_simplex; }
     //! sonId is in C format.
     INTERPKERNEL_EXPORT const unsigned *getNodesConstituentTheSon(unsigned sonId) const { return _sons_con[sonId]; }
+    INTERPKERNEL_EXPORT bool getOrientationStatus(unsigned lgth, const int *conn1, const int *conn2) const;
     INTERPKERNEL_EXPORT unsigned getNumberOfNodes() const { return _nb_of_pts; }
     INTERPKERNEL_EXPORT unsigned getNumberOfSons() const { return _nb_of_sons; }
     INTERPKERNEL_EXPORT unsigned getNumberOfSons2(const int *conn, int lgth) const;
index 07b6d5ca3ce16a1673c379afa5a7bd1177b58c5b..60f1fa52825403eaeb7ea690a6b98bbe76daa16c 100644 (file)
@@ -222,6 +222,18 @@ double ComposedEdge::normalize(ComposedEdge *other, double& xBary, double& yBary
   return dimChar;
 }
 
+double ComposedEdge::normalizeExt(ComposedEdge *other, double& xBary, double& yBary)
+{
+  Bounds b;
+  b.prepareForAggregation();
+  fillBounds(b); 
+  other->fillBounds(b);
+  double dimChar=b.getCaracteristicDim();
+  b.getBarycenter(xBary,yBary);
+  applyGlobalSimilarity2(other,xBary,yBary,dimChar);
+  return dimChar;
+}
+
 void ComposedEdge::dumpInXfigFile(std::ostream& stream, int resolution, const Bounds& box) const
 {
   stream.precision(10);
@@ -277,6 +289,26 @@ void ComposedEdge::applyGlobalSimilarity(double xBary, double yBary, double dimC
     (*iter)->applySimilarity(xBary,yBary,dimChar);
 }
 
+/*!
+ * Perform Similarity transformation on all elements of this Nodes and Edges on 'this' and 'other'.
+ * Nodes can be shared between 'this' and 'other'.
+ */
+void ComposedEdge::applyGlobalSimilarity2(ComposedEdge *other, double xBary, double yBary, double dimChar)
+{
+  std::set<Node *> allNodes;
+  getAllNodes(allNodes);
+  std::set<Node *> allNodes2;
+  other->getAllNodes(allNodes2);
+  for(std::set<Node *>::const_iterator it=allNodes2.begin();it!=allNodes2.end();it++)
+    if(allNodes.find(*it)!=allNodes.end())
+      (*it)->declareOn();
+  allNodes.insert(allNodes2.begin(),allNodes2.end());
+  for(std::set<Node *>::iterator iter=allNodes.begin();iter!=allNodes.end();iter++)
+    (*iter)->applySimilarity(xBary,yBary,dimChar);
+  for(std::list<ElementaryEdge *>::iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++)
+    (*iter)->applySimilarity(xBary,yBary,dimChar);
+}
+
 /*!
  * This method append to param 'partConsidered' the part of length of subedges IN or ON.
  * @param partConsidered INOUT param.
@@ -360,7 +392,7 @@ bool ComposedEdge::isInOrOut(Node *nodeToTest) const
       if(val)
         {
           Edge *e=val->getPtr();
-          std::auto_ptr<EdgeIntersector> intersc(Edge::buildIntersectorWith(e1,e));
+          std::auto_ptr<EdgeIntersector> intersc(Edge::BuildIntersectorWith(e1,e));
           bool obviousNoIntersection,areOverlapped;
           intersc->areOverlappedOrOnlyColinears(0,obviousNoIntersection,areOverlapped);
           if(obviousNoIntersection)
index 5e4299c0ae7defbb308529be320fea06e43605bc..3f0bd9c62d162fd9ae9015c597828f3685a72dd4 100644 (file)
@@ -55,9 +55,11 @@ namespace INTERP_KERNEL
     void getBarycenter(double *bary) const;
     void getBarycenterGeneral(double *bary) const;
     double normalize(ComposedEdge *other, double& xBary, double& yBary);
+    double normalizeExt(ComposedEdge *other, double& xBary, double& yBary);
     void fillBounds(Bounds& output) const;
     void applySimilarity(double xBary, double yBary, double dimChar);
     void applyGlobalSimilarity(double xBary, double yBary, double dimChar);
+    void applyGlobalSimilarity2(ComposedEdge *other, double xBary, double yBary, double dimChar);
     void dispatchPerimeter(double& partConsidered) const;
     void dispatchPerimeterExcl(double& partConsidered, double& commonPart) const;
     double dispatchPerimeterAdv(const ComposedEdge& father, std::vector<double>& result) const;
index 5096946099589364d9f58dea28c2843594489f47..6b06899a49f83e4e2dcdc638456ca15f119196bf 100644 (file)
@@ -541,12 +541,12 @@ void Edge::getNormalVector(double *vectOutput) const
   vectOutput[1]=-tmp;
 }
 
-Edge *Edge::buildEdgeFrom(Node *start, Node *end)
+Edge *Edge::BuildEdgeFrom(Node *start, Node *end)
 {
   return new EdgeLin(start,end);
 }
 
-Edge *Edge::buildFromXfigLine(std::istream& str)
+Edge *Edge::BuildFromXfigLine(std::istream& str)
 {
   unsigned char type;
   str >> type;
@@ -577,13 +577,13 @@ bool Edge::intersectWith(const Edge *other, MergePoints& commonNode,
     return false;
   delete merge;
   merge=0;
-  EdgeIntersector *intersector=buildIntersectorWith(this,other);
-  ret=intersect(this,other,intersector,merge,commonNode,outVal1,outVal2);
+  EdgeIntersector *intersector=BuildIntersectorWith(this,other);
+  ret=Intersect(this,other,intersector,merge,commonNode,outVal1,outVal2);
   delete intersector;
   return ret;
 }
 
-bool Edge::intersectOverlapped(const Edge *f1, const Edge *f2, EdgeIntersector *intersector, MergePoints& commonNode,
+bool Edge::IntersectOverlapped(const Edge *f1, const Edge *f2, EdgeIntersector *intersector, MergePoints& commonNode,
                                ComposedEdge& outValForF1, ComposedEdge& outValForF2)
 {
   bool rev=intersector->haveTheySameDirection();
@@ -591,14 +591,14 @@ bool Edge::intersectOverlapped(const Edge *f1, const Edge *f2, EdgeIntersector *
   Node *f2End=f2->getNode(rev?END:START);
   TypeOfLocInEdge place1, place2;
   intersector->getPlacements(f2Start,f2End,place1,place2,commonNode);
-  int codeForIntersectionCase=combineCodes(place1,place2);
-  return splitOverlappedEdges(f1,f2,f2Start,f2End,rev,codeForIntersectionCase,outValForF1,outValForF2);
+  int codeForIntersectionCase=CombineCodes(place1,place2);
+  return SplitOverlappedEdges(f1,f2,f2Start,f2End,rev,codeForIntersectionCase,outValForF1,outValForF2);
 }
 
 /*!
  * Perform 1D linear interpolation. Warning distrib1 and distrib2 are expected to be in ascending mode.
  */
-void Edge::interpolate1DLin(const std::vector<double>& distrib1, const std::vector<double>& distrib2, std::map<int, std::map<int,double> >& result)
+void Edge::Interpolate1DLin(const std::vector<double>& distrib1, const std::vector<double>& distrib2, std::map<int, std::map<int,double> >& result)
 {
   int nbOfV1=distrib1.size()-1;
   int nbOfV2=distrib2.size()-1;
@@ -622,7 +622,7 @@ void Edge::interpolate1DLin(const std::vector<double>& distrib1, const std::vect
                   SegSegIntersector inters(*e1,*e2);
                   bool b1,b2;
                   inters.areOverlappedOrOnlyColinears(0,b1,b2);
-                  if(intersectOverlapped(e1,e2,&inters,commonNode,*f1,*f2))
+                  if(IntersectOverlapped(e1,e2,&inters,commonNode,*f1,*f2))
                     {
                       result[i][j]=f1->getCommonLengthWith(*f2)/e1->getCurveLength();
                     }
@@ -635,7 +635,7 @@ void Edge::interpolate1DLin(const std::vector<double>& distrib1, const std::vect
   n1->decrRef(); n2->decrRef(); n3->decrRef(); n4->decrRef();
 }
 
-EdgeIntersector *Edge::buildIntersectorWith(const Edge *e1, const Edge *e2)
+EdgeIntersector *Edge::BuildIntersectorWith(const Edge *e1, const Edge *e2)
 {
   EdgeIntersector *ret=0;
   const EdgeLin *tmp1=0;
@@ -671,14 +671,14 @@ void Edge::applySimilarity(double xBary, double yBary, double dimChar)
   _bounds.applySimilarity(xBary,yBary,dimChar);
 }
 
-bool Edge::intersect(const Edge *f1, const Edge *f2, EdgeIntersector *intersector, const Bounds *whereToFind, MergePoints& commonNode,
+bool Edge::Intersect(const Edge *f1, const Edge *f2, EdgeIntersector *intersector, const Bounds *whereToFind, MergePoints& commonNode,
                      ComposedEdge& outValForF1, ComposedEdge& outValForF2)
 {
   bool obviousNoIntersection;
   bool areOverlapped;
   intersector->areOverlappedOrOnlyColinears(whereToFind,obviousNoIntersection,areOverlapped);
   if(areOverlapped)
-    return intersectOverlapped(f1,f2,intersector,commonNode,outValForF1,outValForF2);
+    return IntersectOverlapped(f1,f2,intersector,commonNode,outValForF1,outValForF2);
   if(obviousNoIntersection)
     return false;
   std::vector<Node *> newNodes;
@@ -712,7 +712,7 @@ bool Edge::intersect(const Edge *f1, const Edge *f2, EdgeIntersector *intersecto
     return false;
 }
 
-int Edge::combineCodes(TypeOfLocInEdge code1, TypeOfLocInEdge code2)
+int Edge::CombineCodes(TypeOfLocInEdge code1, TypeOfLocInEdge code2)
 {
   int ret=(int)code1;
   ret*=OFFSET_FOR_TYPEOFLOCINEDGE;
@@ -729,7 +729,7 @@ int Edge::combineCodes(TypeOfLocInEdge code1, TypeOfLocInEdge code2)
  * @param direction is param that specifies if e2 and e1 have same directions (true) or opposed (false).
  * @param code is the code returned by method Edge::combineCodes.
  */
-bool Edge::splitOverlappedEdges(const Edge *e1, const Edge *e2, Node *nS, Node *nE, bool direction, int code,
+bool Edge::SplitOverlappedEdges(const Edge *e1, const Edge *e2, Node *nS, Node *nE, bool direction, int code,
                                 ComposedEdge& outVal1, ComposedEdge& outVal2)
 {
   Edge *tmp;
index 28207b13d586d242ead1ce7bd41257e58c30edcd..0c539f596c3330148de92b3fcccede9a66387534 100644 (file)
@@ -219,11 +219,11 @@ namespace INTERP_KERNEL
     bool changeEndNodeWithAndKeepTrack(Node *otherEndNode, std::vector<Node *>& track) const;
     void addSubEdgeInVector(Node *start, Node *end, ComposedEdge& vec) const;
     void getNormalVector(double *vectOutput) const;
-    static EdgeIntersector *buildIntersectorWith(const Edge *e1, const Edge *e2);
-    static Edge *buildFromXfigLine(std::istream& str);
-    static Edge *buildEdgeFrom(Node *start, Node *end);
+    static EdgeIntersector *BuildIntersectorWith(const Edge *e1, const Edge *e2);
+    static Edge *BuildFromXfigLine(std::istream& str);
+    static Edge *BuildEdgeFrom(Node *start, Node *end);
     template<TypeOfMod4QuadEdge type>
-    static Edge *buildEdgeFrom(Node *start, Node *middle, Node *end);
+    static Edge *BuildEdgeFrom(Node *start, Node *middle, Node *end);
     virtual void update(Node *m) = 0;
     //! returns area between this and axe Ox delimited along Ox by _start and _end.
     virtual double getAreaOfZone() const = 0;
@@ -250,20 +250,26 @@ namespace INTERP_KERNEL
                                  const EdgeArcCircle * &arcSeg) const = 0;
     bool intersectWith(const Edge *other, MergePoints& commonNode,
                        ComposedEdge& outVal1, ComposedEdge& outVal2) const;
-    static bool intersectOverlapped(const Edge *f1, const Edge *f2, EdgeIntersector *intersector, MergePoints& commonNode,
+    static bool IntersectOverlapped(const Edge *f1, const Edge *f2, EdgeIntersector *intersector, MergePoints& commonNode,
                                     ComposedEdge& outValForF1, ComposedEdge& outValForF2);
-    static void interpolate1DLin(const std::vector<double>& distrib1, const std::vector<double>& distrib2,
+    static void Interpolate1DLin(const std::vector<double>& distrib1, const std::vector<double>& distrib2,
                                  std::map<int, std::map<int,double> >& result);
     virtual void dumpInXfigFile(std::ostream& stream, bool direction, int resolution, const Bounds& box) const = 0;
     bool isEqual(const Edge& other) const;
+  public:
+    virtual void fillGlobalInfoAbs(bool direction, 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>& 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; 
   protected:
     Edge():_cnt(1),_loc(FULL_UNKNOWN),_start(0),_end(0) { }
     virtual ~Edge();
-    static int combineCodes(TypeOfLocInEdge code1, TypeOfLocInEdge code2);
-    static bool intersect(const Edge *f1, const Edge *f2, EdgeIntersector *intersector, const Bounds *whereToFind, MergePoints& commonNode,
+    static int CombineCodes(TypeOfLocInEdge code1, TypeOfLocInEdge code2);
+    static bool Intersect(const Edge *f1, const Edge *f2, EdgeIntersector *intersector, const Bounds *whereToFind, MergePoints& commonNode,
                           ComposedEdge& outValForF1, ComposedEdge& outValForF2);
     //! 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,
+    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:
index c6d3c20b55e2ca02571ef42a4e682322f35d2716..bddb26aee83050c4c15dc56e185caabe3a8ea1b0 100644 (file)
@@ -22,7 +22,7 @@
 #include "InterpKernelGeo2DEdgeArcCircle.hxx"
 
 template<INTERP_KERNEL::TypeOfMod4QuadEdge type>
-INTERP_KERNEL::Edge *INTERP_KERNEL::Edge::buildEdgeFrom(Node *start, Node *middle, Node *end)
+INTERP_KERNEL::Edge *INTERP_KERNEL::Edge::BuildEdgeFrom(Node *start, Node *middle, Node *end)
 {
   return new INTERP_KERNEL::EdgeArcCircle(start,middle,end);
 }
index c3345562444609993cf0b3074859c4abbb9d4dcf..fc978933b0bdbea6c07b1254c54ec3fa389d36ab 100644 (file)
@@ -21,6 +21,7 @@
 #include "InterpKernelGeo2DEdgeLin.hxx"
 #include "InterpKernelException.hxx"
 #include "InterpKernelGeo2DNode.hxx"
+#include "NormalizedUnstructuredMesh.hxx"
 
 #include <sstream>
 #include <algorithm>
@@ -693,3 +694,43 @@ void EdgeArcCircle::updateBounds()
   if(isIn2Pi(_angle0,_angle,M_PI))
     _bounds[0]=_center[0]-_radius;
 }
+
+void EdgeArcCircle::fillGlobalInfoAbs(bool direction, 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>& edgesThis, std::vector<double>& addCoo, std::map<INTERP_KERNEL::Node *,int> mapAddCoo) const
+{
+  int tmp[2];
+  _start->fillGlobalInfoAbs(mapThis,mapOther,offset1,offset2,fact,baryX,baryY,addCoo,mapAddCoo,tmp);
+  _end->fillGlobalInfoAbs(mapThis,mapOther,offset1,offset2,fact,baryX,baryY,addCoo,mapAddCoo,tmp+1);
+  if(direction)
+    {
+      edgesThis.push_back(tmp[0]);
+      edgesThis.push_back(tmp[1]);
+    }
+  else
+    {
+      edgesThis.push_back(tmp[1]);
+      edgesThis.push_back(tmp[0]);
+    }
+}
+
+void EdgeArcCircle::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
+{
+  _start->fillGlobalInfoAbs2(mapThis,mapOther,offset1,offset2,fact,baryX,baryY,addCoo,mapAddCoo,edgesOther);
+  _end->fillGlobalInfoAbs2(mapThis,mapOther,offset1,offset2,fact,baryX,baryY,addCoo,mapAddCoo,edgesOther);
+}
+
+void EdgeArcCircle::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)
+{
+  Bounds b;
+  b.prepareForAggregation();
+  b.aggregate(getBounds());
+  double xBary,yBary;
+  double dimChar=b.getCaracteristicDim();
+  b.getBarycenter(xBary,yBary);
+  applySimilarity(xBary,yBary,dimChar);
+  for(std::vector<Node *>::const_iterator iter=addNodes.begin();iter!=addNodes.end();iter++)
+    (*iter)->applySimilarity(xBary,yBary,dimChar);
+  _start->applySimilarity(xBary,yBary,dimChar);
+  _end->applySimilarity(xBary,yBary,dimChar);
+}
index 8cf60482d3f764f0c215fb1dc64c921271b8ada6..5d2e80f5fdebd9d4ffe666c2a0cc9055ee9d2af3 100644 (file)
@@ -111,6 +111,11 @@ namespace INTERP_KERNEL
   protected:
     void updateBounds();
     Edge *buildEdgeLyingOnMe(Node *start, Node *end, bool direction=true) const;
+    void fillGlobalInfoAbs(bool direction, 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>& 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;
+    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);
   protected:
     //!Value between -2Pi and 2Pi
     double _angle;
index 55938f25c4a9289113e7ad1c862fd2b0a01fe458..e31aa3cc5cf129a33879b9a9e1925b4cd2005f2e 100644 (file)
@@ -20,6 +20,7 @@
 #include "InterpKernelGeo2DEdgeLin.hxx"
 #include "InterpKernelGeo2DNode.hxx"
 #include "InterpKernelException.hxx"
+#include "NormalizedUnstructuredMesh.hxx"
 
 using namespace INTERP_KERNEL;
 
@@ -292,3 +293,83 @@ double EdgeLin::getCharactValueEng(const double *node) const
   double car1_1y=node[1]-(*(_start))[1]; double car1_2y=(*(_end))[1]-(*(_start))[1];
   return (car1_1x*car1_2x+car1_1y*car1_2y)/(car1_2x*car1_2x+car1_2y*car1_2y);
 }
+
+void EdgeLin::fillGlobalInfoAbs(bool direction, 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>& edgesThis, std::vector<double>& addCoo, std::map<INTERP_KERNEL::Node *,int> mapAddCoo) const
+{
+  int tmp[2];
+  _start->fillGlobalInfoAbs(mapThis,mapOther,offset1,offset2,fact,baryX,baryY,addCoo,mapAddCoo,tmp);
+  _end->fillGlobalInfoAbs(mapThis,mapOther,offset1,offset2,fact,baryX,baryY,addCoo,mapAddCoo,tmp+1);
+  if(direction)
+    {
+      edgesThis.push_back(tmp[0]);
+      edgesThis.push_back(tmp[1]);
+    }
+  else
+    {
+      edgesThis.push_back(tmp[1]);
+      edgesThis.push_back(tmp[0]);
+    }
+}
+
+void EdgeLin::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
+{
+  _start->fillGlobalInfoAbs2(mapThis,mapOther,offset1,offset2,fact,baryX,baryY,addCoo,mapAddCoo,edgesOther);
+  _end->fillGlobalInfoAbs2(mapThis,mapOther,offset1,offset2,fact,baryX,baryY,addCoo,mapAddCoo,edgesOther);
+}
+
+inline bool eqpair(const std::pair<double,Node *>& p1, const std::pair<double,Node *>& p2)
+{
+  return fabs(p1.first-p2.first)<QUADRATIC_PLANAR::_precision;
+}
+
+void EdgeLin::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)
+{
+  Bounds b;
+  b.prepareForAggregation();
+  b.aggregate(getBounds());
+  double xBary,yBary;
+  double dimChar=b.getCaracteristicDim();
+  b.getBarycenter(xBary,yBary);
+  for(std::vector<Node *>::const_iterator iter=addNodes.begin();iter!=addNodes.end();iter++)
+    (*iter)->applySimilarity(xBary,yBary,dimChar);
+  _start->applySimilarity(xBary,yBary,dimChar);
+  _end->applySimilarity(xBary,yBary,dimChar);
+  std::size_t sz=addNodes.size();
+  std::vector< std::pair<double,Node *> > an2(sz);
+  for(std::size_t i=0;i<sz;i++)
+    an2[i]=std::pair<double,Node *>(getCharactValue(*addNodes[i]),addNodes[i]);
+  std::sort(an2.begin(),an2.end());
+  int startId=(*mapp1.find(_start)).second;
+  int endId=(*mapp1.find(_end)).second;
+  std::vector<int> tmpp;
+  std::vector< std::pair<double,Node *> >::const_iterator itend=std::unique(an2.begin(),an2.end(),eqpair);
+  for(std::vector< std::pair<double,Node *> >::const_iterator it=an2.begin();it!=itend;it++)
+    {
+      int idd=(*mapp2.find((*it).second)).second;
+      if((*it).first<QUADRATIC_PLANAR::_precision)
+        {
+          startId=idd;
+          continue;
+        }
+      if((*it).first>1-QUADRATIC_PLANAR::_precision)
+        {
+          endId=idd;
+          continue;
+        }
+      tmpp.push_back(idd);
+    }
+  std::vector<int> tmpp2(tmpp.size()+2);
+  tmpp2[0]=startId;
+  std::copy(tmpp.begin(),tmpp.end(),tmpp2.begin()+1);
+  tmpp2[tmpp.size()+1]=endId;
+  std::vector<int>::iterator itt=std::unique(tmpp2.begin(),tmpp2.end());
+  tmpp2.resize(std::distance(tmpp2.begin(),itt));
+  int nbOfEdges=tmpp2.size()-1;
+  for(int i=0;i<nbOfEdges;i++)
+    {
+      edgesThis.push_back(tmpp2[i]);
+      edgesThis.push_back(tmpp2[i+1]);
+    }
+}
index 85c60f47642b97cc5c4261bef9966214cdd627ee..1c7e901ddc3d316e0959ddb772232c9c8a0b30b5 100644 (file)
@@ -74,6 +74,11 @@ namespace INTERP_KERNEL
     EdgeLin() { }
     void updateBounds();
     Edge *buildEdgeLyingOnMe(Node *start, Node *end, bool direction) const;
+    void fillGlobalInfoAbs(bool direction, 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>& 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;
+    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);
   };
 }
 
index 4369f24868e8669909ef61ba0306dfcbedf7c497..ff5a98a4fcdd7bd0c4bae1e0b80aa1b2498a9c41 100644 (file)
@@ -200,3 +200,32 @@ bool ElementaryEdge::isEqual(const ElementaryEdge& other) const
 {
   return _ptr->isEqual(*other._ptr);
 }
+
+/*!
+ * Called by QuadraticPolygon::splitAbs method.
+ */
+void ElementaryEdge::fillGlobalInfoAbs(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>& edgesThis, std::vector<double>& addCoo, std::map<INTERP_KERNEL::Node *,int> mapAddCoo) const
+{
+  _ptr->fillGlobalInfoAbs(_direction,mapThis,mapOther,offset1,offset2,fact,baryX,baryY,edgesThis,addCoo,mapAddCoo);
+}
+
+/*!
+ * Called by QuadraticPolygon::splitAbs method. Close to ElementaryEdge::fillGlobalInfoAbs method expect that here edgesOther (that replace edgesThis) is here an in/out parameter that only contains nodes
+ * unsorted because the "other" mesh is not subdivided yet.
+ */
+void ElementaryEdge::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
+{
+  _ptr->fillGlobalInfoAbs2(mapThis,mapOther,offset1,offset2,fact,baryX,baryY,edgesOther,addCoo,mapAddCoo);
+}
+
+/*!
+ * 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)
+{
+  Edge *ptr=Edge::BuildEdgeFrom(start,end);
+  return new ElementaryEdge(ptr,direction);
+}
index e70dfd0ba1b0145b7aeca1ebc99c57e6ee77674f..5a23a6d963186164072b6a7a4f49355c75069c9b 100644 (file)
@@ -65,6 +65,12 @@ namespace INTERP_KERNEL
     bool getDirection() const { return _direction; }
     bool intresincEqCoarse(const Edge *other) const;
     bool isEqual(const ElementaryEdge& other) const;
+  public:
+    void fillGlobalInfoAbs(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>& 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);
   private:
     bool _direction;
     Edge *_ptr;
index 9ac557b0e9090208c9484cf5022015820ecde707..7e336ade238f6964533631f0c29a564f6d01f7e9 100644 (file)
@@ -130,3 +130,54 @@ void Node::applySimilarity(double xBary, double yBary, double dimChar)
   _coords[0]=(_coords[0]-xBary)/dimChar;
   _coords[1]=(_coords[1]-yBary)/dimChar;
 }
+
+/*!
+ * Called by QuadraticPolygon::splitAbs method.
+ */
+void Node::fillGlobalInfoAbs(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<double>& addCoo, std::map<INTERP_KERNEL::Node *,int> mapAddCoo, int *nodeId) const
+{
+  std::map<INTERP_KERNEL::Node *,int>::const_iterator it=mapThis.find(const_cast<Node *>(this));
+  if(it!=mapThis.end())
+    {
+      *nodeId=(*it).second;
+      return;
+    }
+  it=mapOther.find(const_cast<Node *>(this));
+  if(it!=mapOther.end())
+    {
+      *nodeId=(*it).second+offset1;
+      return;
+    }
+  it=mapAddCoo.find(const_cast<Node *>(this));
+  if(it!=mapAddCoo.end())
+    {
+      *nodeId=(*it).second;
+      return;
+    }
+  int id=addCoo.size()/2;
+  addCoo.push_back(fact*_coords[0]+baryX);
+  addCoo.push_back(fact*_coords[0]+baryX);
+  mapAddCoo[const_cast<Node *>(this)]=offset2+id;
+}
+
+/*!
+ * Called by QuadraticPolygon::splitAbs method.
+ */
+void Node::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<double>& addCoo, std::map<INTERP_KERNEL::Node *,int> mapAddCoo, std::vector<int>& pointsOther) const
+{
+  int tmp;
+  std::size_t sz1=addCoo.size();
+  fillGlobalInfoAbs(mapThis,mapOther,offset1,offset2,fact,baryX,baryY,addCoo,mapAddCoo,&tmp);
+  if(sz1!=addCoo.size())
+    {
+      pointsOther.push_back(tmp);
+      return ;
+    }
+  std::vector<int>::const_iterator it=std::find(pointsOther.begin(),pointsOther.end(),tmp);
+  if(it!=pointsOther.end())
+    return ;
+  if(tmp<offset1)
+    pointsOther.push_back(tmp);
+}
index 9adb15294304960813f031190ba4da4abd4edf7c..c8ed49e8bd3d2e84189c81709b79c4273bb2dbcf 100644 (file)
@@ -23,6 +23,7 @@
 #include "InterpKernelGeo2DPrecision.hxx"
 #include "INTERPKERNELGEOMETRIC2DDefines.hxx"
 
+#include <map>
 #include <cmath>
 #include <vector>
 #include <iostream>
@@ -83,6 +84,11 @@ namespace INTERP_KERNEL
     static bool areDoubleEqualsWP(double a, double b, double k) { return fabs(a-b) < k*QUADRATIC_PLANAR::_precision; }
     static double distanceBtw2Pt(const double *a, const double *b) { return sqrt((a[0]-b[0])*(a[0]-b[0])+(a[1]-b[1])*(a[1]-b[1])); }
     static double distanceBtw2PtSq(const double *a, const double *b) { return (a[0]-b[0])*(a[0]-b[0])+(a[1]-b[1])*(a[1]-b[1]); }
+    //
+    void fillGlobalInfoAbs(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<double>& addCoo, std::map<INTERP_KERNEL::Node *,int> mapAddCoo, int *nodeId) 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<double>& addCoo, std::map<INTERP_KERNEL::Node *,int> mapAddCoo, std::vector<int>& pointsOther) const;
   protected:
     ~Node();
   protected:
index d66bdae4e45fe6ed95eb5bb492353a9431b3aaa4..845e9fc5dacf6069e4f1b92f5483a418bb01822e 100644 (file)
@@ -49,7 +49,7 @@ QuadraticPolygon::QuadraticPolygon(const char *file)
       while(strcmp(currentLine,"1200 2")!=0);
       do
         {
-          Edge *newEdge=Edge::buildFromXfigLine(stream);
+          Edge *newEdge=Edge::BuildFromXfigLine(stream);
           if(!empty())
             newEdge->changeStartNodeWith(back()->getEndNode());
           pushBack(newEdge);
@@ -207,6 +207,149 @@ double QuadraticPolygon::intersectWithAbs(QuadraticPolygon& other)
   return ret*fact*fact;
 }
 
+/*!
+ * This method splits 'this' with 'other' into smaller pieces localizable. 'mapThis' is a map that gives the correspondance between nodes contained in 'this' and node ids in a global mesh.
+ * In the same way, 'mapOther' gives the correspondance between nodes contained in 'other' and node ids in a global mesh from wich 'other' is extracted.
+ * This method has 1 out paramater : 'edgesThis', After the call of this method contains nodal connectivity (including type) of 'this' into globlal "this mesh".
+ * This method has 2 in/out parameters : 'subDivOther' and 'addCoo'.'otherEdgeIds' is useful to put values in 'edgesThis', 'subDivOther' and 'addCoo'.
+ * Size of 'otherEdgeIds' has to be equal to number of ElementaryEdges in 'other'. No check of that will be done.
+ * @param offset1 is the number of nodes contained in global mesh from which 'this' is extracted.
+ * @param offset2 is the sum of nodes contained in global mesh from which 'this' is extracted and 'other' is extracted.
+ * @otherEdgeIds is a vector with the same size than other before calling this method. It gives in the same order the cell id in global other mesh.
+ */
+void QuadraticPolygon::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, std::vector< std::vector<int> >& subDivOther, std::vector<double>& addCoo)
+{
+  double xBaryBB, yBaryBB;
+  double fact=normalize(&other, xBaryBB, yBaryBB);
+  //
+  IteratorOnComposedEdge it1(this),it3(&other);
+  MergePoints merge;
+  ComposedEdge *c1=new ComposedEdge;
+  ComposedEdge *c2=new ComposedEdge;
+  int i=0;
+  std::map<INTERP_KERNEL::Node *,int> mapAddCoo;
+  for(it3.first();!it3.finished();it3.next(),i++)
+    {
+      QuadraticPolygon otherTmp;
+      ElementaryEdge* curE3=it3.current();
+      otherTmp.pushBack(new ElementaryEdge(curE3->getPtr(),curE3->getDirection())); curE3->getPtr()->incrRef();
+      IteratorOnComposedEdge it2(&otherTmp);
+      for(it2.first();it2.finished();it2.next())
+        {
+          ElementaryEdge* curE2=it2.current();
+          if(!curE2->isThereStartPoint())
+            it1.first();
+          else
+            it1=curE2->getIterator();
+          for(;!it1.finished();)
+            { 
+              ElementaryEdge* curE1=it1.current();
+              merge.clear();
+              if(curE1->getPtr()->intersectWith(curE2->getPtr(),merge,*c1,*c2))
+                {
+                  if(!curE1->getDirection()) c1->reverse();
+                  if(!curE2->getDirection()) c2->reverse();
+                  updateNeighbours(merge,it1,it2,c1,c2);
+                  //Substitution of simple edge by sub-edges.
+                  delete curE1; // <-- destroying simple edge coming from pol1
+                  delete curE2; // <-- destroying simple edge coming from pol2
+                  it1.insertElemEdges(c1,true);// <-- 2nd param is true to go next.
+                  it2.insertElemEdges(c2,false);// <-- 2nd param is false to avoid to go next.
+                  curE2=it2.current();
+                  //
+                  it1.assignMySelfToAllElems(c2);//To avoid that others
+                  SoftDelete(c1);
+                  SoftDelete(c2);
+                  c1=new ComposedEdge;
+                  c2=new ComposedEdge;
+                }
+              else
+                {
+                  updateNeighbours(merge,it1,it2,curE1,curE2);
+                  it1.next();
+                }
+            }
+        }
+      if(otherTmp._sub_edges.size()>1)
+        {
+          for(std::list<ElementaryEdge *>::const_iterator it=otherTmp._sub_edges.begin();it!=otherTmp._sub_edges.end();it++)
+            (*it)->fillGlobalInfoAbs2(mapThis,mapOther,offset1,offset2,/**/fact,xBaryBB,yBaryBB,/**/subDivOther[otherEdgeIds[i]],addCoo,mapAddCoo);
+        }
+    }
+  Delete(c1);
+  Delete(c2);
+  //
+  for(std::list<ElementaryEdge *>::const_iterator it=_sub_edges.begin();it!=_sub_edges.end();it++)
+    (*it)->fillGlobalInfoAbs(mapThis,mapOther,offset1,offset2,/**/fact,xBaryBB,yBaryBB,/**/edgesThis,addCoo,mapAddCoo);
+  //
+}
+
+/*!
+ * 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)
+{
+  int nbOfSeg=std::distance(descBg,descEnd);
+  for(int i=0;i<nbOfSeg;i++)
+    {
+      bool direct=descBg[i]>0;
+      int edgeId=abs(descBg[i])-1;
+      const std::vector<int>& subEdge=intersectEdges[edgeId];
+      int nbOfSubEdges=subEdge.size()-1;
+      for(int j=0;j<nbOfSubEdges;j++)
+        {
+          Node *start=(*mapp.find(direct?subEdge[j]:subEdge[nbOfSubEdges-j])).second;
+          Node *end=(*mapp.find(direct?subEdge[j+1]:subEdge[nbOfSubEdges-j-1])).second;
+          ElementaryEdge *e=ElementaryEdge::BuildEdgeFromCrudeDataArray(isQuad,direct,start,end);
+          pushBack(e);
+        }
+    }
+}
+
+void QuadraticPolygon::appendCrudeData(const std::map<INTERP_KERNEL::Node *,int>& mapp, std::vector<int>& conn, std::vector<int>& connI)
+{
+  int nbOfNodesInPg=0,i=0;
+  for(std::list<ElementaryEdge *>::const_iterator it=_sub_edges.begin();it!=_sub_edges.end();it++,i++)
+    {
+      Node *tmp=0;
+      if(i==0)
+        {
+          tmp=(*it)->getStartNode();
+          std::map<INTERP_KERNEL::Node *,int>::const_iterator it=mapp.find(tmp);
+          conn.push_back((*it).second);
+          nbOfNodesInPg++;
+        }
+      tmp=(*it)->getEndNode();
+      std::map<INTERP_KERNEL::Node *,int>::const_iterator it=mapp.find(tmp);
+      conn.push_back((*it).second);
+      nbOfNodesInPg++;
+    }
+  connI.push_back(connI.back()+nbOfNodesInPg);
+}
+
+/*!
+ * This method make the hypothesis that 'this' and 'other' are splited at the minimum into edges that are fully IN, OUT or ON.
+ * This method returns newly created polygons in 'conn' and 'connI' and the corresponding ids ('idThis','idOther') are stored respectively into 'nbThis' and 'nbOther'.
+ */
+void QuadraticPolygon::buildPartitionsAbs(QuadraticPolygon& other, const std::map<INTERP_KERNEL::Node *,int>& mapp, int idThis, int idOther, std::vector<int>& conn, std::vector<int>& connI, std::vector<int>& nbThis, std::vector<int>& nbOther)
+{
+  double xBaryBB, yBaryBB;
+  normalizeExt(&other, xBaryBB, yBaryBB);
+  //Locate 'this' relative to 'other'
+  other.performLocatingOperation(*this);
+  dumpInXfigFileWithOther(other,"tony.fig");
+  std::vector<QuadraticPolygon *> res=other.buildIntersectionPolygons(*this,other);
+  for(std::vector<QuadraticPolygon *>::iterator it=res.begin();it!=res.end();it++)
+    {
+      (*it)->appendCrudeData(mapp,conn,connI);
+      nbThis.push_back(idThis);
+      nbOther.push_back(idOther);
+      delete *it;
+    }
+}
+
 /*!
  * Warning This method is \b NOT const. 'this' and 'other' are modified after call of this method.
  * 'other' is a QuadraticPolygon of \b non closed edges.
index 5b9e2bc6ee296f7a4afe84056cc6f9a0a43b54c8..dcfe0ecb2f88cfe2238e3443709c6947bcbb4846 100644 (file)
@@ -54,6 +54,12 @@ namespace INTERP_KERNEL
     double intersectWithAbs1D(QuadraticPolygon& other, bool& isColinear);
     //! Before intersecting as intersectWith a normalization is done.
     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, 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 appendCrudeData(const std::map<INTERP_KERNEL::Node *,int>& mapp, std::vector<int>& conn, std::vector<int>& connI);
+    void buildPartitionsAbs(QuadraticPolygon& other, const std::map<INTERP_KERNEL::Node *,int>& mapp, int idThis, int idOther, std::vector<int>& conn, std::vector<int>& connI, std::vector<int>& nb1, std::vector<int>& nb2);
+
     double intersectWith(const QuadraticPolygon& other) const;
     double intersectWith(const QuadraticPolygon& other, double* barycenter) const;
     std::vector<QuadraticPolygon *> intersectMySelfWith(const QuadraticPolygon& other) const;
index 5ebce3c4c361c09425475ad0378e6155ddc71871..d8d5e6ae9b8222e72b679583671db4bd28b053d8 100644 (file)
@@ -60,7 +60,7 @@ INTERP_KERNEL::NormalizedCellType CellSimplify::simplifyDegeneratedCell(INTERP_K
       for(int i=1;i<lgth;i++)
         if(std::find(tmp,tmp+newPos,conn[i])==tmp+newPos)
           tmp[newPos++]=conn[i];
-      INTERP_KERNEL::NormalizedCellType ret=tryToUnPoly2D(tmp,newPos,retConn,retLgth);
+      INTERP_KERNEL::NormalizedCellType ret=tryToUnPoly2D(cm.isQuadratic(),tmp,newPos,retConn,retLgth);
       delete [] tmp;
       return ret;
     }
@@ -80,18 +80,33 @@ INTERP_KERNEL::NormalizedCellType CellSimplify::simplifyDegeneratedCell(INTERP_K
  * This static method tries to unpolygonize a cell whose connectivity is given by 'conn' and 'lgth'.
  * Contrary to INTERP_KERNEL::CellSimplify::simplifyDegeneratedCell method 'conn' and 'retConn' do not overlap. 
  */
-INTERP_KERNEL::NormalizedCellType CellSimplify::tryToUnPoly2D(const int *conn, int lgth, int *retConn, int& retLgth)
+INTERP_KERNEL::NormalizedCellType CellSimplify::tryToUnPoly2D(bool isQuad, const int *conn, int lgth, int *retConn, int& retLgth)
 {
   retLgth=lgth;
   std::copy(conn,conn+lgth,retConn);
-  switch(lgth)
+  if(!isQuad)
     {
-    case 3:
-      return INTERP_KERNEL::NORM_TRI3;
-    case 4:
-      return INTERP_KERNEL::NORM_QUAD4;
-    default:
-      return INTERP_KERNEL::NORM_POLYGON;
+      switch(lgth)
+        {
+        case 3:
+          return INTERP_KERNEL::NORM_TRI3;
+        case 4:
+          return INTERP_KERNEL::NORM_QUAD4;
+        default:
+          return INTERP_KERNEL::NORM_POLYGON;
+        }
+    }
+  else
+    {
+      switch(lgth)
+        {
+          case 6:
+            return INTERP_KERNEL::NORM_TRI6;
+          case 8:
+            return INTERP_KERNEL::NORM_QUAD8;
+          default:
+            return INTERP_KERNEL::NORM_QPOLYG;
+        }
     }
 }
 
@@ -126,7 +141,7 @@ int *CellSimplify::getFullPolyh3DCell(INTERP_KERNEL::NormalizedCellType type, co
           continue;
         }
       int tmp3;
-      faces.push_back(tryToUnPoly2D(tmp2,newPos,work,tmp3));
+      faces.push_back(tryToUnPoly2D(CellModel::GetCellModel(type).isQuadratic(),tmp2,newPos,work,tmp3));
       delete [] tmp2;
       //
       work+=newPos;
index 6b2434e1934b5a375988221adc563adce9cd0248..1cf3d7bb99f4b0411807d566ad5f31fdf6748997 100644 (file)
@@ -33,7 +33,7 @@ namespace INTERP_KERNEL
                                                                      int *retConn, int& retLgth) throw(INTERP_KERNEL::Exception);
     static int *getFullPolyh3DCell(INTERP_KERNEL::NormalizedCellType type, const int *conn, int lgth,
                                    int& retNbOfFaces, int& retLgth);
-    static INTERP_KERNEL::NormalizedCellType tryToUnPoly2D(const int *conn, int lgth, int *retConn, int& retLgth);
+    static INTERP_KERNEL::NormalizedCellType tryToUnPoly2D(bool isQuad, const int *conn, int lgth, int *retConn, int& retLgth);
     static INTERP_KERNEL::NormalizedCellType tryToUnPoly3D(const int *conn, int nbOfFaces, int lgth, int *retConn, int& retLgth);
     static INTERP_KERNEL::NormalizedCellType tryToUnPolyHex8(const int *conn, int nbOfFaces, int lgth, int *retConn, int& retLgth);
     static INTERP_KERNEL::NormalizedCellType tryToUnPolyHexp12(const int *conn, int nbOfFaces, int lgth, int *retConn, int& retLgth);
index 54025ae422f6ae59e37fb0aa0c7761f51ce15638..5681a69a6207198fb43853a2d68332258026e6b2 100644 (file)
 #include "InterpKernelGeo2DEdgeArcCircle.hxx"
 #include "MEDCouplingAutoRefCountObjectPtr.hxx"
 #include "InterpKernelAutoPtr.hxx"
+#include "InterpKernelGeo2DNode.hxx"
+#include "InterpKernelGeo2DEdgeLin.hxx"
+#include "InterpKernelGeo2DEdgeArcCircle.hxx"
+#include "InterpKernelGeo2DQuadraticPolygon.hxx"
 
 #include <sstream>
 #include <fstream>
@@ -506,11 +510,57 @@ void MEDCouplingUMesh::getReverseNodalConnectivity(DataArrayInt *revNodal, DataA
     }
 }
 
+/// @cond INTERNAL
+
+int MEDCouplingFastNbrer(int id, unsigned nb, const INTERP_KERNEL::CellModel& cm, bool compute, const int *conn1, const int *conn2)
+{
+  return id;
+}
+
+int MEDCouplingOrientationSensitiveNbrer(int id, unsigned nb, const INTERP_KERNEL::CellModel& cm, bool compute, const int *conn1, const int *conn2)
+{
+  if(!compute)
+    return id+1;
+  else
+    {
+      if(cm.getOrientationStatus(nb,conn1,conn2))
+        return id+1;
+      else
+        return -(id+1);
+    }
+}
+
+/// @endcond
+
 /*!
  * \b WARNING this method do the assumption that connectivity lies on the coordinates set.
  * For speed reasons no check of this will be done.
  */
 MEDCouplingUMesh *MEDCouplingUMesh::buildDescendingConnectivity(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx) const throw(INTERP_KERNEL::Exception)
+{
+  return buildDescendingConnectivityGen(desc,descIndx,revDesc,revDescIndx,MEDCouplingFastNbrer);
+}
+
+/*!
+ * WARNING this method do the assumption that connectivity lies on the coordinates set.
+ * For speed reasons no check of this will be done.
+ * This method differs from MEDCouplingUMesh::buildDescendingConnectivity method in that 'desc' is in different format.
+ * This method is more precise because it returns in descending connectivity giving the direction. If value is positive the n-1 dim element is taken in the same direction,
+ * if it is in the opposite direction it is retrieved negative. So the problem is for elemt #0 in C convention. That's why this method is the only one that retrieves 
+ * an array in relative "FORTRAN" mode. 
+ */
+MEDCouplingUMesh *MEDCouplingUMesh::buildDescendingConnectivity2(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx) const throw(INTERP_KERNEL::Exception)
+{
+  return  buildDescendingConnectivityGen(desc,descIndx,revDesc,revDescIndx,MEDCouplingOrientationSensitiveNbrer);
+}
+
+/// @cond INTERNAL
+
+/*!
+ * \b WARNING this method do the assumption that connectivity lies on the coordinates set.
+ * For speed reasons no check of this will be done.
+ */
+MEDCouplingUMesh *MEDCouplingUMesh::buildDescendingConnectivityGen(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx, DimM1DescNbrer nbrer) const throw(INTERP_KERNEL::Exception)
 {
   checkFullyDefined();
   int nbOfCells=getNumberOfCells();
@@ -568,13 +618,13 @@ MEDCouplingUMesh *MEDCouplingUMesh::buildDescendingConnectivity(DataArrayInt *de
                 revNodalB[tmp[k]].push_back(cellDM1Id);
               revDescMeshConnB.resize(cellDM1Id+1);
               revDescMeshConnB.back().push_back(eltId);
-              descMeshConnB[eltId].push_back(cellDM1Id);
+              descMeshConnB[eltId].push_back(nbrer(cellDM1Id,0,cms,false,0,0));
             }
           else
             {
               int DM1cellId=shareableCellsL.front();
               revDescMeshConnB[DM1cellId].push_back(eltId);
-              descMeshConnB[eltId].push_back(DM1cellId);
+              descMeshConnB[eltId].push_back(nbrer(DM1cellId,nbOfNodesSon,cms,true,tmp,&meshDM1Conn[meshDM1ConnIndex[DM1cellId]]));
             }
         }
       delete [] tmp;
@@ -618,6 +668,9 @@ struct MEDCouplingAccVisit
   int _new_nb_of_nodes;
 };
 
+/// @endcond
+
+
 /*!
  * This method convert this into dynamic types without changing geometry.
  * That is to say if 'this' is a 2D, mesh after the invocation of this method it will contain only polygons.
@@ -637,7 +690,13 @@ void MEDCouplingUMesh::convertToPolyTypes(const std::vector<int>& cellIdsToConve
       const int *connIndex=_nodal_connec_index->getConstPointer();
       int *conn=_nodal_connec->getPointer();
       for(std::vector<int>::const_iterator iter=cellIdsToConvert.begin();iter!=cellIdsToConvert.end();iter++)
-        conn[connIndex[*iter]]=INTERP_KERNEL::NORM_POLYGON;
+        {
+          const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)conn[connIndex[*iter]]);
+          if(!cm.isDynamic())
+            conn[connIndex[*iter]]=INTERP_KERNEL::NORM_POLYGON;
+          else
+            conn[connIndex[*iter]]=INTERP_KERNEL::NORM_QPOLYG;
+        }
     }
   else
     {
@@ -800,7 +859,7 @@ void MEDCouplingUMesh::unPolyze()
             {
               INTERP_KERNEL::AutoPtr<int> tmp=new int[lgthOfCurCell-1];
               std::copy(conn+posOfCurCell+1,conn+posOfCurCell+lgthOfCurCell,(int *)tmp);
-              newType=INTERP_KERNEL::CellSimplify::tryToUnPoly2D(tmp,lgthOfCurCell-1,conn+newPos+1,newLgth);
+              newType=INTERP_KERNEL::CellSimplify::tryToUnPoly2D(cm.isQuadratic(),tmp,lgthOfCurCell-1,conn+newPos+1,newLgth);
             }
           if(cm.getDimension()==3)
             {
@@ -2370,6 +2429,112 @@ namespace ParaMEDMEM
     INTERP_KERNEL::NormalizedCellType getTypeOfElement(int) const { return (INTERP_KERNEL::NormalizedCellType)0; }
     // end
   };
+
+  INTERP_KERNEL::Edge *MEDCouplingUMeshBuildQPFromEdge(INTERP_KERNEL::NormalizedCellType typ, std::map<int, INTERP_KERNEL::Node *>& mapp2, const int *bg)
+  {
+    INTERP_KERNEL::Edge *ret=0;
+    switch(typ)
+      {
+      case INTERP_KERNEL::NORM_SEG2:
+        {
+          ret=new INTERP_KERNEL::EdgeLin(mapp2[bg[0]],mapp2[bg[1]]);
+          break;
+        }
+      case INTERP_KERNEL::NORM_SEG3:
+        {
+          ret=new INTERP_KERNEL::EdgeArcCircle(mapp2[bg[0]],mapp2[bg[2]],mapp2[bg[1]]);
+          break;
+        }
+      default:
+        throw INTERP_KERNEL::Exception("MEDCouplingUMeshBuildQPFromEdge : Expecting a mesh with spaceDim==2 and meshDim==1 !");
+      }
+    return ret;
+  }
+
+  /*!
+   * This method creates a sub mesh in Geometric2D DS. The sub mesh is composed be the sub set of cells in 'candidates' and the global mesh 'mDesc'.
+   * The input meth 'mDesc' must be so that mDim==1 et spaceDim==3.
+   * 'mapp' contains a mapping between local numbering in submesh and the global node numbering in 'mDesc'.
+   */
+  INTERP_KERNEL::QuadraticPolygon *MEDCouplingUMeshBuildQPFromMesh(const MEDCouplingUMesh *mDesc, const std::vector<int>& candidates, std::map<INTERP_KERNEL::Node *,int>& mapp) throw(INTERP_KERNEL::Exception)
+  {
+    mapp.clear();
+    std::map<int, INTERP_KERNEL::Node *> mapp2;
+    const double *coo=mDesc->getCoords()->getConstPointer();
+    const int *c=mDesc->getNodalConnectivity()->getConstPointer();
+    const int *cI=mDesc->getNodalConnectivityIndex()->getConstPointer();
+    std::set<int> s;
+    for(std::vector<int>::const_iterator it=candidates.begin();it!=candidates.end();it++)
+      s.insert(c+cI[*it]+1,c+cI[(*it)+1]);
+    for(std::set<int>::const_iterator it2=s.begin();it2!=s.end();it2++)
+      {
+        INTERP_KERNEL::Node *n=new INTERP_KERNEL::Node(coo[2*(*it2)],coo[2*(*it2)+1]);
+        mapp[n]=(*it2); mapp2[*it2]=n;
+      }
+    INTERP_KERNEL::QuadraticPolygon *ret=new INTERP_KERNEL::QuadraticPolygon;
+    for(std::vector<int>::const_iterator it=candidates.begin();it!=candidates.end();it++)
+      {
+        INTERP_KERNEL::NormalizedCellType typ=(INTERP_KERNEL::NormalizedCellType)c[cI[*it]];
+        ret->pushBack(MEDCouplingUMeshBuildQPFromEdge(typ,mapp2,c+cI[*it]+1));
+      }
+    for(std::set<int>::const_iterator it2=s.begin();it2!=s.end();it2++)
+      mapp2[*it2]->decrRef();
+    return ret;
+  }
+
+  INTERP_KERNEL::Node *MEDCouplingUMeshBuildQPNode(int nodeId, const double *coo1, int offset1, const double *coo2, int offset2, const std::vector<double>& addCoo)
+  {
+    if(nodeId>=offset2)
+      {
+        int locId=nodeId-offset2;
+        return new INTERP_KERNEL::Node(addCoo[2*locId],addCoo[2*locId+1]);
+      }
+    if(nodeId>=offset1)
+      {
+        int locId=nodeId-offset1;
+        return new INTERP_KERNEL::Node(coo2[2*locId],coo2[2*locId+1]);
+      }
+    return new INTERP_KERNEL::Node(coo1[2*nodeId],coo1[2*nodeId+1]);
+  }
+
+  void MEDCouplingUMeshBuildQPFromMesh2(const double *coo1, int offset1, const double *coo2, int offset2, const std::vector<double>& addCoo,
+                                        bool isQuad1, const int *desc1Bg, const int *desc1End, const std::vector<std::vector<int> >& intesctEdges1,
+                                        bool isQuad2, const int *desc2Bg, const int *desc2End, const std::vector<std::vector<int> >& intesctEdges2,
+                                        /*output*/INTERP_KERNEL::QuadraticPolygon& pol1, INTERP_KERNEL::QuadraticPolygon& pol2, std::map<INTERP_KERNEL::Node *,int>& mapp)
+  {
+    std::map<int,INTERP_KERNEL::Node *> mappRev;
+    for(const int *desc1=desc1Bg;desc1!=desc1End;desc1++)
+      {
+        int eltId1=abs(*desc1)-1;
+        for(std::vector<int>::const_iterator it1=intesctEdges1[eltId1].begin();it1!=intesctEdges1[eltId1].end();it1++)
+          {
+            std::map<int,INTERP_KERNEL::Node *>::const_iterator it=mappRev.find(*it1);
+            if(it==mappRev.end())
+              {
+                INTERP_KERNEL::Node *node=MEDCouplingUMeshBuildQPNode(*it1,coo1,offset1,coo2,offset2,addCoo);
+                mapp[node]=*it1;
+                mappRev[*it1]=node;
+              }
+          }
+      }
+    for(const int *desc2=desc2Bg;desc2!=desc2End;desc2++)
+      {
+        int eltId2=abs(*desc2)-1;
+        for(std::vector<int>::const_iterator it2=intesctEdges2[eltId2].begin();it2!=intesctEdges2[eltId2].end();it2++)
+          {
+            std::map<int,INTERP_KERNEL::Node *>::const_iterator it=mappRev.find(*it2);
+            if(it==mappRev.end())
+              {
+                INTERP_KERNEL::Node *node=MEDCouplingUMeshBuildQPNode(*it2,coo1,offset1,coo2,offset2,addCoo);
+                mapp[node]=*it2;
+                mappRev[*it2]=node;
+              }
+          }
+      }
+    //
+    pol1.buildFromCrudeDataArray(mappRev,isQuad1,desc1Bg,desc1End,intesctEdges1);
+    pol2.buildFromCrudeDataArray(mappRev,isQuad2,desc2Bg,desc2End,intesctEdges2);
+  }
 }
 
 /// @endcond
@@ -2780,7 +2945,7 @@ MEDCouplingUMesh *MEDCouplingUMesh::buildExtrudedMeshFromThisLowLev(int nbOfNode
   std::vector<int> newc;
   for(int j=0;j<nbOf2DCells;j++)
     {
-      appendExtrudedCell(conn+connI[j],conn+connI[j+1],nbOfNodesOf1Lev,isQuad,newc);
+      AppendExtrudedCell(conn+connI[j],conn+connI[j+1],nbOfNodesOf1Lev,isQuad,newc);
       *newConnIPtr++=newc.size();
     }
   newConn->alloc(newc.size()*nbOf1DCells,1);
@@ -3111,9 +3276,10 @@ void MEDCouplingUMesh::are2DCellsNotCorrectlyOriented(const double *vec, bool po
   for(int i=0;i<nbOfCells;i++)
     {
       INTERP_KERNEL::NormalizedCellType type=(INTERP_KERNEL::NormalizedCellType)conn[connI[i]];
-      if(!polyOnly || type==INTERP_KERNEL::NORM_POLYGON)
+      if(!polyOnly || (type==INTERP_KERNEL::NORM_POLYGON || type==INTERP_KERNEL::NORM_QPOLYG))
         {
-          if(!IsPolygonWellOriented(vec,conn+connI[i]+1,conn+connI[i+1],coordsPtr))
+          bool isQuadratic=INTERP_KERNEL::CellModel::GetCellModel(type).isQuadratic();
+          if(!IsPolygonWellOriented(isQuadratic,vec,conn+connI[i]+1,conn+connI[i+1],coordsPtr))
             cells.push_back(i);
         }
     }
@@ -3136,14 +3302,17 @@ void MEDCouplingUMesh::orientCorrectly2DCells(const double *vec, bool polyOnly)
   for(int i=0;i<nbOfCells;i++)
     {
       INTERP_KERNEL::NormalizedCellType type=(INTERP_KERNEL::NormalizedCellType)conn[connI[i]];
-      if(!polyOnly || type==INTERP_KERNEL::NORM_POLYGON)
-        if(!IsPolygonWellOriented(vec,conn+connI[i]+1,conn+connI[i+1],coordsPtr))
-          {
-            isModified=true;
-            std::vector<int> tmp(connI[i+1]-connI[i]-2);
-            std::copy(conn+connI[i]+2,conn+connI[i+1],tmp.rbegin());
-            std::copy(tmp.begin(),tmp.end(),conn+connI[i]+2);
-          }
+      if(!polyOnly || (type==INTERP_KERNEL::NORM_POLYGON || type==INTERP_KERNEL::NORM_QPOLYG))
+        {
+          bool isQuadratic=INTERP_KERNEL::CellModel::GetCellModel(type).isQuadratic();
+          if(!IsPolygonWellOriented(isQuadratic,vec,conn+connI[i]+1,conn+connI[i+1],coordsPtr))
+            {
+              isModified=true;
+              std::vector<int> tmp(connI[i+1]-connI[i]-2);
+              std::copy(conn+connI[i]+2,conn+connI[i+1],tmp.rbegin());
+              std::copy(tmp.begin(),tmp.end(),conn+connI[i]+2);
+            }
+        }
     }
   if(isModified)
     _nodal_connec->declareAsNew();
@@ -3254,19 +3423,19 @@ MEDCouplingFieldDouble *MEDCouplingUMesh::getEdgeRatioField() const throw(INTERP
         {
           case INTERP_KERNEL::NORM_TRI3:
             {
-              fillInCompact3DMode(spaceDim,3,conn+1,coo,tmp);
+              FillInCompact3DMode(spaceDim,3,conn+1,coo,tmp);
               *pt=INTERP_KERNEL::triEdgeRatio(tmp);
               break;
             }
           case INTERP_KERNEL::NORM_QUAD4:
             {
-              fillInCompact3DMode(spaceDim,4,conn+1,coo,tmp);
+              FillInCompact3DMode(spaceDim,4,conn+1,coo,tmp);
               *pt=INTERP_KERNEL::quadEdgeRatio(tmp);
               break;
             }
           case INTERP_KERNEL::NORM_TETRA4:
             {
-              fillInCompact3DMode(spaceDim,4,conn+1,coo,tmp);
+              FillInCompact3DMode(spaceDim,4,conn+1,coo,tmp);
               *pt=INTERP_KERNEL::tetraEdgeRatio(tmp);
               break;
             }
@@ -3314,19 +3483,19 @@ MEDCouplingFieldDouble *MEDCouplingUMesh::getAspectRatioField() const throw(INTE
         {
           case INTERP_KERNEL::NORM_TRI3:
             {
-              fillInCompact3DMode(spaceDim,3,conn+1,coo,tmp);
+              FillInCompact3DMode(spaceDim,3,conn+1,coo,tmp);
               *pt=INTERP_KERNEL::triAspectRatio(tmp);
               break;
             }
           case INTERP_KERNEL::NORM_QUAD4:
             {
-              fillInCompact3DMode(spaceDim,4,conn+1,coo,tmp);
+              FillInCompact3DMode(spaceDim,4,conn+1,coo,tmp);
               *pt=INTERP_KERNEL::quadAspectRatio(tmp);
               break;
             }
           case INTERP_KERNEL::NORM_TETRA4:
             {
-              fillInCompact3DMode(spaceDim,4,conn+1,coo,tmp);
+              FillInCompact3DMode(spaceDim,4,conn+1,coo,tmp);
               *pt=INTERP_KERNEL::tetraAspectRatio(tmp);
               break;
             }
@@ -3374,7 +3543,7 @@ MEDCouplingFieldDouble *MEDCouplingUMesh::getWarpField() const throw(INTERP_KERN
         {
           case INTERP_KERNEL::NORM_QUAD4:
             {
-              fillInCompact3DMode(3,4,conn+1,coo,tmp);
+              FillInCompact3DMode(3,4,conn+1,coo,tmp);
               *pt=INTERP_KERNEL::quadWarp(tmp);
               break;
             }
@@ -3422,7 +3591,7 @@ MEDCouplingFieldDouble *MEDCouplingUMesh::getSkewField() const throw(INTERP_KERN
         {
           case INTERP_KERNEL::NORM_QUAD4:
             {
-              fillInCompact3DMode(3,4,conn+1,coo,tmp);
+              FillInCompact3DMode(3,4,conn+1,coo,tmp);
               *pt=INTERP_KERNEL::quadSkew(tmp);
               break;
             }
@@ -3730,8 +3899,8 @@ MEDCouplingUMesh *MEDCouplingUMesh::emulateMEDMEMBDC(const MEDCouplingUMesh *nM1
  */
 DataArrayInt *MEDCouplingUMesh::sortCellsInMEDFileFrmt() throw(INTERP_KERNEL::Exception)
 {
-  static const int N=18;
-  static const INTERP_KERNEL::NormalizedCellType MEDMEM_ORDER[N] = { INTERP_KERNEL::NORM_POINT1, INTERP_KERNEL::NORM_SEG2, INTERP_KERNEL::NORM_SEG3, INTERP_KERNEL::NORM_TRI3, INTERP_KERNEL::NORM_QUAD4, INTERP_KERNEL::NORM_TRI6, INTERP_KERNEL::NORM_QUAD8, INTERP_KERNEL::NORM_TETRA4, INTERP_KERNEL::NORM_PYRA5, INTERP_KERNEL::NORM_PENTA6, INTERP_KERNEL::NORM_HEXA8, INTERP_KERNEL::NORM_HEXGP12, INTERP_KERNEL::NORM_TETRA10, INTERP_KERNEL::NORM_PYRA13, INTERP_KERNEL::NORM_PENTA15, INTERP_KERNEL::NORM_HEXA20, INTERP_KERNEL::NORM_POLYGON, INTERP_KERNEL::NORM_POLYHED };
+  static const int N=19;
+  static const INTERP_KERNEL::NormalizedCellType MEDMEM_ORDER[N] = { INTERP_KERNEL::NORM_POINT1, INTERP_KERNEL::NORM_SEG2, INTERP_KERNEL::NORM_SEG3, INTERP_KERNEL::NORM_TRI3, INTERP_KERNEL::NORM_QUAD4, INTERP_KERNEL::NORM_TRI6, INTERP_KERNEL::NORM_QUAD8, INTERP_KERNEL::NORM_TETRA4, INTERP_KERNEL::NORM_PYRA5, INTERP_KERNEL::NORM_PENTA6, INTERP_KERNEL::NORM_HEXA8, INTERP_KERNEL::NORM_HEXGP12, INTERP_KERNEL::NORM_TETRA10, INTERP_KERNEL::NORM_PYRA13, INTERP_KERNEL::NORM_PENTA15, INTERP_KERNEL::NORM_HEXA20, INTERP_KERNEL::NORM_POLYGON, INTERP_KERNEL::NORM_QPOLYG, INTERP_KERNEL::NORM_POLYHED };
   checkConnectivityFullyDefined();
   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=getRenumArrForConsecutiveCellTypesSpec(MEDMEM_ORDER,MEDMEM_ORDER+N);
   renumberCells(ret->getConstPointer(),false);
@@ -3986,6 +4155,25 @@ MEDCouplingUMesh *MEDCouplingUMesh::keepSpecifiedCells(INTERP_KERNEL::Normalized
   return ret2;
 }
 
+/*!
+ * This method returns a vector of size 'this->getNumberOfCells()'.
+ * This method retrieves for each cell in 'this' if it is linear (false) or quadratic(true).
+ */
+std::vector<bool> MEDCouplingUMesh::getQuadraticStatus() const throw(INTERP_KERNEL::Exception)
+{
+  int ncell=getNumberOfCells();
+  std::vector<bool> ret(ncell);
+  const int *cI=getNodalConnectivityIndex()->getConstPointer();
+  const int *c=getNodalConnectivity()->getConstPointer();
+  for(int i=0;i<ncell;i++)
+    {
+      INTERP_KERNEL::NormalizedCellType typ=(INTERP_KERNEL::NormalizedCellType)c[cI[i]];
+      const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(typ);
+      ret[i]=cm.isQuadratic();
+    }
+  return ret;
+}
+
 /*!
  * Returns a newly created mesh (with ref count ==1) that contains merge of 'this' and 'other'.
  */
@@ -4254,7 +4442,7 @@ MEDCouplingUMesh *MEDCouplingUMesh::FuseUMeshesOnSameCoords(const std::vector<co
  * @param isQuad specifies the policy of connectivity.
  * @ret in/out parameter in which the result will be append
  */
-void MEDCouplingUMesh::appendExtrudedCell(const int *connBg, const int *connEnd, int nbOfNodesPerLev, bool isQuad, std::vector<int>& ret)
+void MEDCouplingUMesh::AppendExtrudedCell(const int *connBg, const int *connEnd, int nbOfNodesPerLev, bool isQuad, std::vector<int>& ret)
 {
   INTERP_KERNEL::NormalizedCellType flatType=(INTERP_KERNEL::NormalizedCellType)connBg[0];
   const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(flatType);
@@ -4334,10 +4522,12 @@ void MEDCouplingUMesh::appendExtrudedCell(const int *connBg, const int *connEnd,
 /*!
  * This static operates only for coords in 3D. The polygon is specfied by its connectivity nodes in [begin,end).
  */
-bool MEDCouplingUMesh::IsPolygonWellOriented(const double *vec, const int *begin, const int *end, const double *coords)
+bool MEDCouplingUMesh::IsPolygonWellOriented(bool isQuadratic, const double *vec, const int *begin, const int *end, const double *coords)
 {
   double v[3]={0.,0.,0.};
   int sz=std::distance(begin,end);
+  if(isQuadratic)
+    sz/=2;
   for(int i=0;i<sz;i++)
     {
       v[0]+=coords[3*begin[i]+1]*coords[3*begin[(i+1)%sz]+2]-coords[3*begin[i]+2]*coords[3*begin[(i+1)%sz]+1];
@@ -4432,7 +4622,7 @@ void MEDCouplingUMesh::TryToCorrectPolyhedronOrientation(int *begin, int *end, c
  * This method put in zip format into parameter 'zipFrmt' in full interlace mode.
  * This format is often asked by INTERP_KERNEL algorithms to avoid many indirections into coordinates array.
  */
-void MEDCouplingUMesh::fillInCompact3DMode(int spaceDim, int nbOfNodesInCell, const int *conn, const double *coo, double *zipFrmt) throw(INTERP_KERNEL::Exception)
+void MEDCouplingUMesh::FillInCompact3DMode(int spaceDim, int nbOfNodesInCell, const int *conn, const double *coo, double *zipFrmt) throw(INTERP_KERNEL::Exception)
 {
   double *w=zipFrmt;
   if(spaceDim==3)
@@ -4447,12 +4637,12 @@ void MEDCouplingUMesh::fillInCompact3DMode(int spaceDim, int nbOfNodesInCell, co
         }
     }
   else
-    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::fillInCompact3DMode : Invalid spaceDim specified : must be 2 or 3 !");
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::FillInCompact3DMode : Invalid spaceDim specified : must be 2 or 3 !");
 }
 
 void MEDCouplingUMesh::writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData) const throw(INTERP_KERNEL::Exception)
 {
-  static const int PARAMEDMEM2VTKTYPETRADUCER[INTERP_KERNEL::NORM_MAXTYPE+1]={1,3,21,5,9,7,22,-1,23,-1,-1,-1,-1,-1,10,14,13,-1,12,-1,24,-1,16,27,-1,26,-1,-1,-1,-1,25,42};
+  static const int PARAMEDMEM2VTKTYPETRADUCER[INTERP_KERNEL::NORM_MAXTYPE+1]={1,3,21,5,9,7,22,-1,23,-1,-1,-1,-1,-1,10,14,13,-1,12,-1,24,-1,16,27,-1,26,-1,-1,-1,-1,25,42,-1};
   ofs << "  <" << getVTKDataSetType() << ">\n";
   ofs << "    <Piece NumberOfPoints=\"" << getNumberOfNodes() << "\" NumberOfCells=\"" << getNumberOfCells() << "\">\n";
   ofs << "      <PointData>\n" << pointData << std::endl;
@@ -4482,7 +4672,7 @@ void MEDCouplingUMesh::writeVTKLL(std::ostream& ofs, const std::string& cellData
   c2->writeVTK(ofs,8,"UInt8","types");
   ofs << "      </Cells>\n";
   ofs << "    </Piece>\n";
-  ofs << "  </UnstructuredGrid>\n";
+  ofs << "  </" << getVTKDataSetType() << ">\n";
 }
 
 std::string MEDCouplingUMesh::getVTKDataSetType() const throw(INTERP_KERNEL::Exception)
@@ -4490,6 +4680,181 @@ std::string MEDCouplingUMesh::getVTKDataSetType() const throw(INTERP_KERNEL::Exc
   return std::string("UnstructuredGrid");
 }
 
+MEDCouplingUMesh *MEDCouplingUMesh::Intersect2DMeshes(const MEDCouplingUMesh *m1, const MEDCouplingUMesh *m2, double eps, DataArrayInt *&cellNb1, DataArrayInt *&cellNb2) throw(INTERP_KERNEL::Exception)
+{
+  std::vector< std::vector<int> > intersectEdge1, subDiv2;
+  MEDCouplingUMesh *m1Desc=0,*m2Desc=0;
+  DataArrayInt *desc1=0,*descIndx1=0,*revDesc1=0,*revDescIndx1=0,*desc2=0,*descIndx2=0,*revDesc2=0,*revDescIndx2=0;
+  std::vector<double> addCoo;
+  INTERP_KERNEL::QUADRATIC_PLANAR::_precision=eps;
+  IntersectDescending2DMeshes(m1,m2,eps,intersectEdge1,subDiv2,m1Desc,desc1,descIndx1,revDesc1,revDescIndx1,
+                              m2Desc,desc2,descIndx2,revDesc2,revDescIndx2,addCoo);
+  revDesc1->decrRef(); revDescIndx1->decrRef(); revDesc2->decrRef(); revDescIndx2->decrRef();
+  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(); m1Desc->decrRef(); m2Desc->decrRef();
+  std::vector<int> cr,crI;
+  std::vector<int> cNb1,cNb2;
+  BuildIntersecting2DCellsFromEdges(eps,m1,b1,desc1->getConstPointer(),descIndx1->getConstPointer(),intersectEdge1,m2,b2,desc2->getConstPointer(),descIndx2->getConstPointer(),intersectEdge2,addCoo,
+                                    /* outputs -> */cr,crI,cNb1,cNb2);
+#if 0
+  //tony
+  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> addCooDa=DataArrayDouble::New();
+  addCooDa->alloc(addCoo.size()/2,2);
+  std::copy(addCoo.begin(),addCoo.end(),addCooDa->getPointer());
+  std::vector<const DataArrayDouble *> coordss(3);
+  coordss[0]=m1->getCoords(); coordss[1]=m2->getCoords(); coordss[2]=addCooDa;
+  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coo=DataArrayDouble::Aggregate(coordss);
+  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New("Intersect2D",2);
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> conn=DataArrayInt::New(); conn->alloc(cr.size(),1); std::copy(cr.begin(),cr.end(),conn->getPointer());
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> connI=DataArrayInt::New(); connI->alloc(crI.size(),1); std::copy(crI.begin(),crI.end(),connI->getPointer());
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c1=DataArrayInt::New(); c1->alloc(cNb1.size(),1); std::copy(cNb1.begin(),cNb1.end(),c1->getPointer()); cellNb1=c1;
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c2=DataArrayInt::New(); c2->alloc(cNb2.size(),1); std::copy(cNb2.begin(),cNb2.end(),c2->getPointer()); cellNb2=c2;
+  ret->setConnectivity(conn,connI,true);
+  ret->setCoords(coo);
+  ret->incrRef(); c1->incrRef(); c2->incrRef();
+  return ret;
+#endif
+  desc1->decrRef(); descIndx1->decrRef(); desc2->decrRef(); descIndx2->decrRef();
+  return 0;
+}
+
+void MEDCouplingUMesh::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 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)
+{
+  static const int SPACEDIM=2;
+  std::vector<double> bbox1,bbox2;
+  const double *coo1=m1->getCoords()->getConstPointer();
+  int offset1=m1->getNumberOfNodes();
+  const double *coo2=m2->getCoords()->getConstPointer();
+  int offset2=offset1+m2->getNumberOfNodes();
+  m1->getBoundingBoxForBBTree(bbox1);
+  m2->getBoundingBoxForBBTree(bbox2);
+  BBTree<SPACEDIM,int> myTree(&bbox2[0],0,0,m2->getNumberOfCells(),-eps);
+  int ncell1=m1->getNumberOfCells();
+  crI.push_back(0);
+  for(int i=0;i<ncell1;i++)
+    {
+      std::vector<int> candidates2;
+      myTree.getIntersectingElems(&bbox1[i*2*SPACEDIM],candidates2);
+      for(std::vector<int>::const_iterator it2=candidates2.begin();it2!=candidates2.end();it2++)
+        {
+          INTERP_KERNEL::QuadraticPolygon pol1,pol2;
+          std::map<INTERP_KERNEL::Node *,int> mapp;
+          MEDCouplingUMeshBuildQPFromMesh2(coo1,offset1,coo2,offset2,addCoords,
+                                           b1[i],desc1+descIndx1[i],desc1+descIndx1[i+1],intesctEdges1,
+                                           b2[*it2],desc2+descIndx2[*it2],desc2+descIndx2[*it2+1],intesctEdges2,
+                                           /* output */pol1,pol2,mapp);
+          pol1.buildPartitionsAbs(pol2,mapp,i,*it2,cr,crI,cNb1,cNb2);
+        }
+    }
+}
+
+/*!
+ * This method is private and is the first step of Partition of 2D mesh (spaceDim==2 and meshDim==2).
+ * 
+ */
+void MEDCouplingUMesh::IntersectDescending2DMeshes(const MEDCouplingUMesh *m1, const MEDCouplingUMesh *m2, double eps,
+                                                   std::vector< std::vector<int> >& intersectEdge1, std::vector< std::vector<int> >& subDiv2,
+                                                   MEDCouplingUMesh *& m1Desc, DataArrayInt *&desc1, DataArrayInt *&descIndx1, DataArrayInt *&revDesc1, DataArrayInt *&revDescIndx1,
+                                                   MEDCouplingUMesh *& m2Desc, DataArrayInt *&desc2, DataArrayInt *&descIndx2, DataArrayInt *&revDesc2, DataArrayInt *&revDescIndx2,
+                                                   std::vector<double>& addCoo) throw(INTERP_KERNEL::Exception)
+{
+  static const int SPACEDIM=2;
+  desc1=DataArrayInt::New(); descIndx1=DataArrayInt::New(); revDesc1=DataArrayInt::New(); revDescIndx1=DataArrayInt::New();
+  desc2=DataArrayInt::New(); descIndx2=DataArrayInt::New(); revDesc2=DataArrayInt::New(); revDescIndx2=DataArrayInt::New();
+  m1Desc=m1->buildDescendingConnectivity2(desc1,descIndx1,revDesc1,revDescIndx1);
+  m2Desc=m2->buildDescendingConnectivity2(desc2,descIndx2,revDesc2,revDescIndx2);
+  std::vector<double> bbox1,bbox2;
+  m1Desc->getBoundingBoxForBBTree(bbox1);
+  m2Desc->getBoundingBoxForBBTree(bbox2);
+  int ncell1=m1Desc->getNumberOfCells();
+  int ncell2=m2Desc->getNumberOfCells();
+  intersectEdge1.resize(ncell1);
+  subDiv2.resize(ncell2);
+  BBTree<SPACEDIM,int> myTree(&bbox2[0],0,0,m2Desc->getNumberOfCells(),-eps);
+  std::vector<int> candidates1(1);
+  int offset1=m1->getNumberOfNodes();
+  int offset2=offset1+m2->getNumberOfNodes();
+  for(int i=0;i<ncell1;i++)
+    {
+      std::vector<int> candidates2;
+      myTree.getIntersectingElems(&bbox1[i*2*SPACEDIM],candidates2);
+      if(!candidates2.empty())
+        {
+          std::map<INTERP_KERNEL::Node *,int> map1,map2;
+          INTERP_KERNEL::QuadraticPolygon *pol2=MEDCouplingUMeshBuildQPFromMesh(m2Desc,candidates2,map2);
+          INTERP_KERNEL::QuadraticPolygon *pol1=MEDCouplingUMeshBuildQPFromMesh(m1Desc,candidates1,map1);
+          pol1->splitAbs(*pol2,map1,map2,offset1,offset2,candidates2,intersectEdge1[i],subDiv2,addCoo);
+          delete pol2;
+          delete pol1;
+        }
+    }
+}
+
+/*!
+ * This method performs the 2nd step of Partition of 2D mesh.
+ * This method has 4 inputs :
+ *  - a mesh 'm1' with meshDim==1 and a SpaceDim==2
+ *  - a mesh 'm2' with meshDim==1 and a SpaceDim==2
+ *  - subDiv of size 'm->getNumberOfCells()' that lists for each seg cell in 'm' the splitting node ids in randomly sorted.
+ * The aim of this method is to sort the splitting nodes, if any, and to put in 'intersectEdge' output paramter based on edges of mesh 'm2'
+ * @param m1 is expected to be a mesh of meshDimension equal to 1 and spaceDim equal to 2. No check of that is performed by this method. Only present for its coords in case of 'subDiv' shares some nodes of 'm1'
+ * @param m2 is expected to be a mesh of meshDimension equal to 1 and spaceDim equal to 2. No check of that is performed by this method.
+ * @param addCoo input parameter with additionnal nodes linked to intersection of the 2 meshes.
+ */
+void MEDCouplingUMesh::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)
+{
+  int offset1=m1->getNumberOfCells();
+  int ncell=m2->getNumberOfCells();
+  const int *c=m2->getNodalConnectivity()->getConstPointer();
+  const int *cI=m2->getNodalConnectivityIndex()->getConstPointer();
+  const double *coo=m2->getCoords()->getConstPointer();
+  const double *cooBis=m1->getCoords()->getConstPointer();
+  int offset2=offset1+ncell;
+  intersectEdge.resize(ncell);
+  for(int i=0;i<ncell;i++,cI++)
+    {
+      const std::vector<int>& divs=subDiv[i];
+      int nnode=cI[1]-cI[0]-1;
+      std::map<int, INTERP_KERNEL::Node *> mapp2;
+      std::map<INTERP_KERNEL::Node *, int> mapp22;
+      for(int j=0;j<nnode;j++)
+        {
+          INTERP_KERNEL::Node *nn=new INTERP_KERNEL::Node(coo[2*c[(*cI)+j+1]],coo[2*c[(*cI)+j+1]+1]);
+          int nnid=c[(*cI)+j+1];
+          mapp2[nnid]=nn;
+          mapp22[nn]=nnid;
+        }
+      INTERP_KERNEL::Edge *e=MEDCouplingUMeshBuildQPFromEdge((INTERP_KERNEL::NormalizedCellType)c[*cI],mapp2,c+(*cI)+1);
+      for(std::map<int, INTERP_KERNEL::Node *>::const_iterator it=mapp2.begin();it!=mapp2.end();it++)
+        (*it).second->decrRef();
+      std::vector<INTERP_KERNEL::Node *> addNodes(divs.size());
+      std::map<INTERP_KERNEL::Node *,int> mapp3;
+      for(std::size_t j=0;j<divs.size();i++)
+        {
+          int id=divs[j];
+          INTERP_KERNEL::Node *tmp=0;
+          if(id<offset1)
+            tmp=new INTERP_KERNEL::Node(cooBis[2*id],cooBis[2*id+1]);
+          else if(id<offset2)
+            tmp=new INTERP_KERNEL::Node(coo[2*(id-offset1)],cooBis[2*(id-offset1)+1]);//if it happens, bad news mesh 'm2' is non conform.
+          else
+            tmp=new INTERP_KERNEL::Node(addCoo[2*(id-offset2)],addCoo[2*(id-offset2)+1]);
+          addNodes[j]=tmp;
+          mapp3[tmp]=id;
+        }
+      e->sortIdsAbs(addNodes,mapp22,mapp3,intersectEdge[i]);
+      for(std::vector<INTERP_KERNEL::Node *>::const_iterator it=addNodes.begin();it!=addNodes.end();it++)
+        (*it)->decrRef();
+      e->decrRef();
+    }
+}
+
 MEDCouplingUMeshCellIterator::MEDCouplingUMeshCellIterator(MEDCouplingUMesh *mesh):_mesh(mesh),_cell(new MEDCouplingUMeshCell(mesh)),
                                                                                    _own_cell(true),_cell_id(-1),_nb_cell(0)
 {
index e6e680c2b94ec0d5c84ef28425f4ab07b3e76f3f..64a22bedff5606d780d3f96282a67a8ddc540d8b 100644 (file)
@@ -24,6 +24,8 @@
 #include "MEDCouplingPointSet.hxx"
 #include "MEDCouplingMemArray.hxx"
 
+#include "CellModel.hxx"
+
 #include <set>
 
 namespace ParaMEDMEM
@@ -101,6 +103,7 @@ namespace ParaMEDMEM
     MEDCOUPLING_EXPORT bool areCellsIncludedIn(const MEDCouplingUMesh *other, int compType, DataArrayInt *& arr) const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT void getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT MEDCouplingUMesh *buildDescendingConnectivity(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx) const throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT MEDCouplingUMesh *buildDescendingConnectivity2(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx) const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT DataArrayInt *mergeNodes(double precision, bool& areNodesMerged, int& newNbOfNodes);
     MEDCOUPLING_EXPORT DataArrayInt *mergeNodes2(double precision, bool& areNodesMerged, int& newNbOfNodes);
     MEDCOUPLING_EXPORT void tryToShareSameCoordsPermute(const MEDCouplingPointSet& other, double epsilon) throw(INTERP_KERNEL::Exception);
@@ -163,6 +166,7 @@ namespace ParaMEDMEM
     MEDCOUPLING_EXPORT DataArrayInt *keepCellIdsByType(INTERP_KERNEL::NormalizedCellType type, const int *begin, const int *end) const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT DataArrayInt *convertCellArrayPerGeoType(const DataArrayInt *da) const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT MEDCouplingUMesh *keepSpecifiedCells(INTERP_KERNEL::NormalizedCellType type, const int *idsPerGeoTypeBg, const int *idsPerGeoTypeEnd) const;
+    MEDCOUPLING_EXPORT std::vector<bool> getQuadraticStatus() const throw(INTERP_KERNEL::Exception);
     //
     MEDCOUPLING_EXPORT MEDCouplingMesh *mergeMyselfWith(const MEDCouplingMesh *other) const;
     MEDCOUPLING_EXPORT DataArrayDouble *getBarycenterAndOwner() const;
@@ -173,9 +177,10 @@ namespace ParaMEDMEM
     MEDCOUPLING_EXPORT static MEDCouplingUMesh *MergeUMeshesOnSameCoords(const MEDCouplingUMesh *mesh1, const MEDCouplingUMesh *mesh2) throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT static MEDCouplingUMesh *MergeUMeshesOnSameCoords(const std::vector<const MEDCouplingUMesh *>& meshes);
     MEDCOUPLING_EXPORT static MEDCouplingUMesh *FuseUMeshesOnSameCoords(const std::vector<const MEDCouplingUMesh *>& meshes, int compType, std::vector<DataArrayInt *>& corr);
-    MEDCOUPLING_EXPORT static bool IsPolygonWellOriented(const double *vec, const int *begin, const int *end, const double *coords);
+    MEDCOUPLING_EXPORT static bool IsPolygonWellOriented(bool isQuadratic, const double *vec, const int *begin, const int *end, const double *coords);
     MEDCOUPLING_EXPORT static bool IsPolyhedronWellOriented(const int *begin, const int *end, const double *coords);
     MEDCOUPLING_EXPORT static void TryToCorrectPolyhedronOrientation(int *begin, int *end, const double *coords) throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT static MEDCouplingUMesh *Intersect2DMeshes(const MEDCouplingUMesh *m1, const MEDCouplingUMesh *m2, double eps, DataArrayInt *&cellNb1, DataArrayInt *&cellNb2) throw(INTERP_KERNEL::Exception);
   private:
     MEDCouplingUMesh();
     MEDCouplingUMesh(const MEDCouplingUMesh& other, bool deepCpy);
@@ -200,8 +205,22 @@ namespace ParaMEDMEM
     template<int SPACEDIM>
     void getCellsContainingPointsAlg(const double *coords, const double *pos, int nbOfPoints,
                                      double eps, std::vector<int>& elts, std::vector<int>& eltsIndex) const;
-    static void fillInCompact3DMode(int spaceDim, int nbOfNodesInCell, const int *conn, const double *coo, double *zipFrmt) throw(INTERP_KERNEL::Exception);
-    static void appendExtrudedCell(const int *connBg, const int *connEnd, int nbOfNodesPerLev, bool isQuad, std::vector<int>& ret);
+/// @cond INTERNAL
+    typedef int (*DimM1DescNbrer)(int id, unsigned nb, const INTERP_KERNEL::CellModel& cm, bool compute, const int *conn1, const int *conn2);
+    MEDCouplingUMesh *buildDescendingConnectivityGen(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx, DimM1DescNbrer nbrer) const throw(INTERP_KERNEL::Exception);
+    static void FillInCompact3DMode(int spaceDim, int nbOfNodesInCell, const int *conn, const double *coo, double *zipFrmt) throw(INTERP_KERNEL::Exception);
+    static void AppendExtrudedCell(const int *connBg, const int *connEnd, int nbOfNodesPerLev, bool isQuad, std::vector<int>& ret);
+    static void IntersectDescending2DMeshes(const MEDCouplingUMesh *m1, const MEDCouplingUMesh *m2, double eps,
+                                            std::vector< std::vector<int> >& intersectEdge1, std::vector< std::vector<int> >& subDiv2,
+                                            MEDCouplingUMesh *& m1Desc, DataArrayInt *&desc1, DataArrayInt *&descIndx1, DataArrayInt *&revDesc1, DataArrayInt *&revDescIndx1,
+                                            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 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);
+/// @endcond
   private:
     //! this iterator stores current position in _nodal_connec array.
     mutable int _iterator;
index a5da7e9806d21e3ea5f237063be24d7b24b8b48f..8e3ea8ff1df1af4da3c50452ae67e1b6d9e738ef 100644 (file)
@@ -240,6 +240,7 @@ using namespace INTERP_KERNEL;
 %newobject ParaMEDMEM::MEDCouplingUMesh::cellsByType;
 %newobject ParaMEDMEM::MEDCouplingUMesh::zipConnectivityTraducer;
 %newobject ParaMEDMEM::MEDCouplingUMesh::buildDescendingConnectivity;
+%newobject ParaMEDMEM::MEDCouplingUMesh::buildDescendingConnectivity2;
 %newobject ParaMEDMEM::MEDCouplingUMesh::buildExtrudedMesh;
 %newobject ParaMEDMEM::MEDCouplingUMesh::MergeUMeshes;
 %newobject ParaMEDMEM::MEDCouplingUMesh::MergeUMeshesOnSameCoords;
@@ -1001,6 +1002,7 @@ namespace ParaMEDMEM
     void computeTypes() throw(INTERP_KERNEL::Exception);
     std::string reprConnectivityOfThis() const throw(INTERP_KERNEL::Exception);
     //tools
+    std::vector<bool> getQuadraticStatus() const throw(INTERP_KERNEL::Exception);
     DataArrayInt *findCellsIdsOnBoundary() const throw(INTERP_KERNEL::Exception);
     bool checkConsecutiveCellTypes() const throw(INTERP_KERNEL::Exception);
     DataArrayInt *rearrange2ConsecutiveCellTypes() throw(INTERP_KERNEL::Exception);
@@ -1008,6 +1010,7 @@ namespace ParaMEDMEM
     DataArrayInt *convertCellArrayPerGeoType(const DataArrayInt *da) const throw(INTERP_KERNEL::Exception);
     DataArrayInt *zipConnectivityTraducer(int compType) throw(INTERP_KERNEL::Exception);
     MEDCouplingUMesh *buildDescendingConnectivity(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx) const throw(INTERP_KERNEL::Exception);
+    MEDCouplingUMesh *buildDescendingConnectivity2(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx) const throw(INTERP_KERNEL::Exception);
     void orientCorrectlyPolyhedrons() throw(INTERP_KERNEL::Exception);
     bool isPresenceOfQuadratic() const throw(INTERP_KERNEL::Exception);
     MEDCouplingFieldDouble *buildDirectionVectorField() const throw(INTERP_KERNEL::Exception);
@@ -1259,6 +1262,26 @@ namespace ParaMEDMEM
         d3->incrRef();
         return ret;
       }
+
+      PyObject *buildDescendingConnectivity2() const throw(INTERP_KERNEL::Exception)
+      {
+        MEDCouplingAutoRefCountObjectPtr<DataArrayInt> d0=DataArrayInt::New();
+        MEDCouplingAutoRefCountObjectPtr<DataArrayInt> d1=DataArrayInt::New();
+        MEDCouplingAutoRefCountObjectPtr<DataArrayInt> d2=DataArrayInt::New();
+        MEDCouplingAutoRefCountObjectPtr<DataArrayInt> d3=DataArrayInt::New();
+        MEDCouplingUMesh *m=self->buildDescendingConnectivity2(d0,d1,d2,d3);
+        PyObject *ret=PyTuple_New(5);
+        PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(m),SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh, SWIG_POINTER_OWN | 0 ));
+        PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(d0),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ));
+        PyTuple_SetItem(ret,2,SWIG_NewPointerObj(SWIG_as_voidptr(d1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ));
+        PyTuple_SetItem(ret,3,SWIG_NewPointerObj(SWIG_as_voidptr(d2),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ));
+        PyTuple_SetItem(ret,4,SWIG_NewPointerObj(SWIG_as_voidptr(d3),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ));
+        d0->incrRef();
+        d1->incrRef();
+        d2->incrRef();
+        d3->incrRef();
+        return ret;
+      }
       
       PyObject *emulateMEDMEMBDC(const MEDCouplingUMesh *nM1LevMesh)
       {
@@ -1358,6 +1381,17 @@ namespace ParaMEDMEM
             return self->getCellIdsLyingOnNodes(da2->getConstPointer(),da2->getConstPointer()+da2->getNbOfElems(),fullyIn);
           }
       }
+
+      static PyObject *Intersect2DMeshes(const MEDCouplingUMesh *m1, const MEDCouplingUMesh *m2, double eps) throw(INTERP_KERNEL::Exception)
+      {
+        DataArrayInt *cellNb1=0,*cellNb2=0;
+        MEDCouplingUMesh *mret=MEDCouplingUMesh::Intersect2DMeshes(m1,m2,eps,cellNb1,cellNb2);
+        PyObject *ret=PyTuple_New(3);
+        PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(mret),SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh, SWIG_POINTER_OWN | 0 ));
+        PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(cellNb1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ));
+        PyTuple_SetItem(ret,2,SWIG_NewPointerObj(SWIG_as_voidptr(cellNb2),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ));
+        return ret;
+      }
     }
     void convertToPolyTypes(const std::vector<int>& cellIdsToConvert) throw(INTERP_KERNEL::Exception);
     void convertAllToPoly();