X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FModel%2FModel_AttributeSelection.cpp;h=d2456c85e199fa4bb5f7838cf14d78549250d2a8;hb=f6bd0f4e080b833c0de7ef25822ebee641073445;hp=95af31053e7cc424e589db0b5b2c09d2ba2b746b;hpb=e7936a7615b6be5d69d4428088e6249f541480b8;p=modules%2Fshaper.git diff --git a/src/Model/Model_AttributeSelection.cpp b/src/Model/Model_AttributeSelection.cpp index 95af31053..d2456c85e 100644 --- a/src/Model/Model_AttributeSelection.cpp +++ b/src/Model/Model_AttributeSelection.cpp @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -110,9 +111,11 @@ bool Model_AttributeSelection::setValue(const ResultPtr& theContext, bool isOldShape = isOldContext && (theSubShape == anOldShape || (theSubShape && anOldShape && theSubShape->isEqual(anOldShape))); if (isOldShape) return false; // shape is the same, so context is also unchanged + bool aToUnblock = false; // update the referenced object if needed if (!isOldContext) { - myRef.setValue(theContext); + aToUnblock = !owner()->data()->blockSendAttributeUpdated(true); + myRef.setValue(theContext); } // do noth use naming if selected shape is result shape itself, but not sub-shape @@ -135,6 +138,8 @@ bool Model_AttributeSelection::setValue(const ResultPtr& theContext, TDF_Label aRefLab = myRef.myRef->Label(); aSelLab.ForgetAllAttributes(true); myRef.myRef = TDF_Reference::Set(aSelLab.Father(), aSelLab.Father()); + if (aToUnblock) + owner()->data()->blockSendAttributeUpdated(false); return false; } if (theContext->groupName() == ModelAPI_ResultBody::group()) { @@ -169,6 +174,10 @@ bool Model_AttributeSelection::setValue(const ResultPtr& theContext, } owner()->data()->sendAttributeUpdated(this); + + if (aToUnblock) + owner()->data()->blockSendAttributeUpdated(false); + return true; } @@ -264,6 +273,8 @@ GeomShapePtr centerByEdge(GeomShapePtr theEdge, ModelAPI_AttributeSelection::Cen std::shared_ptr Model_AttributeSelection::value() { + if (!ModelAPI_AttributeSelection::isInitialized() && !myTmpContext.get() && !myTmpSubShape.get()) + return std::shared_ptr(); CenterType aType = NOT_CENTER; std::shared_ptr aResult = internalValue(aType); return centerByEdge(aResult, aType); @@ -398,6 +409,11 @@ void Model_AttributeSelection::setID(const std::string theID) } ResultPtr Model_AttributeSelection::context() { + /* + if (!ModelAPI_AttributeSelection::isInitialized() && !myTmpContext.get() && !myTmpSubShape.get()) + return ResultPtr(); + */ + if (myTmpContext.get() || myTmpSubShape.get()) { return myTmpContext; } @@ -447,13 +463,14 @@ TDF_LabelMap& Model_AttributeSelection::scope() } } // for group Scope is not limitet: this is always up to date objects - bool isGroup = aFeature.get() && aFeature->getKind() == "Group"; + // this causes problem in galeries.py + //bool isGroup = aFeature.get() && aFeature->getKind() == "Group"; for(; aFIter != allFeatures.end(); aFIter++) { if (*aFIter == owner()) { // the left features are created later (except subs of composite) aMePassed = true; continue; } - if (isGroup) aMePassed = false; + //if (isGroup) aMePassed = false; bool isInScope = !aMePassed; if (!isInScope && aComposite.get()) { // try to add sub-elements of composite if this is composite @@ -583,6 +600,11 @@ bool Model_AttributeSelection::update() bool aModified = true; bool aValid = aConstructionContext->update(anIndex->Get(), owner()->document(), aModified); setInvalidIfFalse(aSelLab, aValid); + if (aConstructionContext->isInfinite()) { + // Update the selected shape. + TNaming_Builder aBuilder(aSelLab); + aBuilder.Generated(aConstructionContext->shape()->impl()); + } if (aModified) owner()->data()->sendAttributeUpdated(this); return aValid; @@ -653,7 +675,7 @@ void Model_AttributeSelection::selectBody( bool isFound = false; TopExp_Explorer anExp(aNewContext, aNewSub.ShapeType()); for(; anExp.More(); anExp.Next()) { - if (anExp.Current().IsEqual(aNewSub)) { + if (anExp.Current().IsSame(aNewSub)) { isFound = true; break; } @@ -859,6 +881,81 @@ void Model_AttributeSelection::selectSubShape( } } } + // if compsolid is context, try to take sub-solid as context: like in GUI and scripts + if (aCont.get() && aShapeToBeSelected.get()) { + ResultCompSolidPtr aComp = std::dynamic_pointer_cast(aCont); + if (aComp && aComp->numberOfSubs()) { + for(int aSubNum = 0; aSubNum < aComp->numberOfSubs(); aSubNum++) { + ResultPtr aSub = aComp->subResult(aSubNum); + if (aSub && aSub->shape().get() && aSub->shape()->isSubShape(aShapeToBeSelected)) { + aCont = aSub; + break; + } + } + } + } + // try to find the latest active result that must be used instead of the selected + // to set the active context (like in GUI selection), not concealed one + bool aFindNewContext = true; + while(aFindNewContext && aCont.get()) { + aFindNewContext = false; + // take references to all results: root one, any sub + ResultCompSolidPtr aCompContext = ModelAPI_Tools::compSolidOwner(aCont); + int aSubsSize = (aCompContext.get() ? aCompContext->numberOfSubs() : 0) + 1; + for(int aResultNum = 0; aResultNum < aSubsSize; aResultNum++) { + ResultPtr aResCont = aCont; + if (aCompContext.get()) + if (aResultNum == aSubsSize - 1) + aResCont = aCompContext; + else aResCont = aCompContext->subResult(aResultNum); + const std::set& aRefs = aResCont->data()->refsToMe(); + std::set::const_iterator aRef = aRefs.begin(); + for(; !aFindNewContext && aRef != aRefs.end(); aRef++) { + if (!aRef->get() || !(*aRef)->owner().get()) + continue; + // concealed attribute only + FeaturePtr aRefFeat = std::dynamic_pointer_cast((*aRef)->owner()); + if (!ModelAPI_Session::get()->validators()->isConcealed( + aRefFeat->getKind(), (*aRef)->id())) + continue; + // search the feature result that contains sub-shape selected + std::list > aResults; + + // take all sub-results or one result + const std::list >& aFResults = aRefFeat->results(); + std::list >::const_iterator aRIter = aFResults.begin(); + for (; aRIter != aFResults.cend(); aRIter++) { + // iterate sub-bodies of compsolid + ResultCompSolidPtr aComp = + std::dynamic_pointer_cast(*aRIter); + if (aComp.get() && aComp->numberOfSubs() > 0) { + int aNumSub = aComp->numberOfSubs(); + for(int a = 0; a < aNumSub; a++) { + aResults.push_back(aComp->subResult(a)); + } + } else { + aResults.push_back(*aRIter); + } + } + std::list >::iterator aResIter = aResults.begin(); + for(; aResIter != aResults.end(); aResIter++) { + if (!aResIter->get() || !(*aResIter)->data()->isValid() || (*aResIter)->isDisabled()) + continue; + GeomShapePtr aShape = (*aResIter)->shape(); + GeomShapePtr aSelectedShape = + aShapeToBeSelected.get() ? aShapeToBeSelected : aCont->shape(); + if (aShape.get() && aShape->isSubShape(aSelectedShape, false)) { + aCont = *aResIter; // found new context (produced from this) with same subshape + //if (!aShape->isSubShape(aShapeToBeSelected, true)) // take context orientation + // aShapeToBeSelected->setOrientation(); + aFindNewContext = true; // continue searching futher + break; + } + } + } + } + } + if (aCenterType != NOT_CENTER) { if (!aShapeToBeSelected->isEdge()) continue; @@ -1073,40 +1170,50 @@ bool Model_AttributeSelection::searchNewContext(std::shared_ptr { std::set aResults; // to avoid duplicates, new context, null if deleted TopTools_ListOfShape aResContShapes; - TNaming_SameShapeIterator aModifIter(theContShape, theAccessLabel); - for(; aModifIter.More(); aModifIter.Next()) { - TDF_Label anObjLab = aModifIter.Label().Father(); - ResultPtr aModifierObj = std::dynamic_pointer_cast - (theDoc->objects()->object(anObjLab)); - if (!aModifierObj.get()) { - // #2241: shape may be sub-element of new object, not main (shell created from faces) - if (!anObjLab.IsRoot()) - aModifierObj = std::dynamic_pointer_cast - (theDoc->objects()->object(anObjLab.Father())); - if (!aModifierObj.get()) + // iterate context and shape, but also if it is sub-shape of main shape, check also it + TopTools_ListOfShape aContextList; + aContextList.Append(theContShape); + if (theContext.get()) { + ResultPtr aComposite = ModelAPI_Tools::compSolidOwner(theContext); + if (aComposite.get() && aComposite->shape().get() && !aComposite->shape()->isNull()) + aContextList.Append(aComposite->shape()->impl()); + } + for(TopTools_ListOfShape::Iterator aContIter(aContextList); aContIter.More(); aContIter.Next()) { + TNaming_SameShapeIterator aModifIter(aContIter.ChangeValue(), theAccessLabel); + for(; aModifIter.More(); aModifIter.Next()) { + TDF_Label anObjLab = aModifIter.Label().Father(); + ResultPtr aModifierObj = std::dynamic_pointer_cast + (theDoc->objects()->object(anObjLab)); + if (!aModifierObj.get()) { + // #2241: shape may be sub-element of new object, not main (shell created from faces) + if (!anObjLab.IsRoot()) + aModifierObj = std::dynamic_pointer_cast + (theDoc->objects()->object(anObjLab.Father())); + if (!aModifierObj.get()) + continue; + } + FeaturePtr aModifierFeat = theDoc->feature(aModifierObj); + if (!aModifierFeat.get()) continue; - } - FeaturePtr aModifierFeat = theDoc->feature(aModifierObj); - if (!aModifierFeat.get()) - continue; - FeaturePtr aThisFeature = std::dynamic_pointer_cast(owner()); - if (aModifierFeat == aThisFeature || theDoc->objects()->isLater(aModifierFeat, aThisFeature)) - continue; // the modifier feature is later than this, so, should not be used - FeaturePtr aCurrentModifierFeat = theDoc->feature(theContext); - if (aCurrentModifierFeat == aModifierFeat || - theDoc->objects()->isLater(aCurrentModifierFeat, aModifierFeat)) - continue; // the current modifier is later than the found, so, useless - Handle(TNaming_NamedShape) aNewNS; - 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()); - } else { // not-precessed modification => don't support it - continue; + FeaturePtr aThisFeature = std::dynamic_pointer_cast(owner()); + if (aModifierFeat == aThisFeature || theDoc->objects()->isLater(aModifierFeat, aThisFeature)) + continue; // the modifier feature is later than this, so, should not be used + FeaturePtr aCurrentModifierFeat = theDoc->feature(theContext); + if (aCurrentModifierFeat == aModifierFeat || + theDoc->objects()->isLater(aCurrentModifierFeat, aModifierFeat)) + continue; // the current modifier is later than the found, so, useless + Handle(TNaming_NamedShape) aNewNS; + 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()); + } else { // not-precessed modification => don't support it + continue; + } } } if (aResults.empty())