From 84615e2e0c6c8df070e877727d25ef7db02f1cf8 Mon Sep 17 00:00:00 2001 From: mpv Date: Fri, 12 Oct 2018 18:06:34 +0300 Subject: [PATCH] Name generation in the selector --- src/Model/Model_AttributeSelection.cpp | 39 +++++++++++- src/Model/Model_AttributeSelection.h | 7 ++- src/Model/Model_Document.cpp | 15 ++++- src/Model/Model_Document.h | 2 + src/Model/Model_SelectionNaming.cpp | 40 ------------- src/Selector/CMakeLists.txt | 2 + src/Selector/Selector_NameGenerator.cpp | 1 + src/Selector/Selector_NameGenerator.h | 44 ++++++++++++++ src/Selector/Selector_Selector.cpp | 79 +++++++++++++++++++++++-- src/Selector/Selector_Selector.h | 8 ++- 10 files changed, 187 insertions(+), 50 deletions(-) create mode 100644 src/Selector/Selector_NameGenerator.cpp create mode 100644 src/Selector/Selector_NameGenerator.h diff --git a/src/Model/Model_AttributeSelection.cpp b/src/Model/Model_AttributeSelection.cpp index 316413de8..3aa4ffeaa 100644 --- a/src/Model/Model_AttributeSelection.cpp +++ b/src/Model/Model_AttributeSelection.cpp @@ -843,7 +843,10 @@ void Model_AttributeSelection::selectBody( try { //aSel.Select(aNewSub, aNewContext); aSelectorOk = aSel.select(aNewContext, aNewSub); - aSel.store(); + if (aSelectorOk) { + aSel.store(); + aSelectorOk = aSel.solve(aNewContext); + } } catch(...) { aSelectorOk = false; } @@ -968,9 +971,15 @@ std::string Model_AttributeSelection::namingName(const std::string& theDefaultNa return aNameStream.str(); } + Selector_Selector aSelector(aSelLab); + std::string aResult; + if (aSelector.restore()) + aResult = aSelector.name(this); + /* Model_SelectionNaming aSelNaming(aSelLab); std::string aResult = aSelNaming.namingName( aCont, aSubSh, theDefaultName, owner()->document() != aCont->document()); + */ if (aCenterType != NOT_CENTER) { aResult += centersMap()[aCenterType]; } @@ -1706,3 +1715,31 @@ bool Model_AttributeSelection::isWeakNaming() { return selectionLabel().IsAttribute(kWEAK_NAMING); } + +std::string Model_AttributeSelection::contextName(const TDF_Label theSelectionLab) +{ + DocumentPtr aMyDoc = owner()->document(); + std::shared_ptr aDoc = std::dynamic_pointer_cast(aMyDoc); + FeaturePtr aFeatureOwner = aDoc->featureByLab(theSelectionLab); + if (aFeatureOwner.get()) { + // searching also for result - real context + ResultPtr aResult = aDoc->resultByLab(theSelectionLab); + if (aResult.get()) { + // this is to avoid duplicated names of results problem + std::string aContextName = aResult->data()->name(); + // myLab corresponds to the current time + TDF_Label aCurrentLab = selectionLabel(); + while(aCurrentLab.Depth() > 3) + aCurrentLab = aCurrentLab.Father(); + + int aNumInHistoryNames = + aDoc->numberOfNameInHistory(aResult, aCurrentLab); + while(aNumInHistoryNames > 1) { // add "_" before name the needed number of times + aContextName = "_" + aContextName; + aNumInHistoryNames--; + } + return aContextName; + } + } + return ""; // invalid case +} diff --git a/src/Model/Model_AttributeSelection.h b/src/Model/Model_AttributeSelection.h index 66f628ebb..b0c3034d6 100644 --- a/src/Model/Model_AttributeSelection.h +++ b/src/Model/Model_AttributeSelection.h @@ -24,6 +24,7 @@ #include "Model.h" #include "Model_AttributeReference.h" #include +#include #include #include #include @@ -35,7 +36,8 @@ class Model_Document; * \ingroup DataModel * \brief Attribute that contains reference to the sub-shape of some result, the selected shape. */ -class Model_AttributeSelection : public ModelAPI_AttributeSelection +class Model_AttributeSelection : public ModelAPI_AttributeSelection, + public Selector_NameGenerator { Model_AttributeReference myRef; ///< The reference functionality reusage TDF_LabelMap myScope; ///< the map of valid labels for naming selection solving @@ -128,6 +130,9 @@ public: /// Returns true if the name was stored using weak naming principle MODEL_EXPORT virtual bool isWeakNaming(); + // Implementation of the name generator method from the Selector package + // This method returns the context name by the label of the sub-selected shape + MODEL_EXPORT virtual std::string contextName(const TDF_Label theSelectionLab) override; protected: /// Objects are created for features automatically diff --git a/src/Model/Model_Document.cpp b/src/Model/Model_Document.cpp index 7acdecde2..86c89c420 100755 --- a/src/Model/Model_Document.cpp +++ b/src/Model/Model_Document.cpp @@ -1334,7 +1334,6 @@ Standard_Boolean IsEqual(const TDF_Label& theLab1, const TDF_Label& theLab2) return TDF_LabelMapHasher::IsEqual(theLab1, theLab2); } -// searches in this document feature that contains this label FeaturePtr Model_Document::featureByLab(const TDF_Label& theLab) { TDF_Label aCurrentLab = theLab; while(aCurrentLab.Depth() > 3) @@ -1342,6 +1341,20 @@ FeaturePtr Model_Document::featureByLab(const TDF_Label& theLab) { return myObjs->feature(aCurrentLab); } +ResultPtr Model_Document::resultByLab(const TDF_Label& theLab) +{ + TDF_Label aCurrentLab = theLab; + while(aCurrentLab.Depth() > 3) { + ObjectPtr aResultObj = myObjs->object(aCurrentLab); + if (aResultObj.get()) { + return std::dynamic_pointer_cast(aResultObj); // this may be null if feature + } + aCurrentLab = aCurrentLab.Father(); + } + return ResultPtr(); // not found +} + + void Model_Document::addNamingName(const TDF_Label theLabel, std::string theName) { std::map >::iterator aFind = myNamingNames.find(theName); diff --git a/src/Model/Model_Document.h b/src/Model/Model_Document.h index 0842d3d32..0e1c89a47 100644 --- a/src/Model/Model_Document.h +++ b/src/Model/Model_Document.h @@ -375,6 +375,8 @@ class Model_Document : public ModelAPI_Document /// searches in this document feature that contains this label FeaturePtr featureByLab(const TDF_Label& theLab); + /// searches in this document result that contains this label + ResultPtr resultByLab(const TDF_Label& theLab); /// returns true if theThis is later in the features trre and dependencies than theOther bool isLaterByDep(FeaturePtr theThis, FeaturePtr theOther); diff --git a/src/Model/Model_SelectionNaming.cpp b/src/Model/Model_SelectionNaming.cpp index 802b13cfc..1075ef610 100644 --- a/src/Model/Model_SelectionNaming.cpp +++ b/src/Model/Model_SelectionNaming.cpp @@ -258,46 +258,6 @@ const TopoDS_Shape findCommonShape( return aSharedShape; } -// searches theType shape that contains theConnectionType sub-shapes in each shape from the List, -// so, implements the neighbours searching -/* -const TopoDS_Shape findCommonShapeByNB(const TopAbs_ShapeEnum theType, - const TopAbs_ShapeEnum theConnectionType, const TopTools_ListOfShape& theList) -{ -TopTools_MapOfShape aCheckedShapes; // already checked shapes of type theType - TopoDS_Shape aResult; // theType result shape - for(TopTools_ListIteratorOfListOfShape anIt(theList); anIt.More(); anIt.Next()) { // iterate all - for(TopExp_Explorer anExp(anIt.ChangeValue(), theType); anExp.More(); anExp.Next()) { - if (aCheckedShapes.Contains(anExp.Current())) - continue; // already checked - aCheckedShapes.Add(anExp.Current()); - TopTools_MapOfShape aConnectors; // all connectors of the checked theType shape - for(TopExp_Explorer aCExp(anExp.Current(), theConnectionType); aCExp.More(); aCExp.Next()) { - aConnectors.Add(aCExp.Current()); - } - // check that all shapes from the List contain the connector sub-shapes - bool aFound = true; - for(TopTools_ListIteratorOfListOfShape anIt2(theList); anIt2.More() && aFound; anIt2.Next()) { - if (anIt2.Value().IsSame(anIt.Value())) - continue; - aFound = false; - for(TopExp_Explorer anE(anIt2.ChangeValue(), theConnectionType); anE.More(); anE.Next()) { - if (aConnectors.Contains(anE.Current())) { - aFound = true; - break; - } - } - } - if (aFound) { - if (!aResult.IsNull()) // more than one result - return TopoDS_Shape(); - aResult = anExp.Current(); - } - } - } - return aResult; -}*/ - std::string Model_SelectionNaming::vertexNameByEdges(TopoDS_Shape theContext, TopoDS_Shape theSub, std::shared_ptr theDoc, ResultPtr& theContextRes, const bool theAnotherDoc) { diff --git a/src/Selector/CMakeLists.txt b/src/Selector/CMakeLists.txt index 67ae4371f..f3bf654ea 100644 --- a/src/Selector/CMakeLists.txt +++ b/src/Selector/CMakeLists.txt @@ -23,10 +23,12 @@ INCLUDE(Common) SET(PROJECT_HEADERS Selector.h Selector_Selector.h + Selector_NameGenerator.h ) SET(PROJECT_SOURCES Selector_Selector.cpp + Selector_NameGenerator.cpp ) SET(PROJECT_LIBRARIES diff --git a/src/Selector/Selector_NameGenerator.cpp b/src/Selector/Selector_NameGenerator.cpp new file mode 100644 index 000000000..0c4ed036b --- /dev/null +++ b/src/Selector/Selector_NameGenerator.cpp @@ -0,0 +1 @@ +#include diff --git a/src/Selector/Selector_NameGenerator.h b/src/Selector/Selector_NameGenerator.h new file mode 100644 index 000000000..80fb8650c --- /dev/null +++ b/src/Selector/Selector_NameGenerator.h @@ -0,0 +1,44 @@ +// 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 +// + +#ifndef Selector_NameGenerator_H_ +#define Selector_NameGenerator_H_ + +#include "Selector.h" + +#include + +/**\class Selector_NameGenerator + * \ingroup DataModel + * \brief An interface for generation of the naming name basing on the current selection and + * document information. This requires higher-level data access, so, the caller of "name" method + * of Selector must implement this helper-class abstract methods. + */ +class Selector_NameGenerator +{ +public: + // empty constructor, nothing to add + Selector_NameGenerator() {}; + + // This method returns the context name by the label of the sub-selected shape + virtual std::string contextName(const TDF_Label theSelectionLab) = 0; +}; + +#endif diff --git a/src/Selector/Selector_Selector.cpp b/src/Selector/Selector_Selector.cpp index c4b6539d1..f97d20c8c 100644 --- a/src/Selector/Selector_Selector.cpp +++ b/src/Selector/Selector_Selector.cpp @@ -20,6 +20,8 @@ #include +#include + #include #include #include @@ -35,6 +37,7 @@ #include #include #include +#include #include @@ -253,16 +256,21 @@ bool Selector_Selector::select(const TopoDS_Shape theContext, const TopoDS_Shape } // try to find the shape of the higher level type in the context shape - while(aSelectionType != TopAbs_FACE) { - if (aSelectionType == TopAbs_VERTEX) aSelectionType = TopAbs_EDGE; - else if (aSelectionType == TopAbs_EDGE) aSelectionType = TopAbs_FACE; + bool aFacesTried = false; // for identification of vertices, faces are tried, then edges + while(aSelectionType != TopAbs_FACE || !aFacesTried) { + if (aSelectionType == TopAbs_FACE && theValue.ShapeType() == TopAbs_VERTEX) { + aFacesTried = true; + aSelectionType = TopAbs_EDGE; + } else + aSelectionType = TopAbs_FACE; TopTools_MapOfShape anIntersectors; // shapes of aSelectionType that contain theValue TopoDS_ListOfShape anIntList; // same as anIntersectors for(TopExp_Explorer aSelExp(theContext, aSelectionType); aSelExp.More(); aSelExp.Next()) { TopExp_Explorer aSubExp(aSelExp.Current(), theValue.ShapeType()); for(; aSubExp.More(); aSubExp.Next()) { if (aSubExp.Current().IsSame(theValue)) { - anIntersectors.Add(aSelExp.Current()); + if (anIntersectors.Add(aSelExp.Current())) + anIntList.Append(aSelExp.Current()); break; } } @@ -613,6 +621,7 @@ bool Selector_Selector::solve(const TopoDS_Shape& theContext) } if (aFinalsCommon.Extent() == 1) // only in this case result is valid: found only one shape aResult = aFinalsCommon.First(); + break; } case SELTYPE_FILTER_BY_NEIGHBOR: { std::list > aNBs; /// neighbor sub-shape -> level of neighborhood @@ -646,7 +655,67 @@ TopoDS_Shape Selector_Selector::value() return TopoDS_Shape(); // empty, error shape } -bool Selector_Selector::selectBySubSelector(const TopoDS_Shape theContext, const TopoDS_Shape theValue) +std::string Selector_Selector::name(Selector_NameGenerator* theNameGenerator) { + switch(myType) { + case SELTYPE_CONTAINER: + case SELTYPE_INTERSECT: { + std::string aResult; + // add names of sub-components one by one separated by "&" + std::list::iterator aSubSel = mySubSelList.begin(); + for(; aSubSel != mySubSelList.end(); aSubSel++) { + if (aSubSel != mySubSelList.begin()) + aResult += "&"; + aResult += aSubSel->name(theNameGenerator); + } + return aResult; + } + case SELTYPE_PRIMITIVE: { + Handle(TDataStd_Name) aName; + if (!myFinal.FindAttribute(TDataStd_Name::GetID(), aName)) + return ""; + return theNameGenerator->contextName(myFinal) + "/" + + std::string(TCollection_AsciiString(aName->Get()).ToCString()); + } + case SELTYPE_MODIFICATION: { + // final&/base1&base2 + std::string aResult; + Handle(TDataStd_Name) aName; + if (!myFinal.FindAttribute(TDataStd_Name::GetID(), aName)) + return ""; + aResult += theNameGenerator->contextName(myFinal) + "/" + + std::string(TCollection_AsciiString(aName->Get()).ToCString()) + "&/"; + for(TDF_LabelList::iterator aBase = myBases.begin(); aBase != myBases.end(); aBase++) { + if (aBase != myBases.begin()) + aResult += "&"; + if (aBase->FindAttribute(TDataStd_Name::GetID(), aName)) + return ""; + aResult += theNameGenerator->contextName(*aBase) + "/" + + std::string(TCollection_AsciiString(aName->Get()).ToCString()); + } + return aResult; + } + case SELTYPE_FILTER_BY_NEIGHBOR: { + // (nb1)level_if_more_than_1&(nb2)level_if_more_than_1&(nb3)level_if_more_than_1 + std::string aResult; + std::list::iterator aLevel = myNBLevel.begin(); + std::list::iterator aSubSel = mySubSelList.begin(); + for(; aSubSel != mySubSelList.end(); aSubSel++, aLevel++) { + if (aSubSel != mySubSelList.begin()) + aResult += "&"; + aResult += "(" + aSubSel->name(theNameGenerator) + ")"; + if (*aLevel > 1) + aResult += *aLevel; + } + return aResult; + } + default: { // unknown case + } + }; + return ""; +} + +bool Selector_Selector::selectBySubSelector( + const TopoDS_Shape theContext, const TopoDS_Shape theValue) { mySubSelList.push_back(Selector_Selector(myLab.FindChild(int(mySubSelList.size()) + 1))); if (!mySubSelList.back().select(theContext, theValue)) { diff --git a/src/Selector/Selector_Selector.h b/src/Selector/Selector_Selector.h index 225ab131f..cbed4c983 100644 --- a/src/Selector/Selector_Selector.h +++ b/src/Selector/Selector_Selector.h @@ -28,12 +28,13 @@ #include #include +class Selector_NameGenerator; + /**\class Selector_Selector * \ingroup DataModel * \brief Main object for selection of the sub-shapes in the parametrically updated * shapes using topological naming mechanism. */ - class Selector_Selector { /// Type of a selector: on this type depends what is stored in this label and how to @@ -77,9 +78,12 @@ class Selector_Selector /// Updates the current shape by the stored topological name SELECTOR_EXPORT bool solve(const TopoDS_Shape& theContext); - /// Returns the current sub-shape value (null if can not resolve) + /// Returns the current sub-shape value (null if can not resolve) SELECTOR_EXPORT TopoDS_Shape value(); + /// Returns the naming name of the selection + SELECTOR_EXPORT std::string name(Selector_NameGenerator* theNameGenerator); + private: /// Create and keep in the list the sub-sulector that select the given value. -- 2.39.2