#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>
aFeatureOwner->removeResults(0, false, false);
}
aSel.Select(aNewSub, aNewContext);
+ // face may become divided after the model update, so, new labels may be added to the scope
+ myScope.Clear();
if (aEraseResults) { // flash after Select : in Groups it makes selection with shift working
static Events_Loop* aLoop = Events_Loop::loop();
reset();
}
-
-// Check the point is within shape's bounding box
-static bool isPointWithinBB(const GeomPointPtr& thePoint, const GeomShapePtr& theShape)
-{
- double aXMin, aXMax, aYMin, aYMax, aZMin, aZMax;
- theShape->computeSize(aXMin, aYMin, aZMin, aXMax, aYMax, aZMax);
- return thePoint->x() >= aXMin - Precision::Confusion() &&
- thePoint->x() <= aXMax + Precision::Confusion() &&
- thePoint->y() >= aYMin - Precision::Confusion() &&
- thePoint->y() <= aYMax + Precision::Confusion() &&
- thePoint->z() >= aZMin - Precision::Confusion() &&
- thePoint->z() <= aZMax + Precision::Confusion();
-}
-
-// Select sub-shape of the given type, which contains the given point
-static GeomShapePtr findSubShape(const GeomShapePtr& theShape,
- const GeomAPI_Shape::ShapeType& theType,
- const GeomPointPtr& thePoint)
-{
- std::list<GeomShapePtr> aSubs = theShape->subShapes(theType);
- for (std::list<GeomShapePtr>::const_iterator aSubIt = aSubs.begin();
- aSubIt != aSubs.end(); ++aSubIt) {
- if ((*aSubIt)->middlePoint()->distance(thePoint) < Precision::Confusion())
- return *aSubIt;
- }
-
- // not found
- return GeomShapePtr();
-}
-
void Model_AttributeSelection::selectSubShape(const std::string& theType,
const GeomPointPtr& thePoint)
{
if (theType.empty() || !thePoint)
return;
+ // list of parent features
+ FeaturePtr anOwner = ModelAPI_Feature::feature(owner());
+ std::set<FeaturePtr> aParents = ModelAPI_Tools::getParents(anOwner);
+
+ int aSelectionIndex = 0;
GeomAPI_Shape::ShapeType aType = GeomAPI_Shape::shapeTypeByStr(theType);
- GeomShapePtr aFoundSubShape;
+ 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;
+ }
+ }
- std::list<FeaturePtr> aFeatures = owner()->document()->allFeatures();
+ std::list<ModelGeomAlgo_Shape::SubshapeOfResult> anAppropriate;
+
+ // 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) {
- const std::list<ResultPtr>& aResults = (*anIt)->results();
- for (std::list<ResultPtr>::const_iterator aResIt = aResults.begin();
- aResIt != aResults.end(); ++aResIt) {
- GeomShapePtr aCurShape = (*aResIt)->shape();
- // first of all, check the point is within bounding box of the result
- if (!isPointWithinBB(thePoint, aCurShape))
- continue;
- // now, process all sub-shapes of the given type and check their inner points
- aFoundSubShape = findSubShape(aCurShape, aType, thePoint);
- if (aFoundSubShape) {
- setValue(*aResIt, aFoundSubShape);
+ // selection cannot be linked to the parent features
+ if (aParents.find(*anIt) != aParents.end())
+ continue;
+ // 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, anAppropriate)) {
+ std::list<ModelGeomAlgo_Shape::SubshapeOfResult>::iterator anApIt = anAppropriate.begin();
+ for (; aSelectionIndex > 0 && anApIt != anAppropriate.end(); --aSelectionIndex)
+ ++anApIt; // skip this shape, because one of the previous is selected
+
+ if (anApIt != anAppropriate.end()) {
+ if (anApIt->myCenterType == (int)ModelAPI_AttributeSelection::NOT_CENTER)
+ setValue(anApIt->myResult, anApIt->mySubshape);
+ else
+ setValueCenter(anApIt->myResult, anApIt->mySubshape->edge(),
+ (ModelAPI_AttributeSelection::CenterType)anApIt->myCenterType);
return;
}
-
- // special case for ResultConstruction if the FACE is selected
- ResultConstructionPtr aResConstr =
- std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(*aResIt);
- if (aResConstr && aType >= GeomAPI_Shape::FACE) {
- int aNbFaces = aResConstr->facesNum();
- for (int aFaceInd = 0; aFaceInd < aNbFaces; ++aFaceInd) {
- GeomFacePtr aCurFace = aResConstr->face(aFaceInd);
- // check the point is within bounding box of the face
- if (!isPointWithinBB(thePoint, aCurFace))
- continue;
- aFoundSubShape = findSubShape(aCurFace, aType, thePoint);
- if (aFoundSubShape) {
- setValue(*aResIt, aFoundSubShape);
- return;
- }
- }
- }
}
}