NORM_POLYGON = 5,
NORM_TRI6 = 6,
NORM_QUAD8 = 8,
+ NORM_QPOLYG = 32,
//
NORM_TETRA4 = 14,
NORM_PYRA5 = 15,
NORM_HEXA20 = 30,
NORM_POLYHED = 31,
NORM_ERROR = 40,
- NORM_MAXTYPE = 31 // = NORM_POLYHED
+ NORM_MAXTYPE = 32
} NormalizedCellType;
class GenericMesh
#include <algorithm>
#include <sstream>
+#include <vector>
#include <limits>
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"};
_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)
_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();
{
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;
}
{
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;
}
{
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
if(_dim==2)//polygon
{
- return 2;
+ if(_type==NORM_POLYGON)
+ return 2;
+ else
+ return 3;
}
else
{//polyedron
}
}
+ /*!
+ * 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;
+ }
+ }
+ }
+
}
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;
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);
(*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.
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)
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;
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;
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();
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;
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();
}
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;
_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;
return false;
}
-int Edge::combineCodes(TypeOfLocInEdge code1, TypeOfLocInEdge code2)
+int Edge::CombineCodes(TypeOfLocInEdge code1, TypeOfLocInEdge code2)
{
int ret=(int)code1;
ret*=OFFSET_FOR_TYPEOFLOCINEDGE;
* @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;
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;
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:
#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);
}
#include "InterpKernelGeo2DEdgeLin.hxx"
#include "InterpKernelException.hxx"
#include "InterpKernelGeo2DNode.hxx"
+#include "NormalizedUnstructuredMesh.hxx"
#include <sstream>
#include <algorithm>
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);
+}
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;
#include "InterpKernelGeo2DEdgeLin.hxx"
#include "InterpKernelGeo2DNode.hxx"
#include "InterpKernelException.hxx"
+#include "NormalizedUnstructuredMesh.hxx"
using namespace INTERP_KERNEL;
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]);
+ }
+}
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);
};
}
{
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);
+}
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;
_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);
+}
#include "InterpKernelGeo2DPrecision.hxx"
#include "INTERPKERNELGEOMETRIC2DDefines.hxx"
+#include <map>
#include <cmath>
#include <vector>
#include <iostream>
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:
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);
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.
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;
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;
}
* 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;
+ }
}
}
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;
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);
#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>
}
}
+/// @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();
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;
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.
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
{
{
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)
{
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
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);
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);
}
}
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();
{
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;
}
{
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;
}
{
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;
}
{
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;
}
*/
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);
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'.
*/
* @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);
/*!
* 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];
* 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)
}
}
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;
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)
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)
{
#include "MEDCouplingPointSet.hxx"
#include "MEDCouplingMemArray.hxx"
+#include "CellModel.hxx"
+
#include <set>
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);
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;
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);
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;
%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;
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);
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);
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)
{
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();