From 3ba3498fee60d1daa52ca163531766e0b28f11c5 Mon Sep 17 00:00:00 2001 From: ageay Date: Fri, 19 Sep 2008 10:12:15 +0000 Subject: [PATCH] *** empty log message *** --- .../Geometric2D/ComposedEdge.cxx | 35 +++++++++++++++++-- .../Geometric2D/ComposedEdge.hxx | 3 ++ src/INTERP_KERNEL/Geometric2D/Edge.cxx | 28 +++++++-------- src/INTERP_KERNEL/Geometric2D/Edge.hxx | 3 +- .../Geometric2D/QuadraticPolygon.cxx | 18 +++++++++- .../Geometric2D/QuadraticPolygon.hxx | 1 + .../Test/QuadraticPlanarInterpTest4.cxx | 12 +++++++ 7 files changed, 82 insertions(+), 18 deletions(-) diff --git a/src/INTERP_KERNEL/Geometric2D/ComposedEdge.cxx b/src/INTERP_KERNEL/Geometric2D/ComposedEdge.cxx index a50f334da..b866ee643 100644 --- a/src/INTERP_KERNEL/Geometric2D/ComposedEdge.cxx +++ b/src/INTERP_KERNEL/Geometric2D/ComposedEdge.cxx @@ -158,11 +158,42 @@ bool ComposedEdge::changeStartNodeWith(Node *node) const void ComposedEdge::fillBounds(Bounds& output) const { - list::const_iterator iter=_subEdges.begin(); - for(;iter!=_subEdges.end();iter++) + for(list::const_iterator iter=_subEdges.begin();iter!=_subEdges.end();iter++) (*iter)->fillBounds(output); } +/*! + * @param part1 INOUT parameter. If an edge in 'this' is found with an id in 'ids1', 'part1' is \b incremented. + * @param part2 INOUT parameter. If an edge in 'this' is found with an id in 'ids2', 'part2' is \b incremented. + * @param commonPart INOUT parameter. If an edge in 'this' is found with an id neither in 'ids1' nor 'ids2', 'commonPart' is \b incremented. + */ +void ComposedEdge::dispatchPerimeter(const std::set& ids1, const std::set& ids2, double& part1, double& part2, double& commonPart) const +{ + for(list::const_iterator iter=_subEdges.begin();iter!=_subEdges.end();iter++) + { + int curEdgeId=(*iter)->getPtr()->getId(); + double val=(*iter)->getPtr()->getCurveLength(); + if(ids1.find(curEdgeId)!=ids1.end()) + { + if((*iter)->getLoc()!=FULL_ON_1) + part1+=val; + else + commonPart+=val; + } + else + if(ids2.find(curEdgeId)!=ids2.end()) + part2+=val; + else + commonPart+=val; + } +} + +void ComposedEdge::fillAllEdgeIds(std::set& ids) const +{ + for(list::const_iterator iter=_subEdges.begin();iter!=_subEdges.end();iter++) + ids.insert((*iter)->getPtr()->getId()); +} + void ComposedEdge::getAllNodes(std::set& output) const { list::const_iterator iter=_subEdges.begin(); diff --git a/src/INTERP_KERNEL/Geometric2D/ComposedEdge.hxx b/src/INTERP_KERNEL/Geometric2D/ComposedEdge.hxx index c07a4c9f5..fd3e9c8be 100644 --- a/src/INTERP_KERNEL/Geometric2D/ComposedEdge.hxx +++ b/src/INTERP_KERNEL/Geometric2D/ComposedEdge.hxx @@ -30,6 +30,9 @@ namespace INTERP_KERNEL double getPerimeter() const; double getHydraulicDiameter() const; void fillBounds(Bounds& output) const; + void dispatchPerimeter(const std::set& ids1, const std::set& ids2, + double& part1, double& part2, double& commonPart) const; + void fillAllEdgeIds(std::set& ids) const; void getAllNodes(std::set& output) const; void getBarycenter(double *bary, double& weigh) const; bool completed() const { return getEndNode()==getStartNode(); } diff --git a/src/INTERP_KERNEL/Geometric2D/Edge.cxx b/src/INTERP_KERNEL/Geometric2D/Edge.cxx index f1a692522..bdf640f5f 100644 --- a/src/INTERP_KERNEL/Geometric2D/Edge.cxx +++ b/src/INTERP_KERNEL/Geometric2D/Edge.cxx @@ -714,36 +714,36 @@ bool Edge::splitOverlappedEdges(const Edge *e1, const Edge *e2, Node *nS, Node * case END*OFFSET_FOR_TYPEOFLOCINEDGE+OUT_AFTER: // END - OUT_AFTER return false; case INSIDE*OFFSET_FOR_TYPEOFLOCINEDGE+OUT_AFTER: // INSIDE - OUT_AFTER - outVal1.pushBack(e1->buildEdgeLyingOnMeWithId(e1->getStartNode(),nS,true)); - tmp=e1->buildEdgeLyingOnMeWithId(nS,e1->getEndNode()); tmp->incrRef(); + outVal1.pushBack(e1->buildEdgeLyingOnMe(e1->getStartNode(),nS,true)); + tmp=e1->buildEdgeLyingOnMe(nS,e1->getEndNode()); tmp->incrRef(); outVal1.pushBack(tmp); outVal2.resize(2); outVal2.setValueAt(direction?0:1,tmp,direction); tmp->declareOn(); - outVal2.setValueAt(direction?1:0,e1->buildEdgeLyingOnMeWithId(e1->getEndNode(),nE,direction)); + outVal2.setValueAt(direction?1:0,e1->buildEdgeLyingOnMe(e1->getEndNode(),nE,direction)); return true; case INSIDE*OFFSET_FOR_TYPEOFLOCINEDGE+INSIDE: // INSIDE - INSIDE e2->incrRef(); e2->incrRef(); outVal1.resize(3); - outVal1.setValueAt(0,e1->buildEdgeLyingOnMeWithId(e1->getStartNode(),nS)); + outVal1.setValueAt(0,e1->buildEdgeLyingOnMe(e1->getStartNode(),nS)); outVal1.setValueAt(1,(Edge*)e2,direction); - outVal1.setValueAt(2,e1->buildEdgeLyingOnMeWithId(nE,e1->getEndNode())); + outVal1.setValueAt(2,e1->buildEdgeLyingOnMe(nE,e1->getEndNode())); outVal2.pushBack((Edge*)e2); e2->declareOn(); return true; case OUT_BEFORE*OFFSET_FOR_TYPEOFLOCINEDGE+INSIDE: // OUT_BEFORE - INSIDE - tmp=e1->buildEdgeLyingOnMeWithId(e1->getStartNode(),nE); tmp->incrRef(); + tmp=e1->buildEdgeLyingOnMe(e1->getStartNode(),nE); tmp->incrRef(); outVal1.pushBack(tmp); - outVal1.pushBack(e1->buildEdgeLyingOnMeWithId(nE,e1->getEndNode())); + outVal1.pushBack(e1->buildEdgeLyingOnMe(nE,e1->getEndNode())); outVal2.resize(2); - outVal2.setValueAt(direction?0:1,e1->buildEdgeLyingOnMeWithId(nS,e1->getStartNode(),direction)); + outVal2.setValueAt(direction?0:1,e1->buildEdgeLyingOnMe(nS,e1->getStartNode(),direction)); outVal2.setValueAt(direction?1:0,tmp,direction); tmp->declareOn(); return true; case OUT_BEFORE*OFFSET_FOR_TYPEOFLOCINEDGE+OUT_AFTER: // OUT_BEFORE - OUT_AFTER e1->incrRef(); e1->incrRef(); outVal1.pushBack((Edge*)e1); outVal2.resize(3); - outVal2.setValueAt(direction?0:2,e1->buildEdgeLyingOnMeWithId(nS,e1->getStartNode(),direction)); + outVal2.setValueAt(direction?0:2,e1->buildEdgeLyingOnMe(nS,e1->getStartNode(),direction)); outVal2.setValueAt(1,(Edge*)e1,direction); e1->declareOn(); - outVal2.setValueAt(direction?2:0,e1->buildEdgeLyingOnMeWithId(e1->getEndNode(),nE,direction)); + outVal2.setValueAt(direction?2:0,e1->buildEdgeLyingOnMe(e1->getEndNode(),nE,direction)); return true; case START*OFFSET_FOR_TYPEOFLOCINEDGE+END: // START - END e1->incrRef(); e1->incrRef(); @@ -755,11 +755,11 @@ bool Edge::splitOverlappedEdges(const Edge *e1, const Edge *e2, Node *nS, Node * outVal1.pushBack((Edge*)e1); outVal2.resize(2); outVal2.setValueAt(direction?0:1,(Edge*)e1,direction); e1->declareOn(); - outVal2.setValueAt(direction?1:0,e1->buildEdgeLyingOnMeWithId(e1->getEndNode(),nE,direction)); + outVal2.setValueAt(direction?1:0,e1->buildEdgeLyingOnMe(e1->getEndNode(),nE,direction)); return true; case INSIDE*OFFSET_FOR_TYPEOFLOCINEDGE+END: // INSIDE - END e2->incrRef(); e2->incrRef(); - outVal1.pushBack(e1->buildEdgeLyingOnMeWithId(e1->getStartNode(),nS,true)); + outVal1.pushBack(e1->buildEdgeLyingOnMe(e1->getStartNode(),nS,true)); outVal1.pushBack((Edge*)e2,direction); outVal2.pushBack((Edge*)e2); e2->declareOn(); return true; @@ -767,13 +767,13 @@ bool Edge::splitOverlappedEdges(const Edge *e1, const Edge *e2, Node *nS, Node * e1->incrRef(); e1->incrRef(); outVal1.pushBack((Edge*)e1); outVal2.resize(2); - outVal2.setValueAt(direction?0:1,e1->buildEdgeLyingOnMeWithId(nS,e1->getStartNode(),direction)); + outVal2.setValueAt(direction?0:1,e1->buildEdgeLyingOnMe(nS,e1->getStartNode(),direction)); outVal2.setValueAt(direction?1:0,(Edge*)e1,direction); e1->declareOn(); return true; case START*OFFSET_FOR_TYPEOFLOCINEDGE+INSIDE: // START - INSIDE e2->incrRef(); e2->incrRef(); outVal1.pushBack((Edge*)e2,direction); - outVal1.pushBack(e1->buildEdgeLyingOnMeWithId(nE,e1->getEndNode())); + outVal1.pushBack(e1->buildEdgeLyingOnMe(nE,e1->getEndNode())); outVal2.pushBack((Edge*)e2); e2->declareOn(); return true; default: diff --git a/src/INTERP_KERNEL/Geometric2D/Edge.hxx b/src/INTERP_KERNEL/Geometric2D/Edge.hxx index d838be422..2a0b02a2b 100644 --- a/src/INTERP_KERNEL/Geometric2D/Edge.hxx +++ b/src/INTERP_KERNEL/Geometric2D/Edge.hxx @@ -166,6 +166,7 @@ namespace INTERP_KERNEL TypeOfEdgeLocInPolygon getLoc() const { return _loc; } void incrRef() const { _cnt++; } bool decrRef(); + int getId() const { return _id; } void setId(int val) { _id=val; } void initLocs() const { _loc=FULL_UNKNOWN; _start->initLocs(); _end->initLocs(); } void declareOn() const; @@ -227,7 +228,7 @@ namespace INTERP_KERNEL //! The code 'code' is built by method combineCodes static bool splitOverlappedEdges(const Edge *e1, const Edge *e2, Node *nS, Node *nE, bool direction, int code, ComposedEdge& outVal1, ComposedEdge& outVal2); - virtual Edge *buildEdgeLyingOnMe(Node *start, Node *end, bool direction) const = 0; + virtual Edge *buildEdgeLyingOnMe(Node *start, Node *end, bool direction=true) const = 0; protected: mutable unsigned char _cnt; mutable TypeOfEdgeLocInPolygon _loc; diff --git a/src/INTERP_KERNEL/Geometric2D/QuadraticPolygon.cxx b/src/INTERP_KERNEL/Geometric2D/QuadraticPolygon.cxx index 614e112fc..0ab60b1ac 100644 --- a/src/INTERP_KERNEL/Geometric2D/QuadraticPolygon.cxx +++ b/src/INTERP_KERNEL/Geometric2D/QuadraticPolygon.cxx @@ -147,7 +147,7 @@ void QuadraticPolygon::dumpInXfigFile(std::ostream& stream, int resolution, cons double QuadraticPolygon::intersectWith(const QuadraticPolygon& other) const { - double ret=0; + double ret=0.; vector polygs=intersectMySelfWith(other); for(vector::iterator iter=polygs.begin();iter!=polygs.end();iter++) { @@ -157,6 +157,22 @@ double QuadraticPolygon::intersectWith(const QuadraticPolygon& other) const return ret; } +void QuadraticPolygon::intersectForPerimeter(const QuadraticPolygon& other, double& perimeterThisPart, double& perimeterOtherPart, double& perimeterCommonPart, double& area) const +{ + perimeterThisPart=0.; perimeterOtherPart=0.; perimeterCommonPart=0.; area=0.; + vector polygs=intersectMySelfWith(other); + set idsFromThis; + set idsFromOther; + fillAllEdgeIds(idsFromThis); + other.fillAllEdgeIds(idsFromOther); + for(vector::iterator iter=polygs.begin();iter!=polygs.end();iter++) + { + area+=fabs((*iter)->getArea()); + (*iter)->dispatchPerimeter(idsFromThis,idsFromOther,perimeterThisPart,perimeterOtherPart,perimeterCommonPart); + delete *iter; + } +} + std::vector QuadraticPolygon::intersectMySelfWith(const QuadraticPolygon& other) const { QuadraticPolygon cpyOfThis(*this); diff --git a/src/INTERP_KERNEL/Geometric2D/QuadraticPolygon.hxx b/src/INTERP_KERNEL/Geometric2D/QuadraticPolygon.hxx index d4a4489bf..41c4556ea 100644 --- a/src/INTERP_KERNEL/Geometric2D/QuadraticPolygon.hxx +++ b/src/INTERP_KERNEL/Geometric2D/QuadraticPolygon.hxx @@ -29,6 +29,7 @@ namespace INTERP_KERNEL void dumpInXfigFileWithOther(const ComposedEdge& other, const char *fileName) const; double intersectWith(const QuadraticPolygon& other) const; std::vector intersectMySelfWith(const QuadraticPolygon& other) const; + void intersectForPerimeter(const QuadraticPolygon& other, double& perimeterThisPart, double& perimeterOtherPart, double& perimeterCommonPart, double& area) const; public://Only public for tests reasons void performLocatingOperation(QuadraticPolygon& pol2) const; void splitPolygonsEachOther(QuadraticPolygon& pol1, QuadraticPolygon& pol2, int& nbOfSplits) const; diff --git a/src/INTERP_KERNEL/Test/QuadraticPlanarInterpTest4.cxx b/src/INTERP_KERNEL/Test/QuadraticPlanarInterpTest4.cxx index b69ca4ff0..0adf79e1b 100644 --- a/src/INTERP_KERNEL/Test/QuadraticPlanarInterpTest4.cxx +++ b/src/INTERP_KERNEL/Test/QuadraticPlanarInterpTest4.cxx @@ -35,6 +35,12 @@ void QuadraticPlanarInterpTest::checkPolygonsIntersection1() result=pol1.intersectMySelfWith(pol2); CPPUNIT_ASSERT_EQUAL(1,(int)result.size()); checkBasicsOfPolygons(*result[0],*result[0],false); CPPUNIT_ASSERT_EQUAL(3,result[0]->recursiveSize()); + double tmp1=0.,tmp2=0.,tmp3=0.,tmp4=0.; + pol1.intersectForPerimeter(pol2,tmp1,tmp2,tmp3,tmp4); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.7,tmp1,1.e-14); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.5652475842498528,tmp2,1.e-14); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,tmp3,1.e-14);//no common edge + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.245,tmp4,1.e-14); delete result[0]; } } @@ -116,6 +122,12 @@ void QuadraticPlanarInterpTest::checkPolygonsIntersection1() CPPUNIT_ASSERT_EQUAL(1,(int)result.size()); checkBasicsOfPolygons(*result[0],*result[0],false); CPPUNIT_ASSERT_EQUAL(3,result[0]->recursiveSize()); delete result[0]; + double tmp1=0.,tmp2=0.,tmp3=0.,tmp4=0.; + pol7.intersectForPerimeter(pol8,tmp1,tmp2,tmp3,tmp4); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,tmp1,1.e-14); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,tmp2,1.e-14); + CPPUNIT_ASSERT_DOUBLES_EQUAL(3.2360679774997898,tmp3,1.e-14); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,tmp4,1.e-14); } } //clean-up test4 -- 2.39.2