From 296487d8e685152d02f2be0447ad0332426fcbfb Mon Sep 17 00:00:00 2001 From: mpv Date: Mon, 24 Dec 2018 16:50:39 +0300 Subject: [PATCH] Fix for the tests from EDF mail: changing of conception Fillet don't have geometrical naming flag, but compounds of edges must be divided (while working with compounds is not implemented this change can not be rolled back). --- src/CollectionPlugin/CMakeLists.txt | 1 + src/CollectionPlugin/Test/TestGroup2.py | 112 +++++++++++++++++++++++ src/Model/Model_AttributeSelection.cpp | 113 ++++-------------------- src/Model/Model_AttributeSelection.h | 7 +- src/Selector/Selector_NameGenerator.h | 3 - 5 files changed, 131 insertions(+), 105 deletions(-) create mode 100644 src/CollectionPlugin/Test/TestGroup2.py diff --git a/src/CollectionPlugin/CMakeLists.txt b/src/CollectionPlugin/CMakeLists.txt index 19d992b54..cd20d6185 100644 --- a/src/CollectionPlugin/CMakeLists.txt +++ b/src/CollectionPlugin/CMakeLists.txt @@ -105,6 +105,7 @@ INSTALL(FILES ${TEXT_RESOURCES} DESTINATION ${SHAPER_INSTALL_XML_RESOURCES}) ADD_UNIT_TESTS( TestGroup.py + TestGroup2.py TestField.py TestGroup1799.py TestGroupMove.py diff --git a/src/CollectionPlugin/Test/TestGroup2.py b/src/CollectionPlugin/Test/TestGroup2.py new file mode 100644 index 000000000..7f83b5a96 --- /dev/null +++ b/src/CollectionPlugin/Test/TestGroup2.py @@ -0,0 +1,112 @@ +## Copyright (C) 2014-2017 CEA/DEN, EDF R&D +## +## This library is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with this library; if not, write to the Free Software +## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +## +## See http:##www.salome-platform.org/ or +## email : webmaster.salome@opencascade.com +## + +# Test that splitted edges in the group are still correct edges in the group +# Based on the CEA report mail 04.12.2018, page 4 + +# -*- coding: utf-8 -*- + +from SketchAPI import * +from ModelAPI import * +from GeomAPI import * +from salome.shaper import model + +model.begin() +partSet = model.moduleDocument() +Part_1 = model.addPart(partSet) +Part_1_doc = Part_1.document() +param_p = model.addParameter(Part_1_doc, "r", "15") +Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY")) +SketchArc_1 = Sketch_1.addArc(7.5, 7.5, 22.5, 7.499992770095306, 7.499999582962127, 22.5, False) +SketchLine_1 = Sketch_1.addLine(7.499999582962127, 22.5, 7.499999582962127, 52.5) +SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchArc_1.endPoint(), SketchLine_1.startPoint()) +SketchLine_2 = Sketch_1.addLine(22.5, 7.499992770095306, 52.5, 7.499992770095306) +SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchArc_1.startPoint(), SketchLine_2.startPoint()) +SketchArc_2 = Sketch_1.addArc(7.5, 7.5, 52.5, 7.499992770095306, 7.499999582962127, 52.5, False) +SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchArc_1.center(), SketchArc_2.center()) +SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchArc_2.startPoint()) +SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchArc_2.endPoint(), SketchLine_1.endPoint()) +SketchConstraintVertical_1 = Sketch_1.setVertical(SketchLine_1.result()) +SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_2.result()) +SketchConstraintLength_1 = Sketch_1.setLength(SketchLine_2.result(), "r*2") +SketchConstraintEqual_1 = Sketch_1.setEqual(SketchLine_1.result(), SketchLine_2.result()) +SketchConstraintRadius_1 = Sketch_1.setRadius(SketchArc_1.results()[1], "r") +SketchConstraintRadius_2 = Sketch_1.setRadius(SketchArc_2.results()[1], "3*r") +SketchProjection_1 = Sketch_1.addProjection(model.selection("VERTEX", "PartSet/Origin"), False) +SketchPoint_1 = SketchProjection_1.createdFeature() +SketchConstraintDistanceHorizontal_1 = Sketch_1.setHorizontalDistance(SketchAPI_Point(SketchPoint_1).coordinates(), SketchArc_2.center(), "r/2") +SketchConstraintDistanceVertical_1 = Sketch_1.setVerticalDistance(SketchAPI_Point(SketchPoint_1).coordinates(), SketchArc_1.center(), "r/2") +model.do() +Face_1 = model.addFace(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_2f-SketchArc_2_2f-SketchLine_1r-SketchArc_1_2r")]) +Sketch_2 = model.addSketch(Part_1_doc, model.selection("FACE", "Sketch_1/Face-SketchLine_2f-SketchArc_2_2f-SketchLine_1r-SketchArc_1_2r")) +SketchCircle_1 = Sketch_2.addCircle(27.71638597484288, 11.4805029721516, 3) +SketchCircle_2 = Sketch_2.addCircle(45.03912720992525, 18.6558173277981, 3) +SketchLine_3 = Sketch_2.addLine(0, 0, 45.03912720992525, 18.6558173277981) +SketchLine_3.setAuxiliary(True) +SketchProjection_2 = Sketch_2.addProjection(model.selection("VERTEX", "PartSet/Origin"), False) +SketchPoint_2 = SketchProjection_2.createdFeature() +SketchConstraintCoincidence_6 = Sketch_2.setCoincident(SketchLine_3.startPoint(), SketchPoint_2.result()) +SketchConstraintCoincidence_7 = Sketch_2.setCoincident(SketchCircle_2.center(), SketchLine_3.endPoint()) +SketchConstraintCoincidence_8 = Sketch_2.setCoincident(SketchLine_3.result(), SketchCircle_1.center()) +SketchConstraintRadius_3 = Sketch_2.setRadius(SketchCircle_1.results()[1], "r/5") +SketchConstraintRadius_4 = Sketch_2.setRadius(SketchCircle_2.results()[1], "r/5") +SketchConstraintDistance_1 = Sketch_2.setDistance(SketchLine_3.startPoint(), SketchCircle_1.center(), "2*r", True) +SketchConstraintDistance_2 = Sketch_2.setDistance(SketchCircle_1.center(), SketchLine_3.endPoint(), "r*1.25", True) +SketchProjection_3 = Sketch_2.addProjection(model.selection("EDGE", "PartSet/OX"), False) +SketchLine_4 = SketchProjection_3.createdFeature() +SketchConstraintAngle_1 = Sketch_2.setAngle(SketchLine_4.result(), SketchLine_3.result(), "r*1.5") +model.do() +Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("COMPOUND", "Sketch_2")], model.selection(), 10, 0) +AngularCopy_1 = model.addMultiRotation(Part_1_doc, [model.selection("COMPOUND", "all-in-Extrusion_1")], model.selection("EDGE", "PartSet/OZ"), "90.-r*3", 2) +Cut_1 = model.addCut(Part_1_doc, [model.selection("FACE", "Face_1_1")], [model.selection("COMPOUND", "AngularCopy_1_1")]) +Group_1 = model.addGroup(Part_1_doc, [model.selection("EDGE", "Face_1_1/Edge_4")]) +Group_1.setName("edge_int") +Group_1.result().setName("edge_int") +Group_2 = model.addGroup(Part_1_doc, [model.selection("EDGE", "Face_1_1/Edge_1")]) +Group_2.setName("edge_bottom") +Group_2.result().setName("edge_bottom") +Group_3 = model.addGroup(Part_1_doc, [model.selection("EDGE", "Face_1_1/Edge_3")]) +Group_3.setName("edge_left") +Group_3.result().setName("edge_left") +Group_4 = model.addGroup(Part_1_doc, [model.selection("EDGE", "Face_1_1/Edge_2")]) +Group_4.setName("edge_ext") +Group_4.result().setName("edge_ext") +model.do() +# change parameter "p" to make one ylinder split bottom and left edges +param_p.setValue(12) +model.end() + +# check that int and ext groups are still edges, bottom and left groups are compounds of edges +aFactory = ModelAPI_Session.get().validators() + +for group in [Group_1, Group_4]: + assert(aFactory.validate(group.feature())) + selectionList = group.feature().selectionList("group_list") + assert(selectionList.size() == 1) + assert(group.groupList().value(0).value().shapeType() == GeomAPI_Shape.EDGE) + +for group in [Group_2, Group_3]: + assert(aFactory.validate(group.feature())) + selectionList = group.feature().selectionList("group_list") + assert(selectionList.size() == 2) + assert(group.groupList().value(0).value().shapeType() == GeomAPI_Shape.EDGE) + assert(group.groupList().value(1).value().shapeType() == GeomAPI_Shape.EDGE) + +assert(model.checkPythonDump()) diff --git a/src/Model/Model_AttributeSelection.cpp b/src/Model/Model_AttributeSelection.cpp index 9bc93aab7..063642c3f 100644 --- a/src/Model/Model_AttributeSelection.cpp +++ b/src/Model/Model_AttributeSelection.cpp @@ -448,7 +448,8 @@ void Model_AttributeSelection::setID(const std::string theID) ModelAPI_AttributeSelection::setID(theID); FeaturePtr aFeature = std::dynamic_pointer_cast(owner()); if (myParent) { - myIsGeometricalSelection = true;//myParent->isGeometricalSelection(); + // to be able to select as geometrical selection and then - split + myIsGeometricalSelection = true; // myParent->isGeometricalSelection(); } else { myIsGeometricalSelection = ModelAPI_Session::get()->validators()->isGeometricalSelection(aFeature->getKind(), id()); @@ -591,10 +592,9 @@ bool Model_AttributeSelection::update() if (anOldShape.IsNull() || aNewShape.IsNull() || !anOldShape.IsEqual(aNewShape)) { // shape type should not be changed: if shape becomes compound of such shapes, then split - if (!myIsGeometricalSelection && myParent && !anOldShape.IsNull() && !aNewShape.IsNull() && + if (myParent && !anOldShape.IsNull() && !aNewShape.IsNull() && anOldShape.ShapeType() != aNewShape.ShapeType() && - (aNewShape.ShapeType() == TopAbs_COMPOUND || aNewShape.ShapeType() == TopAbs_COMPSOLID)) - { + aNewShape.ShapeType() == TopAbs_COMPOUND) { split(aContext, aNewShape, anOldShape.ShapeType()); } owner()->data()->sendAttributeUpdated(this); // send updated if shape is changed @@ -1516,18 +1516,6 @@ bool Model_AttributeSelection::restoreContext(std::string theName, return true; } -TDF_Label Model_AttributeSelection::newestContext(const TDF_Label theCurrentContext) { - std::shared_ptr aDoc = myRestoreDocument.get() ? myRestoreDocument : - std::dynamic_pointer_cast(owner()->document()); - ResultPtr aContext = aDoc->resultByLab(theCurrentContext); - if (aContext.get()) { - aContext = newestContext(aContext, GeomShapePtr(), true); - if (aContext.get()) - return std::dynamic_pointer_cast(aContext->data())->label(); - } - return theCurrentContext; // nothing is changed -} - bool Model_AttributeSelection::isLater( const TDF_Label theResult1, const TDF_Label theResult2) const { @@ -1543,7 +1531,7 @@ bool Model_AttributeSelection::isLater( } ResultPtr Model_AttributeSelection::newestContext( - const ResultPtr theCurrent, const GeomShapePtr theValue, const bool theAnyValue) + const ResultPtr theCurrent, const GeomShapePtr theValue) { ResultPtr aResult = theCurrent; GeomShapePtr aSelectedShape = theValue.get() ? theValue : theCurrent->shape(); @@ -1566,7 +1554,7 @@ ResultPtr Model_AttributeSelection::newestContext( TDF_Label aLab = aNS->Label(); ResultPtr aRes = aDoc->resultByLab(aLab); if (aRes.get()) { - if (theAnyValue || aRes->shape()->isSubShape(aSelectedShape)) { + if (aRes->shape()->isSubShape(aSelectedShape)) { aResult = aRes; aFindNewContext = true; continue; @@ -1575,47 +1563,6 @@ ResultPtr Model_AttributeSelection::newestContext( } } } - if (theAnyValue) { // only for neighbors for now - // try to find modification of sub-shapes: the best number of matches - std::map aMatches; // result -> number of matches of shapes to find the best - TDF_Label aResLab = std::dynamic_pointer_cast(aResult->data())->shapeLab(); - TDF_ChildIDIterator aModifIter(aResLab, TNaming_NamedShape::GetID()); - for(; aModifIter.More(); aModifIter.Next()) { - Handle(TNaming_NamedShape) aNS = Handle(TNaming_NamedShape)::DownCast(aModifIter.Value()); - if (aNS->Evolution() == TNaming_MODIFY || aNS->Evolution() == TNaming_GENERATED) { - for(TNaming_Iterator aNSIter(aNS); aNSIter.More(); aNSIter.Next()) { - TNaming_NewShapeIterator aNewIter(aNSIter.NewShape(), aNS->Label()); - for(; aNewIter.More(); aNewIter.Next()) { - TDF_Label aLab = aNewIter.Label(); - if (isLater(aLab, aNS->Label()) && isLater(selectionLabel(), aLab)) { - ResultPtr aRes = aDoc->resultByLab(aLab); - if (aRes.get()) { - if (aMatches.find(aRes) == aMatches.end()) - aMatches[aRes] = 0; - aMatches[aRes]++; // found result, add matches - } - } - } - } - } - } - // searching for the best result-candidate - int aBest = 0; - ResultPtr aBestResult; - std::map::iterator aMatchIter = aMatches.begin(); - for(; aMatchIter != aMatches.end(); aMatchIter++) { - if (aMatchIter->second > aBest) { - aBest = aMatchIter->second; - aBestResult = aMatchIter->first; - } - } - if (aBestResult.get()) { - aResult = aBestResult; - aFindNewContext = true; - continue; - } - } - // TestFillWireVertex.py - sketch constructions for wire may participate too //if (aResult->groupName() == ModelAPI_ResultBody::group()) { @@ -1661,43 +1608,15 @@ ResultPtr Model_AttributeSelection::newestContext( } std::list >::iterator aResIter = aResults.begin(); - if (theAnyValue) { // searching the best sub-result by maximum number of references to orig - int aReferencesCount = 0; - ResultPtr aBestResult; - for (; aResIter != aResults.end(); aResIter++) { - if (!aResIter->get() || !(*aResIter)->data()->isValid() || (*aResIter)->isDisabled()) - continue; - TDF_Label aCandidateLab = - std::dynamic_pointer_cast((*aResIter)->data())->shapeLab(); - Handle(TDF_Reference) aRef; - if (aCandidateLab.FindAttribute(TDF_Reference::GetID(), aRef)) { - TDF_Label aRefLab = aRef->Get(); - ResultPtr aRefRes = aDoc->resultByLab(aRefLab); - if (aRefRes.get() && aRefRes->shape().get() && - aRefRes->shape()->isEqual(aResult->shape())) {// it directly references to result - aResult = *aResIter; // found new context (produced from this) with same subshape - aFindNewContext = true; // continue searching further - break; - } - } else { - if (!aBestResult.get()) - aBestResult = *aResIter; - } - } - if (aBestResult.get() && !aFindNewContext) { // the first good result for now - aResult = aBestResult; // found new context - aFindNewContext = true; - } - } else { // searching by sub-shape - for (; aResIter != aResults.end(); aResIter++) { - if (!aResIter->get() || !(*aResIter)->data()->isValid() || (*aResIter)->isDisabled()) - continue; - GeomShapePtr aShape = (*aResIter)->shape(); - if (aShape.get() && (theAnyValue || aShape->isSubShape(aSelectedShape, false))) { - aResult = *aResIter; // found new context (produced from this) with same subshape - aFindNewContext = true; // continue searching further - break; - } + // searching by sub-shape + for (; aResIter != aResults.end(); aResIter++) { + if (!aResIter->get() || !(*aResIter)->data()->isValid() || (*aResIter)->isDisabled()) + continue; + GeomShapePtr aShape = (*aResIter)->shape(); + if (aShape.get() && aShape->isSubShape(aSelectedShape, false)) { + aResult = *aResIter; // found new context (produced from this) with same subshape + aFindNewContext = true; // continue searching further + break; } } } @@ -1712,7 +1631,7 @@ ResultPtr Model_AttributeSelection::newestContext( for (; aS != allSubs.end(); aS++) { ResultBodyPtr aSub = std::dynamic_pointer_cast(*aS); if (aSub && aSub->numberOfSubs() == 0 && aSub->shape().get() && - (theAnyValue || aSub->shape()->isSubShape(aSelectedShape))) { + aSub->shape()->isSubShape(aSelectedShape)) { aResult = aSub; break; } diff --git a/src/Model/Model_AttributeSelection.h b/src/Model/Model_AttributeSelection.h index 66bbc59ff..741929433 100644 --- a/src/Model/Model_AttributeSelection.h +++ b/src/Model/Model_AttributeSelection.h @@ -133,9 +133,6 @@ public: MODEL_EXPORT virtual bool restoreContext(std::string theName, TDF_Label& theContext, TDF_Label& theValue) override; - /// Returns the label of the newest context presented by the current one - MODEL_EXPORT virtual TDF_Label newestContext(const TDF_Label theCurrentContext) override; - /// Returns true if the first result is newer than the second one in the tree of features MODEL_EXPORT virtual bool isLater(const TDF_Label theResult1, const TDF_Label theResult2) const override; @@ -188,8 +185,8 @@ protected: std::list& theResults, TopTools_ListOfShape& theValShapes); /// Searches for the newest context, modification of the current, that contains theValue - ResultPtr newestContext(const ResultPtr theCurrent, - const std::shared_ptr theValue, const bool theAnyValue = false); + ResultPtr newestContext( + const ResultPtr theCurrent, const std::shared_ptr theValue); /// computes theShapes list - shapes that were generated/modified/deleted the theValShape /// during creation from new to old context diff --git a/src/Selector/Selector_NameGenerator.h b/src/Selector/Selector_NameGenerator.h index 6ac0f4ce4..4a06abc07 100644 --- a/src/Selector/Selector_NameGenerator.h +++ b/src/Selector/Selector_NameGenerator.h @@ -47,9 +47,6 @@ public: /// Returns true if the first result is older than the second one in the tree of features virtual bool isLater(const TDF_Label theResult1, const TDF_Label theResult2) const = 0; - - /// Returns the label of the newest context presented by the current one - virtual TDF_Label newestContext(const TDF_Label theCurrentContext) = 0; }; #endif -- 2.39.2