void Model_Document::addNamingName(const TDF_Label theLabel, std::string theName)
{
+ std::map<std::string, std::list<TDF_Label> >::iterator aFind = myNamingNames.find(theName);
+ if (aFind != myNamingNames.end()) { // to avoid duplicate-labels
+ std::list<TDF_Label>::iterator aLabIter = aFind->second.begin();
+ while(aLabIter != aFind->second.end()) {
+ if (theLabel.IsEqual(*aLabIter)) {
+ std::list<TDF_Label>::iterator aTmpIter = aLabIter;
+ aLabIter++;
+ aFind->second.erase(aTmpIter);
+ } else {
+ aLabIter++;
+ }
+ }
+ }
myNamingNames[theName].push_back(theLabel);
}
}
}
-TDF_Label Model_Document::findNamingName(std::string theName)
+TDF_Label Model_Document::findNamingName(std::string theName, ResultPtr theContext)
{
std::map<std::string, std::list<TDF_Label> >::iterator aFind = myNamingNames.find(theName);
if (aFind != myNamingNames.end()) {
- return *(aFind->second.rbegin());
+ std::list<TDF_Label>::reverse_iterator aLabIter = aFind->second.rbegin();
+ for(; aLabIter != aFind->second.rend(); aLabIter++) {
+ if (theContext.get()) {
+ // context is defined and not like this, so, skip
+ if (theContext == myObjs->object(aLabIter->Father()))
+ return *aLabIter;
+ }
+ }
+ return *(aFind->second.rbegin()); // no more variannts, so, return the last
}
// not found exact name, try to find by sub-components
std::string::size_type aSlash = theName.rfind('/');
// iterate all possible same-named labels starting from the last one (the recent)
std::list<TDF_Label>::reverse_iterator aLabIter = aFind->second.rbegin();
for(; aLabIter != aFind->second.rend(); aLabIter++) {
+ if (theContext.get()) {
+ // context is defined and not like this, so, skip
+ if (theContext != myObjs->object(aLabIter->Father()))
+ continue;
+ }
// searching sub-labels with this name
TDF_ChildIDIterator aNamesIter(*aLabIter, TDataStd_Name::GetID(), Standard_True);
for(; aNamesIter.More(); aNamesIter.Next()) {
return TDF_Label(); // not found
}
-ResultPtr Model_Document::findByName(const std::string theName)
+int Model_Document::numberOfNameInHistory(
+ const ObjectPtr& theNameObject, const TDF_Label& theStartFrom)
{
- return myObjs->findByName(theName);
+ std::map<std::string, std::list<TDF_Label> >::iterator aFind =
+ myNamingNames.find(theNameObject->data()->name());
+ if (aFind == myNamingNames.end() || aFind->second.size() < 2) {
+ return 1; // no need to specify the name by additional identifiers
+ }
+ // get the feature of the object for relative compare
+ FeaturePtr aStart = myObjs->feature(theStartFrom);
+ if (!aStart.get()) // strange, but can not find feature by the label
+ return 1;
+ // feature that contain result with this name
+ FeaturePtr aNameFeature;
+ ResultPtr aNameResult = std::dynamic_pointer_cast<ModelAPI_Result>(theNameObject);
+ if (aNameResult)
+ aNameFeature = myObjs->feature(aNameResult);
+ else
+ aNameFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theNameObject);
+ // iterate all labels with this name to find the nearest just before or equal relative
+ std::list<TDF_Label>::reverse_iterator aLabIter = aFind->second.rbegin();
+ for(; aLabIter != aFind->second.rend(); aLabIter++) {
+ TDF_Label aCurrentLab = *aLabIter;
+ while(aCurrentLab.Depth() > 3)
+ aCurrentLab = aCurrentLab.Father();
+ FeaturePtr aLabFeat = myObjs->feature(aCurrentLab);
+ if (!aLabFeat.get())
+ continue;
+ if (aLabFeat == aStart || myObjs->isLater(aStart, aLabFeat))
+ break;
+ }
+ int aResIndex = 1;
+ for(; aLabIter != aFind->second.rend(); aLabIter++) {
+ TDF_Label aCurrentLab = *aLabIter;
+ while(aCurrentLab.Depth() > 3)
+ aCurrentLab = aCurrentLab.Father();
+ FeaturePtr aLabFeat = myObjs->feature(aCurrentLab);
+ if (!aLabFeat.get())
+ continue;
+ if (aLabFeat == aNameFeature || myObjs->isLater(aNameFeature, aLabFeat))
+ return aResIndex;
+ aResIndex++;
+ }
+ return aResIndex; // strange
+}
+
+ResultPtr Model_Document::findByName(std::string& theName, std::string& theSubShapeName)
+{
+ int aNumInHistory = 0;
+ std::string aName = theName;
+ ResultPtr aRes = myObjs->findByName(aName);
+ while(!aRes.get() && aName[0] == '_') { // this may be thecontext with the history index
+ aNumInHistory++;
+ aName = aName.substr(1);
+ aRes = myObjs->findByName(aName);
+ }
+ if (aNumInHistory) {
+ std::map<std::string, std::list<TDF_Label> >::iterator aFind = myNamingNames.find(aName);
+ if (aFind != myNamingNames.end() && aFind->second.size() > aNumInHistory) {
+ std::list<TDF_Label>::reverse_iterator aLibIt = aFind->second.rbegin();
+ for(; aNumInHistory != 0; aNumInHistory--)
+ aLibIt++;
+ const TDF_Label& aResultLab = *aLibIt;
+ aRes = std::dynamic_pointer_cast<ModelAPI_Result>(myObjs->object(aResultLab.Father()));
+ if (aRes) { // modify the incoming names
+ if (!theSubShapeName.empty())
+ theSubShapeName = theSubShapeName.substr(theName.size() - aName.size());
+ theName = aName;
+ }
+ }
+ }
+ return aRes;
}
std::list<std::shared_ptr<ModelAPI_Feature> > Model_Document::allFeatures()
void changeNamingName(std::string theOldName, const std::string theNewName,
const TDF_Label& theLabel);
//! Returns the label, keeper of the name for the topological naming needs
- TDF_Label findNamingName(std::string theName);
+ TDF_Label findNamingName(std::string theName, ResultPtr theContext);
+ //! Returns the number of the name in the history relatively to the given object (by label).
+ //! Start from 1 (this object).
+ int numberOfNameInHistory(const ObjectPtr& theNameObject, const TDF_Label& theStartFrom);
//! Returns the result by name of the result (names of results must be unique, used for naming
//! selection by name.
- ResultPtr findByName(const std::string theName);
+ ResultPtr findByName(std::string& theName, std::string& theSubShapeName);
///! Returns all features of the document including the hidden features which are not in
///! history. Not very fast method, for calling once, not in big cycles.
aNewContext = theDoc->objects()->object(aNSDataLab);
}
if (aNewContext.get()) {
- aName = aNewContext->data()->name() + "/" + aName;
+ // this is to avoid duplicated names of results problem
+ std::string aContextName = aNewContext->data()->name();
+ // myLab corresponds to the current time
+ TDF_Label aCurrentLab = myLab;
+ while(aCurrentLab.Depth() > 3)
+ aCurrentLab = aCurrentLab.Father();
+
+ int aNumInHistoryNames =
+ theDoc->numberOfNameInHistory(aNewContext, aCurrentLab);
+ while(aNumInHistoryNames > 1) { // add "_" before name the needed number of times
+ aContextName = "_" + aContextName;
+ aNumInHistoryNames--;
+ }
+
+ aName = aContextName + "/" + aName;
}
}
}
}
const TopoDS_Shape findFaceByName(
- const std::string& theSubShapeName, std::shared_ptr<Model_Document> theDoc)
+ const std::string& theSubShapeName, std::shared_ptr<Model_Document> theDoc,
+ const ResultPtr theDetectedContext)
{
TopoDS_Shape aFace;
std::string aSubString = theSubShapeName;
- TDF_Label aLabel = theDoc->findNamingName(aSubString);
+ TDF_Label aLabel = theDoc->findNamingName(aSubString, theDetectedContext);
if (aLabel.IsNull()) { // try to remove additional artificial suffix
std::string::size_type n = aSubString.rfind('_');
if (n != std::string::npos) {
aSubString = aSubString.substr(0, n);
- aLabel = theDoc->findNamingName(aSubString);
+ aLabel = theDoc->findNamingName(aSubString, theDetectedContext);
}
}
if(aLabel.IsNull()) return aFace;
std::string aContName = getContextName(aSubShapeName);
if(aContName.empty()) return false;
- ResultPtr aCont = aDoc->findByName(aContName);
+ ResultPtr aCont = aDoc->findByName(aContName, aSubShapeName);
// possible this is body where postfix is added to distinguish several shapes on the same label
int aSubShapeId = -1; // -1 means sub shape not found
// for result body the name wihtout "_" has higher priority than with it: it is always added
aContName == aSubShapeName) {
size_t aPostIndex = aContName.rfind('_');
if (aPostIndex != std::string::npos) {
- std::string aSubContName = aContName.substr(0, aPostIndex);
- ResultPtr aSubCont = aDoc->findByName(aSubContName);
+ std::string anEmpty, aSubContName = aContName.substr(0, aPostIndex);
+ ResultPtr aSubCont = aDoc->findByName(aSubContName, anEmpty);
if (aSubCont.get()) {
try {
std::string aNum = aContName.substr(aPostIndex + 1);
case TopAbs_FACE:
case TopAbs_WIRE:
{
- aSelection = findFaceByName(aSubShapeName, aDoc);
+ aSelection = findFaceByName(aSubShapeName, aDoc, aCont);
}
break;
case TopAbs_EDGE:
{
- const TDF_Label& aLabel = aDoc->findNamingName(aSubShapeName);
+ const TDF_Label& aLabel = aDoc->findNamingName(aSubShapeName, aCont);
if(!aLabel.IsNull()) {
Handle(TNaming_NamedShape) aNS;
if(aLabel.FindAttribute(TNaming_NamedShape::GetID(), aNS)) {
break;
case TopAbs_VERTEX:
{
- const TDF_Label& aLabel = aDoc->findNamingName(aSubShapeName);
+ const TDF_Label& aLabel = aDoc->findNamingName(aSubShapeName, aCont);
if(!aLabel.IsNull()) {
Handle(TNaming_NamedShape) aNS;
if(aLabel.FindAttribute(TNaming_NamedShape::GetID(), aNS)) {
if(aN >= 1) {
TopTools_ListOfShape aList;
std::list<std::string>::iterator it = aListofNames.begin();
- for(; it != aListofNames.end(); it++){
- const TopoDS_Shape aFace = findFaceByName(*it, aDoc);
+ for(; it != aListofNames.end(); it++) {
+ ResultPtr aFaceContext = aCont;
+ if (it != aListofNames.begin()) { // there may be other context for different sub-faces
+ std::string aContName = getContextName(*it);
+ if(!aContName.empty()) {
+ aFaceContext = aDoc->findByName(aContName, *it);
+ }
+ }
+ const TopoDS_Shape aFace = findFaceByName(*it, aDoc, aFaceContext);
if(!aFace.IsNull())
aList.Append(aFace);
}
if (aN < 2) {
size_t aConstrNamePos = aSubShapeName.find("/");
bool isFullName = aConstrNamePos == std::string::npos;
- std::string aContrName = aContName;
- ResultPtr aConstr = aDoc->findByName(aContrName);
+ std::string anEmpty, aContrName = aContName;
+ ResultPtr aConstr = aDoc->findByName(aContrName, anEmpty);
if (aConstr.get() && aConstr->groupName() == ModelAPI_ResultConstruction::group()) {
theCont = aConstr;
if (isFullName) {