From bd3ab72f59b046cca4561d4cb597c9f4c216ad66 Mon Sep 17 00:00:00 2001 From: bruneton Date: Mon, 13 Jan 2014 10:57:58 +0000 Subject: [PATCH] + Bug fix : ComposedEdge::applyGlobalSimilarity() was potentially passing twice on the same (Edge*). + Various comments --- .../InterpKernelGeo2DComposedEdge.cxx | 22 +++++++++++++----- .../InterpKernelGeo2DEdgeArcCircle.cxx | 2 +- .../Geometric2D/InterpKernelGeo2DNode.cxx | 2 +- .../InterpKernelGeo2DQuadraticPolygon.cxx | 1 - .../QuadraticPlanarInterpTest.hxx | 5 ++++ .../QuadraticPlanarInterpTest5.cxx | 23 +++++++++++++++++++ src/MEDCoupling/MEDCouplingUMesh.cxx | 4 +++- 7 files changed, 49 insertions(+), 10 deletions(-) diff --git a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DComposedEdge.cxx b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DComposedEdge.cxx index bc3c20662..ba6ce3141 100644 --- a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DComposedEdge.cxx +++ b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DComposedEdge.cxx @@ -284,9 +284,14 @@ void ComposedEdge::unApplyGlobalSimilarityExt(ComposedEdge& other, double xBary, other.getAllNodes(allNodes); for(std::set::iterator iter=allNodes.begin();iter!=allNodes.end();iter++) (*iter)->unApplySimilarity(xBary,yBary,fact); + + // [Adrien] - same issue as in applyGlobalSimilarity() - see comments there + std::set allEdges; for(std::list::iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) - (*iter)->unApplySimilarity(xBary,yBary,fact); + allEdges.insert((*iter)->getPtr()); for(std::list::iterator iter=other._sub_edges.begin();iter!=other._sub_edges.end();iter++) + allEdges.insert((*iter)->getPtr()); + for(std::set::iterator iter = allEdges.begin();iter != allEdges.end();iter++) (*iter)->unApplySimilarity(xBary,yBary,fact); } @@ -373,10 +378,15 @@ void ComposedEdge::applyGlobalSimilarity2(ComposedEdge *other, double xBary, dou allNodes.insert(allNodes2.begin(),allNodes2.end()); for(std::set::iterator iter=allNodes.begin();iter!=allNodes.end();iter++) (*iter)->applySimilarity(xBary,yBary,dimChar); + // [Adrien] many ElementaryEdge might reference the same Edge* - ensure we don'y scale twice! + std::set allEdges; for(std::list::iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) - (*iter)->applySimilarity(xBary,yBary,dimChar); + allEdges.insert((*iter)->getPtr()); for(std::list::iterator iter=other->_sub_edges.begin();iter!=other->_sub_edges.end();iter++) - (*iter)->applySimilarity(xBary,yBary,dimChar); + allEdges.insert((*iter)->getPtr()); + // Similarity only on set of unique underlying edges: + for(std::set::iterator iter = allEdges.begin();iter != allEdges.end();iter++) + (*iter)->applySimilarity(xBary,yBary,dimChar); } /*! @@ -486,8 +496,8 @@ double ComposedEdge::isInOrOutAlg(Node *nodeToTest, std::set< IntersectElement > { Bounds b; b.prepareForAggregation(); fillBounds(b); - if(b.nearlyWhere((*nodeToTest)[0],(*nodeToTest)[1])==OUT) - return false; + //if(b.nearlyWhere((*nodeToTest)[0],(*nodeToTest)[1])==OUT) + // return false; // searching for e1 std::set nodes; getAllNodes(nodes); @@ -515,7 +525,7 @@ double ComposedEdge::isInOrOutAlg(Node *nodeToTest, std::set< IntersectElement > Edge *e=val->getPtr(); std::auto_ptr intersc(Edge::BuildIntersectorWith(e1,e)); bool obviousNoIntersection,areOverlapped; - intersc->areOverlappedOrOnlyColinears(0,obviousNoIntersection,areOverlapped); + intersc->areOverlappedOrOnlyColinears(0,obviousNoIntersection,areOverlapped); // first parameter never used if(obviousNoIntersection) { continue; diff --git a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeArcCircle.cxx b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeArcCircle.cxx index 8233ef049..46b2fb156 100644 --- a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeArcCircle.cxx +++ b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeArcCircle.cxx @@ -308,7 +308,7 @@ ArcCSegIntersector::ArcCSegIntersector(const EdgeArcCircle& e1, const EdgeLin& e void ArcCSegIntersector::areOverlappedOrOnlyColinears(const Bounds *whereToFind, bool& obviousNoIntersection, bool& areOverlapped) { - areOverlapped=false;//No overlapping by contruction + areOverlapped=false;//No overlapping by construction const double *center=getE1().getCenter(); _dx=(*(_e2.getEndNode()))[0]-(*(_e2.getStartNode()))[0]; _dy=(*(_e2.getEndNode()))[1]-(*(_e2.getStartNode()))[1]; diff --git a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DNode.cxx b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DNode.cxx index 06d19bc98..61e949db5 100644 --- a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DNode.cxx +++ b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DNode.cxx @@ -93,7 +93,7 @@ double Node::distanceWithSq(const Node& other) const /*! * WARNING different from 'computeAngle' method ! The returned value are not in the same interval ! - * Here in -Pi/2; Pi/2. Typically this method returns the same value by exchanging pt1 and pt2. + * Here in [0; Pi). Typically this method returns the same value by exchanging pt1 and pt2. * Use in process of detection of a point in or not in polygon. */ double Node::computeSlope(const double *pt1, const double *pt2) diff --git a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DQuadraticPolygon.cxx b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DQuadraticPolygon.cxx index f8c6a4477..e4ecd62bc 100644 --- a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DQuadraticPolygon.cxx +++ b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DQuadraticPolygon.cxx @@ -332,7 +332,6 @@ void QuadraticPolygon::buildFromCrudeDataArray(const std::map& mapp, bool isQuad, const int *nodalBg, const double *coords, const int *descBg, const int *descEnd, const std::vector >& intersectEdges) diff --git a/src/INTERP_KERNELTest/QuadraticPlanarInterpTest.hxx b/src/INTERP_KERNELTest/QuadraticPlanarInterpTest.hxx index 18ed28c2c..b26696bf1 100644 --- a/src/INTERP_KERNELTest/QuadraticPlanarInterpTest.hxx +++ b/src/INTERP_KERNELTest/QuadraticPlanarInterpTest.hxx @@ -106,6 +106,8 @@ namespace INTERP_TEST // CPPUNIT_TEST( checkNormalize ); CPPUNIT_TEST( checkMakePartitionAbs1 ); + // + CPPUNIT_TEST( checkIsInOrOut ); CPPUNIT_TEST_SUITE_END(); public: void setUp(); @@ -194,6 +196,9 @@ namespace INTERP_TEST // void checkNormalize(); void checkMakePartitionAbs1(); + // From Adrien: + void checkIsInOrOut(); + private: INTERP_KERNEL::QuadraticPolygon *buildQuadraticPolygonCoarseInfo(const double *coords, const int *conn, int lgth); INTERP_KERNEL::EdgeArcCircle *buildArcOfCircle(const double *center, double radius, double alphaStart, double alphaEnd); diff --git a/src/INTERP_KERNELTest/QuadraticPlanarInterpTest5.cxx b/src/INTERP_KERNELTest/QuadraticPlanarInterpTest5.cxx index 23210afa5..72c4c45a7 100644 --- a/src/INTERP_KERNELTest/QuadraticPlanarInterpTest5.cxx +++ b/src/INTERP_KERNELTest/QuadraticPlanarInterpTest5.cxx @@ -1171,4 +1171,27 @@ void QuadraticPlanarInterpTest::checkNonRegressionOmar0030() delete pol2; } +void QuadraticPlanarInterpTest::checkIsInOrOut() +{ + double coords[8]={ 0.30662641093707971, -0.47819928619088981, + -0.47819928619088964, 0.30662641093707987, + 0.0, 0.0, + 0.4, 0.4 + }; + coords[4] = (coords[0] + coords[2]) / 2.0; + coords[5] = (coords[1] + coords[3]) / 2.0; + +/* double r = 0.55495557248864675969; + coords[6] = coords[4]; + coords[7] = coords[5] + r;*/ + + int tab4[4]={ 0, 1, 2, 3}; + QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab4,4); + Node * n = new Node(0.3175267678416348, -0.4890996430954449); + + CPPUNIT_ASSERT(! pol1->isInOrOut(n)); // node should be out + delete pol1; +} + + } diff --git a/src/MEDCoupling/MEDCouplingUMesh.cxx b/src/MEDCoupling/MEDCouplingUMesh.cxx index 70e17c9c1..10f88afc0 100644 --- a/src/MEDCoupling/MEDCouplingUMesh.cxx +++ b/src/MEDCoupling/MEDCouplingUMesh.cxx @@ -8508,6 +8508,7 @@ void MEDCouplingUMesh::BuildIntersecting2DCellsFromEdges(double eps, const MEDCo INTERP_KERNEL::QuadraticPolygon pol1; INTERP_KERNEL::NormalizedCellType typ=(INTERP_KERNEL::NormalizedCellType)conn1[connI1[i]]; const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(typ); + // Populate mapp and mappRev with nodes from the current cell (i) from mesh1 - this also builds the Node* objects: MEDCouplingUMeshBuildQPFromMesh3(coo1,offset1,coo2,offset2,addCoords,desc1+descIndx1[i],desc1+descIndx1[i+1],intesctEdges1,/* output */mapp,mappRev); // pol1 is the full cell from mesh2, in QP format, with all the additional intersecting nodes. pol1.buildFromCrudeDataArray(mappRev,cm.isQuadratic(),conn1+connI1[i]+1,coo1, @@ -8526,10 +8527,11 @@ void MEDCouplingUMesh::BuildIntersecting2DCellsFromEdges(double eps, const MEDCo { INTERP_KERNEL::NormalizedCellType typ2=(INTERP_KERNEL::NormalizedCellType)conn2[connI2[*it2]]; const INTERP_KERNEL::CellModel& cm2=INTERP_KERNEL::CellModel::GetCellModel(typ2); + // Complete mapping with elements coming from the current cell it2 in mesh2: MEDCouplingUMeshBuildQPFromMesh3(coo1,offset1,coo2,offset2,addCoords,desc2+descIndx2[*it2],desc2+descIndx2[*it2+1],intesctEdges2,/* output */mapp,mappRev); // pol2 is the new QP in the final merged result. pol2s[ii].buildFromCrudeDataArray2(mappRev,cm2.isQuadratic(),conn2+connI2[*it2]+1,coo2,desc2+descIndx2[*it2],desc2+descIndx2[*it2+1],intesctEdges2, - pol1,desc1+descIndx1[i],desc1+descIndx1[i+1],intesctEdges1,colinear2,edgesIn2ForShare); + pol1,desc1+descIndx1[i],desc1+descIndx1[i+1],intesctEdges1,colinear2, /* output */ edgesIn2ForShare); } ii=0; for(std::vector::const_iterator it2=candidates2.begin();it2!=candidates2.end();it2++,ii++) -- 2.39.2