From: mpv Date: Mon, 18 Sep 2017 09:07:55 +0000 (+0300) Subject: Issue #2252 : adding a rotation feature in the history of the partset duplicates... X-Git-Tag: V_2.8.0~10 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=51492b14f4d677eb09bc413257ebd791a7e01810;p=modules%2Fshaper.git Issue #2252 : adding a rotation feature in the history of the partset duplicates the part. Update in history applied also for the Part Results. --- diff --git a/src/Model/Model_AttributeSelection.cpp b/src/Model/Model_AttributeSelection.cpp index 53fbdccb8..f26270a9f 100644 --- a/src/Model/Model_AttributeSelection.cpp +++ b/src/Model/Model_AttributeSelection.cpp @@ -963,18 +963,52 @@ bool Model_AttributeSelection::searchNewContext(std::shared_ptr void Model_AttributeSelection::updateInHistory() { ResultPtr aContext = std::dynamic_pointer_cast(myRef.value()); - // only bodies may be modified later in the history, don't do anything otherwise - if (!aContext.get() || aContext->groupName() != ModelAPI_ResultBody::group()) + // only bodies and parts may be modified later in the history, don't do anything otherwise + if (!aContext.get() || (aContext->groupName() != ModelAPI_ResultBody::group() && + aContext->groupName() != ModelAPI_ResultPart::group())) return; + std::shared_ptr aDoc = + std::dynamic_pointer_cast(aContext->document()); std::shared_ptr aContData = std::dynamic_pointer_cast(aContext->data()); if (!aContData.get() || !aContData->isValid()) return; TDF_Label aContLab = aContData->label(); // named shape where the selected context is located Handle(TNaming_NamedShape) aContNS; - if (!aContLab.FindAttribute(TNaming_NamedShape::GetID(), aContNS)) + if (!aContLab.FindAttribute(TNaming_NamedShape::GetID(), aContNS)) { + bool aFoundNewContext = true; + ResultPtr aNewContext = aContext; + while(aFoundNewContext) { + aFoundNewContext = false; + // parts have no shape in result, so, trace references using the Part info + if (aNewContext->groupName() == ModelAPI_ResultPart::group()) { + ResultPartPtr aPartContext = std::dynamic_pointer_cast(aNewContext); + if (aPartContext.get()) { // searching for the up to date references to the referenced cont + const std::set& aRefs = aPartContext->data()->refsToMe(); + std::set::const_iterator aRef = aRefs.begin(); + for(; aRef != aRefs.end(); aRef++) { + // to avoid detection of part changes by local selection only + AttributeSelectionPtr aSel = + std::dynamic_pointer_cast(*aRef); + if (aSel.get() && !aSel->value()->isSame(aSel->context()->shape())) + continue; + + FeaturePtr aRefFeat = std::dynamic_pointer_cast((*aRef)->owner()); + if (aRefFeat.get() && aRefFeat != owner()) { + FeaturePtr aThisFeature = std::dynamic_pointer_cast(owner()); + if (aDoc->objects()->isLater(aThisFeature, aRefFeat)) { // found better feature + aFoundNewContext = true; + aNewContext = aRefFeat->firstResult(); + } + } + } + } + } + } + if (aNewContext != aContext) { + setValue(aNewContext, value()); + } return; - std::shared_ptr aDoc = - std::dynamic_pointer_cast(aContext->document()); + } FeaturePtr aThisFeature = std::dynamic_pointer_cast(owner()); FeaturePtr aCurrentModifierFeat = aDoc->feature(aContext); // iterate the context shape modifications in order to find a feature that is upper in history diff --git a/src/Model/Model_Document.h b/src/Model/Model_Document.h index 84a2706be..67e48301e 100644 --- a/src/Model/Model_Document.h +++ b/src/Model/Model_Document.h @@ -150,7 +150,7 @@ class Model_Document : public ModelAPI_Document //! Sets the current feature: all features below will be disabled, new features //! will be appended after this one. - //! \param theCurrent the selected feature as current: blow it everythin become disabled + //! \param theCurrent the selected feature as current: below it everything becomes disabled //! \param theVisible use visible features only: flag is true for Object Browser functionality MODEL_EXPORT virtual void setCurrentFeature(std::shared_ptr theCurrent, const bool theVisible); diff --git a/src/Model/Model_ResultPart.cpp b/src/Model/Model_ResultPart.cpp index 863a681c0..ddac1acb2 100644 --- a/src/Model/Model_ResultPart.cpp +++ b/src/Model/Model_ResultPart.cpp @@ -62,7 +62,7 @@ void Model_ResultPart::initAttributes() std::shared_ptr Model_ResultPart::partDoc() { - if (myTrsf.get() && baseRef().get()) { // the second condition is to to #2035 + if (myTrsf.get() && baseRef().get()) { // the second condition is due to #2035 return baseRef()->partDoc(); } DocumentPtr aRes = data()->document(DOC_REF())->value(); @@ -93,7 +93,7 @@ void Model_ResultPart::activate() if (!aDocRef->value().get()) { // create (or open) a document if it is not yet created Handle(Model_Application) anApp = Model_Application::getApplication(); if (anApp->isLoadByDemand(data()->name(), aDocRef->docId())) { - anApp->loadDocument(data()->name(), aDocRef->docId()); // if it is just ne part, load may fail + anApp->loadDocument(data()->name(), aDocRef->docId()); // if it is just new part, load fails } else { anApp->createDocument(aDocRef->docId()); } @@ -113,7 +113,7 @@ void Model_ResultPart::activate() std::shared_ptr Model_ResultPart::original() { - if (myTrsf.get() && baseRef().get()) { // the second condition is to to #2035 + if (myTrsf.get() && baseRef().get()) { // the second condition is due to #2035 return baseRef()->original(); } return std::dynamic_pointer_cast(data()->owner()); diff --git a/src/Model/Model_ResultPart.h b/src/Model/Model_ResultPart.h index a9c8e5dda..b6a130511 100644 --- a/src/Model/Model_ResultPart.h +++ b/src/Model/Model_ResultPart.h @@ -53,7 +53,7 @@ class Model_ResultPart : public ModelAPI_ResultPart /// Returns the part-document of this result MODEL_EXPORT virtual std::shared_ptr partDoc(); - /// Returns the original part result: for transfomration features results this is + /// Returns the original part result: for transformation features results this is /// the original Part feature result MODEL_EXPORT virtual std::shared_ptr original(); diff --git a/src/ModelAPI/CMakeLists.txt b/src/ModelAPI/CMakeLists.txt index 0abe0893a..0e9e5e2e4 100644 --- a/src/ModelAPI/CMakeLists.txt +++ b/src/ModelAPI/CMakeLists.txt @@ -169,4 +169,5 @@ ADD_UNIT_TESTS(TestConstants.py TestExternalConstruction.py Test2228.py Test2241.py + Test2252.py ) diff --git a/src/ModelAPI/Test/Test2252.py b/src/ModelAPI/Test/Test2252.py new file mode 100644 index 000000000..3b4306e64 --- /dev/null +++ b/src/ModelAPI/Test/Test2252.py @@ -0,0 +1,69 @@ +## 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 +## + +from salome.shaper import model +from ModelAPI import * +from GeomAlgoAPI import * + +model.begin() +partSet = model.moduleDocument() +Part_1 = model.addPart(partSet) +Part_1_doc = Part_1.document() +Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY")) +SketchLine_1 = Sketch_1.addLine(60, 0, 0, 0) +SketchPoint_1 = Sketch_1.addPoint(model.selection("VERTEX", "PartSet/Origin")) +SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchPoint_1.result()) +SketchLine_2 = Sketch_1.addLine(0, 0, 0, 60) +SketchLine_3 = Sketch_1.addLine(0, 60, 60, 60) +SketchLine_4 = Sketch_1.addLine(60, 60, 60, 0) +SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_1.startPoint()) +SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint()) +SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint()) +SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint()) +SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_1.result()) +SketchConstraintVertical_1 = Sketch_1.setVertical(SketchLine_2.result()) +SketchConstraintHorizontal_2 = Sketch_1.setHorizontal(SketchLine_3.result()) +SketchConstraintVertical_2 = Sketch_1.setVertical(SketchLine_4.result()) +SketchConstraintLength_1 = Sketch_1.setLength(SketchLine_3.result(), 60) +SketchConstraintEqual_1 = Sketch_1.setEqual(SketchLine_3.result(), SketchLine_4.result()) +model.do() +Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_1r-SketchLine_2r-SketchLine_3r-SketchLine_4r")], model.selection(), 90, 0) +model.do() +aSession = ModelAPI_Session.get() +aSession.setActiveDocument(partSet, False) +Translation_1 = model.addTranslation(partSet, [model.selection("COMPOUND", "Part_1/")], model.selection("EDGE", "OX"), 100) +model.do() +# move timeline before Translation +partSet.setCurrentFeature(Part_1.feature(), True) +Rotation_1 = model.addRotation(partSet, [model.selection("COMPOUND", "Part_1/")], model.selection("EDGE", "OY"), 90) +model.do() +# move timeline to the end of history +partSet.setCurrentFeature(Translation_1.feature(), True) +model.end() + +# check that rotation then translation were applied consequently +assert(partSet.size("Parts") == 1) +resShape = modelAPI_Result(partSet.object("Parts", 0)).shape() +# height of extrusion 90 / 2 + translation 100 +assert(GeomAlgoAPI_ShapeTools_centreOfMass(resShape).x() == 145) +# rotated +assert(floor(GeomAlgoAPI_ShapeTools_centreOfMass(resShape).z()) == -30) + +assert(model.checkPythonDump())