From: mpv Date: Wed, 21 Dec 2016 14:20:06 +0000 (+0300) Subject: Fix for the issue #1799 : split faces in groups when move in history X-Git-Tag: before_porting_8.2.0~2 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=96436dab4317da2fea70cf7c18635df47352e44f;p=modules%2Fshaper.git Fix for the issue #1799 : split faces in groups when move in history --- diff --git a/src/Model/Model_AttributeSelection.cpp b/src/Model/Model_AttributeSelection.cpp index 2b3fe9b78..6ffe934a6 100644 --- a/src/Model/Model_AttributeSelection.cpp +++ b/src/Model/Model_AttributeSelection.cpp @@ -11,6 +11,7 @@ #include "Model_Document.h" #include "Model_SelectionNaming.h" #include +#include #include #include #include @@ -295,6 +296,7 @@ Model_AttributeSelection::Model_AttributeSelection(TDF_Label& theLabel) : myRef(theLabel) { myIsInitialized = myRef.isInitialized(); + myParent = NULL; } void Model_AttributeSelection::setID(const std::string theID) @@ -429,9 +431,6 @@ bool Model_AttributeSelection::update() aBuilder.Generated(aContext->shape()->impl()); std::shared_ptr aMyDoc = std::dynamic_pointer_cast(owner()->document()); - //std::string aName = contextName(aContext); - //aMyDoc->addNamingName(aSelLab, aName); - //TDataStd_Name::Set(aSelLab, aName.c_str()); } return setInvalidIfFalse(aSelLab, aContext->shape() && !aContext->shape()->isNull()); } @@ -461,10 +460,39 @@ bool Model_AttributeSelection::update() aNewShape = aSelector.NamedShape()->Get(); } if (anOldShape.IsNull() || aNewShape.IsNull() || - !anOldShape.IsEqual(aSelector.NamedShape()->Get())) // send updated if shape is changed - owner()->data()->sendAttributeUpdated(this); + !anOldShape.IsEqual(aSelector.NamedShape()->Get())) { + // shape type shoud not not changed: if shape becomes compound of such shapes, then split + if (myParent && !anOldShape.IsNull() && !aNewShape.IsNull() && + anOldShape.ShapeType() != aNewShape.ShapeType() && + aNewShape.ShapeType() == TopAbs_COMPOUND) { + TopTools_ListOfShape aSubs; + for(TopoDS_Iterator anExplorer(aNewShape); anExplorer.More(); anExplorer.Next()) { + if (!anExplorer.Value().IsNull() && + anExplorer.Value().ShapeType() == anOldShape.ShapeType()) { + aSubs.Append(anExplorer.Value()); + } else { // invalid case; bad result shape, so, impossible to split easily + aSubs.Clear(); + break; + } + } + if (aSubs.Extent() > 1) { // ok to split + TopTools_ListIteratorOfListOfShape aSub(aSubs); + GeomShapePtr aSubSh(new GeomAPI_Shape); + aSubSh->setImpl(new TopoDS_Shape(aSub.Value())); + setValue(aContext, aSubSh); + for(aSub.Next(); aSub.More(); aSub.Next()) { + GeomShapePtr aSubSh(new GeomAPI_Shape); + aSubSh->setImpl(new TopoDS_Shape(aSub.Value())); + myParent->append(aContext, aSubSh); + } + } + } + owner()->data()->sendAttributeUpdated(this); // send updated if shape is changed + } return aResult; - } else if (aContext->groupName() == ModelAPI_ResultConstruction::group()) { + } + + if (aContext->groupName() == ModelAPI_ResultConstruction::group()) { // construction: identification by the results indexes, recompute faces and // take the face that more close by the indexes ResultConstructionPtr aConstructionContext = @@ -633,7 +661,7 @@ void Model_AttributeSelection::selectBody( TNaming_Selector aSel(selectionLabel()); TopoDS_Shape aContext; - ResultBodyPtr aBody = std::dynamic_pointer_cast(myRef.value()); + ResultBodyPtr aBody = std::dynamic_pointer_cast(theContext);//myRef.value() if (aBody) { aContext = aBody->shape()->impl(); } else { @@ -694,6 +722,13 @@ void Model_AttributeSelection::selectBody( } } if (!isFound) { // sub-shape is not found in the up-to-date instance of the context shape + // if context is sub-result of compound/compsolid, selection of sub-shape better propagate to + // the main result (which is may be modified), case is in 1799 + ResultCompSolidPtr aMain = ModelAPI_Tools::compSolidOwner(theContext); + if (aMain.get()) { + selectBody(aMain, theSubShape); + return; + } setInvalidIfFalse(aSelLab, false); Events_InfoMessage("Model_AttributeSelection", "Failed to select sub-shape already modified").send(); @@ -1151,15 +1186,6 @@ void Model_AttributeSelection::updateInHistory() aCurrentModifierFeat = aModifierFeat; TNaming_Iterator aPairIter(aNewNS); aNewShape = aPairIter.NewShape(); - /* - // searching for sub-shape equivalent on the sub-label of the new context result - TDF_ChildIDIterator aNSIter(aNewNS->Label(), TNaming_NamedShape::GetID()); - for(; aNSIter.More(); aNSIter.Next()) { - TNaming_Iterator aPairsIter(aNSIter.Value()->Label()); - for(; aPairsIter.More(); aPairsIter.Next()) { - if (aSubShape->impl().IsEqual() - } - }*/ anIterate = true; break; } else if (aNewNS->Evolution() == TNaming_DELETE) { // a shape was deleted => result is null @@ -1171,36 +1197,6 @@ void Model_AttributeSelection::updateInHistory() continue; } } - - /* - TNaming_NewShapeIterator aModifIter(aPairIter.NewShape(), aContLab); - if (aModifIter.More()) aModifIter.Next(); // skip this shape result - for(; aModifIter.More(); aModifIter.Next()) { - ResultPtr aModifierObj = std::dynamic_pointer_cast - (aDoc->objects()->object(aModifIter.Label().Father())); - if (!aModifierObj.get()) - break; - FeaturePtr aModifierFeat = aDoc->feature(aModifierObj); - if (!aModifierFeat.get()) - break; - if (aModifierFeat == aThisFeature || aDoc->objects()->isLater(aModifierFeat, aThisFeature)) - break; // the modifier feature is later than this, so, should not be used - Handle(TNaming_NamedShape) aNewNS = aModifIter.NamedShape(); - if (aNewNS->Evolution() == TNaming_MODIFY || aNewNS->Evolution() == TNaming_GENERATED) { - aModifierResFound = aModifierObj; - } else if (aNewNS->Evolution() == TNaming_DELETE) { // a shape was deleted => result is null - ResultPtr anEmptyContext; - std::shared_ptr anEmptyShape; - setValue(anEmptyContext, anEmptyShape); // nullify the selection - return; - } else { // not-precessed modification => don't support it - break; - } - } - // already found what is needed, don't iterate the next pair since normally - if (aModifierResFound.get()) // there must be only one pair in the result-shape - break; - */ } if (aModifierResFound.get()) { // update scope to reset to a new one @@ -1208,38 +1204,9 @@ void Model_AttributeSelection::updateInHistory() myRef.setValue(aModifierResFound); update(); // it must recompute a new sub-shape automatically } - /* - if (aModifierResFound.get()) { - // update scope to reset to a new one - myScope.Clear(); - if (!aSubShape.get() || aSubShape->isNull()) { // no sub-shape, so, just update a context - setValue(aModifierResFound, aSubShape); - return; - } - // seaching for the same sub-shape: the old topology stays the same - TopoDS_Shape anOldShape = aSubShape->impl(); - TopAbs_ShapeEnum aSubType = anOldShape.ShapeType(); - TopoDS_Shape aNewContext = aModifierResFound->shape()->impl(); - TopExp_Explorer anExp(aNewContext, aSubType); - for(; anExp.More(); anExp.Next()) { - if (anExp.Current().IsEqual(anOldShape)) - break; - } - if (anExp.More()) { // found - setValue(aModifierResFound, aSubShape); - return; - } - // seaching for the same sub-shape: equal geometry - for(anExp.Init(aNewContext, aSubType); anExp.More(); anExp.Next()) { - if (aSubType == TopAbs_VERTEX) { - - } - } - }*/ - // if sub-shape selection exists, search also sub-shape new instance - /* - GeomShapePtr aSubShape = value(); - if (aSubShape.get() && aSubShape != aContext->shape()) { +} - }*/ +void Model_AttributeSelection::setParent(Model_AttributeSelectionList* theParent) +{ + myParent = theParent; } diff --git a/src/Model/Model_AttributeSelection.h b/src/Model/Model_AttributeSelection.h index 144ff01c9..a24ca2d81 100644 --- a/src/Model/Model_AttributeSelection.h +++ b/src/Model/Model_AttributeSelection.h @@ -12,11 +12,12 @@ #include #include +class Model_AttributeSelectionList; + /**\class Model_AttributeSelection * \ingroup DataModel * \brief Attribute that contains reference to the sub-shape of some result, the selected shape. */ - class Model_AttributeSelection : public ModelAPI_AttributeSelection { Model_AttributeReference myRef; ///< The reference functionality reusage @@ -25,6 +26,8 @@ class Model_AttributeSelection : public ModelAPI_AttributeSelection ResultPtr myTmpContext; /// temporarily storages to avoid keeping in the data structure if not needed std::shared_ptr myTmpSubShape; + /// Reference to the partent attribute, if any (to split selection compounds in issue 1799) + Model_AttributeSelectionList* myParent; public: /// Defines the result and its selected sub-shape /// \param theContext object where the sub-shape was selected @@ -115,6 +118,9 @@ protected: /// Returns the name by context. Adds the part name if the context is located in other document std::string contextName(const ResultPtr& theContext) const; + /// Sets the parent attribute + void setParent(Model_AttributeSelectionList* theParent); + friend class Model_Data; friend class Model_AttributeSelectionList; }; diff --git a/src/Model/Model_AttributeSelectionList.cpp b/src/Model/Model_AttributeSelectionList.cpp index d8ea9da5c..72e830852 100644 --- a/src/Model/Model_AttributeSelectionList.cpp +++ b/src/Model/Model_AttributeSelectionList.cpp @@ -45,6 +45,7 @@ void Model_AttributeSelectionList::append( std::shared_ptr(new Model_AttributeSelection(aNewLab)); if (owner()) { aNewAttr->setObject(owner()); + aNewAttr->setParent(this); } aNewAttr->setID(id()); mySize->Set(aNewTag); @@ -66,6 +67,7 @@ void Model_AttributeSelectionList::append( std::shared_ptr(new Model_AttributeSelection(aNewLab)); if (owner()) { aNewAttr->setObject(owner()); + aNewAttr->setParent(this); } aNewAttr->setID(id()); mySize->Set(aNewTag); @@ -272,6 +274,7 @@ std::shared_ptr aNewAttr->setID(id()); if (owner()) { aNewAttr->setObject(owner()); + aNewAttr->setParent(this); } return aNewAttr; } @@ -288,6 +291,7 @@ void Model_AttributeSelectionList::clear() std::shared_ptr(new Model_AttributeSelection(aLab)); if (owner()) { aNewAttr->setObject(owner()); + aNewAttr->setParent(this); } REMOVE_BACK_REF(aNewAttr->context()); diff --git a/src/Model/Model_Update.cpp b/src/Model/Model_Update.cpp index 6efd1b1a7..f95f59d7c 100755 --- a/src/Model/Model_Update.cpp +++ b/src/Model/Model_Update.cpp @@ -445,6 +445,8 @@ bool Model_Update::processFeature(FeaturePtr theFeature) // too many repetition of processing (in VS it may crash on 330 with stack overflow) Events_InfoMessage("Model_Update", "Feature '%1' is updated in infinitive loop").arg(theFeature->data()->name()).send(); + // to stop iteration + myModified.clear(); return false; } myProcessed[theFeature] = aCount + 1; diff --git a/src/XGUI/CMakeLists.txt b/src/XGUI/CMakeLists.txt index 7adccd4eb..83469a5d6 100644 --- a/src/XGUI/CMakeLists.txt +++ b/src/XGUI/CMakeLists.txt @@ -129,7 +129,7 @@ SET(PROJECT_INCLUDES ${CAS_INCLUDE_DIRS} ${SUIT_INCLUDE}) -IF(${VInspectorAPI}) +IF(VInspectorAPI) message("VINSPECTOR is defined") SET(PROJECT_LIBRARIES ${PROJECT_LIBRARIES} ${VInspectorAPI}) SET(PROJECT_INCLUDES ${PROJECT_INCLUDES} ${VINSPECTOR_INCLUDE_DIR}) @@ -141,7 +141,7 @@ IF(NOT ${HAVE_SALOME}) SET(PROJECT_INCLUDES ${PROJECT_INCLUDES} ${APPELEMENTS_INCLUDE_DIR}) ENDIF(NOT ${HAVE_SALOME}) -IF(${DFBrowserAPI}) +IF(DFBrowserAPI) message("DFBROWSER is defined") SET(PROJECT_LIBRARIES ${PROJECT_LIBRARIES} ${DFBrowserAPI}) SET(PROJECT_INCLUDES ${PROJECT_INCLUDES} ${DFBROWSER_INCLUDE_DIR})