try {
//aSel.Select(aNewSub, aNewContext);
aSelectorOk = aSel.select(aNewContext, aNewSub);
- aSel.store();
+ if (aSelectorOk) {
+ aSel.store();
+ aSelectorOk = aSel.solve(aNewContext);
+ }
} catch(...) {
aSelectorOk = false;
}
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];
}
{
return selectionLabel().IsAttribute(kWEAK_NAMING);
}
+
+std::string Model_AttributeSelection::contextName(const TDF_Label theSelectionLab)
+{
+ DocumentPtr aMyDoc = owner()->document();
+ std::shared_ptr<Model_Document> aDoc = std::dynamic_pointer_cast<Model_Document>(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
+}
#include "Model.h"
#include "Model_AttributeReference.h"
#include <ModelAPI_AttributeSelection.h>
+#include <Selector_NameGenerator.h>
#include <TDF_LabelMap.hxx>
#include <TopoDS_Shape.hxx>
#include <TopTools_ListOfShape.hxx>
* \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
/// 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
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)
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<ModelAPI_Result>(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<std::string, std::list<TDF_Label> >::iterator aFind = myNamingNames.find(theName);
/// 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);
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<Model_Document> theDoc, ResultPtr& theContextRes, const bool theAnotherDoc)
{
SET(PROJECT_HEADERS
Selector.h
Selector_Selector.h
+ Selector_NameGenerator.h
)
SET(PROJECT_SOURCES
Selector_Selector.cpp
+ Selector_NameGenerator.cpp
)
SET(PROJECT_LIBRARIES
--- /dev/null
+#include <Selector_NameGenerator.h>
--- /dev/null
+// 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<mailto:webmaster.salome@opencascade.com>
+//
+
+#ifndef Selector_NameGenerator_H_
+#define Selector_NameGenerator_H_
+
+#include "Selector.h"
+
+#include <TDF_Label.hxx>
+
+/**\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
#include <Selector_Selector.h>
+#include <Selector_NameGenerator.h>
+
#include <TDF_ChildIDIterator.hxx>
#include <TopoDS_Iterator.hxx>
#include <TopoDS_Builder.hxx>
#include <TDataStd_Integer.hxx>
#include <TDataStd_ReferenceArray.hxx>
#include <TDataStd_IntegerArray.hxx>
+#include <TDataStd_Name.hxx>
#include <list>
}
// 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;
}
}
}
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<std::pair<TopoDS_Shape, int> > aNBs; /// neighbor sub-shape -> level of neighborhood
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<Selector_Selector>::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<int>::iterator aLevel = myNBLevel.begin();
+ std::list<Selector_Selector>::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)) {
#include <TopoDS_Shape.hxx>
#include <list>
+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
/// 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.