From 4c3187cc7421ac8e0ce165992a633f67e9eee5c2 Mon Sep 17 00:00:00 2001 From: mpv Date: Fri, 2 Nov 2018 11:31:05 +0300 Subject: [PATCH] Support of PartSet sketch selection from Part (naming in two documents), make recover "Modify" object, not Primitive, some unit-tests correction. --- src/CollectionPlugin/Test/TestField.py | 10 +- src/CollectionPlugin/Test/TestGroup.py | 27 +-- src/FeaturesPlugin/FeaturesPlugin_Recover.cpp | 19 +- src/Model/Model_AttributeSelection.cpp | 226 ++++-------------- src/Model/Model_BodyBuilder.cpp | 21 +- src/Model/Model_Document.h | 1 + src/ModelAPI/Test/Test1064.py | 8 +- src/ModelAPI/Test/Test1757.py | 4 +- src/ModelAPI/Test/Test2241.py | 2 +- src/ModelAPI/Test/Test2396.py | 1 + src/ModelAPI/Test/TestWeakNaming2222.py | 20 +- src/Selector/Selector_Selector.cpp | 124 +++++++--- src/Selector/Selector_Selector.h | 9 +- 13 files changed, 193 insertions(+), 279 deletions(-) diff --git a/src/CollectionPlugin/Test/TestField.py b/src/CollectionPlugin/Test/TestField.py index 3fc6ade66..e6cdc133b 100644 --- a/src/CollectionPlugin/Test/TestField.py +++ b/src/CollectionPlugin/Test/TestField.py @@ -73,16 +73,10 @@ aLineCEndPoint.setValue(-100., 0.) aSession.finishOperation() # Build sketch faces aSession.startOperation() -aSketchResult = aTriangleSketchFeature.firstResult() -aSketchEdges = modelAPI_ResultConstruction(aSketchResult).shape() -origin = geomDataAPI_Point(aTriangleSketchFeature.attribute("Origin")).pnt() -dirX = geomDataAPI_Dir(aTriangleSketchFeature.attribute("DirX")).dir() -norm = geomDataAPI_Dir(aTriangleSketchFeature.attribute("Norm")).dir() -aSketchFaces = ShapeList() -GeomAlgoAPI_SketchBuilder.createFaces(origin, dirX, norm, aSketchEdges, aSketchFaces) +aSketchResult = modelAPI_ResultConstruction(aTriangleSketchFeature.firstResult()) # Create extrusion on them anExtrusionFt = aPart.addFeature("Extrusion") -anExtrusionFt.selectionList("base").append(aSketchResult, aSketchFaces[0]) +anExtrusionFt.selectionList("base").append(aSketchResult, aSketchResult.face(0)) anExtrusionFt.string("CreationMethod").setValue("BySizes") anExtrusionFt.real("to_size").setValue(50) anExtrusionFt.real("from_size").setValue(50) diff --git a/src/CollectionPlugin/Test/TestGroup.py b/src/CollectionPlugin/Test/TestGroup.py index 0ecbd0ddc..2892bbabd 100644 --- a/src/CollectionPlugin/Test/TestGroup.py +++ b/src/CollectionPlugin/Test/TestGroup.py @@ -73,21 +73,13 @@ aLineCEndPoint.setValue(-100., 0.) aSession.finishOperation() # Build sketch faces aSession.startOperation() -aSketchResult = aTriangleSketchFeature.firstResult() -aSketchEdges = modelAPI_ResultConstruction(aSketchResult).shape() -origin = geomDataAPI_Point(aTriangleSketchFeature.attribute("Origin")).pnt() -dirX = geomDataAPI_Dir(aTriangleSketchFeature.attribute("DirX")).dir() -norm = geomDataAPI_Dir(aTriangleSketchFeature.attribute("Norm")).dir() -aSketchFaces = ShapeList() -GeomAlgoAPI_SketchBuilder.createFaces(origin, dirX, norm, aSketchEdges, aSketchFaces) +aSketchResult = modelAPI_ResultConstruction(aTriangleSketchFeature.firstResult()) # Create extrusion on them anExtrusionFt = aPart.addFeature("Extrusion") -anExtrusionFt.selectionList("base").append(aSketchResult, aSketchFaces[0]) +anExtrusionFt.selectionList("base").append(aSketchResult, aSketchResult.face(0)) anExtrusionFt.string("CreationMethod").setValue("BySizes") anExtrusionFt.real("to_size").setValue(50) anExtrusionFt.real("from_size").setValue(50) -anExtrusionFt.real("to_offset").setValue(0) #TODO: remove -anExtrusionFt.real("from_offset").setValue(0) #TODO: remove anExtrusionFt.execute() aSession.finishOperation() anExtrusionBody = modelAPI_ResultBody(anExtrusionFt.firstResult()) @@ -206,26 +198,17 @@ aSession.finishOperation() # Make extrusion on circle #========================================================================= # Build shape from sketcher results -aCircleSketchResult = aCircleSketchFeature.firstResult() -aCircleSketchEdges = modelAPI_ResultConstruction(aCircleSketchResult).shape() -origin = geomDataAPI_Point(aCircleSketchFeature.attribute("Origin")).pnt() -dirX = geomDataAPI_Dir(aCircleSketchFeature.attribute("DirX")).dir() -norm = geomDataAPI_Dir(aCircleSketchFeature.attribute("Norm")).dir() -aCircleSketchFaces = ShapeList() -GeomAlgoAPI_SketchBuilder.createFaces(origin, dirX, norm, aCircleSketchEdges, aCircleSketchFaces) -assert(len(aCircleSketchFaces) > 0) -assert(aCircleSketchFaces[0] is not None) +aCircleSketchResult = modelAPI_ResultConstruction(aCircleSketchFeature.firstResult()) +assert(aCircleSketchResult.numFaces() > 0) # Create extrusion aSession.startOperation() anExtrusionFt = aPart.addFeature("Extrusion") assert (anExtrusionFt.getKind() == "Extrusion") # selection type FACE=4 -anExtrusionFt.selectionList("base").append(aCircleSketchResult, aCircleSketchFaces[0]) +anExtrusionFt.selectionList("base").append(aCircleSketchResult, aCircleSketchResult.face(0)) anExtrusionFt.string("CreationMethod").setValue("BySizes") anExtrusionFt.real("to_size").setValue(50) anExtrusionFt.real("from_size").setValue(50) -anExtrusionFt.real("to_offset").setValue(0) #TODO: remove -anExtrusionFt.real("from_offset").setValue(0) #TODO: remove anExtrusionFt.execute() aSession.finishOperation() aCylinderBody = modelAPI_ResultBody(anExtrusionFt.firstResult()) diff --git a/src/FeaturesPlugin/FeaturesPlugin_Recover.cpp b/src/FeaturesPlugin/FeaturesPlugin_Recover.cpp index ba575fbea..f4c92fee8 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Recover.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_Recover.cpp @@ -59,31 +59,30 @@ void FeaturesPlugin_Recover::execute() continue; // Copy shape. - GeomAlgoAPI_Copy aCopyAlgo(aShape); + std::shared_ptr aCopyAlgo(new GeomAlgoAPI_Copy(aShape)); // Check that algo is done. - if(!aCopyAlgo.isDone()) { + if(!aCopyAlgo->isDone()) { setError("Error: recover algorithm failed."); return; } // Check if shape is not null. - if(!aCopyAlgo.shape().get() || aCopyAlgo.shape()->isNull()) { + if(!aCopyAlgo->shape().get() || aCopyAlgo->shape()->isNull()) { setError("Error: resulting shape is null."); return; } // Check that resulting shape is valid. - if(!aCopyAlgo.isValid()) { + if(!aCopyAlgo->isValid()) { setError("Error: resulting shape is not valid."); return; } // Store result. ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex); - aResultBody->store(aCopyAlgo.shape());//, aCopyAlgo.shape()); - std::shared_ptr aSubShapes = aCopyAlgo.mapOfSubShapes(); - // like in import: forget any history - int aTag(1); - std::string aNameMS = "Shape"; - aResultBody->loadFirstLevel(aCopyAlgo.shape(), aNameMS); + aResultBody->store(aCopyAlgo->shape());//, aCopyAlgo.shape()); + + aResultBody->loadModifiedShapes(aCopyAlgo, aShape, GeomAPI_Shape::VERTEX); + aResultBody->loadModifiedShapes(aCopyAlgo, aShape, GeomAPI_Shape::EDGE); + aResultBody->loadModifiedShapes(aCopyAlgo, aShape, GeomAPI_Shape::FACE); setResult(aResultBody, aResultIndex); ++aResultIndex; diff --git a/src/Model/Model_AttributeSelection.cpp b/src/Model/Model_AttributeSelection.cpp index 434376735..15f95f6df 100644 --- a/src/Model/Model_AttributeSelection.cpp +++ b/src/Model/Model_AttributeSelection.cpp @@ -90,14 +90,6 @@ Standard_GUID kCIRCLE_CENTER("d0d0e0f1-217a-4b95-8fbb-0c4132f23718"); Standard_GUID kELLIPSE_CENTER1("f70df04c-3168-4dc9-87a4-f1f840c1275d"); // identifier of the selection of the second focus point of ellipse on edge Standard_GUID kELLIPSE_CENTER2("1395ae73-8e02-4cf8-b204-06ff35873a32"); -// reference to the external sketch face -Standard_GUID kEXT_SKETCH_FACE("ba32aa31-bde7-422f-80b4-79c757c77b49"); -// reference to the external sketch wire -Standard_GUID kEXT_SKETCH_WIRE("ba32aa31-bde7-422f-80b4-79c757c77b46"); -// reference to the external sketch edge -Standard_GUID kEXT_SKETCH_EDGE("ba32aa31-bde7-422f-80b4-79c757c77b48"); -// reference to the external sketch vertex -Standard_GUID kEXT_SKETCH_VERT("ba32aa31-bde7-422f-80b4-79c757c77b47"); // prefix for the whole feature context identification const static std::string kWHOLE_FEATURE = "all-in-"; @@ -144,10 +136,6 @@ bool Model_AttributeSelection::setValue(const ObjectPtr& theContext, aSelLab.ForgetAttribute(kCIRCLE_CENTER); aSelLab.ForgetAttribute(kELLIPSE_CENTER1); aSelLab.ForgetAttribute(kELLIPSE_CENTER2); - aSelLab.ForgetAttribute(kEXT_SKETCH_FACE); - aSelLab.ForgetAttribute(kEXT_SKETCH_WIRE); - aSelLab.ForgetAttribute(kEXT_SKETCH_EDGE); - aSelLab.ForgetAttribute(kEXT_SKETCH_VERT); bool isDegeneratedEdge = false; // do not use the degenerated edge as a shape, a null context and shape is used in the case @@ -388,53 +376,6 @@ std::shared_ptr Model_AttributeSelection::internalValue(CenterTyp if (aConstr) { if (aConstr->isInfinite()) return aResult; // empty result - // external sketch face - Handle(TDataStd_Integer) anIndex; - if (aSelLab.FindAttribute(kEXT_SKETCH_FACE, anIndex)) { - return aConstr->face(anIndex->Get()); - } - if (aSelLab.FindAttribute(kEXT_SKETCH_WIRE, anIndex)) { - GeomShapePtr aFace = aConstr->face(anIndex->Get()); - if (aFace.get()) { - GeomAPI_ShapeExplorer aFaceExp(aFace, GeomAPI_Shape::WIRE); - if (aFaceExp.more()) { - return aFaceExp.current(); - } - } - } - if (aSelLab.FindAttribute(kEXT_SKETCH_EDGE, anIndex) || - aSelLab.FindAttribute(kEXT_SKETCH_VERT, anIndex)) { - bool isVert = anIndex->ID() == kEXT_SKETCH_VERT; // vertex is selected - CompositeFeaturePtr aComposite = std::dynamic_pointer_cast( - aConstr->document()->feature(aConstr)); - if (aComposite.get()) { - int aSubNum = anIndex->Get() % 1000000; - int aVertShape = (anIndex->Get() - aSubNum) / 1000000; - FeaturePtr aSubFeat = aComposite->subFeature(aSubNum); - if (aSubFeat.get()) { - const std::list >& aResults = aSubFeat->results(); - std::list >::const_iterator aRes = aResults.cbegin(); - for (; aRes != aResults.cend(); aRes++) { - ResultConstructionPtr aConstr = - std::dynamic_pointer_cast(*aRes); - if (aConstr->shape()) { - if (!isVert && aConstr->shape()->isEdge()) - return aConstr->shape(); - else if (isVert && aVertShape == 0 && aConstr->shape()->isVertex()) - return aConstr->shape(); - else if (isVert && aVertShape > 1 && aConstr->shape()->isEdge()) { - GeomAPI_ShapeExplorer anExp(aConstr->shape(), GeomAPI_Shape::VERTEX); - for(; anExp.more(); anExp.next()) { - if (aVertShape == 1) - return anExp.current(); - aVertShape--; - } - } - } - } - } - } - } } if (!aConstr.get()) { // for construction context, return empty result as usual even // the whole feature is selected @@ -643,6 +584,10 @@ bool Model_AttributeSelection::update() anOldShape = aNS->Get(); Selector_Selector aSelector(aSelLab); + if (ModelAPI_Session::get()->moduleDocument() != owner()->document()) { + aSelector.setBaseDocument(std::dynamic_pointer_cast + (ModelAPI_Session::get()->moduleDocument())->extConstructionsLabel()); + } if (aSelector.restore()) { // it is stored in old OCCT format, use TNaming_Selector TopoDS_Shape aContextShape = aContext->shape()->impl(); aResult = aSelector.solve(aContextShape); @@ -671,23 +616,12 @@ bool Model_AttributeSelection::update() std::shared_ptr aConstructionContext = std::dynamic_pointer_cast(aContext); if (!aConstructionContext->isInfinite()) { - // external sketch face - Handle(TDataStd_Integer) anIndex; - if (aSelLab.FindAttribute(kEXT_SKETCH_FACE, anIndex) || - aSelLab.FindAttribute(kEXT_SKETCH_WIRE, anIndex)) { - return setInvalidIfFalse(aSelLab, anIndex->Get() < aConstructionContext->facesNum()); - } - if (aSelLab.FindAttribute(kEXT_SKETCH_EDGE, anIndex) || - aSelLab.FindAttribute(kEXT_SKETCH_VERT, anIndex)) { - CompositeFeaturePtr aComposite = std::dynamic_pointer_cast( - aConstructionContext->document()->feature(aConstructionContext)); - if (aComposite.get()) { - FeaturePtr aSubFeat = aComposite->subFeature(anIndex->Get() % 1000000); - return setInvalidIfFalse(aSelLab, aSubFeat.get() != NULL); - } - return setInvalidIfFalse(aSelLab, false); // composite sub-feature is not found - } Selector_Selector aSelector(aSelLab); + if (ModelAPI_Session::get()->moduleDocument() != owner()->document()) { + aSelector.setBaseDocument(std::dynamic_pointer_cast + (ModelAPI_Session::get()->moduleDocument())->extConstructionsLabel()); + } + aResult = aSelector.restore(); TopoDS_Shape anOldShape = aSelector.value(); if (aResult) { @@ -728,88 +662,13 @@ void Model_AttributeSelection::selectBody( if (!aContext.IsNull()) { TDF_Label aSelLab = selectionLabel(); TopoDS_Shape aNewSub = theSubShape->impl(); - FeaturePtr aFeatureOwner = std::dynamic_pointer_cast(owner()); - if (aFeatureOwner->document() != theContext->document() && - theContext->groupName() == ModelAPI_ResultConstruction::group()) {// condition for parts - // reference to the sketch face - if (theSubShape->shapeType() == GeomAPI_Shape::FACE || - theSubShape->shapeType() == GeomAPI_Shape::WIRE) { // sketch face or sketch face wire - ResultConstructionPtr aConstr = - std::dynamic_pointer_cast(theContext); - int aFaceIndex = -1, aFacesNum = aConstr->facesNum(); - for(int a = 0; a < aFacesNum; a++) { - bool isEqual = false; - GeomShapePtr aFace = aConstr->face(a); - if (!aFace.get() || aFace->isNull()) - continue; - if (theSubShape->shapeType() == GeomAPI_Shape::FACE) { - isEqual = aFace->isEqual(theSubShape); - } else { - GeomAPI_ShapeExplorer anExp(aFace, GeomAPI_Shape::WIRE); - if (anExp.more()) - isEqual = anExp.current()->isEqual(theSubShape); - } - if (isEqual) { - aFaceIndex = a; - break; - } - } - if (aFaceIndex >= 0) { - TDataStd_Integer::Set(aSelLab, theSubShape->shapeType() == GeomAPI_Shape::FACE ? - kEXT_SKETCH_FACE : kEXT_SKETCH_WIRE, aFaceIndex); // store index of the face - return; - } - } else if (theSubShape->shapeType() == GeomAPI_Shape::EDGE ||// sketch result edge (full one) - theSubShape->shapeType() == GeomAPI_Shape::VERTEX) { // or start/end vertex - bool isVertex = theSubShape->shapeType() == GeomAPI_Shape::VERTEX; - CompositeFeaturePtr aComposite = std::dynamic_pointer_cast( - theContext->document()->feature(theContext)); - if (aComposite.get()) { // iterate edges of composite to find index of matched with value - int aSub, anEdgeIndex = -1, aSubNum = aComposite->numberOfSubs(); - int aVertIndex = -1, aVertShape = -1; // shape: 0 full, 1 start, 2 end - for(aSub = 0; aSub < aSubNum && anEdgeIndex == -1; aSub++) { - FeaturePtr aSubFeat = aComposite->subFeature(aSub); - const std::list >& aResults = aSubFeat->results(); - std::list >::const_iterator aRes = aResults.cbegin(); - for (; aRes != aResults.cend(); aRes++) { - ResultConstructionPtr aConstr = - std::dynamic_pointer_cast(*aRes); - if (aConstr->shape() && aConstr->shape()->isEdge()) { - if (isVertex) { - GeomAPI_ShapeExplorer aVertExp(aConstr->shape(), GeomAPI_Shape::VERTEX); - for(int aNum = 1; aVertExp.more(); aVertExp.next(), aNum++) { - if (aVertExp.current()->isSame(theSubShape) && aVertShape != 0) { - aVertIndex = aSub; - aVertShape = aNum; - } - } - } else { - if (aConstr->shape()->isSame(theSubShape)) { - anEdgeIndex = aSub; - break; - } - } - } else if (isVertex && aConstr->shape() && aConstr->shape()->isVertex()) { - if (aConstr->shape()->isSame(theSubShape)) { - aVertIndex = aSub; - aVertShape = 0; - } - } - } - } - if (anEdgeIndex >= 0) { - TDataStd_Integer::Set(aSelLab, kEXT_SKETCH_EDGE, anEdgeIndex); // store index of edge - return; - } else if (aVertIndex >= 0) { - aVertIndex += aVertShape * 1000000; // to store both integers: index and shape - TDataStd_Integer::Set(aSelLab, kEXT_SKETCH_VERT, aVertIndex); // store index of edge - return; - } - } - } - } + bool aSelectorOk = true; Selector_Selector aSel(aSelLab); + if (ModelAPI_Session::get()->moduleDocument() != owner()->document()) { + aSel.setBaseDocument(std::dynamic_pointer_cast + (ModelAPI_Session::get()->moduleDocument())->extConstructionsLabel()); + } try { aSelectorOk = aSel.select(aContext, aNewSub); if (aSelectorOk) { @@ -932,36 +791,17 @@ std::string Model_AttributeSelection::namingName(const std::string& theDefaultNa ResultConstructionPtr aConstr = std::dynamic_pointer_cast(aCont); if (aConstr->isInfinite()) { return contextName(aCont); - } else { - // external sketch face - Handle(TDataStd_Integer) anIndex; - if (aSelLab.FindAttribute(kEXT_SKETCH_FACE, anIndex) || - aSelLab.FindAttribute(kEXT_SKETCH_WIRE, anIndex) || - aSelLab.FindAttribute(kEXT_SKETCH_EDGE, anIndex) || - aSelLab.FindAttribute(kEXT_SKETCH_VERT, anIndex)) { - std::shared_ptr anExtDoc = - std::dynamic_pointer_cast(aCont->document()); - Selector_Selector aSelector(anExtDoc->extConstructionsLabel()); - TopoDS_Shape aContShape = aConstr->shape()->impl(); - TopoDS_Shape aValShape = value()->impl(); - aSelector.select(aContShape, aValShape); - myRestoreDocument = anExtDoc; - std::string aName = anExtDoc->kind() + "/" + aSelector.name(this); - myRestoreDocument.reset(); - return aName; - } } } Selector_Selector aSelector(aSelLab); + if (ModelAPI_Session::get()->moduleDocument() != owner()->document()) { + aSelector.setBaseDocument(std::dynamic_pointer_cast + (ModelAPI_Session::get()->moduleDocument())->extConstructionsLabel()); + } 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]; } @@ -1067,6 +907,10 @@ void Model_AttributeSelection::selectSubShape( } Selector_Selector aSelector(aDoc->generalLabel()); + if (ModelAPI_Session::get()->moduleDocument() != owner()->document()) { + aSelector.setBaseDocument(std::dynamic_pointer_cast + (ModelAPI_Session::get()->moduleDocument())->extConstructionsLabel()); + } myRestoreDocument = aDoc; TDF_Label aContextLabel = aSelector.restoreByName(aSubShapeName, aShapeType, this); myRestoreDocument.reset(); @@ -1612,6 +1456,12 @@ std::string Model_AttributeSelection::contextName(const TDF_Label theSelectionLa std::shared_ptr aDoc = myRestoreDocument.get() ? myRestoreDocument : std::dynamic_pointer_cast(owner()->document()); FeaturePtr aFeatureOwner = aDoc->featureByLab(theSelectionLab); + bool aBaseDocumnetUsed = false; + if (!aFeatureOwner.get()) { // use module document + aDoc = std::dynamic_pointer_cast(ModelAPI_Session::get()->moduleDocument()); + aFeatureOwner = aDoc->featureByLab(theSelectionLab); + aBaseDocumnetUsed = true; + } if (aFeatureOwner.get()) { // if it is sub-element of the sketch, the context name is the name of the sketch // searching also for result - real context @@ -1638,6 +1488,8 @@ std::string Model_AttributeSelection::contextName(const TDF_Label theSelectionLa aContextName = "_" + aContextName; aNumInHistoryNames--; } + if (aBaseDocumnetUsed) + aContextName = aDoc->kind() + "/" + aContextName; return aContextName; } } @@ -1664,8 +1516,22 @@ bool Model_AttributeSelection::restoreContext(std::string theName, if (aName.empty()) return false; bool anUniqueContext = false; ResultPtr aCont = aDoc->findByName(aName, aSubShapeName, anUniqueContext); - if (!aCont.get() || !aCont->shape().get() || aCont->shape()->isNull()) - return false; + if (!aCont.get() || !aCont->shape().get() || aCont->shape()->isNull()) { + // name in PartSet? + aDoc = std::dynamic_pointer_cast( + ModelAPI_Session::get()->moduleDocument()); + if (theName.find(aDoc->kind()) == 0) { // remove the document identifier from name if exists + aSubShapeName = theName.substr(aDoc->kind().size() + 1); + aName = aSubShapeName; + std::string::size_type n = aName.find('/'); + if (n != std::string::npos) { + aName = aName.substr(0, n); + } + } + aCont = aDoc->findByName(aName, aSubShapeName, anUniqueContext); + if (!aCont.get() || !aCont->shape().get() || aCont->shape()->isNull()) + return false; + } // searching the sub-shape static const ResultPtr anEmpty; diff --git a/src/Model/Model_BodyBuilder.cpp b/src/Model/Model_BodyBuilder.cpp index c751bcba9..9b05c442d 100755 --- a/src/Model/Model_BodyBuilder.cpp +++ b/src/Model/Model_BodyBuilder.cpp @@ -22,6 +22,7 @@ #include #include +#include #include #include #include @@ -466,7 +467,7 @@ static void keepTopLevelShapes(ListOfShape& theShapes, } } -// returns an ancestor shape-type thaty used for naming-definition of the sub-type +// returns an ancestor shape-type that used for naming-definition of the sub-type TopAbs_ShapeEnum typeOfAncestor(const TopAbs_ShapeEnum theSubType) { if (theSubType == TopAbs_VERTEX) return TopAbs_EDGE; @@ -502,8 +503,12 @@ void Model_BodyBuilder::loadModifiedShapes(const GeomMakeShapePtr& theAlgo, // There is no sense to write history if shape already processed // or old shape does not exist in the document. bool anOldSubShapeAlreadyProcessed = !anAlreadyProcessedShapes.Add(anOldSubShape_); - bool anOldSubShapeNotInTree = TNaming_Tool::NamedShape(anOldSubShape_, aData->shapeLab()) - .IsNull(); + bool anOldSubShapeNotInTree = !TNaming_Tool::HasLabel(aData->shapeLab(), anOldSubShape_); + if (anOldSubShapeNotInTree) {// check this is in the module document + TDF_Label anAccess = std::dynamic_pointer_cast( + ModelAPI_Session::get()->moduleDocument())->generalLabel(); + anOldSubShapeNotInTree = !TNaming_Tool::HasLabel(anAccess, anOldSubShape_); + } if (anOldSubShapeAlreadyProcessed || anOldSubShapeNotInTree) { @@ -586,8 +591,12 @@ void Model_BodyBuilder::loadGeneratedShapes(const GeomMakeShapePtr& theAlgo, // There is no sense to write history if shape already processed // or old shape does not exist in the document. bool anOldSubShapeAlreadyProcessed = !anAlreadyProcessedShapes.Add(anOldSubShape_); - bool anOldSubShapeNotInTree = TNaming_Tool::NamedShape(anOldSubShape_, aData->shapeLab()) - .IsNull(); + bool anOldSubShapeNotInTree = !TNaming_Tool::HasLabel(aData->shapeLab(), anOldSubShape_); + if (anOldSubShapeNotInTree) {// check this is in the module document + TDF_Label anAccess = std::dynamic_pointer_cast( + ModelAPI_Session::get()->moduleDocument())->generalLabel(); + anOldSubShapeNotInTree = !TNaming_Tool::HasLabel(anAccess, anOldSubShape_); + } if (anOldSubShapeAlreadyProcessed || anOldSubShapeNotInTree) { @@ -910,7 +919,7 @@ void Model_BodyBuilder::loadDisconnectedEdges(GeomShapePtr theShape, const std:: if(anEdgesToDelete.Contains(anEdge2)) continue; if (anEdge1.IsSame(anEdge2)) continue; const TopTools_ListOfShape& aList2 = itr.Value(); - // compare lists of the neighbour faces of edge1 and edge2 + // compare lists of the neighbor faces of edge1 and edge2 if (aList1.Extent() == aList2.Extent()) { Standard_Integer aMatches = 0; for(TopTools_ListIteratorOfListOfShape aLIter1(aList1);aLIter1.More();aLIter1.Next()) diff --git a/src/Model/Model_Document.h b/src/Model/Model_Document.h index 20626c1d7..670449242 100644 --- a/src/Model/Model_Document.h +++ b/src/Model/Model_Document.h @@ -401,6 +401,7 @@ class Model_Document : public ModelAPI_Document friend class Model_ResultBody; friend class Model_ResultConstruction; friend class Model_SelectionNaming; + friend class Model_BodyBuilder; friend class DFBrowser; private: diff --git a/src/ModelAPI/Test/Test1064.py b/src/ModelAPI/Test/Test1064.py index cae7ccd6b..39cd4f49b 100644 --- a/src/ModelAPI/Test/Test1064.py +++ b/src/ModelAPI/Test/Test1064.py @@ -71,14 +71,10 @@ aPart = aSession.activeDocument() #========================================================================= # Make extrusion on triangle #========================================================================= -aSketchResult = aSketchFeature.firstResult() -aSketchEdges = modelAPI_ResultConstruction(aSketchResult).shape() -aSketchFaces = ShapeList() -GeomAlgoAPI_SketchBuilder.createFaces( - origin.pnt(), dirx.dir(), norm.dir(), aSketchEdges, aSketchFaces) +aSketchResult = modelAPI_ResultConstruction(aSketchFeature.firstResult()) aSession.startOperation() anExtrusionFt = aPart.addFeature("Extrusion") -anExtrusionFt.selectionList("base").append(aSketchResult, aSketchFaces[0]) +anExtrusionFt.selectionList("base").append(aSketchResult, aSketchResult.face(0)) anExtrusionFt.string("CreationMethod").setValue("BySizes") anExtrusionFt.real("to_size").setValue(50) anExtrusionFt.real("from_size").setValue(0) diff --git a/src/ModelAPI/Test/Test1757.py b/src/ModelAPI/Test/Test1757.py index 31152fb18..4881b65ea 100644 --- a/src/ModelAPI/Test/Test1757.py +++ b/src/ModelAPI/Test/Test1757.py @@ -80,7 +80,7 @@ model.do() # 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&Sketch_1/SketchLine_3"), 0, [model.selection("SOLID", "ExtrusionCut_1_1")]) -Sketch_3 = model.addSketch(Part_1_doc, model.selection("FACE", "ExtrusionCut_1_1/Modified_Face&Sketch_1/SketchLine_1&weak_name_2")) +Sketch_3 = model.addSketch(Part_1_doc, model.selection("FACE", "(ExtrusionCut_1_1/Modified_Face&Extrusion_1_1/From_Face)(ExtrusionCut_1_1/Generated_Face&Sketch_2/SketchLine_6)(ExtrusionCut_1_1/Modified_Face&Extrusion_1_1/To_Face)(Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_4)")) SketchCircle_1 = Sketch_3.addCircle(143.412751420315, -228.52745656314, 32.158435160764) ExtrusionCut_2.setNestedSketch(Sketch_3) @@ -125,6 +125,6 @@ import ModelAPI 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/Modified_Face&Sketch_1/SketchLine_1&weak_name_3") +assert(Sketch_3.feature().selection("External").namingName() == "(ExtrusionCut_1_1/Modified_Face&Extrusion_1_1/From_Face)(ExtrusionCut_3_1/Modified_Face&Sketch_2/SketchLine_6)(ExtrusionCut_1_1/Modified_Face&Extrusion_1_1/To_Face)(Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_4)") assert(model.checkPythonDump()) diff --git a/src/ModelAPI/Test/Test2241.py b/src/ModelAPI/Test/Test2241.py index d03f1dbd8..521adb37f 100644 --- a/src/ModelAPI/Test/Test2241.py +++ b/src/ModelAPI/Test/Test2241.py @@ -135,7 +135,7 @@ Recover_2 = model.addRecover(Part_1_doc, LinearCopy_1, [Face_5.result()]) Translation_2 = model.addTranslation(Part_1_doc, [model.selection("FACE", "Recover_2_1")], model.selection("VERTEX", "[Face_4_1/Edge_6]e[Face_4_1/Edge_7]e"), model.selection("VERTEX", "[Face_4_1/Edge_2]e[Face_4_1/Edge_3]e")) LinearCopy_3 = model.addMultiTranslation(Part_1_doc, [model.selection("FACE", "Translation_2_1")], model.selection("EDGE", "PartSet/OX"), "l", 4) Recover_3 = model.addRecover(Part_1_doc, LinearCopy_1, [Face_5.result()]) -Translation_3 = model.addTranslation(Part_1_doc, [model.selection("FACE", "Recover_3_1")], model.selection("VERTEX", "[Face_4_1/Edge_6]e[Face_4_1/Edge_7]e"), model.selection("VERTEX", "[LinearCopy_3_1_1/ME:Translated_Edge&Recover_2_1/Shape_1]e[LinearCopy_3_1_1/ME:Translated_Edge&Recover_2_1/Shape_2]e")) +Translation_3 = model.addTranslation(Part_1_doc, [model.selection("FACE", "Recover_3_1")], model.selection("VERTEX", "[Face_4_1/Edge_6]e[Face_4_1/Edge_7]e"), model.selection("VERTEX", "[LinearCopy_3_1_1/ME:Translated_Edge&Face_5_1/Edge_1]e[LinearCopy_3_1_1/ME:Translated_Edge&Face_5_1/Edge_2]e")) LinearCopy_4 = model.addMultiTranslation(Part_1_doc, [model.selection("FACE", "Translation_3_1")], model.selection("EDGE", "PartSet/OX"), "l", 3) Recover_4 = model.addRecover(Part_1_doc, LinearCopy_1, [Face_5.result()]) Translation_4 = model.addTranslation(Part_1_doc, [model.selection("FACE", "Recover_4_1")], model.selection("VERTEX", "[Face_4_1/Edge_6]e[Face_4_1/Edge_7]e"), model.selection("VERTEX", "[Face_4_1/Edge_1]e[Face_4_1/Edge_9]e")) diff --git a/src/ModelAPI/Test/Test2396.py b/src/ModelAPI/Test/Test2396.py index 3c744fba1..cead3dfb7 100644 --- a/src/ModelAPI/Test/Test2396.py +++ b/src/ModelAPI/Test/Test2396.py @@ -21,6 +21,7 @@ # -*- coding: utf-8 -*- from salome.shaper import model +from GeomAPI import GeomAPI_Shape model.begin() partSet = model.moduleDocument() diff --git a/src/ModelAPI/Test/TestWeakNaming2222.py b/src/ModelAPI/Test/TestWeakNaming2222.py index 631d33561..9d76f132e 100644 --- a/src/ModelAPI/Test/TestWeakNaming2222.py +++ b/src/ModelAPI/Test/TestWeakNaming2222.py @@ -160,52 +160,52 @@ Edge_1_objects = [model.selection("EDGE", "Sketch_3/SketchLine_15"), model.selec Edge_1 = model.addEdge(Part_1_doc, Edge_1_objects) Extrusion_3_objects = [model.selection("EDGE", "Edge_1_1"), model.selection("EDGE", "Edge_1_2"), model.selection("EDGE", "Edge_1_3"), model.selection("EDGE", "Edge_1_4"), model.selection("EDGE", "Edge_1_5")] Extrusion_3 = model.addExtrusion(Part_1_doc, Extrusion_3_objects, model.selection("EDGE", "PartSet/OZ"), "h_ouverture", 0) -Plane_4 = model.addPlane(Part_1_doc, model.selection("VERTEX", "[Extrusion_3_1/Generated_Edge&Sketch_3/SketchLine_17_StartVertex]e[Extrusion_3_1/To_Edge]e"), model.selection("VERTEX", "[Extrusion_3_3/Generated_Edge&Sketch_3/SketchLine_20_StartVertex]e[Extrusion_3_3/To_Edge]e"), model.selection("VERTEX", "[Extrusion_3_4/Generated_Edge&Sketch_3/SketchLine_22_EndVertex]e[Extrusion_3_4/To_Edge]e")) +Plane_4 = model.addPlane(Part_1_doc, model.selection("VERTEX", "[Extrusion_3_1/Generated_Edge&Sketch_3/SketchLine_15_StartVertex]e[Extrusion_3_1/To_Edge]e"), model.selection("VERTEX", "[Extrusion_3_3/Generated_Edge&Sketch_3/SketchLine_18_StartVertex]e[Extrusion_3_3/To_Edge]e"), model.selection("VERTEX", "[Extrusion_3_4/Generated_Edge&Sketch_3/SketchLine_20_EndVertex]e[Extrusion_3_4/To_Edge]e")) Sketch_4 = model.addSketch(Part_1_doc, model.selection("FACE", "Plane_1")) SketchLine_27 = Sketch_4.addLine(0, 2.950000000000001, 0, 0) SketchLine_27.setName("SketchLine_26") SketchLine_27.result().setName("SketchLine_26") -SketchPoint_2 = Sketch_4.addPoint(model.selection("VERTEX", "[Extrusion_3_1/Generated_Edge&Sketch_3/SketchLine_17_StartVertex]e[Extrusion_3_1/To_Edge]e")) +SketchPoint_2 = Sketch_4.addPoint(model.selection("VERTEX", "[Extrusion_3_1/Generated_Edge&Sketch_3/SketchLine_15_StartVertex]e[Extrusion_3_1/To_Edge]e")) SketchConstraintCoincidence_22 = Sketch_4.setCoincident(SketchLine_27.startPoint(), SketchPoint_2.result()) -SketchPoint_3 = Sketch_4.addPoint(model.selection("VERTEX", "[Extrusion_3_3/Generated_Edge&Sketch_3/SketchLine_20_StartVertex]e[Extrusion_3_3/To_Edge]e")) +SketchPoint_3 = Sketch_4.addPoint(model.selection("VERTEX", "[Extrusion_3_3/Generated_Edge&Sketch_3/SketchLine_18_StartVertex]e[Extrusion_3_3/To_Edge]e")) SketchConstraintCoincidence_23 = Sketch_4.setCoincident(SketchLine_27.endPoint(), SketchPoint_3.result()) SketchLine_28 = Sketch_4.addLine(0, 0, 3.975000000000001, 0) SketchLine_28.setName("SketchLine_27") SketchLine_28.result().setName("SketchLine_27") SketchConstraintCoincidence_24 = Sketch_4.setCoincident(SketchLine_27.endPoint(), SketchLine_28.startPoint()) -SketchPoint_4 = Sketch_4.addPoint(model.selection("VERTEX", "[Extrusion_3_4/Generated_Edge&Sketch_3/SketchLine_22_EndVertex]e[Extrusion_3_4/To_Edge]e")) +SketchPoint_4 = Sketch_4.addPoint(model.selection("VERTEX", "[Extrusion_3_4/Generated_Edge&Sketch_3/SketchLine_20_EndVertex]e[Extrusion_3_4/To_Edge]e")) SketchConstraintCoincidence_25 = Sketch_4.setCoincident(SketchLine_28.endPoint(), SketchPoint_4.result()) SketchLine_29 = Sketch_4.addLine(3.975000000000001, 0, 3.975000000000001, 0.95) SketchLine_29.setName("SketchLine_28") SketchLine_29.result().setName("SketchLine_28") SketchConstraintCoincidence_26 = Sketch_4.setCoincident(SketchLine_28.endPoint(), SketchLine_29.startPoint()) -SketchPoint_5 = Sketch_4.addPoint(model.selection("VERTEX", "[Extrusion_3_5/Generated_Edge&Sketch_3/SketchLine_23_EndVertex]e[Extrusion_3_5/To_Edge]e")) +SketchPoint_5 = Sketch_4.addPoint(model.selection("VERTEX", "[Extrusion_3_5/Generated_Edge&Sketch_3/SketchLine_21_EndVertex]e[Extrusion_3_5/To_Edge]e")) SketchConstraintCoincidence_27 = Sketch_4.setCoincident(SketchLine_29.endPoint(), SketchPoint_5.result()) model.do() Edge_2_objects = [model.selection("EDGE", "Sketch_4/SketchLine_26"), model.selection("EDGE", "Sketch_4/SketchLine_27"), model.selection("EDGE", "Sketch_4/SketchLine_28")] Edge_2 = model.addEdge(Part_1_doc, Edge_2_objects) Extrusion_4_objects = [model.selection("EDGE", "Edge_2_1"), model.selection("EDGE", "Edge_2_2"), model.selection("EDGE", "Edge_2_3")] Extrusion_4 = model.addExtrusion(Part_1_doc, Extrusion_4_objects, model.selection("EDGE", "PartSet/OZ"), "h_apres_ouverture-ep_dalles/2", 0) -Plane_5 = model.addPlane(Part_1_doc, model.selection("VERTEX", "[Extrusion_4_1/Generated_Edge&Sketch_4/SketchLine_27_StartVertex]e[Extrusion_4_1/To_Edge]e"), model.selection("VERTEX", "[Extrusion_4_1/Generated_Edge&Sketch_4/SketchLine_27_EndVertex]e[Extrusion_4_1/To_Edge]e"), model.selection("VERTEX", "[Extrusion_4_2/Generated_Edge&Sketch_4/SketchLine_28_EndVertex]e[Extrusion_4_2/To_Edge]e")) +Plane_5 = model.addPlane(Part_1_doc, model.selection("VERTEX", "[Extrusion_4_1/Generated_Edge&Sketch_4/SketchLine_26_StartVertex]e[Extrusion_4_1/To_Edge]e"), model.selection("VERTEX", "[Extrusion_4_1/Generated_Edge&Sketch_4/SketchLine_26_EndVertex]e[Extrusion_4_1/To_Edge]e"), model.selection("VERTEX", "[Extrusion_4_2/Generated_Edge&Sketch_4/SketchLine_27_EndVertex]e[Extrusion_4_2/To_Edge]e")) Sketch_5 = model.addSketch(Part_1_doc, model.selection("FACE", "Plane_2")) SketchLine_30 = Sketch_5.addLine(0, 2.950000000000001, 0, 0) SketchLine_30.setName("SketchLine_29") SketchLine_30.result().setName("SketchLine_29") -SketchPoint_6 = Sketch_5.addPoint(model.selection("VERTEX", "[Extrusion_4_1/Generated_Edge&Sketch_4/SketchLine_27_StartVertex]e[Extrusion_4_1/To_Edge]e")) +SketchPoint_6 = Sketch_5.addPoint(model.selection("VERTEX", "[Extrusion_4_1/Generated_Edge&Sketch_4/SketchLine_26_StartVertex]e[Extrusion_4_1/To_Edge]e")) SketchConstraintCoincidence_28 = Sketch_5.setCoincident(SketchLine_30.startPoint(), SketchPoint_6.result()) -SketchPoint_7 = Sketch_5.addPoint(model.selection("VERTEX", "[Extrusion_4_1/Generated_Edge&Sketch_4/SketchLine_27_EndVertex]e[Extrusion_4_1/To_Edge]e")) +SketchPoint_7 = Sketch_5.addPoint(model.selection("VERTEX", "[Extrusion_4_1/Generated_Edge&Sketch_4/SketchLine_26_EndVertex]e[Extrusion_4_1/To_Edge]e")) SketchConstraintCoincidence_29 = Sketch_5.setCoincident(SketchLine_30.endPoint(), SketchPoint_7.result()) SketchLine_31 = Sketch_5.addLine(0, 0, 3.975000000000001, 0) SketchLine_31.setName("SketchLine_30") SketchLine_31.result().setName("SketchLine_30") SketchConstraintCoincidence_30 = Sketch_5.setCoincident(SketchLine_30.endPoint(), SketchLine_31.startPoint()) -SketchPoint_8 = Sketch_5.addPoint(model.selection("VERTEX", "[Extrusion_4_2/Generated_Edge&Sketch_4/SketchLine_28_EndVertex]e[Extrusion_4_2/To_Edge]e")) +SketchPoint_8 = Sketch_5.addPoint(model.selection("VERTEX", "[Extrusion_4_2/Generated_Edge&Sketch_4/SketchLine_27_EndVertex]e[Extrusion_4_2/To_Edge]e")) SketchConstraintCoincidence_31 = Sketch_5.setCoincident(SketchLine_31.endPoint(), SketchPoint_8.result()) SketchLine_32 = Sketch_5.addLine(3.975000000000001, 0, 3.975000000000001, 0.95) SketchLine_32.setName("SketchLine_31") SketchLine_32.result().setName("SketchLine_31") SketchConstraintCoincidence_32 = Sketch_5.setCoincident(SketchLine_31.endPoint(), SketchLine_32.startPoint()) -SketchPoint_9 = Sketch_5.addPoint(model.selection("VERTEX", "[Extrusion_4_3/Generated_Edge&Sketch_4/SketchLine_29_EndVertex]e[Extrusion_4_3/To_Edge]e")) +SketchPoint_9 = Sketch_5.addPoint(model.selection("VERTEX", "[Extrusion_4_3/Generated_Edge&Sketch_4/SketchLine_28_EndVertex]e[Extrusion_4_3/To_Edge]e")) SketchConstraintCoincidence_33 = Sketch_5.setCoincident(SketchLine_32.endPoint(), SketchPoint_9.result()) SketchLine_33 = Sketch_5.addLine(3.975000000000001, 0.95, 0, 2.950000000000001) SketchLine_33.setName("SketchLine_32") diff --git a/src/Selector/Selector_Selector.cpp b/src/Selector/Selector_Selector.cpp index 11cfbf25f..752b9b97a 100644 --- a/src/Selector/Selector_Selector.cpp +++ b/src/Selector/Selector_Selector.cpp @@ -66,11 +66,18 @@ TDF_Label Selector_Selector::label() return myLab; } +void Selector_Selector::setBaseDocument(const TDF_Label theAccess) +{ + myBaseDocumentLab = theAccess; +} + // adds to theResult all labels that contain initial shapes for theValue located in theFinal -static void findBases(Handle(TNaming_NamedShape) theFinal, const TopoDS_Shape& theValue, - bool aMustBeAtFinal, TDF_LabelList& theResult) +static void findBases(TDF_Label theAccess, Handle(TNaming_NamedShape) theFinal, + const TopoDS_Shape& theValue, + bool aMustBeAtFinal, const TDF_Label& theAdditionalDocument, TDF_LabelList& theResult) { - TNaming_SameShapeIterator aLabIter(theValue, theFinal->Label()); + 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)) { @@ -87,17 +94,26 @@ static void findBases(Handle(TNaming_NamedShape) theFinal, const TopoDS_Shape& t } 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(theFinal, aThisIter.OldShape(), false, theResult); + findBases(theAccess, theFinal, aThisIter.OldShape(), + false, theAdditionalDocument, theResult); + aFoundAnyShape = true; } } } } } + if (!aFoundAnyShape && !theAdditionalDocument.IsNull()) { // try to find in additional document + static TDF_Label anEmpty; + if (TNaming_Tool::HasLabel(theAdditionalDocument, theValue)) + findBases(theAdditionalDocument, Handle(TNaming_NamedShape)(), theValue, + false, anEmpty, theResult); + } } // returns the sub-shapes of theSubType which belong to all theShapes (so, common or intersection) @@ -269,6 +285,23 @@ bool Selector_Selector::select(const TopoDS_Shape theContext, const TopoDS_Shape } } } + // searching in the base document + if (!aIsFound && !myBaseDocumentLab.IsNull() && + TNaming_Tool::HasLabel(myBaseDocumentLab, theValue)) + { + TNaming_SameShapeIterator aShapes(theValue, myBaseDocumentLab); + for(; aShapes.More(); aShapes.Next()) + { + Handle(TNaming_NamedShape) aNS; + if (aShapes.Label().FindAttribute(TNaming_NamedShape::GetID(), aNS)) { + if (aNS->Evolution() == TNaming_MODIFY || aNS->Evolution() == TNaming_GENERATED || + aNS->Evolution() == TNaming_PRIMITIVE) { + aIsFound = true; + break; + } + } + } + } if (!aIsFound) { TopAbs_ShapeEnum aSelectionType = theValue.ShapeType(); myShapeType = aSelectionType; @@ -352,6 +385,7 @@ bool Selector_Selector::select(const TopoDS_Shape theContext, const TopoDS_Shape TopoDS_Shape aNewNBShape = anOrder.Current(); // check which can be named correctly, without "by neighbors" type Selector_Selector aSelector(myLab.FindChild(1)); + aSelector.setBaseDocument(myBaseDocumentLab); if (aSelector.select(theContext, aNewNBShape, false, false)) { // add to list of good NBs aNBs.push_back(std::pair(aNewNBShape, aLevel)); } @@ -430,22 +464,27 @@ bool Selector_Selector::select(const TopoDS_Shape theContext, const TopoDS_Shape // searching for the base shapes of the value Handle(TNaming_NamedShape) aPrimitiveNS; NCollection_List aModifList; - for(TNaming_SameShapeIterator aShapes(theValue, myLab); aShapes.More(); aShapes.Next()) - { - Handle(TNaming_NamedShape) aNS; - if (aShapes.Label().FindAttribute(TNaming_NamedShape::GetID(), aNS)) { - TNaming_Evolution anEvolution = aNS->Evolution(); - if (anEvolution == TNaming_PRIMITIVE) { // the value shape is declared as PRIMITIVE - aPrimitiveNS = aNS; - break; - } else if (anEvolution == TNaming_GENERATED || anEvolution == TNaming_MODIFY) { - // check this is a new shape - TNaming_Iterator aNSIter(aNS); - for(; aNSIter.More(); aNSIter.Next()) - if (aNSIter.NewShape().IsSame(theValue)) - break; - if (aNSIter.More()) // new was found - aModifList.Append(aNS); + for(int aUseExternal = 0; aUseExternal < 2; aUseExternal++) { + TDF_Label aLab = aUseExternal == 0 ? myLab : myBaseDocumentLab; + if (aLab.IsNull() || !TNaming_Tool::HasLabel(aLab, theValue)) + continue; + for(TNaming_SameShapeIterator aShapes(theValue, aLab); aShapes.More(); aShapes.Next()) + { + Handle(TNaming_NamedShape) aNS; + if (aShapes.Label().FindAttribute(TNaming_NamedShape::GetID(), aNS)) { + TNaming_Evolution anEvolution = aNS->Evolution(); + if (anEvolution == TNaming_PRIMITIVE) { // the value shape is declared as PRIMITIVE + aPrimitiveNS = aNS; + break; + } else if (anEvolution == TNaming_GENERATED || anEvolution == TNaming_MODIFY) { + // check this is a new shape + TNaming_Iterator aNSIter(aNS); + for(; aNSIter.More(); aNSIter.Next()) + if (aNSIter.NewShape().IsSame(theValue)) + break; + if (aNSIter.More()) // new was found + aModifList.Append(aNS); + } } } } @@ -479,7 +518,7 @@ bool Selector_Selector::select(const TopoDS_Shape theContext, const TopoDS_Shape if (!aModifList.IsEmpty()) { // searching for all the base shapes of this modification - findBases(aModifList.First(), theValue, true, myBases); + findBases(myLab, aModifList.First(), theValue, true, myBaseDocumentLab, myBases); if (!myBases.IsEmpty()) { myFinal = aModifList.First()->Label(); TopoDS_ListOfShape aCommon; @@ -504,6 +543,8 @@ bool Selector_Selector::select(const TopoDS_Shape theContext, const TopoDS_Shape TopoDS_Shape aNewNBShape = anOrder.Current(); // check which can be named correctly, without "by neighbors" type Selector_Selector aSelector(myLab.FindChild(1)); + if (!myBaseDocumentLab.IsNull()) + aSelector.setBaseDocument(myBaseDocumentLab); if (aSelector.select(theContext, aNewNBShape, false)) {// add to list of good NBs aNBs.push_back(std::pair(aNewNBShape, aLevel)); } @@ -645,6 +686,7 @@ bool Selector_Selector::restore() mySubSelList.clear(); for(TDF_ChildIDIterator aSub(myLab, kSEL_TYPE, false); aSub.More(); aSub.Next()) { mySubSelList.push_back(Selector_Selector(aSub.Value()->Label())); + mySubSelList.back().setBaseDocument(myBaseDocumentLab); if (!mySubSelList.back().restore()) aSubResult = false; } @@ -688,6 +730,7 @@ bool Selector_Selector::restore() mySubSelList.clear(); for(TDF_ChildIDIterator aSub(myLab, kSEL_TYPE, false); aSub.More(); aSub.Next()) { mySubSelList.push_back(Selector_Selector(aSub.Value()->Label())); + mySubSelList.back().setBaseDocument(myBaseDocumentLab); if (!mySubSelList.back().restore()) aSubResult = false; } @@ -722,26 +765,39 @@ bool Selector_Selector::restore() } /// Returns in theResults all shapes with history started in theBase and ended in theFinal -static void findFinals(const TopoDS_Shape& theBase, const TDF_Label& theFinal, - TopTools_MapOfShape& theResults) +static void findFinals(const TDF_Label& anAccess, const TopoDS_Shape& theBase, + const TDF_Label& theFinal, + const TDF_Label& theAdditionalDoc, TopTools_MapOfShape& theResults) { - for(TNaming_NewShapeIterator aBaseIter(theBase, theFinal); aBaseIter.More(); aBaseIter.Next()) { - TNaming_Evolution anEvolution = aBaseIter.NamedShape()->Evolution(); - if (anEvolution == TNaming_GENERATED || anEvolution == TNaming_MODIFY) { - if (aBaseIter.NamedShape()->Label().IsEqual(theFinal)) { - theResults.Add(aBaseIter.Shape()); - } else { - findFinals(aBaseIter.Shape(), theFinal, theResults); + if (TNaming_Tool::HasLabel(anAccess, theBase)) { + for(TNaming_NewShapeIterator aBaseIter(theBase, anAccess); aBaseIter.More(); aBaseIter.Next()) + { + TNaming_Evolution anEvolution = aBaseIter.NamedShape()->Evolution(); + if (anEvolution == TNaming_GENERATED || anEvolution == TNaming_MODIFY) { + if (aBaseIter.NamedShape()->Label().IsEqual(theFinal)) { + theResults.Add(aBaseIter.Shape()); + } else { + findFinals(anAccess, aBaseIter.Shape(), theFinal, theAdditionalDoc, theResults); + } } } } + if (!theAdditionalDoc.IsNull()) { // search additionally by the additional access label + static TDF_Label anEmpty; + findFinals(theAdditionalDoc, theBase, theFinal, anEmpty, theResults); + } } void Selector_Selector::findModificationResult(TopoDS_ListOfShape& theCommon) { for(TDF_LabelList::Iterator aBase(myBases); aBase.More(); aBase.Next()) { + TDF_Label anAdditionalDoc; // this document if base is started in extra document + if (aBase.Value().Root() != myLab.Root()) { + anAdditionalDoc = myLab; + } TopTools_MapOfShape aFinals; - for(TNaming_Iterator aBaseShape(aBase.Value()); aBaseShape.More(); aBaseShape.Next()) - findFinals(aBaseShape.NewShape(), myFinal, aFinals); + for(TNaming_Iterator aBaseShape(aBase.Value()); aBaseShape.More(); aBaseShape.Next()) { + findFinals(aBase.Value(), aBaseShape.NewShape(), myFinal, anAdditionalDoc, aFinals); + } if (!aFinals.IsEmpty()) { if (theCommon.IsEmpty()) { // just copy all to common for(TopTools_MapOfShape::Iterator aFinal(aFinals); aFinal.More(); aFinal.Next()) { @@ -1051,6 +1107,7 @@ TDF_Label Selector_Selector::restoreByName( } } mySubSelList.push_back(Selector_Selector(myLab.FindChild(int(mySubSelList.size()) + 1))); + mySubSelList.back().setBaseDocument(myBaseDocumentLab); TDF_Label aSubContext = mySubSelList.back().restoreByName(aSubStr, aSubShapeType, theNameGenerator); if (aSubContext.IsNull()) @@ -1074,6 +1131,7 @@ TDF_Label Selector_Selector::restoreByName( if (anEndPos != std::string::npos) { std::string aSubStr = theName.substr(aStart + 1, anEndPos - aStart - 1); mySubSelList.push_back(Selector_Selector(myLab.FindChild(int(mySubSelList.size()) + 1))); + mySubSelList.back().setBaseDocument(myBaseDocumentLab); TDF_Label aSubContext = mySubSelList.back().restoreByName(aSubStr, theShapeType, theNameGenerator); if (aSubContext.IsNull()) @@ -1161,6 +1219,8 @@ bool Selector_Selector::selectBySubSelector( const bool theUseNeighbors, const bool theUseIntersections) { mySubSelList.push_back(Selector_Selector(myLab.FindChild(int(mySubSelList.size()) + 1))); + if (!myBaseDocumentLab.IsNull()) + mySubSelList.back().setBaseDocument(myBaseDocumentLab); if (!mySubSelList.back().select(theContext, theValue, theUseNeighbors, theUseIntersections)) { mySubSelList.clear(); // if one of the selector is failed, all become invalid return false; diff --git a/src/Selector/Selector_Selector.h b/src/Selector/Selector_Selector.h index 2e4bc0b29..92f513a32 100644 --- a/src/Selector/Selector_Selector.h +++ b/src/Selector/Selector_Selector.h @@ -55,16 +55,21 @@ class Selector_Selector TDF_LabelList myBases; ///< initial labels that contain shapes that produce the modification int myWeakIndex; ///< index of the shape among commons for the modification type (-1 - not set) - std::list myNBLevel; ///< list of integers corresponding to subsellist neighborhood level + std::list myNBLevel; ///< list of integers corresponding to mySubSelList neighborhood level TDF_Label myLab; ///< main label where selector is performed + TDF_Label myBaseDocumentLab; ///< an access-label to the document that may contain initial shapes + public: /// Initializes selector on the label SELECTOR_EXPORT Selector_Selector(TDF_Label theLab); /// Returns label of this selector SELECTOR_EXPORT TDF_Label label(); + /// Sets the base document access label. + SELECTOR_EXPORT void setBaseDocument(const TDF_Label theAccess); + /// Initializes the selector structure on the label. /// Stores the name data to restore after modification. SELECTOR_EXPORT bool select(const TopoDS_Shape theContext, const TopoDS_Shape theValue, @@ -94,7 +99,7 @@ class Selector_Selector private: - /// Create and keep in the list the sub-sulector that select the given value. + /// Create and keep in the list the sub-selector that select the given value. /// Returns true if selection is correct. bool selectBySubSelector(const TopoDS_Shape theContext, const TopoDS_Shape theValue, const bool theUseNeighbors = true, const bool theUseIntersections = true); -- 2.39.2