#include <Model_ResultConstruction.h>
#include <ModelAPI_Feature.h>
#include <ModelAPI_ResultBody.h>
-#include <ModelAPI_ResultCompSolid.h>
+#include <ModelAPI_ResultBody.h>
#include <ModelAPI_ResultConstruction.h>
#include <ModelAPI_ResultPart.h>
#include <ModelAPI_CompositeFeature.h>
// TDataStd_IntPackedMap - indexes of edges in composite element (for construction)
// TDataStd_Integer - type of the selected shape (for construction)
// TDF_Reference - from ReferenceAttribute, the context
-bool Model_AttributeSelection::setValue(const ResultPtr& theContext,
+bool Model_AttributeSelection::setValue(const ObjectPtr& theContext,
const std::shared_ptr<GeomAPI_Shape>& theSubShape, const bool theTemporarily)
{
- if (theTemporarily) { // just keep the stored without DF update
- myTmpContext = theContext;
+ if (theTemporarily &&
+ (!theContext.get() || theContext->groupName() != ModelAPI_Feature::group())) {
+ // just keep the stored without DF update
+ myTmpContext = std::dynamic_pointer_cast<ModelAPI_Result>(theContext);
myTmpSubShape = theSubShape;
owner()->data()->sendAttributeUpdated(this);
return true;
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
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()) {
+ ResultBodyPtr aContextBody = std::dynamic_pointer_cast<ModelAPI_ResultBody>(theContext);
// do not select the whole shape for body:it is already must be in the data framework
// equal and null selected objects mean the same: object is equal to context,
- if (theContext->shape().get() &&
- (theContext->shape()->isEqual(theSubShape) || !theSubShape.get())) {
+ if (aContextBody->shape().get() &&
+ (aContextBody->shape()->isEqual(theSubShape) || !theSubShape.get())) {
aSelLab.ForgetAllAttributes(true);
TDataStd_UAttribute::Set(aSelLab, kSIMPLE_REF_ID);
} else {
- selectBody(theContext, theSubShape);
+ selectBody(aContextBody, theSubShape);
}
} else if (theContext->groupName() == ModelAPI_ResultConstruction::group()) {
+ ResultConstructionPtr aContextConstruction =
+ std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(theContext);
aSelLab.ForgetAllAttributes(true); // to remove old selection data
std::shared_ptr<Model_ResultConstruction> aConstruction =
std::dynamic_pointer_cast<Model_ResultConstruction>(theContext);
std::shared_ptr<GeomAPI_Shape> aSubShape;
- if (theSubShape.get() && !theContext->shape()->isEqual(theSubShape))
+ if (theSubShape.get() && !aContextConstruction->shape()->isEqual(theSubShape))
aSubShape = theSubShape; // the whole context
if (aConstruction->isInfinite()) {
// For correct naming selection, put the shape into the naming structure.
// It seems sub-shapes are not needed: only this shape is (and can be ) selected.
TNaming_Builder aBuilder(aSelLab);
- aBuilder.Generated(theContext->shape()->impl<TopoDS_Shape>());
+ aBuilder.Generated(aContextConstruction->shape()->impl<TopoDS_Shape>());
}
int anIndex = aConstruction->select(theSubShape, owner()->document());
TDataStd_Integer::Set(aSelLab, anIndex);
} else if (theContext->groupName() == ModelAPI_ResultPart::group()) {
aSelLab.ForgetAllAttributes(true);
TDataStd_UAttribute::Set(aSelLab, kPART_REF_ID);
- selectPart(theContext, theSubShape);
+ selectPart(std::dynamic_pointer_cast<ModelAPI_Result>(theContext), theSubShape);
}
owner()->data()->sendAttributeUpdated(this);
+
+ if (aToUnblock)
+ owner()->data()->blockSendAttributeUpdated(false);
+
return true;
}
void Model_AttributeSelection::setValueCenter(
- const ResultPtr& theContext, const std::shared_ptr<GeomAPI_Edge>& theEdge,
+ const ObjectPtr& theContext, const std::shared_ptr<GeomAPI_Edge>& theEdge,
const CenterType theCenterType, const bool theTemporarily)
{
bool anUpdated = setValue(theContext, theEdge, theTemporarily);
std::shared_ptr<GeomAPI_Shape> Model_AttributeSelection::value()
{
+ if (!ModelAPI_AttributeSelection::isInitialized() && !myTmpContext.get() && !myTmpSubShape.get())
+ return std::shared_ptr<GeomAPI_Shape>();
CenterType aType = NOT_CENTER;
std::shared_ptr<GeomAPI_Shape> aResult = internalValue(aType);
return centerByEdge(aResult, aType);
ModelAPI_AttributeSelection::setID(theID);
}
-ResultPtr Model_AttributeSelection::context() {
+ResultPtr Model_AttributeSelection::context()
+{
+ if (!ModelAPI_AttributeSelection::isInitialized() && !myTmpContext.get() && !myTmpSubShape.get())
+ return ResultPtr();
+
if (myTmpContext.get() || myTmpSubShape.get()) {
return myTmpContext;
}
return aResult;
}
+FeaturePtr Model_AttributeSelection::contextFeature() {
+ if (myTmpContext.get() || myTmpSubShape.get()) {
+ return FeaturePtr(); // feature can not be selected temporarily
+ }
+ return std::dynamic_pointer_cast<ModelAPI_Feature>(myRef.value());
+
+}
+
+
void Model_AttributeSelection::setObject(const std::shared_ptr<ModelAPI_Object>& theObject)
{
}
}
// 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
}
if (!isFound) { // sub-shape is not found in the up-to-date instance of the context shape
// if context is sub-result of compound/compsolid, selection of sub-shape better propagate to
- // the main result (which is may be modified), case is in 1799
- ResultCompSolidPtr aMain = ModelAPI_Tools::compSolidOwner(theContext);
+ // the main result (which is may be modified); the case is in 1799
+ ResultBodyPtr aMain = ModelAPI_Tools::bodyOwner(theContext);
+ while(ModelAPI_Tools::bodyOwner(aMain).get())
+ aMain = ModelAPI_Tools::bodyOwner(theContext);
if (aMain.get()) {
selectBody(aMain, theSubShape);
return;
}
}
}
+ // if compsolid is context, try to take sub-solid as context: like in GUI and scripts
+ if (aCont.get() && aShapeToBeSelected.get()) {
+ ResultBodyPtr aComp = std::dynamic_pointer_cast<ModelAPI_ResultBody>(aCont);
+ if (aComp && aComp->numberOfSubs()) {
+ std::list<ResultPtr> allSubs;
+ ModelAPI_Tools::allSubs(aComp, allSubs);
+ std::list<ResultPtr>::reverse_iterator aS = allSubs.rbegin(); // iterate from lower level
+ for(; aS != allSubs.rend(); aS++) {
+ ResultPtr aSub = *aS;
+ 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() && aShapeToBeSelected.get()) {
+ while(aFindNewContext && aCont.get()) {
aFindNewContext = false;
- const std::set<AttributePtr>& aRefs = aCont->data()->refsToMe();
- std::set<AttributePtr>::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<ModelAPI_Feature>((*aRef)->owner());
- if (!ModelAPI_Session::get()->validators()->isConcealed(
- aRefFeat->getKind(), (*aRef)->id()))
- continue;
- // search the feature result that contains sub-shape selected
- std::list<std::shared_ptr<ModelAPI_Result> > aResults;
- ModelAPI_Tools::allResults(aRefFeat, aResults);
- std::list<std::shared_ptr<ModelAPI_Result> >::iterator aResIter = aResults.begin();
- for(; aResIter != aResults.end(); aResIter++) {
- if (!aResIter->get() || !(*aResIter)->data()->isValid() || (*aResIter)->isDisabled())
+ // take references to all results: root one, any sub
+ ResultBodyPtr aCompContext = ModelAPI_Tools::bodyOwner(aCont);
+ std::list<ResultPtr> allRes;
+ if (aCompContext.get())
+ ModelAPI_Tools::allSubs(aCompContext, allRes);
+ allRes.push_back(aCont);
+ for(std::list<ResultPtr>::iterator aSub = allRes.begin(); aSub != allRes.end(); aSub++) {
+ ResultPtr aResCont = *aSub;
+ const std::set<AttributePtr>& aRefs = aResCont->data()->refsToMe();
+ std::set<AttributePtr>::const_iterator aRef = aRefs.begin();
+ for(; !aFindNewContext && aRef != aRefs.end(); aRef++) {
+ if (!aRef->get() || !(*aRef)->owner().get())
continue;
- GeomShapePtr aShape = (*aResIter)->shape();
- if (aShape.get() && aShape->isSubShape(aShapeToBeSelected, 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;
+ // concealed attribute only
+ FeaturePtr aRefFeat = std::dynamic_pointer_cast<ModelAPI_Feature>((*aRef)->owner());
+ if (!ModelAPI_Session::get()->validators()->isConcealed(
+ aRefFeat->getKind(), (*aRef)->id()))
+ continue;
+ // search the feature result that contains sub-shape selected
+ std::list<std::shared_ptr<ModelAPI_Result> > aResults;
+
+ // take all sub-results or one result
+ std::list<ResultPtr> aRefFeatResults;
+ ModelAPI_Tools::allResults(aRefFeat, aRefFeatResults);
+ std::list<ResultPtr>::iterator aRefResIter = aRefFeatResults.begin();
+ for(; aRefResIter != aRefFeatResults.end(); aRefResIter++) {
+ ResultBodyPtr aBody = std::dynamic_pointer_cast<ModelAPI_ResultBody>(*aRefResIter);
+ if (aBody.get() && aBody->numberOfSubs() == 0) // add only lower level subs
+ aResults.push_back(aBody);
+ }
+ std::list<std::shared_ptr<ModelAPI_Result> >::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
+ aFindNewContext = true; // continue searching futher
+ break;
+ }
}
}
}
{
int anID = 0;
std::shared_ptr<GeomAPI_Shape> aSelection = value();
- std::shared_ptr<GeomAPI_Shape> aContext = context()->shape();
+ ResultPtr aContextRes = context();
// support for compsolids:
- if (context().get() && ModelAPI_Tools::compSolidOwner(context()).get())
- aContext = ModelAPI_Tools::compSolidOwner(context())->shape();
+ while(ModelAPI_Tools::bodyOwner(aContextRes).get()) {
+ aContextRes = ModelAPI_Tools::bodyOwner(aContextRes);
+ }
+ std::shared_ptr<GeomAPI_Shape> aContext = aContextRes->shape();
TopoDS_Shape aMainShape = aContext->impl<TopoDS_Shape>();
const TopoDS_Shape& aSubShape = aSelection->impl<TopoDS_Shape>();
// searching for the latest main shape
- if (aSelection && !aSelection->isNull() &&
- aContext && !aContext->isNull())
+ if (aSelection && !aSelection->isNull() && aContext && !aContext->isNull())
{
std::shared_ptr<Model_Document> aDoc =
std::dynamic_pointer_cast<Model_Document>(context()->document());
void Model_AttributeSelection::setId(int theID)
{
- const ResultPtr& aContext = context();
std::shared_ptr<GeomAPI_Shape> aSelection;
- std::shared_ptr<GeomAPI_Shape> aContextShape = aContext->shape();
+ ResultPtr aContextRes = context();
// support for compsolids:
- if (aContext.get() && ModelAPI_Tools::compSolidOwner(aContext).get())
- aContextShape = ModelAPI_Tools::compSolidOwner(aContext)->shape();
+ while(ModelAPI_Tools::bodyOwner(aContextRes).get()) {
+ aContextRes = ModelAPI_Tools::bodyOwner(aContextRes);
+ }
+ std::shared_ptr<GeomAPI_Shape> aContext = aContextRes->shape();
- TopoDS_Shape aMainShape = aContextShape->impl<TopoDS_Shape>();
+ TopoDS_Shape aMainShape = aContext->impl<TopoDS_Shape>();
// searching for the latest main shape
- if (theID > 0 &&
- aContextShape && !aContextShape->isNull())
+ if (theID > 0 && aContext && !aContext->isNull())
{
std::shared_ptr<Model_Document> aDoc =
- std::dynamic_pointer_cast<Model_Document>(aContext->document());
+ std::dynamic_pointer_cast<Model_Document>(aContextRes->document());
if (aDoc.get()) {
Handle(TNaming_NamedShape) aNS = TNaming_Tool::NamedShape(aMainShape, aDoc->generalLabel());
if (!aNS.IsNull()) {
aSelection = aResult;
}
- setValue(aContext, aSelection);
+ setValue(aContextRes, aSelection);
}
std::string Model_AttributeSelection::contextName(const ResultPtr& theContext) const
// if new context becomes compsolid, the resulting sub may be in sub-solids
std::list<ResultPtr> aNewToIterate;
aNewToIterate.push_back(theNewContext);
- ResultCompSolidPtr aComp = std::dynamic_pointer_cast<ModelAPI_ResultCompSolid>(theNewContext);
+ ResultBodyPtr aComp = std::dynamic_pointer_cast<ModelAPI_ResultBody>(theNewContext);
if (aComp.get()) {
- for(int a = 0; a < aComp->numberOfSubs(); a++)
- aNewToIterate.push_back(aComp->subResult(a, false));
+ std::list<ResultPtr> allNewContextSubs;
+ ModelAPI_Tools::allSubs(aComp, allNewContextSubs);
+ std::list<ResultPtr>::iterator aSub = allNewContextSubs.begin();
+ for(; aSub != allNewContextSubs.end(); aSub++) {
+ ResultBodyPtr aBody = std::dynamic_pointer_cast<ModelAPI_ResultBody>(*aSub);
+ if (aBody.get() && aBody->numberOfSubs() == 0) // add only lower level subs
+ aNewToIterate.push_back(aBody);
+ }
}
// first iteration: searching for the whole shape appearance (like face of the box)
{
std::set<ResultPtr> 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<ModelAPI_Result>
- (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<ModelAPI_Result>
- (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::bodyOwner(theContext);
+ if (aComposite.get() && aComposite->shape().get() && !aComposite->shape()->isNull())
+ aContextList.Append(aComposite->shape()->impl<TopoDS_Shape>());
+ }
+ 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<ModelAPI_Result>
+ (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<ModelAPI_Result>
+ (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<ModelAPI_Feature>(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<TopoDS_Shape>());
- } 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<ModelAPI_Feature>(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<TopoDS_Shape>());
+ } 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())
aValueShape = std::make_shared<GeomAPI_Shape>();
aValueShape->setImpl<TopoDS_Shape>(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);
}
}