From: azv Date: Tue, 7 Mar 2017 15:12:37 +0000 (+0300) Subject: Adjust processing of multi coincidences X-Git-Tag: V_2.7.0~247^2~1 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=9c9b17a5d9f5945230dcd4b9263ae84f2bd4da7f;p=modules%2Fshaper.git Adjust processing of multi coincidences --- diff --git a/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_UpdateCoincidence.cpp b/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_UpdateCoincidence.cpp index 1ac316855..ccd7d0675 100644 --- a/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_UpdateCoincidence.cpp +++ b/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_UpdateCoincidence.cpp @@ -55,14 +55,14 @@ bool PlaneGCSSolver_UpdateCoincidence::checkCoincidence( { bool isAccepted = true; - std::list >::iterator anIt = myCoincident.begin(); - std::list >::iterator + std::list::iterator anIt = myCoincident.begin(); + std::list::iterator aFound[2] = {myCoincident.end(), myCoincident.end()}; for (; anIt != myCoincident.end(); ++anIt) { - if (aFound[0] == myCoincident.end() && anIt->find(theEntity1) != anIt->end()) + if (anIt->isExist(theEntity1)) aFound[0] = anIt; - if (aFound[1] == myCoincident.end() && anIt->find(theEntity2) != anIt->end()) + if (anIt->isExist(theEntity2)) aFound[1] = anIt; if (aFound[0] != myCoincident.end() && aFound[1] != myCoincident.end()) break; @@ -70,37 +70,136 @@ bool PlaneGCSSolver_UpdateCoincidence::checkCoincidence( if (aFound[0] == myCoincident.end() && aFound[1] == myCoincident.end()) { // new group of coincidence - std::set aNewCoinc; - aNewCoinc.insert(theEntity1); - aNewCoinc.insert(theEntity2); - myCoincident.push_back(aNewCoinc); + myCoincident.push_back(CoincidentEntities(theEntity1, theEntity2)); } else if (aFound[0] == aFound[1]) // same group => already coincident isAccepted = false; else { - if (theEntity1->type() == ENTITY_POINT && theEntity2->type() == ENTITY_POINT && - (theEntity1->isExternal() || theEntity2->isExternal())) { - bool hasExternal = false; - for (int i = 0; i < 2 && !hasExternal; ++i) { - if (aFound[i] != myCoincident.end()) { - if (theEntity1->isExternal()) - hasExternal = hasAnotherExternalPoint(*aFound[i], theEntity1); - if (!hasExternal && theEntity2->isExternal()) - hasExternal = hasAnotherExternalPoint(*aFound[i], theEntity2); - } - } - if (hasExternal) - isAccepted = false; - } - if (aFound[0] == myCoincident.end()) - aFound[1]->insert(theEntity1); + isAccepted = aFound[1]->isNewCoincidence(theEntity2, theEntity1); else if (aFound[1] == myCoincident.end()) - aFound[0]->insert(theEntity2); + isAccepted = aFound[0]->isNewCoincidence(theEntity1, theEntity2); else { // merge two groups - aFound[0]->insert(aFound[1]->begin(), aFound[1]->end()); + isAccepted = aFound[0]->isNewCoincidence(theEntity1, *(aFound[1]), theEntity2); myCoincident.erase(aFound[1]); } } return isAccepted; } + + + + +PlaneGCSSolver_UpdateCoincidence::CoincidentEntities::CoincidentEntities( + const EntityWrapperPtr& theEntity1, + const EntityWrapperPtr& theEntity2) +{ + if (theEntity1->isExternal() && theEntity2->isExternal()) { + myExternalAndConnected[theEntity1] = std::set(); + myExternalAndConnected[theEntity2] = std::set(); + } else if (theEntity1->isExternal()) + myExternalAndConnected[theEntity1].insert(theEntity2); + else if (theEntity2->isExternal()) + myExternalAndConnected[theEntity2].insert(theEntity1); + else { + std::set aGroup; + aGroup.insert(theEntity1); + aGroup.insert(theEntity2); + myExternalAndConnected[EntityWrapperPtr()] = aGroup; + } +} + +bool PlaneGCSSolver_UpdateCoincidence::CoincidentEntities::hasExternal() const +{ + return myExternalAndConnected.size() != 1 || + myExternalAndConnected.find(EntityWrapperPtr()) == myExternalAndConnected.end(); +} + +bool PlaneGCSSolver_UpdateCoincidence::CoincidentEntities::isExist( + const EntityWrapperPtr& theEntity) const +{ + std::map >::const_iterator + anIt = myExternalAndConnected.begin(); + for (; anIt != myExternalAndConnected.end(); ++anIt) + if (anIt->first == theEntity || + anIt->second.find(theEntity) != anIt->second.end()) + return true; + return false; +} + +bool PlaneGCSSolver_UpdateCoincidence::CoincidentEntities::isNewCoincidence( + const EntityWrapperPtr& theEntityExist, + const EntityWrapperPtr& theOtherEntity) +{ + if (theOtherEntity->isExternal()) { + if (hasExternal()) { + if (myExternalAndConnected.find(theOtherEntity) == myExternalAndConnected.end()) + myExternalAndConnected[theOtherEntity] = std::set(); + return false; + } else { + myExternalAndConnected[theOtherEntity] = myExternalAndConnected[EntityWrapperPtr()]; + myExternalAndConnected.erase(EntityWrapperPtr()); + return true; + } + } + + if (theEntityExist->isExternal()) { + myExternalAndConnected[theEntityExist].insert(theOtherEntity); + return true; + } + + std::map >::iterator + anIt = myExternalAndConnected.begin(); + for (; anIt != myExternalAndConnected.end(); ++anIt) + if (anIt->second.find(theEntityExist) != anIt->second.end()) { + anIt->second.insert(theOtherEntity); + break; + } + return true; +} + +bool PlaneGCSSolver_UpdateCoincidence::CoincidentEntities::isNewCoincidence( + const EntityWrapperPtr& theEntityExist, + const CoincidentEntities& theOtherGroup, + const EntityWrapperPtr& theEntityInOtherGroup) +{ + bool hasExt[2] = {hasExternal(), theOtherGroup.hasExternal()}; + if (hasExt[0] && hasExt[1]) { + myExternalAndConnected.insert(theOtherGroup.myExternalAndConnected.begin(), + theOtherGroup.myExternalAndConnected.end()); + return false; + } else if (!hasExt[0] && !hasExt[1]) { + std::map >::const_iterator + aFound = theOtherGroup.myExternalAndConnected.find(EntityWrapperPtr()); + + myExternalAndConnected[EntityWrapperPtr()].insert( + aFound->second.begin(), aFound->second.end()); + return true; + } else { + std::map > aSource, aDest; + EntityWrapperPtr aTarget; + if (hasExt[0]) { + aDest = myExternalAndConnected; + aSource = theOtherGroup.myExternalAndConnected; + aTarget = theEntityExist; + } else { + aSource = myExternalAndConnected; + aDest = theOtherGroup.myExternalAndConnected; + aTarget = theEntityInOtherGroup; + } + + std::map >::const_iterator + aFound = aSource.find(EntityWrapperPtr()); + + std::map >::iterator anIt = aDest.begin(); + for (; anIt != aDest.end(); ++anIt) + if (anIt->first == aTarget || + anIt->second.find(aTarget) != anIt->second.end()) { + anIt->second.insert(aFound->second.begin(), aFound->second.end()); + break; + } + return true; + } + // impossible case + return false; +} diff --git a/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_UpdateCoincidence.h b/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_UpdateCoincidence.h index 44f36c465..afd49a2a1 100644 --- a/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_UpdateCoincidence.h +++ b/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_UpdateCoincidence.h @@ -10,6 +10,8 @@ #include #include +#include + /** \class PlaneGCSSolver_UpdateCoincidence * \ingroup Plugins * \brief Send events to listeners about changing a constraint @@ -44,7 +46,31 @@ public: bool checkCoincidence(const EntityWrapperPtr& theEntity1, const EntityWrapperPtr& theEntity2); private: - std::list > myCoincident; ///< list of coincidences + /// \brief Container for collecting and operating coincident entities + class CoincidentEntities + { + public: + CoincidentEntities(const EntityWrapperPtr& theEntity1, + const EntityWrapperPtr& theEntity2); + + /// Verify the entity is already in the list + bool isExist(const EntityWrapperPtr& theEntity) const; + /// Check the coincidence is not in list yet + bool isNewCoincidence(const EntityWrapperPtr& theEntityExist, + const EntityWrapperPtr& theOtherEntity); + bool isNewCoincidence(const EntityWrapperPtr& theEntityExist, + const CoincidentEntities& theOtherGroup, + const EntityWrapperPtr& theEntityInOtherGroup); + + private: + bool hasExternal() const; + + private: + /// external entity and set of entities connected to it + std::map > myExternalAndConnected; + }; + + std::list myCoincident; ///< list of coincidences }; #endif diff --git a/test.models/gear.py b/test.models/gear.py index c08ffd703..d5190da9a 100644 --- a/test.models/gear.py +++ b/test.models/gear.py @@ -43,22 +43,21 @@ SketchLine_9.setAuxiliary(True) SketchConstraintCoincidence_11 = Sketch_2.setCoincident(SketchPoint_2.coordinates(), SketchLine_9.startPoint()) SketchConstraintVertical_4 = Sketch_2.setVertical(SketchLine_9.result()) SketchLine_10 = Sketch_2.addLine(-2.5, 37.41657386773942, -0.9611800001338426, 34.11656372860793) -SketchArc_1 = Sketch_2.addArc(0, 34.39248583236681, -0.9611800001338426, 34.11656372860793, 0.9611800001338454, 34.11656372860793, False) +SketchArc_1 = Sketch_2.addArc(0, 34.39248583236681, -0.9611800001338426, 34.11656372860793, 0, 33.39248583236681, False) SketchConstraintCoincidence_12 = Sketch_2.setCoincident(SketchLine_10.endPoint(), SketchArc_1.startPoint()) SketchConstraintCoincidence_13 = Sketch_2.setCoincident(SketchArc_1.center(), SketchLine_9.result()) -SketchConstraintMirror_1 = Sketch_2.addMirror(SketchLine_9.result(), [SketchLine_10.result()]) -[SketchLine_11] = SketchConstraintMirror_1.mirrored() -SketchConstraintAngle_1 = Sketch_2.setAngleBackward(SketchLine_10.result(), SketchLine_9.result(), 204.9999999999999) +SketchConstraintAngle_1 = Sketch_2.setAngleBackward(SketchLine_10.result(), SketchLine_9.result(), 205) SketchConstraintRadius_1 = Sketch_2.setRadius(SketchArc_1.results()[1], 1) SketchConstraintDistance_2 = Sketch_2.setDistance(SketchLine_10.startPoint(), SketchLine_9.result(), 2.5) -SketchConstraintCoincidence_14 = Sketch_2.setCoincident(SketchArc_1.endPoint(), SketchAPI_Line(SketchLine_11).endPoint()) -SketchArc_2 = Sketch_2.addArc(0, 0, -2.5, 37.41657386773942, 2.5, 37.41657386773942, True) +SketchConstraintCoincidence_14 = Sketch_2.setCoincident(SketchArc_1.endPoint(), SketchLine_9.result()) +SketchArc_2 = Sketch_2.addArc(0, 0, -2.5, 37.41657386773942, 0, 37.5, True) SketchConstraintCoincidence_15 = Sketch_2.setCoincident(SketchArc_2.center(), SketchPoint_2.result()) SketchConstraintCoincidence_16 = Sketch_2.setCoincident(SketchLine_10.startPoint(), SketchArc_2.startPoint()) -SketchConstraintCoincidence_17 = Sketch_2.setCoincident(SketchAPI_Line(SketchLine_11).startPoint(), SketchArc_2.endPoint()) -SketchMultiRotation_1_objects = [SketchArc_1.results()[1], SketchLine_10.result(), SketchArc_2.results()[1], SketchLine_11.result()] +SketchConstraintCoincidence_17 = Sketch_2.setCoincident(SketchLine_9.result(), SketchArc_2.endPoint()) +SketchConstraintMirror_1 = Sketch_2.addMirror(SketchLine_9.result(), [SketchLine_10.result(), SketchArc_1.results()[1], SketchArc_2.results()[1]]) +[SketchLine_11, SketchArc_3, SketchArc_4] = SketchConstraintMirror_1.mirrored() +SketchMultiRotation_1_objects = [SketchArc_1.results()[1], SketchLine_10.result(), SketchArc_2.results()[1], SketchArc_3.results()[1], SketchLine_11.result(), SketchArc_4.results()[1]] SketchMultiRotation_1 = Sketch_2.addRotation(SketchMultiRotation_1_objects, SketchArc_2.center(), 12, 30) -[SketchArc_3, SketchArc_4, SketchArc_5, SketchArc_6, SketchArc_7, SketchArc_8, SketchArc_9, SketchArc_10, SketchArc_11, SketchArc_12, SketchArc_13, SketchArc_14, SketchArc_15, SketchArc_16, SketchArc_17, SketchArc_18, SketchArc_19, SketchArc_20, SketchArc_21, SketchArc_22, SketchArc_23, SketchArc_24, SketchArc_25, SketchArc_26, SketchArc_27, SketchArc_28, SketchArc_29, SketchArc_30, SketchArc_31, SketchLine_12, SketchLine_13, SketchLine_14, SketchLine_15, SketchLine_16, SketchLine_17, SketchLine_18, SketchLine_19, SketchLine_20, SketchLine_21, SketchLine_22, SketchLine_23, SketchLine_24, SketchLine_25, SketchLine_26, SketchLine_27, SketchLine_28, SketchLine_29, SketchLine_30, SketchLine_31, SketchLine_32, SketchLine_33, SketchLine_34, SketchLine_35, SketchLine_36, SketchLine_37, SketchLine_38, SketchLine_39, SketchLine_40, SketchArc_32, SketchArc_33, SketchArc_34, SketchArc_35, SketchArc_36, SketchArc_37, SketchArc_38, SketchArc_39, SketchArc_40, SketchArc_41, SketchArc_42, SketchArc_43, SketchArc_44, SketchArc_45, SketchArc_46, SketchArc_47, SketchArc_48, SketchArc_49, SketchArc_50, SketchArc_51, SketchArc_52, SketchArc_53, SketchArc_54, SketchArc_55, SketchArc_56, SketchArc_57, SketchArc_58, SketchArc_59, SketchArc_60, SketchLine_11, SketchLine_41, SketchLine_42, SketchLine_43, SketchLine_44, SketchLine_45, SketchLine_46, SketchLine_47, SketchLine_48, SketchLine_49, SketchLine_50, SketchLine_51, SketchLine_52, SketchLine_53, SketchLine_54, SketchLine_55, SketchLine_56, SketchLine_57, SketchLine_58, SketchLine_59, SketchLine_60, SketchLine_61, SketchLine_62, SketchLine_63, SketchLine_64, SketchLine_65, SketchLine_66, SketchLine_67, SketchLine_68, SketchLine_69] = SketchMultiRotation_1.rotated() SketchConstraintRadius_2 = Sketch_2.setRadius(SketchArc_2.results()[1], 37.5) model.do() Sketch_3 = model.addSketch(Part_1_doc, model.defaultPlane("XOY")) @@ -179,9 +178,9 @@ from GeomAPI import GeomAPI_Shape model.testNbResults(RevolutionCut_1, 1) model.testNbSubResults(RevolutionCut_1, [0]) model.testNbSubShapes(RevolutionCut_1, GeomAPI_Shape.SOLID, [1]) -model.testNbSubShapes(RevolutionCut_1, GeomAPI_Shape.FACE, [188]) -model.testNbSubShapes(RevolutionCut_1, GeomAPI_Shape.EDGE, [1104]) -model.testNbSubShapes(RevolutionCut_1, GeomAPI_Shape.VERTEX, [2208]) -model.testResultsVolumes(RevolutionCut_1, [65202.414301669727137777954339981]) +model.testNbSubShapes(RevolutionCut_1, GeomAPI_Shape.FACE, [218]) +model.testNbSubShapes(RevolutionCut_1, GeomAPI_Shape.EDGE, [1284]) +model.testNbSubShapes(RevolutionCut_1, GeomAPI_Shape.VERTEX, [2568]) +model.testResultsVolumes(RevolutionCut_1, [65202.414255050614883657544851303]) assert(model.checkPythonDump())