X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FModel%2FModel_AttributeSelection.cpp;h=3d97c91c9066df87325328677f41cbbe59989750;hb=65fb6fac9731831e7197d0841e4444e69eb7d7ce;hp=8d9b7c2ed275b96772513b59774fadd7fed81eff;hpb=b0196aeefbaa53754b1052fab904386707caad87;p=modules%2Fshaper.git diff --git a/src/Model/Model_AttributeSelection.cpp b/src/Model/Model_AttributeSelection.cpp index 8d9b7c2ed..3d97c91c9 100644 --- a/src/Model/Model_AttributeSelection.cpp +++ b/src/Model/Model_AttributeSelection.cpp @@ -39,6 +39,7 @@ #include #include #include +#include #include #include #include @@ -90,12 +91,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 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-"; @@ -135,16 +130,13 @@ bool Model_AttributeSelection::setValue(const ObjectPtr& theContext, myRef.setValue(theContext); } - // do noth use naming if selected shape is result shape itself, but not sub-shape + // do not use naming if selected shape is result shape itself, but not sub-shape TDF_Label aSelLab = selectionLabel(); aSelLab.ForgetAttribute(kSIMPLE_REF_ID); aSelLab.ForgetAttribute(kINVALID_SELECTION); aSelLab.ForgetAttribute(kCIRCLE_CENTER); aSelLab.ForgetAttribute(kELLIPSE_CENTER1); aSelLab.ForgetAttribute(kELLIPSE_CENTER2); - aSelLab.ForgetAttribute(kEXT_SKETCH_FACE); - 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 @@ -385,44 +377,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_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 @@ -493,7 +447,8 @@ bool Model_AttributeSelection::isInitialized() } Model_AttributeSelection::Model_AttributeSelection(TDF_Label& theLabel) - : myRef(theLabel) +: myRef(theLabel), + myIsGeometricalSelection(false) { myIsInitialized = myRef.isInitialized(); myParent = NULL; @@ -503,6 +458,13 @@ void Model_AttributeSelection::setID(const std::string theID) { myRef.setID(theID); ModelAPI_AttributeSelection::setID(theID); + FeaturePtr aFeature = std::dynamic_pointer_cast(owner()); + if (myParent) { + myIsGeometricalSelection = myParent->isGeometricalSelection(); + } else { + myIsGeometricalSelection = + ModelAPI_Session::get()->validators()->isGeometricalSelection(aFeature->getKind(), id()); + } } ResultPtr Model_AttributeSelection::context() @@ -524,7 +486,7 @@ ResultPtr Model_AttributeSelection::context() if(aPart.get() && aPart->data() == aResult->data()) { ResultPtr aPartResult = std::dynamic_pointer_cast(aPart); FeaturePtr anOwnerFeature = std::dynamic_pointer_cast(owner()); - // check that this result is not this-feature result (it is forbidden t oselect itself) + // check that this result is not this-feature result (it is forbidden to select itself) if(anOwnerFeature.get() && anOwnerFeature->firstResult() != aPartResult) { return aPartResult; } @@ -630,19 +592,17 @@ bool Model_AttributeSelection::update() if (aSelLab.FindAttribute(TNaming_NamedShape::GetID(), aNS)) anOldShape = aNS->Get(); - Selector_Selector aSelector(aSelLab); - if (aSelector.restore()) { // it is stored in old OCCT format, use TNaming_Selector - TopoDS_Shape aContextShape = aContext->shape()->impl(); - aResult = aSelector.solve(aContextShape); - } - aResult = setInvalidIfFalse(aSelLab, aResult); + TopoDS_Shape aContextShape = aContext->shape()->impl(); + Selector_Selector aSelector(aSelLab, baseDocumentLab()); + aResult = aSelector.restore(aContextShape); + setInvalidIfFalse(aSelLab, aResult); TopoDS_Shape aNewShape; if (aSelLab.FindAttribute(TNaming_NamedShape::GetID(), aNS)) aNewShape = aNS->Get(); if (anOldShape.IsNull() || aNewShape.IsNull() || !anOldShape.IsEqual(aNewShape)) { - // shape type shoud not not changed: if shape becomes compound of such shapes, then split + // shape type should not be changed: if shape becomes compound of such shapes, then split if (myParent && !anOldShape.IsNull() && !aNewShape.IsNull() && anOldShape.ShapeType() != aNewShape.ShapeType() && (aNewShape.ShapeType() == TopAbs_COMPOUND || aNewShape.ShapeType() == TopAbs_COMPSOLID)) @@ -659,29 +619,11 @@ 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)) { - 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); - aResult = aSelector.restore(); + TopoDS_Shape aContextShape = aContext->shape()->impl(); + Selector_Selector aSelector(aSelLab, baseDocumentLab()); TopoDS_Shape anOldShape = aSelector.value(); - if (aResult) { - TopoDS_Shape aContextShape = aContext->shape()->impl(); - aResult = aSelector.solve(aContextShape); - } - aResult = setInvalidIfFalse(aSelLab, aResult); + aResult = aSelector.restore(aContextShape); + setInvalidIfFalse(aSelLab, aResult); if (aResult && !anOldShape.IsEqual(aSelector.value())) owner()->data()->sendAttributeUpdated(this); // send updated if shape is changed } else { @@ -698,7 +640,7 @@ void Model_AttributeSelection::selectBody( // perform the selection TopoDS_Shape aContext; - ResultPtr aBody = std::dynamic_pointer_cast(theContext);//myRef.value() + ResultPtr aBody = std::dynamic_pointer_cast(theContext); if (aBody) { aContext = aBody->shape()->impl(); } else { @@ -715,92 +657,22 @@ 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()) { // reference to the sketch face - if (theSubShape->shapeType() == GeomAPI_Shape::FACE) { // sketch face - ResultConstructionPtr aConstr = - std::dynamic_pointer_cast(theContext); - int aFaceIndex = -1, aFacesNum = aConstr->facesNum(); - for(int a = 0; a < aFacesNum; a++) { - if (aConstr->face(a)->isEqual(theSubShape)) { - aFaceIndex = a; - break; - } - } - if (aFaceIndex >= 0) { - TDataStd_Integer::Set(aSelLab, kEXT_SKETCH_FACE, 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); + Selector_Selector aSelector(aSelLab, baseDocumentLab()); try { - aSelectorOk = aSel.select(aContext, aNewSub); + aSelectorOk = aSelector.select(aContext, aNewSub, myIsGeometricalSelection); if (aSelectorOk) { - aSel.store(); - aSelectorOk = aSel.solve(aContext); + aSelectorOk = aSelector.store(aContext); } } catch(...) { aSelectorOk = false; } - Handle(TNaming_NamedShape) aSelectorShape; - if (aSelectorOk && aSelLab.FindAttribute(TNaming_NamedShape::GetID(), aSelectorShape)) - { - TopoDS_Shape aShape = aSelectorShape->Get(); - if (aShape.IsNull() || aShape.ShapeType() != aNewSub.ShapeType()) - aSelectorOk = false; - } - if (!aSelectorOk) { - setInvalidIfFalse(aSelLab, false); + if (aSelectorOk) { + TopoDS_Shape aShape = aSelector.value(); + aSelectorOk = !aShape.IsNull() && aShape.ShapeType() == aNewSub.ShapeType(); } + setInvalidIfFalse(aSelLab, aSelectorOk); } } @@ -904,35 +776,13 @@ 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_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); + Selector_Selector aSelector(aSelLab, baseDocumentLab()); std::string aResult; - if (aSelector.restore()) + if (aSelector.restore(aCont->shape()->impl())) 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]; } @@ -992,12 +842,25 @@ void Model_AttributeSelection::selectSubShape( owner()->document()->objectByName(ModelAPI_ResultPart::group(), aPartName); if (aFound.get()) { // found such part, so asking it for the name ResultPartPtr aPart = std::dynamic_pointer_cast(aFound); - aDoc = std::dynamic_pointer_cast(aPart->partDoc()); - aSubShapeName = aSubShapeName.substr(aPartEnd +1); - if (aSubShapeName.empty()) { // the whole Part result + std::string aNameInPart = aSubShapeName.substr(aPartEnd + 1); + if (aNameInPart.empty()) { // whole part setValue(aPart, anEmptyShape); return; } + int anIndex; + std::shared_ptr aSelected = + aPart->shapeInPart(aNameInPart, aType, anIndex); + if (aSelected.get()) { + if (aCenterType != NOT_CENTER) { + if (!aSelected->isEdge()) + continue; + std::shared_ptr aSelectedEdge(new GeomAPI_Edge(aSelected)); + setValueCenter(aPart, aSelectedEdge, aCenterType); + } else + setValue(aPart, aSelected); + TDataStd_Integer::Set(selectionLabel(), anIndex); + return; + } } } } @@ -1024,9 +887,10 @@ void Model_AttributeSelection::selectSubShape( } } - Selector_Selector aSelector(aDoc->generalLabel()); + Selector_Selector aSelector(selectionLabel(), baseDocumentLab()); myRestoreDocument = aDoc; - TDF_Label aContextLabel = aSelector.restoreByName(aSubShapeName, aShapeType, this); + TDF_Label aContextLabel = aSelector.restoreByName( + aSubShapeName, aShapeType, this, myIsGeometricalSelection); myRestoreDocument.reset(); if (!aContextLabel.IsNull()) { ResultPtr aContext = aDoc->resultByLab(aContextLabel); // any label for document access @@ -1038,14 +902,23 @@ void Model_AttributeSelection::selectSubShape( aShapeToBeSelected->setImpl(new TopoDS_Shape(aSelectorShape)); // make the context result the latest existing aContext = newestContext(aContext, aShapeToBeSelected); - if (aCenterType != NOT_CENTER) { + if (myIsGeometricalSelection || aCenterType == NOT_CENTER) { + // store the currently generated name + selectionLabel().ForgetAllAttributes(true); + bool aToUnblock = false; + aToUnblock = !owner()->data()->blockSendAttributeUpdated(true); + myRef.setValue(aContext); + aSelector.store(aContextShape); + owner()->data()->sendAttributeUpdated(this); + if (aToUnblock) + owner()->data()->blockSendAttributeUpdated(false); + return; + } else { // re-select center of circle/arc by context and value if (!aShapeToBeSelected->isEdge()) continue; std::shared_ptr aSelectedEdge(new GeomAPI_Edge(aShapeToBeSelected)); setValueCenter(aContext, aSelectedEdge, aCenterType); } - else - setValue(aContext, aShapeToBeSelected); return; } } @@ -1146,24 +1019,15 @@ void Model_AttributeSelection::selectSubShape(const std::string& theType, const std::string& theContextName, const int theIndex) { // selection of context by name - //std::string aNamingContextName = theContextName + "/"; - //selectSubShape(theType, aNamingContextName); - std::shared_ptr aDoc = - std::dynamic_pointer_cast(owner()->document()); - if (aDoc.get()) { - bool aUnique = true; - std::string aContextName = theContextName; - std::string anEmptySub = ""; - ResultPtr aContext = aDoc->findByName(aContextName, anEmptySub, aUnique); - //ResultPtr aContext = context(); - if (aContext.get()) { - GeomShapePtr aContShape = aContext->shape(); - if (aContShape.get()) { - GeomAlgoAPI_NExplode aNExp(aContShape, GeomAPI_Shape::shapeTypeByStr(theType)); - GeomShapePtr aValue = aNExp.shape(theIndex); - if (aValue.get()) - setValue(aContext, aValue); - } + selectSubShape(theType, theContextName); + ResultPtr aContext = context(); + if (aContext.get()) { + GeomShapePtr aContShape = aContext->shape(); + if (aContShape.get()) { + GeomAlgoAPI_NExplode aNExp(aContShape, GeomAPI_Shape::shapeTypeByStr(theType)); + GeomShapePtr aValue = aNExp.shape(theIndex); + if (aValue.get()) + setValue(aContext, aValue); } } } @@ -1262,16 +1126,9 @@ void Model_AttributeSelection::computeValues( { bool aWasWholeContext = theValShape.IsNull(); if (aWasWholeContext) { - //theShapes.Append(theValShape); - //return; theValShape = theOldContext->shape()->impl(); } - //TopoDS_Shape anOldContShape = theOldContext->shape()->impl(); TopoDS_Shape aNewContShape = theNewContext->shape()->impl(); - //if (anOldContShape.IsSame(theValShape)) { // full context shape substituted by new full context - //theShapes.Append(aNewContShape); - //return; - //} // if a new value is unchanged in the new context, do nothing: value is correct TopExp_Explorer aSubExp(aNewContShape, theValShape.ShapeType()); for(; aSubExp.More(); aSubExp.Next()) { @@ -1307,7 +1164,7 @@ void Model_AttributeSelection::computeValues( std::dynamic_pointer_cast((*aNewContIter)->data()); TDF_Label aNewLab = aNewData->shapeLab(); // searching for produced sub-shape fully on some label - TDF_ChildIDIterator aNSIter(aNewLab, TNaming_NamedShape::GetID(), Standard_True); + TDF_ChildIDIterator aNSIter(aNewLab, TNaming_NamedShape::GetID()); for(; aNSIter.More(); aNSIter.Next()) { Handle(TNaming_NamedShape) aNS = Handle(TNaming_NamedShape)::DownCast(aNSIter.Value()); for(TNaming_Iterator aPairIter(aNS); aPairIter.More(); aPairIter.Next()) { @@ -1338,7 +1195,7 @@ void Model_AttributeSelection::computeValues( } } if (aToFindPart == 2 && !aNewToOld.IsEmpty()) { - // map of sub-shapes -> number of occurences of these shapes in containers + // map of sub-shapes -> number of occurrences of these shapes in containers NCollection_DataMap aSubs; TopTools_DataMapOfShapeShape::Iterator aContIter(aNewToOld); for(; aContIter.More(); aContIter.Next()) { @@ -1409,8 +1266,6 @@ bool Model_AttributeSelection::searchNewContext(std::shared_ptr aModifIter.Label().FindAttribute(TNaming_NamedShape::GetID(), aNewNS); if (aNewNS->Evolution() == TNaming_MODIFY || aNewNS->Evolution() == TNaming_GENERATED) { aResults.insert(aModifierObj); - //TNaming_Iterator aPairIter(aNewNS); - //aResContShapes.Append(aPairIter.NewShape()); aResContShapes.Append(aModifierObj->shape()->impl()); } else if (aNewNS->Evolution() == TNaming_DELETE) { // a shape was deleted => result is empty aResults.insert(ResultPtr()); @@ -1421,11 +1276,11 @@ bool Model_AttributeSelection::searchNewContext(std::shared_ptr } if (aResults.empty()) return false; // no modifications found, must stay the same - // iterate all results to find futher modifications + // iterate all results to find further modifications std::set::iterator aResIter = aResults.begin(); for(; aResIter != aResults.end(); aResIter++) { if (aResIter->get() != NULL) { - // compute new values by two contextes: the old and the new + // compute new values by two contexts: the old and the new TopTools_ListOfShape aValShapes; computeValues(theContext, *aResIter, theValShape, aValShapes); @@ -1440,7 +1295,7 @@ bool Model_AttributeSelection::searchNewContext(std::shared_ptr if (searchNewContext(theDoc, aNewContShape, *aResIter, aNewValSh, theAccessLabel, aNewRes, aNewUpdatedVal)) { - // appeand new results instead of the current ones + // append new results instead of the current ones std::list::iterator aNewIter = aNewRes.begin(); TopTools_ListIteratorOfListOfShape aNewUpdVal(aNewUpdatedVal); for(; aNewIter != aNewRes.end(); aNewIter++, aNewUpdVal.Next()) { @@ -1530,51 +1385,46 @@ void Model_AttributeSelection::updateInHistory() TopTools_ListOfShape aValShapes; if (searchNewContext(aDoc, aNewCShape, aContext, aValShape, aContLab, aNewContexts, aValShapes)) { + GeomAPI_Shape::ShapeType aListShapeType = GeomAPI_Shape::SHAPE; + if (myParent) { + if (myParent->selectionType() == "VERTEX") aListShapeType = GeomAPI_Shape::VERTEX; + else if (myParent->selectionType() == "EDGE") aListShapeType = GeomAPI_Shape::EDGE; + else if (myParent->selectionType() == "FACE") aListShapeType = GeomAPI_Shape::FACE; + } + std::list::iterator aNewCont = aNewContexts.begin(); TopTools_ListIteratorOfListOfShape aNewValues(aValShapes); - if (aNewCont == aNewContexts.end()) { // all results were deleted + bool aFirst = true; // first is set to this, next are appended to parent + for(; aNewCont != aNewContexts.end(); aNewCont++, aNewValues.Next()) { + + GeomShapePtr aValueShape; + if (!aNewValues.Value().IsNull()) { + aValueShape = std::make_shared(); + aValueShape->setImpl(new TopoDS_Shape(aNewValues.Value())); + } + // Check that list has the same type of shape selection before adding. + GeomAPI_Shape::ShapeType aShapeShapeType = GeomAPI_Shape::SHAPE; + if (aValueShape.get()) { + aShapeShapeType = aValueShape->shapeType(); + } else { + aShapeShapeType = (*aNewCont)->shape()->shapeType(); + } + if (aListShapeType != GeomAPI_Shape::SHAPE && aListShapeType != aShapeShapeType) { + continue; + } + if (aFirst) { + setValue(*aNewCont, aValueShape); + aFirst = false; + } else if (myParent) { + myParent->append(*aNewCont, aValueShape); + } + } + if (aFirst) { // nothing was added, all results were deleted ResultPtr anEmptyContext; std::shared_ptr anEmptyShape; setValue(anEmptyContext, anEmptyShape); // nullify the selection return; } - - GeomShapePtr aValueShape; - if (!aNewValues.Value().IsNull()) { - aValueShape = std::make_shared(); - aValueShape->setImpl(new TopoDS_Shape(aNewValues.Value())); - } - setValue(*aNewCont, aValueShape); - // if there are more than one result, put them by "append" into "parent" list - if (myParent) { - for(aNewCont++, aNewValues.Next(); aNewCont != aNewContexts.end(); - aNewCont++, aNewValues.Next()) { - GeomShapePtr aValueShape; - if (!aNewValues.Value().IsNull()) { - aValueShape = std::make_shared(); - aValueShape->setImpl(new TopoDS_Shape(aNewValues.Value())); - } - - // Check that list has the same type of shape selection before adding. - GeomAPI_Shape::ShapeType aListShapeType = GeomAPI_Shape::SHAPE; - if (myParent->selectionType() == "VERTEX") aListShapeType = GeomAPI_Shape::VERTEX; - else if (myParent->selectionType() == "EDGE") aListShapeType = GeomAPI_Shape::EDGE; - else if (myParent->selectionType() == "FACE") aListShapeType = GeomAPI_Shape::FACE; - - GeomAPI_Shape::ShapeType aShapeShapeType = GeomAPI_Shape::SHAPE; - if (aValueShape.get()) { - aShapeShapeType = aValueShape->shapeType(); - } else { - (*aNewCont)->shape()->shapeType(); - } - - if (aListShapeType != GeomAPI_Shape::SHAPE && aListShapeType != aShapeShapeType) { - continue; - } - - myParent->append(*aNewCont, aValueShape); - } - } } } @@ -1588,6 +1438,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 @@ -1614,6 +1470,8 @@ std::string Model_AttributeSelection::contextName(const TDF_Label theSelectionLa aContextName = "_" + aContextName; aNumInHistoryNames--; } + if (aBaseDocumnetUsed) + aContextName = aDoc->kind() + "/" + aContextName; return aContextName; } } @@ -1640,8 +1498,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; @@ -1664,7 +1536,7 @@ bool Model_AttributeSelection::restoreContext(std::string theName, if ((*aRes)->data()->name() == aCompName) { theValue = std::dynamic_pointer_cast((*aRes)->data())->shapeLab(); break; - } else if (aCompName.find((*aRes)->data()->name()) != std::string::npos) {// sub-vertex + } else { // any sub-label because the sketch line may be renamed, but not sub-vertices TDF_Label aLab = std::dynamic_pointer_cast((*aRes)->data())->shapeLab(); TDF_ChildIDIterator aSubNames(aLab, TDataStd_Name::GetID()); for(; aSubNames.More(); aSubNames.Next()) { @@ -1746,7 +1618,7 @@ ResultPtr Model_AttributeSelection::newestContext( } } } - if (theAnyValue) { // only for neighbours for now + if (theAnyValue) { // only for neighbors for now // try to find modification of sub-shapes: the best number of matches std::map aMatches; // result -> number of matches of shapes to find the best TDF_Label aResLab = std::dynamic_pointer_cast(aResult->data())->shapeLab(); @@ -1837,7 +1709,7 @@ ResultPtr Model_AttributeSelection::newestContext( GeomShapePtr aShape = (*aResIter)->shape(); if (aShape.get() && (theAnyValue || aShape->isSubShape(aSelectedShape, false))) { aResult = *aResIter; // found new context (produced from this) with same subshape - aFindNewContext = true; // continue searching futher + aFindNewContext = true; // continue searching further break; } } @@ -1865,3 +1737,54 @@ ResultPtr Model_AttributeSelection::newestContext( aResult = theCurrent; return aResult; } + +void Model_AttributeSelection::combineGeometrical() +{ + if (myTmpContext.get() || myTmpSubShape.get()) + return; + TDF_Label aSelLab = selectionLabel(); + if (aSelLab.IsAttribute(kINVALID_SELECTION) || !myRef.isInitialized()) + return; + + if (aSelLab.IsAttribute(kCIRCLE_CENTER) || aSelLab.IsAttribute(kELLIPSE_CENTER1) || + aSelLab.IsAttribute(kELLIPSE_CENTER2) || aSelLab.IsAttribute(kSIMPLE_REF_ID)) + return; + + if (aSelLab.IsAttribute(kPART_REF_ID)) { + ResultPartPtr aPart = std::dynamic_pointer_cast(context()); + if (!aPart.get() || !aPart->isActivated()) + return; // postponed naming needed + Handle(TDataStd_Integer) anIndex; + if (aSelLab.FindAttribute(TDataStd_Integer::GetID(), anIndex)) { + if (anIndex->Get()) { // special selection attribute was created, use it + std::string aNewName; + aPart->combineGeometrical(anIndex->Get(), aNewName); + TDataStd_Name::Set(aSelLab, aNewName.c_str()); + } + } + return; + } + + std::shared_ptr aConstr = + std::dynamic_pointer_cast(context()); + if (aConstr.get()) + return; + FeaturePtr aFeature = contextFeature(); + if (aFeature.get()) + return; + + Selector_Selector aSelector(aSelLab, baseDocumentLab()); + TopoDS_Shape aContextShape = context()->shape()->impl(); + if (aSelector.restore(aContextShape)) { + aSelector.combineGeometrical(aContextShape); + } +} + +TDF_Label Model_AttributeSelection::baseDocumentLab() +{ + if (ModelAPI_Session::get()->moduleDocument() != owner()->document()) + return std::dynamic_pointer_cast + (ModelAPI_Session::get()->moduleDocument())->extConstructionsLabel(); + static TDF_Label anEmpty; + return anEmpty; +}