traducer->decrRef();
}
+struct MEDCouplingCompAbs
+{
+ bool operator()(double x, double y) { return std::abs(x)<std::abs(y);}
+};
+
+/*!
+ * This method expects that _coords attribute is set.
+ * @return the carateristic dimension of point set. This caracteristic dimension is the max of difference
+ * @exception If _coords attribute not set.
+ */
+double MEDCouplingPointSet::getCaracteristicDimension() const
+{
+ if(!_coords)
+ throw INTERP_KERNEL::Exception("MEDCouplingPointSet::getCaracteristicDimension : Coordinates not set !");
+ const double *coords=_coords->getConstPointer();
+ int nbOfValues=_coords->getNbOfElems();
+ return std::abs(*std::max_element(coords,coords+nbOfValues,MEDCouplingCompAbs()));
+}
+
/*!
* Non const method that operates a rotation of 'this'.
* If spaceDim==2 'vector' parameter is ignored (and could be 0) and the rotation is done around 'center' with angle specified by 'angle'.
int& newNbOfNodes) const;
void getBoundingBox(double *bbox) const;
void zipCoords();
+ double getCaracteristicDimension() const;
void rotate(const double *center, const double *vector, double angle);
void translate(const double *vector);
void scale(const double *point, double factor);
}
/*!
- *
+ * This method common cells base regarding 'compType' comparison policy described in ParaMEDMEM::MEDCouplingUMesh::zipConnectivityTraducer for details.
+ * This method returns 2 values 'res' and 'resI'.
+ * If 'res' and 'resI' are not empty before calling this method they will be cleared before set.
+ * The format of 'res' and 'resI' is as explained here.
+ * resI.size()-1 is the number of set of cells equal.
+ * The nth set is [res.begin()+resI[n];res.begin()+resI[n+1]) with 0<=n<resI.size()-1
*/
template<int SPACEDIM>
void MEDCouplingUMesh::findCommonCellsBase(int compType, std::vector<int>& res, std::vector<int>& resI) const
int nbOfCells=getNumberOfCells();
getBoundingBoxForBBTree(bbox);
double bb[2*SPACEDIM];
- BBTree<SPACEDIM,int> myTree(&bbox[0],0,0,nbOfCells,1e-12);
+ double eps=getCaracteristicDimension();
+ eps*=1.e-12;
+ BBTree<SPACEDIM,int> myTree(&bbox[0],0,0,nbOfCells,eps);
const int *conn=getNodalConnectivity()->getConstPointer();
const int *connI=getNodalConnectivityIndex()->getConstPointer();
const double *coords=getCoords()->getConstPointer();
}
std::vector<int> candidates;
myTree.getIntersectingElems(bb,candidates);
+ std::vector<int>::iterator it=std::find(candidates.begin(),candidates.end(),k);
+ candidates.erase(candidates.begin(),it);
if(areCellsEqualsInPool(candidates,compType,res))
{
+ int pos=resI.back();
resI.push_back(res.size());
- for(std::vector<int>::const_iterator it=candidates.begin();it!=candidates.end();it++)
+ for(std::vector<int>::const_iterator it=res.begin()+pos;it!=res.end();it++)
isFetched[*it]=true;
}
}
};
}
+/*!
+ * This methods checks that cells are sorted by their types.
+ * This method makes asumption (no check) that connectivity is correctly set before calling.
+ */
bool MEDCouplingUMesh::checkConsecutiveCellTypes() const
{
const int *conn=_nodal_connec->getConstPointer();
return true;
}
+/*!
+ * This methods split this into as mush as untructured meshes that consecutive set of same type cells.
+ * So this method has typically a sense if MEDCouplingUMesh::checkConsecutiveCellTypes has a sense.
+ * This method makes asumption (no check) that connectivity is correctly set before calling.
+ */
+std::vector<MEDCouplingUMesh *> MEDCouplingUMesh::splitByType() const
+{
+ const int *conn=_nodal_connec->getConstPointer();
+ const int *connI=_nodal_connec_index->getConstPointer();
+ int nbOfCells=getNumberOfCells();
+ std::vector<MEDCouplingUMesh *> ret;
+ for(const int *i=connI;i!=connI+nbOfCells;)
+ {
+ INTERP_KERNEL::NormalizedCellType curType=(INTERP_KERNEL::NormalizedCellType)conn[*i];
+ int startCellId=std::distance(connI,i);
+ i=std::find_if(i+1,connI+nbOfCells,ParaMEDMEMImpl::ConnReader(conn,(int)curType));
+ int endCellId=std::distance(connI,i);
+ int sz=endCellId-startCellId;
+ int *cells=new int[sz];
+ for(int j=0;j<sz;j++)
+ cells[j]=startCellId+j;
+ MEDCouplingUMesh *m=(MEDCouplingUMesh *)buildPartOfMySelf(cells,cells+sz,true);
+ delete [] cells;
+ ret.push_back(m);
+ }
+ return ret;
+}
+
/*!
* Returns a newly created mesh (with ref count ==1) that contains merge of 'this' and 'other'.
*/
CPPUNIT_TEST( testOperationsOnFields4 );
CPPUNIT_TEST( testMergeNodesOnField );
CPPUNIT_TEST( testCheckConsecutiveCellTypes );
+ CPPUNIT_TEST( testSplitByType );
+ CPPUNIT_TEST( testFuseUMeshesOnSameCoords );
CPPUNIT_TEST( testBuildOrthogonalField );
CPPUNIT_TEST( testGetCellsContainingPoint );
CPPUNIT_TEST( testGetValueOn1 );
void testOperationsOnFields4();
void testMergeNodesOnField();
void testCheckConsecutiveCellTypes();
+ void testSplitByType();
+ void testFuseUMeshesOnSameCoords();
void testBuildOrthogonalField();
void testGetCellsContainingPoint();
void testGetValueOn1();
sourceMesh->decrRef();
}
+void MEDCouplingBasicsTest::testSplitByType()
+{
+ MEDCouplingUMesh *m1=build3DSurfTargetMesh_1();
+ std::vector<MEDCouplingUMesh *> v=m1->splitByType();
+ CPPUNIT_ASSERT_EQUAL(3,(int)v.size());
+ MEDCouplingUMesh *m2=MEDCouplingUMesh::mergeUMeshesOnSameCoords(v);
+ m2->setName(m1->getName());
+ CPPUNIT_ASSERT(m1->isEqual(m2,1.e-12));
+ for(std::vector<MEDCouplingUMesh *>::const_iterator iter=v.begin();iter!=v.end();iter++)
+ (*iter)->decrRef();
+ m2->decrRef();
+ m1->decrRef();
+}
+
+void MEDCouplingBasicsTest::testFuseUMeshesOnSameCoords()
+{
+ std::vector<MEDCouplingUMesh *> meshes;
+ MEDCouplingUMesh *m2=build2DTargetMesh_1();
+ int cells1[3]={2,3,4};
+ MEDCouplingPointSet *m3_1=m2->buildPartOfMySelf(cells1,cells1+3,true);
+ MEDCouplingUMesh *m3=dynamic_cast<MEDCouplingUMesh *>(m3_1);
+ CPPUNIT_ASSERT(m3);
+ meshes.push_back(m3);
+ int cells2[3]={1,2,4};
+ MEDCouplingPointSet *m4_1=m2->buildPartOfMySelf(cells2,cells2+3,true);
+ MEDCouplingUMesh *m4=dynamic_cast<MEDCouplingUMesh *>(m4_1);
+ CPPUNIT_ASSERT(m4);
+ meshes.push_back(m4);
+ int cells3[2]={1,2};
+ MEDCouplingPointSet *m5_1=m2->buildPartOfMySelf(cells3,cells3+2,true);
+ MEDCouplingUMesh *m5=dynamic_cast<MEDCouplingUMesh *>(m5_1);
+ CPPUNIT_ASSERT(m5);
+ meshes.push_back(m5);
+ m2->decrRef();
+ //
+ std::vector<DataArrayInt *> corr;
+ MEDCouplingUMesh *m7=MEDCouplingUMesh::fuseUMeshesOnSameCoords(meshes,0,corr);
+ CPPUNIT_ASSERT_EQUAL(4,m7->getNumberOfCells());
+ CPPUNIT_ASSERT_EQUAL(3,(int)corr.size());
+ const int expectedVals1[3]={3,3,2};
+ const int expectedVals2[3][3]={{0,1,2},{3,0,2},{3,0,111111}};
+ for(int i=0;i<3;i++)
+ {
+ DataArrayInt *arr=corr[i];
+ CPPUNIT_ASSERT_EQUAL(1,arr->getNumberOfComponents());
+ int nbOfVals=expectedVals1[i];
+ CPPUNIT_ASSERT_EQUAL(nbOfVals,arr->getNumberOfTuples());
+ const int *vals=arr->getConstPointer();
+ for(int j=0;j<nbOfVals;j++)
+ CPPUNIT_ASSERT_EQUAL(expectedVals2[i][j],vals[j]);
+ }
+ std::vector< std::vector<int> > fidsOfGroups;
+ DataArrayInt *arr2=DataArrayInt::makePartition(corr,m7->getNumberOfCells(),fidsOfGroups);
+ const int fidExp[4]={5,1,3,4};
+ const int fidsGrp[3][3]={{1,3,5},{3,4,5},{4,5,23344}};
+ CPPUNIT_ASSERT_EQUAL(3,(int)fidsOfGroups.size());
+ CPPUNIT_ASSERT_EQUAL(1,arr2->getNumberOfComponents());
+ CPPUNIT_ASSERT_EQUAL(4,arr2->getNumberOfTuples());
+ CPPUNIT_ASSERT(std::equal(fidExp,fidExp+4,arr2->getConstPointer()));
+ for(int i=0;i<3;i++)
+ {
+ int nbOfVals=expectedVals1[i];
+ CPPUNIT_ASSERT_EQUAL(nbOfVals,(int)fidsOfGroups[i].size());
+ CPPUNIT_ASSERT(std::equal(fidsOfGroups[i].begin(),fidsOfGroups[i].end(),fidsGrp[i]));
+ }
+ for(std::vector<DataArrayInt *>::iterator iter=corr.begin();iter!=corr.end();iter++)
+ (*iter)->decrRef();
+ arr2->decrRef();
+ m7->decrRef();
+ //
+ m3->decrRef();
+ m4->decrRef();
+ m5->decrRef();
+}
+
void MEDCouplingBasicsTest::testBuildOrthogonalField()
{
MEDCouplingUMesh *targetMesh=build3DSurfTargetMesh_1();