From 41a6aa7f15f25ae8687cd4784e4e89b1b36d63a3 Mon Sep 17 00:00:00 2001 From: azv Date: Mon, 20 Aug 2018 16:25:32 +0300 Subject: [PATCH] Dump with geometrical selection * Fix problem with selection of shapes in compsolid * Correct selection of separate vertices in sketch * Dump by geometric: avoid checking parent features for searching selection point --- src/GeomAPI/GeomAPI_Shape.cpp | 2 + src/ModelGeomAlgo/ModelGeomAlgo_Shape.cpp | 70 ++++++++++++++++++++--- src/ModelHighAPI/ModelHighAPI_Dumper.cpp | 64 +++++++++++++++++++-- src/ModelHighAPI/ModelHighAPI_Tools.cpp | 7 +++ 4 files changed, 130 insertions(+), 13 deletions(-) diff --git a/src/GeomAPI/GeomAPI_Shape.cpp b/src/GeomAPI/GeomAPI_Shape.cpp index c686bbf77..369ad7ef1 100644 --- a/src/GeomAPI/GeomAPI_Shape.cpp +++ b/src/GeomAPI/GeomAPI_Shape.cpp @@ -568,6 +568,8 @@ bool GeomAPI_Shape::computeSize(double& theXmin, double& theYmin, double& theZmi return false; Bnd_Box aBndBox; BRepBndLib::Add(aShape, aBndBox); + if (aBndBox.IsVoid()) + return false; aBndBox.Get(theXmin, theYmin, theZmin, theXmax, theYmax, theZmax); return true; } diff --git a/src/ModelGeomAlgo/ModelGeomAlgo_Shape.cpp b/src/ModelGeomAlgo/ModelGeomAlgo_Shape.cpp index ca7809b39..f5fe49d12 100644 --- a/src/ModelGeomAlgo/ModelGeomAlgo_Shape.cpp +++ b/src/ModelGeomAlgo/ModelGeomAlgo_Shape.cpp @@ -22,8 +22,10 @@ #include "ModelGeomAlgo_Shape.h" +#include #include #include +#include #include #include @@ -57,8 +59,8 @@ namespace ModelGeomAlgo_Shape const double theTolerance) { double aXMin, aXMax, aYMin, aYMax, aZMin, aZMax; - theShape->computeSize(aXMin, aYMin, aZMin, aXMax, aYMax, aZMax); - return thePoint->x() >= aXMin - theTolerance && thePoint->x() <= aXMax + theTolerance && + return theShape->computeSize(aXMin, aYMin, aZMin, aXMax, aYMax, aZMax) && + thePoint->x() >= aXMin - theTolerance && thePoint->x() <= aXMax + theTolerance && thePoint->y() >= aYMin - theTolerance && thePoint->y() <= aYMax + theTolerance && thePoint->z() >= aZMin - theTolerance && thePoint->z() <= aZMax + theTolerance; } @@ -71,8 +73,9 @@ namespace ModelGeomAlgo_Shape { std::list aSubs = theShape->subShapes(theType); for (std::list::const_iterator aSubIt = aSubs.begin(); - aSubIt != aSubs.end(); ++aSubIt) { - if ((*aSubIt)->middlePoint()->distance(thePoint) < theTolerance) + aSubIt != aSubs.end(); ++aSubIt) { + GeomPointPtr aMiddlePoint = (*aSubIt)->middlePoint(); + if (aMiddlePoint && aMiddlePoint->distance(thePoint) < theTolerance) return *aSubIt; } @@ -89,6 +92,7 @@ namespace ModelGeomAlgo_Shape static const double TOLERANCE = 1.e-7; theResult = ResultPtr(); + theSubshape = GeomShapePtr(); const std::list& aResults = theFeature->results(); for (std::list::const_iterator aResIt = aResults.begin(); aResIt != aResults.end(); ++aResIt) { @@ -101,11 +105,31 @@ namespace ModelGeomAlgo_Shape // (it will be processed later) std::shared_ptr aSketchEdges = std::dynamic_pointer_cast(aCurShape); - if (theShapeType != GeomAPI_Shape::COMPOUND || !aSketchEdges) - theSubshape = findSubShape(aCurShape, theShapeType, thePoint, TOLERANCE); - if (theSubshape) { - theResult = *aResIt; - break; + if (theShapeType != GeomAPI_Shape::COMPOUND || !aSketchEdges) { + ResultCompSolidPtr aCompSolid = + std::dynamic_pointer_cast(*aResIt); + if (aCompSolid) { + // process solids + int aNbSolids = aCompSolid->numberOfSubs(); + for (int i = 0; i < aNbSolids && !theSubshape; ++i) { + ResultPtr aSubResult = aCompSolid->subResult(i); + GeomShapePtr aSubSolid = aSubResult->shape(); + if (aSubSolid && isPointWithinBB(thePoint, aSubSolid, TOLERANCE)) { + theSubshape = findSubShape(aSubSolid, theShapeType, thePoint, TOLERANCE); + if (theSubshape) + theResult = aSubResult; + } + } + if (theSubshape) + break; + } + + if (!theSubshape) + theSubshape = findSubShape(aCurShape, theShapeType, thePoint, TOLERANCE); + if (theSubshape) { + theResult = *aResIt; + break; + } } // special case for ResultConstruction if the FACE is selected @@ -139,6 +163,34 @@ namespace ModelGeomAlgo_Shape } } + // one more special case: a vertex selected is a sketch point; + // it is not included into sketch result; thus, it is necessary + // to pass through the sketch sub-features and verify all points + if (!theResult && theShapeType == GeomAPI_Shape::VERTEX && !aResults.empty()) { + CompositeFeaturePtr aCF = std::dynamic_pointer_cast(theFeature); + std::shared_ptr aSketchEdges = + std::dynamic_pointer_cast(aResults.front()->shape()); + + if (aSketchEdges && aCF) { + bool isContinue = true; + int aNbSubs = aCF->numberOfSubs(); + for (int aSubInd = 0; aSubInd < aNbSubs && isContinue; ++aSubInd) { + FeaturePtr aSub = aCF->subFeature(aSubInd); + const std::list& aSubResults = aSub->results(); + for (std::list::const_iterator aSRIt = aSubResults.begin(); + aSRIt != aSubResults.end(); ++aSRIt) { + GeomShapePtr aCurShape = (*aSRIt)->shape(); + theSubshape = findSubShape(aCurShape, theShapeType, thePoint, TOLERANCE); + if (theSubshape) { + theResult = aResults.front(); + isContinue = false; + break; + } + } + } + } + } + return (bool)theResult; } } // namespace ModelGeomAlgo_Shape diff --git a/src/ModelHighAPI/ModelHighAPI_Dumper.cpp b/src/ModelHighAPI/ModelHighAPI_Dumper.cpp index 1cbee858c..d9169c629 100644 --- a/src/ModelHighAPI/ModelHighAPI_Dumper.cpp +++ b/src/ModelHighAPI/ModelHighAPI_Dumper.cpp @@ -51,6 +51,7 @@ #include #include #include +#include #include #include @@ -961,16 +962,64 @@ static int possibleSelectionsByPoint(const GeomPointPtr& thePoint, ++aFIt; } - ResultPtr aResult; - GeomShapePtr aSubshape; + // collect the list of composite features, containing the last feature; + // these features should be excluded from searching, + // because the feature cannot select sub-shapes from its parent + std::set aEndFeatureParents; + for (FeaturePtr aCurFeat = theEndFeature; aCurFeat;) { + CompositeFeaturePtr aFoundComposite; + const std::set& aRefs = aCurFeat->data()->refsToMe(); + for (std::set::const_iterator anIt = aRefs.begin(); + anIt != aRefs.end(); ++anIt) { + FeaturePtr aF = ModelAPI_Feature::feature((*anIt)->owner()); + aFoundComposite = std::dynamic_pointer_cast(aF); + if (aFoundComposite && aFoundComposite->isSub(aCurFeat)) + break; + else + aFoundComposite = CompositeFeaturePtr(); + } + + if (aFoundComposite) { + aEndFeatureParents.insert(aFoundComposite); + aCurFeat = aFoundComposite; + } + else { + // add the part containing high-level feature + SessionPtr aSession = ModelAPI_Session::get(); + DocumentPtr aPartSetDoc = aSession->moduleDocument(); + std::list aPartSetFeatures = aPartSetDoc->allFeatures(); + for (std::list::const_iterator anIt = aPartSetFeatures.begin(); + anIt != aPartSetFeatures.end(); ++anIt) { + aFoundComposite = std::dynamic_pointer_cast(*anIt); + if (aFoundComposite && aFoundComposite->isSub(aCurFeat)) { + aEndFeatureParents.insert(aFoundComposite); + break; + } + } + + aCurFeat = FeaturePtr(); + } + } + int aNbPossibleSelections = 0; for (; aFIt != aFeatures.end() && *aFIt != theEndFeature; ++aFIt) { + bool isSkipFeature = false; if (aLastCompositeFeature && aLastCompositeFeature->isSub(*aFIt)) - continue; + isSkipFeature = true; CompositeFeaturePtr aCompFeat = std::dynamic_pointer_cast(*aFIt); - if (aCompFeat) + if (aCompFeat) { aLastCompositeFeature = aCompFeat; + if (aEndFeatureParents.find(aLastCompositeFeature) != aEndFeatureParents.end()) { + // do not process the parent for the last feature, + // because it cannot select objects from its parent + isSkipFeature = true; + } + } + if (isSkipFeature) + continue; + ResultPtr aResult; + GeomShapePtr aSubshape; if (ModelGeomAlgo_Shape::findSubshapeByPoint(*aFIt, thePoint, theType, aResult, aSubshape)) ++aNbPossibleSelections; } @@ -1011,6 +1060,13 @@ ModelHighAPI_Dumper& ModelHighAPI_Dumper::operator<<( myDumpBuffer << "\"" << aShape->shapeTypeStr(); if (isDumpByGeom) { + // check the selected item is a ResultPart; + // in this case it is necessary to get shape with full transformation + // for correct calculation of the middle point + ResultPartPtr aResPart = + std::dynamic_pointer_cast(theAttrSelect->context()); + if (aResPart) + aShape = aResPart->shape(); GeomPointPtr aMiddlePoint = aShape->middlePoint(); // calculate number of features, which could be selected by the same point FeaturePtr anOwner = ModelAPI_Feature::feature(theAttrSelect->owner()); diff --git a/src/ModelHighAPI/ModelHighAPI_Tools.cpp b/src/ModelHighAPI/ModelHighAPI_Tools.cpp index 87146a7a7..f11d8c099 100644 --- a/src/ModelHighAPI/ModelHighAPI_Tools.cpp +++ b/src/ModelHighAPI/ModelHighAPI_Tools.cpp @@ -305,6 +305,13 @@ GeomAPI_Shape::ShapeType getShapeType(const ModelHighAPI_Selection& theSelection aShapeType = shapeTypeByStr(aType); break; } + case ModelHighAPI_Selection::VT_TypeInnerPointPair: { + TypeInnerPointPair aPair = theSelection.typeInnerPointPair(); + std::string aType = aPair.first; + aType = aType.substr(0, aType.find_first_of('_')); + aShapeType = shapeTypeByStr(aType); + break; + } } return aShapeType; -- 2.39.2