From b8f447013830c73038f8de6abb77eb0a413044ff Mon Sep 17 00:00:00 2001 From: abn Date: Tue, 4 Apr 2017 10:31:06 +0200 Subject: [PATCH] The last optim :-) --- src/MEDCoupling/MEDCouplingUMesh.hxx | 2 +- .../MEDCouplingUMesh_intersection.cxx | 51 +++++++++++++++---- .../MEDCouplingBasicsTest5.py | 12 ----- .../MEDCouplingIntersectTest.py | 15 ------ 4 files changed, 41 insertions(+), 39 deletions(-) diff --git a/src/MEDCoupling/MEDCouplingUMesh.hxx b/src/MEDCoupling/MEDCouplingUMesh.hxx index ccdae4a34..efab092eb 100644 --- a/src/MEDCoupling/MEDCouplingUMesh.hxx +++ b/src/MEDCoupling/MEDCouplingUMesh.hxx @@ -349,7 +349,7 @@ namespace MEDCoupling static void ComputeAllTypesInternal(std::set& types, const DataArrayInt *nodalConnec, const DataArrayInt *nodalConnecIndex); static bool OrderPointsAlongLine(const double * coo, int startNode, int endNode, const int * c, const int * cI, const int *idsBg, const int *endBg, - std::vector & pointIds); + std::vector & pointIds, std::vector & hitSegs); static void ReplaceEdgeInFace(const int * sIdxConn, const int * sIdxConnE, int startNode, int endNode, const std::vector& insidePoints, std::vector& modifiedFace); public: diff --git a/src/MEDCoupling/MEDCouplingUMesh_intersection.cxx b/src/MEDCoupling/MEDCouplingUMesh_intersection.cxx index c3c345915..8865deb8a 100644 --- a/src/MEDCoupling/MEDCouplingUMesh_intersection.cxx +++ b/src/MEDCoupling/MEDCouplingUMesh_intersection.cxx @@ -2001,12 +2001,13 @@ DataArrayInt *MEDCouplingUMesh::colinearize2D(double eps) ///@cond INTERNAL /** - * c, cI describe a wire mesh in 3D space. + * c, cI describe a wire mesh in 3D space, in local numbering + * startNode, endNode in global numbering *\return true if the segment is indeed split */ bool MEDCouplingUMesh::OrderPointsAlongLine(const double * coo, int startNode, int endNode, const int * c, const int * cI, const int *idsBg, const int *endBg, - std::vector & pointIds/*, std::vector & hitSegs*/) + std::vector & pointIds, std::vector & hitSegs) { using namespace std; @@ -2032,17 +2033,37 @@ bool MEDCouplingUMesh::OrderPointsAlongLine(const double * coo, int startNode, i const int idx = (*it).second; if (!go) { - if (idx == startNode) go = 1; - if (idx == endNode) go = 2; + if (idx == startNode) go = 1; + if (idx == endNode) go = 2; + if (go) pointIds.push_back(idx); continue; } + pointIds.push_back(idx); if (idx == endNode || idx == startNode) break; - pointIds.push_back(idx); } + +// vector pointIds2(pointIds.size()+2); +// copy(pointIds.begin(), pointIds.end(), pointIds2.data()+1); +// pointIds2[0] = startNode; +// pointIds2[pointIds2.size()-1] = endNode; + if (go == 2) reverse(pointIds.begin(), pointIds.end()); - return (pointIds.size() != 0); + + // Now identify smaller segments that are not sub-divided - those won't need any further treatment: + for (const int * it = idsBg; it != endBg; ++it) + { + int start = c[cI[*it]+1], end = c[cI[*it]+2]; + vector::const_iterator itStart = find(pointIds.begin(), pointIds.end(), start); + if (itStart == pointIds.end()) continue; + vector::const_iterator itEnd = find(pointIds.begin(), pointIds.end(), end); + if (itEnd == pointIds.end()) continue; + if (abs(distance(itEnd, itStart)) != 1) continue; + hitSegs.push_back(*it); // segment is undivided. + } + + return (pointIds.size() > 2); // something else apart start and end node } void MEDCouplingUMesh::ReplaceEdgeInFace(const int * sIdxConn, const int * sIdxConnE, int startNode, int endNode, @@ -2050,7 +2071,7 @@ void MEDCouplingUMesh::ReplaceEdgeInFace(const int * sIdxConn, const int * sIdxC { using namespace std; int dst = distance(sIdxConn, sIdxConnE); - modifiedFace.reserve(dst + insidePoints.size()); + modifiedFace.reserve(dst + insidePoints.size()-2); modifiedFace.resize(dst); copy(sIdxConn, sIdxConnE, modifiedFace.data()); @@ -2063,9 +2084,9 @@ void MEDCouplingUMesh::ReplaceEdgeInFace(const int * sIdxConn, const int * sIdxC throw INTERP_KERNEL::Exception("MEDCouplingUMesh::ReplaceEdgeInFace: internal error, should never happen!"); int d = distance(startPos, endPos); if (d == 1 || d == (1-dst)) // don't use modulo, for neg numbers, result is implementation defined ... - modifiedFace.insert(++startPos, insidePoints.begin(), insidePoints.end()); + modifiedFace.insert(++startPos, ++insidePoints.begin(), --insidePoints.end()); // insidePoints also contains start and end node. Those dont need to be inserted. else - modifiedFace.insert(++endPos, insidePoints.rbegin(), insidePoints.rend()); + modifiedFace.insert(++endPos, ++insidePoints.rbegin(), --insidePoints.rend()); } ///@endcond @@ -2304,9 +2325,14 @@ DataArrayInt *MEDCouplingUMesh::conformize3D(double eps) } sort(S.rbegin(),S.rend()); // reverse sort + vector hit(nDesc2Cell); + fill(hit.begin(), hit.end(), false); + for( vector>::const_iterator it = S.begin(); it != S.end(); it++) { int eIdx = (*it).second; + if (hit[eIdx]) + continue; vector candidates, cands2; myTree2.getIntersectingElems(bbox2+eIdx*2*SPACEDIM,candidates); @@ -2365,11 +2391,14 @@ DataArrayInt *MEDCouplingUMesh::conformize3D(double eps) continue; // Now the ordering along the Ox axis: - std::vector insidePoints; + std::vector insidePoints, hitSegs; bool isSplit = OrderPointsAlongLine(mPartCand->_coords->getConstPointer(), nodeMap->begin()[startNode], nodeMap->begin()[endNode], mPartCand->getNodalConnectivity()->begin(), mPartCand->getNodalConnectivityIndex()->begin(), idsGoodLine->begin(), idsGoodLine->end(), - /*out*/insidePoints); + /*out*/insidePoints, hitSegs); + // Optim: smaller segments completly included in eIdx and not split won't need any further treatment: + for (vector::const_iterator its=hitSegs.begin(); its != hitSegs.end(); ++its) + hit[cands2[*its]] = true; if (!isSplit) // current segment remains in one piece continue; diff --git a/src/MEDCoupling_Swig/MEDCouplingBasicsTest5.py b/src/MEDCoupling_Swig/MEDCouplingBasicsTest5.py index 43ef390fa..04be1e451 100644 --- a/src/MEDCoupling_Swig/MEDCouplingBasicsTest5.py +++ b/src/MEDCoupling_Swig/MEDCouplingBasicsTest5.py @@ -3719,18 +3719,6 @@ class MEDCouplingBasicsTest5(unittest.TestCase): self.assertEqual(siRef, si.getValues()) self.assertEqual(idxRef, idx.getValues()) self.assertEqual(cRef, val.getValues()) - - print 'toto' - a, b, c = [0,0,0], [0], [] - sla1 = MEDCouplingSkyLineArray() - sla1.set3(DataArrayInt(a),DataArrayInt(b),DataArrayInt(c)) - print sla1 - sla1.pushBackPack(0, [2,3,4]) - print sla1 - sla1.pushBackPack(1, [4,5,6]) - print sla1 - sla1.pushBackPack(0, [7,8,9]) - print sla1 pass def testMEDCouplingUMeshgenerateGraph(self): diff --git a/src/MEDCoupling_Swig/MEDCouplingIntersectTest.py b/src/MEDCoupling_Swig/MEDCouplingIntersectTest.py index 8b3666c96..4029b5db6 100644 --- a/src/MEDCoupling_Swig/MEDCouplingIntersectTest.py +++ b/src/MEDCoupling_Swig/MEDCouplingIntersectTest.py @@ -955,17 +955,11 @@ class MEDCouplingIntersectTest(unittest.TestCase): 7, 11, 21, 19, -1, 19, 21, 20, 18]) cI = DataArrayInt([0, 37, 74, 104, 134]) mesh.setConnectivity(c, cI) -# mretDesc, _, _, _, _ = mesh.buildDescendingConnectivity() -# mretDesc2, _, _, _, _ = mretDesc.buildDescendingConnectivity() -# mretDesc.writeVTK("/tmp/toto_desc.vtu") -# mretDesc2.writeVTK("/tmp/toto_desc2.vtu") ret = mesh.conformize3D(1.0e-8) mretDesc, _, _, _, _ = mesh.buildDescendingConnectivity() mretDesc2, _, _, _, _ = mretDesc.buildDescendingConnectivity() -# mretDesc.writeVTK("/tmp/toto_conf_desc.vtu") -# mretDesc2.writeVTK("/tmp/toto_conf_desc2.vtu") c0, cI0 = mesh.getNodalConnectivity().getValues(), mesh.getNodalConnectivityIndex().getValues() c, cI = mretDesc.getNodalConnectivity().getValues(), mretDesc.getNodalConnectivityIndex().getValues() c2, cI2 = mretDesc2.getNodalConnectivity().getValues(), mretDesc2.getNodalConnectivityIndex().getValues() @@ -997,19 +991,10 @@ class MEDCouplingIntersectTest(unittest.TestCase): mesh.setConnectivity(c, cI) mesh.mergeNodes(eps) # the initial case has double nodes -# mretDesc, _, _, _, _ = mesh.buildDescendingConnectivity() -# mretDesc2, _, _, _, _ = mretDesc.buildDescendingConnectivity() -# mretDesc.writeVTK("/tmp/toto_desc.vtu") -# mretDesc2.writeVTK("/tmp/toto_desc2.vtu") -# print mretDesc2.getNumberOfCells() - ret = mesh.conformize3D(eps) mretDesc, _, _, _, _ = mesh.buildDescendingConnectivity() mretDesc2, _, _, _, _ = mretDesc.buildDescendingConnectivity() -# mesh.writeVTK("/tmp/toto_conf.vtu") -# mretDesc.writeVTK("/tmp/toto_conf_desc.vtu") -# mretDesc2.writeVTK("/tmp/toto_conf_desc2.vtu") c0, cI0 = mesh.getNodalConnectivity().getValues(), mesh.getNodalConnectivityIndex().getValues() c, cI = mretDesc.getNodalConnectivity().getValues(), mretDesc.getNodalConnectivityIndex().getValues() c2, cI2 = mretDesc2.getNodalConnectivity().getValues(), mretDesc2.getNodalConnectivityIndex().getValues() -- 2.39.2