-// Copyright (C) 2014-2019 CEA/DEN, EDF R&D
+// Copyright (C) 2014-2023 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
#include <Selector_NameGenerator.h>
#include <Selector_NExplode.h>
+#include <Locale_Convert.h>
+
#include <TNaming_NamedShape.hxx>
#include <TNaming_Iterator.hxx>
#include <TNaming_SameShapeIterator.hxx>
Selector_Modify::Selector_Modify() : Selector_Algo()
{
myWeakIndex = -1; // no index by default
+ myRecomputeWeakIndex = false;
}
// adds to theResult all labels that contain initial shapes for theValue located in theFinal
bool aMustBeAtFinal, const TDF_Label& theAdditionalDocument, TDF_LabelList& theResult)
{
bool aFoundAnyShape = false;
- TNaming_SameShapeIterator aLabIter(theValue, theAccess);
- for(; aLabIter.More(); aLabIter.Next()) {
- Handle(TNaming_NamedShape) aNS;
- if (aLabIter.Label().FindAttribute(TNaming_NamedShape::GetID(), aNS)) {
- if (aMustBeAtFinal && aNS != theFinal)
- continue; // looking for old at the same final label only
- TNaming_Evolution anEvolution = aNS->Evolution();
- if (anEvolution == TNaming_PRIMITIVE) {
- // check that this is not in the results already
- const TDF_Label aResult = aNS->Label();
- TDF_LabelList::Iterator aResIter(theResult);
- for(; aResIter.More(); aResIter.Next()) {
- if (aResIter.Value().IsEqual(aResult))
- break;
+ if (TNaming_Tool::HasLabel(theAccess, theValue)) {
+ TNaming_SameShapeIterator aLabIter(theValue, theAccess);
+ for(; aLabIter.More(); aLabIter.Next()) {
+ Handle(TNaming_NamedShape) aNS;
+ if (aLabIter.Label().FindAttribute(TNaming_NamedShape::GetID(), aNS)) {
+ if (aMustBeAtFinal && aNS != theFinal)
+ continue; // looking for old at the same final label only
+ TNaming_Evolution anEvolution = aNS->Evolution();
+ if (anEvolution == TNaming_PRIMITIVE) {
+ // check that this is not in the results already
+ const TDF_Label aResult = aNS->Label();
+ TDF_LabelList::Iterator aResIter(theResult);
+ for(; aResIter.More(); aResIter.Next()) {
+ if (aResIter.Value().IsEqual(aResult))
+ break;
+ }
+ if (!aResIter.More()) // not found, so add this new
+ theResult.Append(aResult);
+ aFoundAnyShape = true;
}
- if (!aResIter.More()) // not found, so add this new
- theResult.Append(aResult);
- aFoundAnyShape = true;
- }
- if (anEvolution == TNaming_GENERATED || anEvolution == TNaming_MODIFY) {
- for(TNaming_Iterator aThisIter(aNS); aThisIter.More(); aThisIter.Next()) {
- if (aThisIter.NewShape().IsSame(theValue)) {
- // continue recursively, null NS means that any NS are ok
- findBases(theAccess, theFinal, aThisIter.OldShape(),
- false, theAdditionalDocument, theResult);
- aFoundAnyShape = true;
+ if (anEvolution == TNaming_GENERATED || anEvolution == TNaming_MODIFY) {
+ for(TNaming_Iterator aThisIter(aNS); aThisIter.More(); aThisIter.Next()) {
+ if (aThisIter.NewShape().IsSame(theValue)) {
+ // continue recursively, null NS means that any NS are ok
+ findBases(theAccess, theFinal, aThisIter.OldShape(),
+ false, theAdditionalDocument, theResult);
+ aFoundAnyShape = true;
+ }
}
}
}
const TopoDS_Shape theContext, const TopoDS_Shape theValue)
{
if (theModifList.Extent() > 1) { // searching for the best modification result: by context
+ bool isFound = false;
Handle(TNaming_NamedShape) aCandidate;
NCollection_List<Handle(TNaming_NamedShape)>::Iterator aModIter(theModifList);
- for (; !theModifList.IsEmpty() && aModIter.More(); aModIter.Next()) {
+ for (; aModIter.More() && !isFound; aModIter.Next()) {
aCandidate = aModIter.Value();
TDF_Label aFatherLab = aCandidate->Label().Father();
Handle(TNaming_NamedShape) aFatherNS;
if (aFatherLab.FindAttribute(TNaming_NamedShape::GetID(), aFatherNS)) {
- for (TNaming_Iterator anIter(aFatherNS); anIter.More(); anIter.Next()) {
+ for (TNaming_Iterator anIter(aFatherNS);
+ anIter.More() && !isFound; anIter.Next()) {
if (theContext.IsSame(anIter.NewShape())) { // found the best modification
- theModifList.Clear();
- break;
+ isFound = true;
}
}
}
return false;
}
-TDF_Label Selector_Modify::restoreByName(std::string theName,
+TDF_Label Selector_Modify::restoreByName(std::wstring theName,
const TopAbs_ShapeEnum theShapeType, Selector_NameGenerator* theNameGenerator)
{
+ typedef NCollection_DataMap<TopoDS_Shape, bool, TopTools_ShapeMapHasher> MapOfCompsolids;
+ MapOfCompsolids aWrongSubsCompsolids;
+
TDF_Label aContext;
- for(size_t anEnd, aStart = 0; aStart != std::string::npos; aStart = anEnd) {
+ for(size_t anEnd, aStart = 0; aStart != std::wstring::npos; aStart = anEnd) {
if (aStart != 0)
aStart++;
- anEnd = theName.find('&', aStart);
- std::string aSubStr =
- theName.substr(aStart, anEnd == std::string::npos ? anEnd : anEnd - aStart);
- if (aSubStr.find(weakNameID()) == 0) { // weak name identifier
- std::string aWeakIndex = aSubStr.substr(weakNameID().size());
- myWeakIndex = atoi(aWeakIndex.c_str());
+ anEnd = theName.find(L'&', aStart);
+ std::wstring aSubStr =
+ theName.substr(aStart, anEnd == std::wstring::npos ? anEnd : anEnd - aStart);
+ size_t aFoundOldWeak = aSubStr.find(oldWeakNameID());
+ size_t aFoundNewWeak = aFoundOldWeak != std::wstring::npos ?
+ aSubStr.find(weakNameID()) :
+ aFoundOldWeak;
+ if (aFoundOldWeak == 0 || aFoundNewWeak == 0) { // weak name identifier
+ std::wstring aWeakIndex = aSubStr.substr(aFoundOldWeak + oldWeakNameID().size());
+ myWeakIndex = atoi(Locale::Convert::toString(aWeakIndex).c_str());
+ myRecomputeWeakIndex = aFoundOldWeak == 0;
continue;
}
TDF_Label aSubContext, aValue;
if (!theNameGenerator->restoreContext(aSubStr, aSubContext, aValue))
return TDF_Label(); // can not restore
- if(aSubContext.IsNull() || aValue.IsNull())
+ if (aSubContext.IsNull() || (aValue.IsNull() && theShapeType <= TopAbs_SHELL))
return TDF_Label(); // can not restore
if (myFinal.IsNull()) {
myFinal = aValue;
aContext = aSubContext;
- } else
- myBases.Append(aValue);
+ } else {
+ // This could be a solid in a compsolid, which was not modified by the previous operation,
+ // however, the selected subshape is stored on its sub-label by mistake. Thus, wait until
+ // the end of processing to check whether the subshape is found in another solid.
+ TDF_Label aParent = aSubContext.Father().Father();
+ Handle(TNaming_NamedShape) aNS;
+ if (aParent.FindAttribute(TNaming_NamedShape::GetID(), aNS)) {
+ TopoDS_Shape aShape = aNS->Get();
+ if (aShape.ShapeType() == TopAbs_COMPSOLID) {
+ if (aWrongSubsCompsolids.IsBound(aShape)) {
+ if (!aValue.IsNull())
+ aWrongSubsCompsolids.Bind(aShape, true);
+ } else
+ aWrongSubsCompsolids.Bind(aShape, !aValue.IsNull());
+ }
+ } else if (aValue.IsNull())
+ return TDF_Label();
+
+ if (!aValue.IsNull())
+ myBases.Append(aValue);
+ }
}
+
+ // check all compsolids are processed and names are resolved
+ for (MapOfCompsolids::Iterator anIt(aWrongSubsCompsolids); anIt.More(); anIt.Next())
+ if (!anIt.Value())
+ return TDF_Label();
+
return aContext;
}
aCommon.Append(aNewShape);
}
}
- Selector_NExplode aNexp(aCommon);
+ Selector_NExplode aNexp(aCommon, myRecomputeWeakIndex);
aResult = aNexp.shape(myWeakIndex);
+ myRecomputeWeakIndex = false;
} else { // standard case
TopoDS_ListOfShape aFinalsCommon; // final shapes presented in all results from bases
findModificationResult(aFinalsCommon);
aResult = aFinalsCommon.First();
findNewVersion(theContext, aResult);
} else if (aFinalsCommon.Extent() > 1 && myWeakIndex > 0) {
- Selector_NExplode aNExp(aFinalsCommon);
+ Selector_NExplode aNExp(aFinalsCommon, myRecomputeWeakIndex);
aResult = aNExp.shape(myWeakIndex);
+ myRecomputeWeakIndex = false;
findNewVersion(theContext, aResult);
} else if (aFinalsCommon.Extent() > 1 && geometricalNaming()) {// if same geometry - compound
TopoDS_ListOfShape::Iterator aCommonIter(aFinalsCommon);
return false;
}
-std::string Selector_Modify::name(Selector_NameGenerator* theNameGenerator)
+std::wstring Selector_Modify::name(Selector_NameGenerator* theNameGenerator)
{
// final&base1&base2 +optionally: [weak_name_1]
- std::string aResult;
+ std::wstring aResult;
Handle(TDataStd_Name) aName;
if (!myFinal.FindAttribute(TDataStd_Name::GetID(), aName))
- return "";
- aResult += theNameGenerator->contextName(myFinal) + "/" +
- std::string(TCollection_AsciiString(aName->Get()).ToCString());
+ return L"";
+ aResult += theNameGenerator->contextName(myFinal) + L"/";
+ aResult += Locale::Convert::toWString(aName->Get().ToExtString());
for(TDF_LabelList::iterator aBase = myBases.begin(); aBase != myBases.end(); aBase++) {
if (!aBase->FindAttribute(TDataStd_Name::GetID(), aName))
- return "";
- aResult += "&";
- aResult += theNameGenerator->contextName(*aBase) + "/" +
- std::string(TCollection_AsciiString(aName->Get()).ToCString());
+ return L"";
+ aResult += L"&";
+ aResult += theNameGenerator->contextName(*aBase) + L"/";
+ aResult += Locale::Convert::toWString(aName->Get().ToExtString());
}
if (myWeakIndex != -1) {
- std::ostringstream aWeakStr;
- aWeakStr<<"&"<<weakNameID()<<myWeakIndex;
+ std::wostringstream aWeakStr;
+ aWeakStr<<L"&"<<weakNameID()<<myWeakIndex;
aResult += aWeakStr.str();
}
return aResult;