From 60824ab67362365bee36503124461e646cf55ed6 Mon Sep 17 00:00:00 2001 From: geay Date: Thu, 27 Mar 2014 14:33:43 +0100 Subject: [PATCH] Improve perf of MEDCouplingUMesh::IntersectMeshes --- .../InterpKernelGeo2DComposedEdge.cxx | 124 +++++++++++++----- .../InterpKernelGeo2DComposedEdge.hxx | 10 ++ .../Geometric2D/InterpKernelGeo2DEdge.hxx | 7 + .../Geometric2D/InterpKernelGeo2DNode.hxx | 7 + .../InterpKernelGeo2DQuadraticPolygon.cxx | 4 +- 5 files changed, 117 insertions(+), 35 deletions(-) diff --git a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DComposedEdge.cxx b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DComposedEdge.cxx index 36a13f886..2670f5686 100644 --- a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DComposedEdge.cxx +++ b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DComposedEdge.cxx @@ -279,20 +279,14 @@ double ComposedEdge::normalize(ComposedEdge *other, double& xBary, double& yBary */ void ComposedEdge::unApplyGlobalSimilarityExt(ComposedEdge& other, double xBary, double yBary, double fact) { - std::set allNodes; - getAllNodes(allNodes); - 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++) - 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); + initNodeHitStatus(); + other.initNodeHitStatus(); + unApplySimilarityOnMyNodes(xBary,yBary,fact); + other.unApplySimilarityOnMyNodesIfNotAlreadyHit(xBary,yBary,fact); + initEdgeHitStatus(); + other.initEdgeHitStatus(); + unApplySimilarityOnMyEdges(xBary,yBary,fact); + other.unApplySimilarityOnMyEdgesIfNotAlreadyHit(xBary,yBary,fact); } double ComposedEdge::normalizeExt(ComposedEdge *other, double& xBary, double& yBary) @@ -368,25 +362,14 @@ void ComposedEdge::applyGlobalSimilarity(double xBary, double yBary, double dimC */ void ComposedEdge::applyGlobalSimilarity2(ComposedEdge *other, double xBary, double yBary, double dimChar) { - std::set allNodes; - getAllNodes(allNodes); - std::set allNodes2; - other->getAllNodes(allNodes2); - for(std::set::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::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++) - allEdges.insert((*iter)->getPtr()); - for(std::list::iterator iter=other->_sub_edges.begin();iter!=other->_sub_edges.end();iter++) - 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); + initNodeHitStatus(); + other->initNodeHitStatus(); + applySimilarityOnMyNodes(xBary,yBary,dimChar); + other->applySimilarityOnMyNodesIfNotAlreadyHit(xBary,yBary,dimChar); + initEdgeHitStatus(); + other->initEdgeHitStatus(); + applySimilarityOnMyEdges(xBary,yBary,dimChar); + other->applySimilarityOnMyEdgesIfNotAlreadyHit(xBary,yBary,dimChar); } /*! @@ -425,6 +408,81 @@ void ComposedEdge::getAllNodes(std::set& output) const (*iter)->getAllNodes(output); } +void ComposedEdge::initNodeHitStatus() const + { + for(std::list::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) + { + (*iter)->getStartNode()->initHitStatus(); + (*iter)->getEndNode()->initHitStatus(); + } +} + +void ComposedEdge::applySimilarityOnMyNodes(double xBary, double yBary, double dimChar) const +{ + for(std::list::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) + { + (*iter)->getStartNode()->hitMeAlone(xBary,yBary,dimChar); + (*iter)->getEndNode()->hitMeAlone(xBary,yBary,dimChar); + } +} + +void ComposedEdge::unApplySimilarityOnMyNodes(double xBary, double yBary, double dimChar) const +{ + for(std::list::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) + { + (*iter)->getStartNode()->unHitMeAlone(xBary,yBary,dimChar); + (*iter)->getEndNode()->unHitMeAlone(xBary,yBary,dimChar); + } +} + +void ComposedEdge::applySimilarityOnMyNodesIfNotAlreadyHit(double xBary, double yBary, double dimChar) const +{ + for(std::list::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) + { + (*iter)->getStartNode()->hitMeAfter(xBary,yBary,dimChar); + (*iter)->getEndNode()->hitMeAfter(xBary,yBary,dimChar); + } +} + +void ComposedEdge::unApplySimilarityOnMyNodesIfNotAlreadyHit(double xBary, double yBary, double dimChar) const +{ + for(std::list::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) + { + (*iter)->getStartNode()->unHitMeAfter(xBary,yBary,dimChar); + (*iter)->getEndNode()->unHitMeAfter(xBary,yBary,dimChar); + } +} + +void ComposedEdge::initEdgeHitStatus() const +{ + for(std::list::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) + (*iter)->getPtr()->initHitStatus(); +} + +void ComposedEdge::applySimilarityOnMyEdges(double xBary, double yBary, double dimChar) const +{ + for(std::list::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) + (*iter)->getPtr()->hitMeAlone(xBary,yBary,dimChar); +} + +void ComposedEdge::unApplySimilarityOnMyEdges(double xBary, double yBary, double dimChar) const +{ + for(std::list::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) + (*iter)->getPtr()->unHitMeAlone(xBary,yBary,dimChar); +} + +void ComposedEdge::applySimilarityOnMyEdgesIfNotAlreadyHit(double xBary, double yBary, double dimChar) const +{ + for(std::list::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) + (*iter)->getPtr()->hitMeAfter(xBary,yBary,dimChar); +} + +void ComposedEdge::unApplySimilarityOnMyEdgesIfNotAlreadyHit(double xBary, double yBary, double dimChar) const +{ + for(std::list::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) + (*iter)->getPtr()->unHitMeAfter(xBary,yBary,dimChar); +} + void ComposedEdge::getBarycenter(double *bary, double& weigh) const { weigh=0.; bary[0]=0.; bary[1]=0.; diff --git a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DComposedEdge.hxx b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DComposedEdge.hxx index c3de06e4a..e014d5942 100644 --- a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DComposedEdge.hxx +++ b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DComposedEdge.hxx @@ -71,6 +71,16 @@ namespace INTERP_KERNEL INTERPKERNEL_EXPORT void dispatchPerimeterExcl(double& partConsidered, double& commonPart) const; INTERPKERNEL_EXPORT double dispatchPerimeterAdv(const ComposedEdge& father, std::vector& result) const; INTERPKERNEL_EXPORT void getAllNodes(std::set& output) const; + INTERPKERNEL_EXPORT void initNodeHitStatus() const; + INTERPKERNEL_EXPORT void applySimilarityOnMyNodes(double xBary, double yBary, double dimChar) const; + INTERPKERNEL_EXPORT void unApplySimilarityOnMyNodes(double xBary, double yBary, double dimChar) const; + INTERPKERNEL_EXPORT void applySimilarityOnMyNodesIfNotAlreadyHit(double xBary, double yBary, double dimChar) const; + INTERPKERNEL_EXPORT void unApplySimilarityOnMyNodesIfNotAlreadyHit(double xBary, double yBary, double dimChar) const; + INTERPKERNEL_EXPORT void initEdgeHitStatus() const; + INTERPKERNEL_EXPORT void applySimilarityOnMyEdges(double xBary, double yBary, double dimChar) const; + INTERPKERNEL_EXPORT void unApplySimilarityOnMyEdges(double xBary, double yBary, double dimChar) const; + INTERPKERNEL_EXPORT void applySimilarityOnMyEdgesIfNotAlreadyHit(double xBary, double yBary, double dimChar) const; + INTERPKERNEL_EXPORT void unApplySimilarityOnMyEdgesIfNotAlreadyHit(double xBary, double yBary, double dimChar) const; INTERPKERNEL_EXPORT void getBarycenter(double *bary, double& weigh) const; INTERPKERNEL_EXPORT bool completed() const { return getEndNode()==getStartNode(); } INTERPKERNEL_EXPORT void setValueAt(int i, Edge *e, bool direction=true); diff --git a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdge.hxx b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdge.hxx index 4a3805c50..dd67a8000 100644 --- a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdge.hxx +++ b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdge.hxx @@ -208,6 +208,12 @@ namespace INTERP_KERNEL void declareOn() const; void declareIn() const; void declareOut() const; + void initHitStatus() const { _hit=false; } + bool getHitStatus() const { return _hit; } + void hitMeAlone(double xBary, double yBary, double dimChar) { _hit=true; applySimilarity(xBary,yBary,dimChar); } + void unHitMeAlone(double xBary, double yBary, double dimChar) { _hit=true; unApplySimilarity(xBary,yBary,dimChar); } + void hitMeAfter(double xBary, double yBary, double dimChar) { if(!_hit) hitMeAlone(xBary,yBary,dimChar); } + void unHitMeAfter(double xBary, double yBary, double dimChar) { if(!_hit) unHitMeAlone(xBary,yBary,dimChar); } const Bounds& getBounds() const { return _bounds; } void fillXfigStreamForLoc(std::ostream& stream) const; Node *getNode(TypeOfLocInEdge where) const { if(where==START) return _start; else if(where==END) return _end; else return 0; } @@ -282,6 +288,7 @@ namespace INTERP_KERNEL static bool SplitOverlappedEdges(const Edge *e1, const Edge *e2, Node *nS, Node *nE, bool direction, int code, ComposedEdge& outVal1, ComposedEdge& outVal2); protected: + mutable bool _hit; mutable unsigned char _cnt; mutable TypeOfEdgeLocInPolygon _loc; Bounds _bounds; diff --git a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DNode.hxx b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DNode.hxx index 2adb5c04b..51f907532 100644 --- a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DNode.hxx +++ b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DNode.hxx @@ -55,6 +55,12 @@ namespace INTERP_KERNEL Node(std::istream& stream); void incrRef() const { _cnt++; } bool decrRef(); + void initHitStatus() const { _hit=0; } + char getHitStatus() const { return _hit; } + void hitMeAlone(double xBary, double yBary, double dimChar) { if(_hit==0) { _hit=1; applySimilarity(xBary,yBary,dimChar); } } + void unHitMeAlone(double xBary, double yBary, double dimChar) { if(_hit==0) { _hit=1; unApplySimilarity(xBary,yBary,dimChar); } } + void hitMeAfter(double xBary, double yBary, double dimChar) { if(_hit==0) { hitMeAlone(xBary,yBary,dimChar); _hit=2; } else if(_hit==1) declareOn(); } + void unHitMeAfter(double xBary, double yBary, double dimChar) { if(_hit==0) { unHitMeAlone(xBary,yBary,dimChar); _hit=2; } } void initLocs() const { _loc=UNKNOWN; } void setLoc(TypeOfLocInPolygon loc) const { _loc=loc; } TypeOfLocInPolygon getLoc() const { return _loc; } @@ -95,6 +101,7 @@ namespace INTERP_KERNEL protected: ~Node(); protected: + mutable char _hit; mutable unsigned char _cnt; mutable TypeOfLocInPolygon _loc; double _coords[2]; diff --git a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DQuadraticPolygon.cxx b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DQuadraticPolygon.cxx index cbfed6451..9721d1fc9 100644 --- a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DQuadraticPolygon.cxx +++ b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DQuadraticPolygon.cxx @@ -360,8 +360,8 @@ 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) + const int *nodalBg, const double *coords, + const int *descBg, const int *descEnd, const std::vector >& intersectEdges) { if(!isQuad) { -- 2.39.2