From 2cb8023bec0da9fc7b138da0a467bca74d4b825c Mon Sep 17 00:00:00 2001 From: azv Date: Tue, 21 Aug 2018 16:34:38 +0300 Subject: [PATCH] Dump with geometrical selection Correct selection of center of circle / focus of ellipse --- src/Model/Model_AttributeSelection.cpp | 10 +++- src/Model/Model_AttributeSelectionList.cpp | 2 - src/ModelGeomAlgo/ModelGeomAlgo_Shape.cpp | 55 +++++++++++++++++++++- src/ModelGeomAlgo/ModelGeomAlgo_Shape.h | 4 +- src/ModelHighAPI/ModelHighAPI_Dumper.cpp | 4 +- src/ModelHighAPI/ModelHighAPI_Tools.cpp | 41 ++++++++++++++-- src/ModelHighAPI/ModelHighAPI_Tools.h | 3 ++ 7 files changed, 108 insertions(+), 11 deletions(-) diff --git a/src/Model/Model_AttributeSelection.cpp b/src/Model/Model_AttributeSelection.cpp index 787cc116f..70e364301 100644 --- a/src/Model/Model_AttributeSelection.cpp +++ b/src/Model/Model_AttributeSelection.cpp @@ -1097,6 +1097,7 @@ void Model_AttributeSelection::selectSubShape(const std::string& theType, } ResultPtr aFoundResult; GeomShapePtr aFoundSubShape; + int aFoundCenterType; // collect features from PartSet and the current part SessionPtr aSession = ModelAPI_Session::get(); @@ -1124,12 +1125,17 @@ void Model_AttributeSelection::selectSubShape(const std::string& theType, continue; // process results of the current feature to find appropriate sub-shape + aFoundCenterType = (int)ModelAPI_AttributeSelection::NOT_CENTER; if (ModelGeomAlgo_Shape::findSubshapeByPoint(*anIt, thePoint, aType, - aFoundResult, aFoundSubShape)) { + aFoundResult, aFoundSubShape, aFoundCenterType)) { if (aSelectionIndex > 0) --aSelectionIndex; // skip this shape, because one of the previous is selected else { - setValue(aFoundResult, aFoundSubShape); + if (aFoundCenterType == (int)ModelAPI_AttributeSelection::NOT_CENTER) + setValue(aFoundResult, aFoundSubShape); + else + setValueCenter(aFoundResult, aFoundSubShape->edge(), + (ModelAPI_AttributeSelection::CenterType)aFoundCenterType); return; } } diff --git a/src/Model/Model_AttributeSelectionList.cpp b/src/Model/Model_AttributeSelectionList.cpp index 7575ca2f9..c7e852221 100644 --- a/src/Model/Model_AttributeSelectionList.cpp +++ b/src/Model/Model_AttributeSelectionList.cpp @@ -110,8 +110,6 @@ void Model_AttributeSelectionList::append(const GeomPointPtr& thePoint, const st aNewAttr->setID(id()); mySize->Set(aNewTag); aNewAttr->selectSubShape(theType, thePoint); - if (selectionType().empty()) - setSelectionType(aNewAttr->value()->shapeTypeStr()); owner()->data()->sendAttributeUpdated(this); } diff --git a/src/ModelGeomAlgo/ModelGeomAlgo_Shape.cpp b/src/ModelGeomAlgo/ModelGeomAlgo_Shape.cpp index f5fe49d12..05929ba1c 100644 --- a/src/ModelGeomAlgo/ModelGeomAlgo_Shape.cpp +++ b/src/ModelGeomAlgo/ModelGeomAlgo_Shape.cpp @@ -22,12 +22,15 @@ #include "ModelGeomAlgo_Shape.h" +#include #include #include #include #include #include +#include +#include #include #include @@ -83,16 +86,56 @@ namespace ModelGeomAlgo_Shape return GeomShapePtr(); } + // Find circular/elliptical edge, which center/focus coincide with the given point + static GeomShapePtr findEdgeByCenter(const GeomShapePtr& theBaseShape, + const GeomPointPtr& theCenter, + const double theTolerance, + int& theCenterType) + { + theCenterType = (int)ModelAPI_AttributeSelection::NOT_CENTER; + std::list anEdges = theBaseShape->subShapes(GeomAPI_Shape::EDGE); + for (std::list::const_iterator anIt = anEdges.begin(); + anIt != anEdges.end(); ++anIt) { + GeomEdgePtr anEdge = (*anIt)->edge(); + if (!anEdge) + continue; + + if (anEdge->isCircle()) { + GeomCirclePtr aCircle = anEdge->circle(); + if (aCircle->center()->distance(theCenter) < theTolerance) { + theCenterType = (int)ModelAPI_AttributeSelection::CIRCLE_CENTER; + return *anIt; + } + } + else if (anEdge->isEllipse()) { + GeomEllipsePtr anEllipse = anEdge->ellipse(); + if (anEllipse->firstFocus()->distance(theCenter) < theTolerance) + theCenterType = (int)ModelAPI_AttributeSelection::ELLIPSE_FIRST_FOCUS; + else if (anEllipse->secondFocus()->distance(theCenter) < theTolerance) + theCenterType = (int)ModelAPI_AttributeSelection::ELLIPSE_SECOND_FOCUS; + + if (theCenterType != (int)ModelAPI_AttributeSelection::NOT_CENTER) + return *anIt; + } + } + + // not found + return GeomShapePtr(); + } + bool findSubshapeByPoint(const std::shared_ptr& theFeature, const std::shared_ptr& thePoint, const GeomAPI_Shape::ShapeType& theShapeType, std::shared_ptr& theResult, - std::shared_ptr& theSubshape) + std::shared_ptr& theSubshape, + int& theCenterType) { static const double TOLERANCE = 1.e-7; theResult = ResultPtr(); theSubshape = GeomShapePtr(); + theCenterType = (int)ModelAPI_AttributeSelection::NOT_CENTER; + const std::list& aResults = theFeature->results(); for (std::list::const_iterator aResIt = aResults.begin(); aResIt != aResults.end(); ++aResIt) { @@ -161,6 +204,16 @@ namespace ModelGeomAlgo_Shape theSubshape = GeomShapePtr(); break; } + + // another special case: the center of circle or the focus of ellipse is selected; + // return the corresponding edge and a status of the center + if (theShapeType == GeomAPI_Shape::VERTEX) { + theSubshape = findEdgeByCenter(aCurShape, thePoint, TOLERANCE, theCenterType); + if (theSubshape) { + theResult = *aResIt; + break; + } + } } // one more special case: a vertex selected is a sketch point; diff --git a/src/ModelGeomAlgo/ModelGeomAlgo_Shape.h b/src/ModelGeomAlgo/ModelGeomAlgo_Shape.h index e2fa4a175..fbba1bb25 100644 --- a/src/ModelGeomAlgo/ModelGeomAlgo_Shape.h +++ b/src/ModelGeomAlgo/ModelGeomAlgo_Shape.h @@ -47,13 +47,15 @@ namespace ModelGeomAlgo_Shape { /// \param[in] theShapeType type of the selected shape /// \param[out] theResult applicable result /// \param[out] theSubshape sub-shape of the found result + /// \param[out] theCenterType type of the point if it is a center of circle or a focus of ellipse /// \return \c true if the result and its applicable sub-shape are found MODELGEOMALGO_EXPORT bool findSubshapeByPoint( const std::shared_ptr& theFeature, const std::shared_ptr& thePoint, const GeomAPI_Shape::ShapeType& theShapeType, std::shared_ptr& theResult, - std::shared_ptr& theSubshape); + std::shared_ptr& theSubshape, + int& theCenterType); } #endif diff --git a/src/ModelHighAPI/ModelHighAPI_Dumper.cpp b/src/ModelHighAPI/ModelHighAPI_Dumper.cpp index d9169c629..d5c22c97f 100644 --- a/src/ModelHighAPI/ModelHighAPI_Dumper.cpp +++ b/src/ModelHighAPI/ModelHighAPI_Dumper.cpp @@ -1020,7 +1020,9 @@ static int possibleSelectionsByPoint(const GeomPointPtr& thePoint, ResultPtr aResult; GeomShapePtr aSubshape; - if (ModelGeomAlgo_Shape::findSubshapeByPoint(*aFIt, thePoint, theType, aResult, aSubshape)) + int theCenterType; + if (ModelGeomAlgo_Shape::findSubshapeByPoint(*aFIt, thePoint, theType, + aResult, aSubshape, theCenterType)) ++aNbPossibleSelections; } return aNbPossibleSelections; diff --git a/src/ModelHighAPI/ModelHighAPI_Tools.cpp b/src/ModelHighAPI/ModelHighAPI_Tools.cpp index f11d8c099..901ed0f67 100644 --- a/src/ModelHighAPI/ModelHighAPI_Tools.cpp +++ b/src/ModelHighAPI/ModelHighAPI_Tools.cpp @@ -195,10 +195,8 @@ void fillAttribute(const std::list & theValue, if(!theValue.empty()) { const ModelHighAPI_Selection& aSelection = theValue.front(); - std::string aSelectionType = aSelection.shapeType(); - GeomAPI_Shape::ShapeType aType = GeomAPI_Shape::shapeTypeByStr(aSelectionType); - if (aType != GeomAPI_Shape::SHAPE || aSelectionType == "SHAPE") - theAttribute->setSelectionType(aSelectionType); + GeomAPI_Shape::ShapeType aSelectionType = getShapeType(aSelection); + theAttribute->setSelectionType(strByShapeType(aSelectionType)); } for (auto it = theValue.begin(); it != theValue.end(); ++it) @@ -281,6 +279,41 @@ GeomAPI_Shape::ShapeType shapeTypeByStr(std::string theShapeTypeStr) return aShapeType; } +std::string strByShapeType(GeomAPI_Shape::ShapeType theShapeType) +{ + std::string aShapeTypeStr; + switch (theShapeType) { + case GeomAPI_Shape::COMPOUND: + aShapeTypeStr = "COMPOUND"; + break; + case GeomAPI_Shape::COMPSOLID: + aShapeTypeStr = "COMPSOLID"; + break; + case GeomAPI_Shape::SOLID: + aShapeTypeStr = "SOLID"; + break; + case GeomAPI_Shape::SHELL: + aShapeTypeStr = "SHELL"; + break; + case GeomAPI_Shape::FACE: + aShapeTypeStr = "FACE"; + break; + case GeomAPI_Shape::WIRE: + aShapeTypeStr = "WIRE"; + break; + case GeomAPI_Shape::EDGE: + aShapeTypeStr = "EDGE"; + break; + case GeomAPI_Shape::VERTEX: + aShapeTypeStr = "VERTEX"; + break; + default: + aShapeTypeStr = "SHAPE"; + break; + } + return aShapeTypeStr; +} + //================================================================================================== GeomAPI_Shape::ShapeType getShapeType(const ModelHighAPI_Selection& theSelection) { diff --git a/src/ModelHighAPI/ModelHighAPI_Tools.h b/src/ModelHighAPI/ModelHighAPI_Tools.h index e3bea3305..aa5286d84 100644 --- a/src/ModelHighAPI/ModelHighAPI_Tools.h +++ b/src/ModelHighAPI/ModelHighAPI_Tools.h @@ -156,6 +156,9 @@ void fillAttribute(const ModelHighAPI_Double & theX, MODELHIGHAPI_EXPORT GeomAPI_Shape::ShapeType shapeTypeByStr(std::string theShapeTypeStr); +MODELHIGHAPI_EXPORT +std::string strByShapeType(GeomAPI_Shape::ShapeType theShapeType); + MODELHIGHAPI_EXPORT GeomAPI_Shape::ShapeType getShapeType(const ModelHighAPI_Selection& theSelection); -- 2.39.2