#include <ModelAPI_Tools.h>
#include <ModelAPI_Session.h>
#include <ModelAPI_Validator.h>
+#include <ModelGeomAlgo_Shape.h>
#include <Events_InfoMessage.h>
#include <GeomAPI_Edge.h>
+#include <GeomAPI_Pnt.h>
#include <GeomAPI_Vertex.h>
#include <GeomAlgoAPI_CompoundBuilder.h>
aSelLab.ForgetAllAttributes(true);
TDataStd_UAttribute::Set(aSelLab, kPART_REF_ID);
selectPart(std::dynamic_pointer_cast<ModelAPI_Result>(theContext), theSubShape);
+ } else { // check the feature context: parent-Part of this feature should not be used
+ FeaturePtr aFeatureContext = std::dynamic_pointer_cast<ModelAPI_Feature>(theContext);
+ if (aFeatureContext.get()) {
+ if (owner()->document() != aFeatureContext->document()) {
+ aSelLab.ForgetAllAttributes(true);
+ myRef.setValue(ObjectPtr());
+ if (aToUnblock)
+ owner()->data()->blockSendAttributeUpdated(false);
+ return false;
+ }
+ }
}
owner()->data()->sendAttributeUpdated(this);
if (aConstr->isInfinite())
return aResult; // empty result
}
- // whole feature
- FeaturePtr aFeature = contextFeature();
- if (aFeature.get()) {
- std::list<GeomShapePtr> allShapes;
- std::list<ResultPtr>::const_iterator aRes = aFeature->results().cbegin();
- for (; aRes != aFeature->results().cend(); aRes++) {
- if (aRes->get() && !(*aRes)->isDisabled()) {
- GeomShapePtr aShape = (*aRes)->shape();
- if (aShape.get() && !aShape->isNull()) {
- allShapes.push_back(aShape);
+ if (!aConstr.get()) { // for construction context, return empty result as usual even
+ // the whole feature is selected
+ FeaturePtr aFeature = contextFeature();
+ if (aFeature.get()) {
+ std::list<GeomShapePtr> allShapes;
+ std::list<ResultPtr>::const_iterator aRes = aFeature->results().cbegin();
+ for (; aRes != aFeature->results().cend(); aRes++) {
+ if (aRes->get() && !(*aRes)->isDisabled()) {
+ GeomShapePtr aShape = (*aRes)->shape();
+ if (aShape.get() && !aShape->isNull()) {
+ allShapes.push_back(aShape);
+ }
}
}
+ return GeomAlgoAPI_CompoundBuilder::compound(allShapes);
}
- return GeomAlgoAPI_CompoundBuilder::compound(allShapes);
}
Handle(TNaming_NamedShape) aSelection;
}
ResultPtr Model_AttributeSelection::context()
+{
if (!ModelAPI_AttributeSelection::isInitialized() && !myTmpContext.get() && !myTmpSubShape.get())
return ResultPtr();
ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(myRef.value());
// for parts there could be same-data result, so take the last enabled
- if (aResult.get() && aResult->groupName() == ModelAPI_ResultPart::group()) {
- int aSize = aResult->document()->size(ModelAPI_ResultPart::group());
- for(int a = aSize - 1; a >= 0; a--) {
- ObjectPtr aPart = aResult->document()->object(ModelAPI_ResultPart::group(), a);
- if (aPart.get() && aPart->data() == aResult->data()) {
- ResultPtr aPartResult = std::dynamic_pointer_cast<ModelAPI_Result>(aPart);
- FeaturePtr anOwnerFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(owner());
- // check that this result is not this-feature result (it is forbidden t oselect itself)
- if (anOwnerFeature.get() && anOwnerFeature->firstResult() != aPartResult) {
- return aPartResult;
+ if (aResult.get()) {
+ if(aResult->groupName() == ModelAPI_ResultPart::group()) {
+ int aSize = aResult->document()->size(ModelAPI_ResultPart::group());
+ for(int a = aSize - 1; a >= 0; a--) {
+ ObjectPtr aPart = aResult->document()->object(ModelAPI_ResultPart::group(), a);
+ if(aPart.get() && aPart->data() == aResult->data()) {
+ ResultPtr aPartResult = std::dynamic_pointer_cast<ModelAPI_Result>(aPart);
+ FeaturePtr anOwnerFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(owner());
+ // check that this result is not this-feature result (it is forbidden t oselect itself)
+ if(anOwnerFeature.get() && anOwnerFeature->firstResult() != aPartResult) {
+ return aPartResult;
+ }
}
}
}
+ } else { // if feature - construction is selected, it has only one result, return this result
+ FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(myRef.value());
+ if (aFeature.get() && aFeature->results().size() == 1 &&
+ aFeature->firstResult()->groupName() == ModelAPI_ResultConstruction::group())
+ return aFeature->firstResult();
}
return aResult;
}
return FeaturePtr(); // feature can not be selected temporarily
}
return std::dynamic_pointer_cast<ModelAPI_Feature>(myRef.value());
-
}
-
+ObjectPtr Model_AttributeSelection::contextObject() {
+ FeaturePtr aRes = contextFeature();
+ if (aRes.get())
+ return aRes;
+ return context();
+}
void Model_AttributeSelection::setObject(const std::shared_ptr<ModelAPI_Object>& theObject)
bool Model_AttributeSelection::update()
{
+ FeaturePtr aContextFeature = contextFeature();
+ if (aContextFeature.get()) {
+ return true;
+ }
TDF_Label aSelLab = selectionLabel();
ResultPtr aContext = context();
if (!aContext.get())
std::shared_ptr<GeomAPI_Shape> aSubSh = internalValue(aCenterType);
ResultPtr aCont = context();
- if (!aCont.get()) {
+ if (!aCont.get() ||
+ (aCont->groupName() == ModelAPI_ResultConstruction::group() && contextFeature().get())) {
// selection of a full feature
FeaturePtr aFeatureCont = contextFeature();
if (aFeatureCont.get()) {
aNS = TNaming_Tool::CurrentNamedShape(aNS);
if (!aNS.IsNull() && scope().Contains(aNS->Label())) { // scope check is for 2228
TDF_Label aLab = aNS->Label();
- while(aLab.Depth() != 7 && aLab.Depth() > 5)
+ if (aLab.Depth() % 2 == 0)
aLab = aLab.Father();
ObjectPtr anObj = aDoc->objects()->object(aLab);
+ while(!anObj.get() && aLab.Depth() > 5) {
+ aLab = aLab.Father().Father();
+ anObj = aDoc->objects()->object(aLab);
+ }
+
if (anObj.get()) {
ResultPtr aRes = std::dynamic_pointer_cast<ModelAPI_Result>(anObj);
if (aRes)
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)) {
+ std::list<ResultPtr>::iterator aS = allSubs.begin();
+ for(; aS != allSubs.end(); aS++) {
+ ResultBodyPtr aSub = std::dynamic_pointer_cast<ModelAPI_ResultBody>(*aS);
+ if (aSub && aSub->numberOfSubs() == 0 && aSub->shape().get() &&
+ aSub->shape()->isSubShape(aShapeToBeSelected)) {
aCont = aSub;
break;
}
while(aFindNewContext && aCont.get()) {
aFindNewContext = false;
// take references to all results: root one, any sub
- ResultBodyPtr aCompContext = ModelAPI_Tools::bodyOwner(aCont);
+ ResultBodyPtr aCompContext = ModelAPI_Tools::bodyOwner(aCont, true);
std::list<ResultPtr> allRes;
- if (aCompContext.get())
+ if (aCompContext.get()) {
ModelAPI_Tools::allSubs(aCompContext, allRes);
- allRes.push_back(aCont);
+ allRes.push_back(aCompContext);
+ } else {
+ allRes.push_back(aCont);
+ }
for(std::list<ResultPtr>::iterator aSub = allRes.begin(); aSub != allRes.end(); aSub++) {
ResultPtr aResCont = *aSub;
+ ResultBodyPtr aResBody = std::dynamic_pointer_cast<ModelAPI_ResultBody>(aResCont);
+ // only lower and higher level subs are counted
+ if (aResBody.get() && aResBody->numberOfSubs() > 0 && aResBody != aCompContext)
+ continue;
const std::set<AttributePtr>& aRefs = aResCont->data()->refsToMe();
std::set<AttributePtr>::const_iterator aRef = aRefs.begin();
for(; !aFindNewContext && aRef != aRefs.end(); aRef++) {
reset();
}
+void Model_AttributeSelection::selectSubShape(const std::string& theType,
+ const GeomPointPtr& thePoint)
+{
+ if (theType.empty() || !thePoint)
+ return;
+
+ int aSelectionIndex = 0;
+ GeomAPI_Shape::ShapeType aType = GeomAPI_Shape::shapeTypeByStr(theType);
+ if (aType == GeomAPI_Shape::SHAPE) {
+ // possibly, the string consists of the type and the index,
+ // thus, try to separate them
+ size_t aUndersporePos = theType.find_first_of('_');
+ if (aUndersporePos != std::string::npos)
+ aType = GeomAPI_Shape::shapeTypeByStr(theType.substr(0, aUndersporePos));
+
+ if (aType != GeomAPI_Shape::SHAPE) {
+ for (std::string::const_iterator aChar = theType.begin() + aUndersporePos + 1;
+ aChar != theType.end(); ++aChar) {
+ if (std::isdigit(*aChar))
+ aSelectionIndex = aSelectionIndex * 10 + (*aChar - '0');
+ else {
+ aSelectionIndex = 1;
+ break;
+ }
+ }
+ aSelectionIndex -= 1;
+ }
+ }
+ ResultPtr aFoundResult;
+ GeomShapePtr aFoundSubShape;
+
+ // collect features from PartSet and the current part
+ SessionPtr aSession = ModelAPI_Session::get();
+ std::list<FeaturePtr> aFeatures = aSession->moduleDocument()->allFeatures();
+ if (aSession->moduleDocument() != owner()->document()) {
+ std::list<FeaturePtr> aPartFeatures = owner()->document()->allFeatures();
+ aFeatures.insert(aFeatures.end(), aPartFeatures.begin(), aPartFeatures.end());
+ }
+ // Process results of all features from the last to the first
+ // to find appropriate sub-shape
+ for (std::list<FeaturePtr>::const_reverse_iterator anIt = aFeatures.rbegin();
+ anIt != aFeatures.rend(); ++anIt) {
+ // check the feature is a part of composite feature (like sketch elements),
+ // then do not process it, it will be processed in scope of composite feature
+ bool isSubOfComposite = false;
+ const std::set<AttributePtr>& aRefs = (*anIt)->data()->refsToMe();
+ for (std::set<AttributePtr>::const_iterator aRefIt = aRefs.begin();
+ aRefIt != aRefs.end() && !isSubOfComposite; ++aRefIt) {
+ FeaturePtr aFeature = ModelAPI_Feature::feature((*aRefIt)->owner());
+ CompositeFeaturePtr aCompFeature =
+ std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(aFeature);
+ isSubOfComposite = aCompFeature && aCompFeature->isSub(*anIt);
+ }
+ if (isSubOfComposite)
+ continue;
+
+ // process results of the current feature to find appropriate sub-shape
+ if (ModelGeomAlgo_Shape::findSubshapeByPoint(*anIt, thePoint, aType,
+ aFoundResult, aFoundSubShape)) {
+ if (aSelectionIndex > 0)
+ --aSelectionIndex; // skip this shape, because one of the previous is selected
+ else {
+ setValue(aFoundResult, aFoundSubShape);
+ return;
+ }
+ }
+ }
+
+ TDF_Label aSelLab = selectionLabel();
+ setInvalidIfFalse(aSelLab, false);
+ reset();
+}
+
int Model_AttributeSelection::Id()
{
int anID = 0;