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)
+ aCurrentLab = aCurrentLab.Father();
+ return myObjs->feature(aCurrentLab);
+}
+
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
+ // to keep correct order inspite of history line management
+ std::list<TDF_Label>::iterator anAddAfterThis = aFind->second.end();
+ FeaturePtr anAddedFeature = featureByLab(theLabel);
std::list<TDF_Label>::iterator aLabIter = aFind->second.begin();
while(aLabIter != aFind->second.end()) {
if (theLabel.IsEqual(*aLabIter)) {
aLabIter++;
aFind->second.erase(aTmpIter);
} else {
+ FeaturePtr aCurFeature = featureByLab(*aLabIter);
+ if (aCurFeature.get() && anAddedFeature.get() &&
+ myObjs->isLater(anAddedFeature, aCurFeature))
+ anAddAfterThis = aLabIter;
+
aLabIter++;
}
}
+ if (anAddAfterThis != aFind->second.end()) {
+ anAddAfterThis++;
+ if (anAddAfterThis != aFind->second.end()) {
+ myNamingNames[theName].insert(anAddAfterThis, theLabel); // inserts before anAddAfterThis
+ return;
+ }
+ }
}
myNamingNames[theName].push_back(theLabel);
}
return TDF_Label(); // not found
}
+bool Model_Document::isLaterByDep(FeaturePtr theThis, FeaturePtr theOther) {
+ // check dependencies first: if theOther depends on theThis, theThis is not later
+ std::list<std::pair<std::string, std::list<std::shared_ptr<ModelAPI_Object> > > > aRefs;
+ theOther->data()->referencesToObjects(aRefs);
+ std::list<std::pair<std::string, std::list<std::shared_ptr<ModelAPI_Object> > > >::iterator
+ aRefIt = aRefs.begin();
+ for(; aRefIt != aRefs.end(); aRefIt++) {
+ std::list<ObjectPtr>::iterator aRefObjIt = aRefIt->second.begin();
+ for(; aRefObjIt != aRefIt->second.end(); aRefObjIt++) {
+ ObjectPtr aRefObj = *aRefObjIt;
+ if (aRefObj.get()) {
+ FeaturePtr aRefFeat = std::dynamic_pointer_cast<ModelAPI_Feature>(aRefObj);
+ if (!aRefFeat.get()) { // take feature of the result
+ aRefFeat = feature(std::dynamic_pointer_cast<ModelAPI_Result>(aRefObj));
+ }
+ if (aRefFeat.get() && aRefFeat == theThis) {
+ return false; // other references to this, so this later than other
+ }
+ }
+ }
+ }
+ return myObjs->isLater(theThis, theOther);
+}
+
int Model_Document::numberOfNameInHistory(
const ObjectPtr& theNameObject, const TDF_Label& theStartFrom)
{
// 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);
+ FeaturePtr aLabFeat = featureByLab(*aLabIter);
if (!aLabFeat.get())
continue;
- if (aLabFeat == aStart || myObjs->isLater(aStart, aLabFeat))
+ if (isLaterByDep(aStart, aLabFeat)) // skip also start: its result don't used
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);
+ FeaturePtr aLabFeat = featureByLab(*aLabIter);
if (!aLabFeat.get())
continue;
- if (aLabFeat == aNameFeature || myObjs->isLater(aNameFeature, aLabFeat))
+ if (aLabFeat == aNameFeature || isLaterByDep(aNameFeature, aLabFeat))
return aResIndex;
aResIndex++;
}
return aResIndex; // strange
}
-ResultPtr Model_Document::findByName(std::string& theName, std::string& theSubShapeName)
+ResultPtr Model_Document::findByName(
+ std::string& theName, std::string& theSubShapeName, bool& theUniqueContext)
{
int aNumInHistory = 0;
std::string aName = theName;
ResultPtr aRes = myObjs->findByName(aName);
+ theUniqueContext = !(aRes.get() && myNamingNames.find(aName) != myNamingNames.end());
while(!aRes.get() && aName[0] == '_') { // this may be thecontext with the history index
aNumInHistory++;
aName = aName.substr(1);
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(std::string& theName, std::string& theSubShapeName);
+ ResultPtr findByName(std::string& theName, std::string& theSubShapeName, bool& theUniqueContext);
///! 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.
/// Label that constains structures for selection of constructions of another document
TDF_Label extConstructionsLabel() const;
+ /// searches in this document feature that contains this label
+ FeaturePtr featureByLab(const TDF_Label& theLab);
+
+ /// returns true if theThis is later in the features trre and dependencies than theOther
+ bool isLaterByDep(FeaturePtr theThis, FeaturePtr theOther);
+
friend class Model_Application;
friend class Model_Session;
friend class Model_Update;
ResultPtr Model_Objects::findByName(const std::string theName)
{
+ ResultPtr aResult;
+ FeaturePtr aResFeature; // keep feature to return the latest one
NCollection_DataMap<TDF_Label, FeaturePtr>::Iterator anObjIter(myFeatures);
for(; anObjIter.More(); anObjIter.Next()) {
FeaturePtr& aFeature = anObjIter.ChangeValue();
for (; aRIter != allResults.cend(); aRIter++) {
ResultPtr aRes = *aRIter;
if (aRes.get() && aRes->data() && aRes->data()->isValid() && !aRes->isDisabled() &&
- aRes->data()->name() == theName) {
- return aRes;
+ aRes->data()->name() == theName)
+ {
+ if (!aResult.get() || isLater(aFeature, aResFeature)) { // select the latest
+ aResult = aRes;
+ aResFeature = aFeature;
+ }
}
}
}
- // not found
- return ResultPtr();
+ return aResult;
}
FeaturePtr Model_Objects::nextFeature(FeaturePtr theCurrent, const bool theReverse)
const TopoDS_Shape findFaceByName(
const std::string& theSubShapeName, std::shared_ptr<Model_Document> theDoc,
- const ResultPtr theDetectedContext)
+ const ResultPtr theDetectedContext, bool theContextIsUnique)
{
TopoDS_Shape aFace;
std::string aSubString = theSubShapeName;
- TDF_Label aLabel = theDoc->findNamingName(aSubString, theDetectedContext);
+ static const ResultPtr anEmpty;
+ TDF_Label aLabel = theDoc->findNamingName(aSubString,
+ theContextIsUnique ? theDetectedContext : anEmpty);
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, theDetectedContext);
+ aLabel = theDoc->findNamingName(aSubString,
+ theContextIsUnique ? theDetectedContext : anEmpty);
}
}
if(aLabel.IsNull()) return aFace;
std::string aContName = getContextName(aSubShapeName);
if(aContName.empty()) return false;
- ResultPtr aCont = aDoc->findByName(aContName, aSubShapeName);
+ bool anUniqueContext = false;
+ ResultPtr aCont = aDoc->findByName(aContName, aSubShapeName, anUniqueContext);
// 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
size_t aPostIndex = aContName.rfind('_');
if (aPostIndex != std::string::npos) {
std::string anEmpty, aSubContName = aContName.substr(0, aPostIndex);
- ResultPtr aSubCont = aDoc->findByName(aSubContName, anEmpty);
+ ResultPtr aSubCont = aDoc->findByName(aSubContName, anEmpty, anUniqueContext);
if (aSubCont.get()) {
try {
std::string aNum = aContName.substr(aPostIndex + 1);
}
+ static const ResultPtr anEmpty;
TopoDS_Shape aSelection;
switch (aType)
{
case TopAbs_FACE:
case TopAbs_WIRE:
{
- aSelection = findFaceByName(aSubShapeName, aDoc, aCont);
+ aSelection = findFaceByName(aSubShapeName, aDoc, aCont, anUniqueContext);
}
break;
case TopAbs_EDGE:
{
- const TDF_Label& aLabel = aDoc->findNamingName(aSubShapeName, aCont);
+ const TDF_Label& aLabel =
+ aDoc->findNamingName(aSubShapeName, anUniqueContext ? aCont : anEmpty);
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, aCont);
+ const TDF_Label& aLabel =
+ aDoc->findNamingName(aSubShapeName, anUniqueContext ? aCont : anEmpty);
if(!aLabel.IsNull()) {
Handle(TNaming_NamedShape) aNS;
if(aLabel.FindAttribute(TNaming_NamedShape::GetID(), aNS)) {
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);
+ aFaceContext = aDoc->findByName(aContName, *it, anUniqueContext);
}
}
- const TopoDS_Shape aFace = findFaceByName(*it, aDoc, aFaceContext);
+ const TopoDS_Shape aFace = findFaceByName(*it, aDoc, aFaceContext, anUniqueContext);
if(!aFace.IsNull())
aList.Append(aFace);
}
size_t aConstrNamePos = aSubShapeName.find("/");
bool isFullName = aConstrNamePos == std::string::npos;
std::string anEmpty, aContrName = aContName;
- ResultPtr aConstr = aDoc->findByName(aContrName, anEmpty);
+ ResultPtr aConstr = aDoc->findByName(aContrName, anEmpty, anUniqueContext);
if (aConstr.get() && aConstr->groupName() == ModelAPI_ResultConstruction::group()) {
theCont = aConstr;
if (isFullName) {
#=========================================================================
# Make a cylindrical hole using one of the produced faces
#=========================================================================
-ExtrusionCut_2 = model.addExtrusionCut(Part_1_doc, [], model.selection(), model.selection(), 0, model.selection("FACE", "__Extrusion_1_1/Generated_Face_2"), 0, [model.selection("SOLID", "Extrusion_1_1")])
+ExtrusionCut_2 = model.addExtrusionCut(Part_1_doc, [], model.selection(), model.selection(), 0, model.selection("FACE", "_Extrusion_1_1/Generated_Face_2"), 0, [model.selection("SOLID", "Extrusion_1_1")])
Sketch_3 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_1_1/Modfied_4"))
SketchCircle_1 = Sketch_3.addCircle(143.412751420315, -228.52745656314, 32.158435160764)
ExtrusionCut_2.setNestedSketch(Sketch_3)
assert(ModelAPI.ModelAPI_Session.get().validators().validate(Sketch_4.feature()))
assert(ModelAPI.ModelAPI_Session.get().validators().validate(ExtrusionCut_2.feature()))
-assert(Sketch_3.feature().selection("External").namingName() == "ExtrusionCut_3_1/Modfied_6")
+assert(Sketch_3.feature().selection("External").namingName() == "Extrusion_1_1/Modfied_6")
assert(model.checkPythonDump())
# Shells
Shell_1 = model.addShell(Part_1_doc, [model.selection("FACE", "Face_10_1"), model.selection("FACE", "Face_11_1")])
+Shell_1.result().setName("Shell_1_1")
Shell_2 = model.addShell(Part_1_doc, [model.selection("FACE", "Face_10_1"), model.selection("FACE", "Face_11_1")])
+Shell_2.result().setName("Shell_2_1")
Shell_3 = model.addShell(Part_1_doc, [model.selection("FACE", "Face_10_1"), model.selection("FACE", "Face_11_1")])
+Shell_3.result().setName("Shell_3_1")
Shell_4 = model.addShell(Part_1_doc, [model.selection("FACE", "Face_10_1"), model.selection("FACE", "Face_11_1")])
+Shell_4.result().setName("Shell_4_1")
Shell_5 = model.addShell(Part_1_doc, [model.selection("FACE", "Face_10_1"), model.selection("FACE", "Face_11_1")])
+Shell_5.result().setName("Shell_5_1")
Shell_6 = model.addShell(Part_1_doc, [model.selection("FACE", "Face_12_1"), model.selection("FACE", "Face_13_1")])
+Shell_6.result().setName("Shell_6_1")
Shell_7 = model.addShell(Part_1_doc, [model.selection("FACE", "Face_12_1"), model.selection("FACE", "Face_13_1")])
+Shell_7.result().setName("Shell_7_1")
Shell_8 = model.addShell(Part_1_doc, [model.selection("FACE", "Face_10_1"), model.selection("FACE", "Face_11_1")])
+Shell_8.result().setName("Shell_8_1")
Shell_9 = model.addShell(Part_1_doc, [model.selection("FACE", "Face_10_1"), model.selection("FACE", "Face_11_1")])
+Shell_9.result().setName("Shell_9_1")
# Parameters
model.addParameter(Part_1_doc, "d", "15")