* 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 'm2->getNumberOfCells()' that lists for each seg cell in 'm' the splitting node ids randomly sorted.
+ * - subDiv of size 'm2->getNumberOfCells()' that lists for each seg cell in 'm2' the splitting node ids randomly sorted.
* The aim of this method is to sort the splitting nodes, if any, and to put them in 'intersectEdge' output parameter based on edges of mesh 'm2'
* Nodes end up lying consecutively on a cutted edge.
* \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.
*
* Algorithm : \a splitMesh1D is cut into contiguous parts. Each contiguous parts will build incrementally the output 2D cells.
*
- * \param [in] allEdges a list of pairs (beginNode, endNode). Linked with \a allEdgesPtr to get the equation of edge.
+ * \param [in] allEdges a list of pairs (beginNode, endNode). Represents all edges (already cut) in the single 2D cell being handled here. Linked with \a allEdgesPtr to get the equation of edge.
*/
-MEDCouplingUMesh *BuildMesh2DCutInternal(double eps, const MEDCouplingUMesh *splitMesh1D, const std::vector<int>& allEdges, const std::vector< MCAuto<INTERP_KERNEL::Edge> >& allEdgesPtr, int offset,
+MEDCouplingUMesh *BuildMesh2DCutInternal(double eps, MEDCouplingUMesh *splitMesh1D, const std::vector<int>& allEdges, const std::vector< MCAuto<INTERP_KERNEL::Edge> >& allEdgesPtr, int offset,
MCAuto<DataArrayInt>& idsLeftRight)
{
int nbCellsInSplitMesh1D(splitMesh1D->getNumberOfCells());
idsLeftRight=DataArrayInt::New(); idsLeftRight->alloc(nbCellsInSplitMesh1D*2); idsLeftRight->fillWithValue(-2); idsLeftRight->rearrange(2);
int *idsLeftRightPtr(idsLeftRight->getPointer());
VectorOfCellInfo pool(edge1Bis,edge1BisPtr);
+
+ // Compute contiguous parts of splitMesh1D. We can not make the full assumption that segments are consecutive in the connectivity
+ // (even if the user correctly called orderConsecutiveCells1D()). Indeed the tool might be a closed line whose junction point is in
+ // splitMesh1D. There can be only one such a point, and if this happens this is necessarily at the start
+ // of the connectivity.
+ MCAuto <DataArrayInt> renumb(DataArrayInt::New());
+ renumb->alloc(nbCellsInSplitMesh1D,1);
+ const int * renumbP(renumb->begin());
+
+ int i, first=cSplitPtr[1];
+ // Follow 1D line backward as long as it is connected:
+ for (i=nbCellsInSplitMesh1D-1; cSplitPtr[ciSplitPtr[i]+2] == first; i--)
+ first=cSplitPtr[ciSplitPtr[i]+1];
+ if (i < nbCellsInSplitMesh1D-1)
+ {
+ // Build circular permutation to shift consecutive edges together
+ renumb->iota(i+1);
+ renumb->applyModulus(nbCellsInSplitMesh1D);
+ splitMesh1D->renumberCells(renumbP, false);
+ cSplitPtr = splitMesh1D->getNodalConnectivity()->begin();
+ ciSplitPtr = splitMesh1D->getNodalConnectivityIndex()->begin();
+ }
+ else
+ renumb->iota();
+ //
+
for(int iStart=0;iStart<nbCellsInSplitMesh1D;)
{// split [0:nbCellsInSplitMesh1D) in contiguous parts [iStart:iEnd)
int iEnd(iStart);
}
if(iEnd<nbCellsInSplitMesh1D)
iEnd++;
- //
+
MCAuto<MEDCouplingUMesh> partOfSplitMesh1D(static_cast<MEDCouplingUMesh *>(splitMesh1D->buildPartOfMySelfSlice(iStart,iEnd,1,true)));
int pos(pool.getPositionOf(eps,partOfSplitMesh1D));
//
iStart=iEnd;
}
for(int mm=0;mm<nbCellsInSplitMesh1D;mm++)
- pool.feedEdgeInfoAt(eps,mm,offset,idsLeftRightPtr+2*mm);
+ pool.feedEdgeInfoAt(eps,renumbP[mm],offset,idsLeftRightPtr+2*mm);
+
return pool.getZeMesh().retn();
}
-MEDCouplingUMesh *BuildMesh2DCutFrom(double eps, int cellIdInMesh2D, const MEDCouplingUMesh *mesh2DDesc, const MEDCouplingUMesh *splitMesh1D,
+/*
+ * splitMesh1D is an input parameter but might have its cells renumbered.
+ */
+MEDCouplingUMesh *BuildMesh2DCutFrom(double eps, int cellIdInMesh2D, const MEDCouplingUMesh *mesh2DDesc, MEDCouplingUMesh *splitMesh1D,
const int *descBg, const int *descEnd, const std::vector< std::vector<int> >& intersectEdge1, int offset,
MCAuto<DataArrayInt>& idsLeftRight)
{
self.assertTrue([0,1,2], c.getValues())
self.assertEqual([2,1], d.getValues())
+ def testSwig2Intersect2DMeshWith1DLine18(self):
+ """ Rare case: a *closed* line used as a tool, with the closing point inside a 2D cell ... """
+ tool = MEDCouplingUMesh('circle', 1)
+ coo = DataArrayDouble([(39.35,0),(27.8247,27.8247),(2.40949e-15,39.35),(-27.8247,27.8247),(-39.35,4.81899e-15),(-27.8247,-27.8247),(-7.22848e-15,-39.35),(27.8247,-27.8247),(39.35,7.39805e-15)])
+ tool.setCoords(coo)
+ c = DataArrayInt([2, 3, 5, 8, 2, 5, 3, 4])
+ cI = DataArrayInt([0, 4, 8])
+ tool.setConnectivity(c, cI)
+
+ meh = MEDCouplingUMesh('meh', 2)
+ coo = DataArrayDouble([(-26.4275,36.6199),(-23.5868,31.6996),(-34.1861,41.0993),(-30.3383,25.0214),(-40.1861,30.707),(-35.2622,27.8642),(-37.1861,35.9032),(-30.3068,38.8596),(-25.0071,34.1598),(-26.9625,28.3605),(-25.7138,32.5128),(-27.354,36.4726),(-36.9138,32.5128),(-27.354,28.553),(-26.8908,36.5462),(-28.8461,26.7872)])
+ meh.setCoords(coo)
+ c = DataArrayInt([32, 0, 1, 3, 13, 11, 8, 9, 15, 10, 14,
+ 32, 3, 4, 2, 0, 11, 13, 5, 6, 7, 14, 12, 15])
+ cI = DataArrayInt([0, 11, 24])
+ meh.setConnectivity(c, cI)
+
+ res2D, res1D, m1, m2 = MEDCouplingUMesh.Intersect2DMeshWith1DLine(meh, tool, 1e-12)
+ self.assertEqual(4, res2D.getNumberOfCells())
+ self.assertEqual(res2D.getNodalConnectivity().getValues(),[32, 13, 11, 0, 1, 25, 19, 26, 33, 34, 35, 36, 37, 38, 39, 32, 3, 26, 19, 25, 40, 41, 42, 43,
+ 32, 4, 2, 0, 11, 13, 26, 27, 44, 45, 46, 47, 48, 49, 50, 32, 3, 27, 26, 51, 52, 53])
+ self.assertEqual(res2D.getNodalConnectivityIndex().getValues(),[0, 15, 24, 39, 46])
+ self.assertEqual(res1D.getNodalConnectivity().getValues(),[2, 19, 25, 28, 2, 25, 21, 29, 2, 21, 27, 30, 2, 27, 26, 31, 2, 26, 19, 32])
+ self.assertEqual(res1D.getNodalConnectivityIndex().getValues(),[0, 4, 8, 12, 16, 20])
+ self.assertEqual(m1.getValues(), [0,0,1,1])
+ self.assertEqual(m2.getValues(), [0,1, -1,-1, -1,-1, 2,3, 0,1])
+
def testSwig2Conformize2D1(self):
eps = 1.0e-8
coo = [0.,-0.5,0.,0.,0.5,0.,0.5,-0.5,0.25,