From e728b978296154858b9d8098ffbbf0edcf03d905 Mon Sep 17 00:00:00 2001 From: nds Date: Fri, 29 Dec 2017 11:45:16 +0300 Subject: [PATCH] Issue #2293 Size of the view of a sketch is lost when pressing Set Plane View --- src/PartSet/PartSet_PreviewSketchPlane.cpp | 81 +++++++++++++++++++++- src/PartSet/PartSet_PreviewSketchPlane.h | 17 ++++- src/PartSet/PartSet_SketcherMgr.cpp | 7 ++ 3 files changed, 102 insertions(+), 3 deletions(-) diff --git a/src/PartSet/PartSet_PreviewSketchPlane.cpp b/src/PartSet/PartSet_PreviewSketchPlane.cpp index afd0e268c..26e5dcad3 100644 --- a/src/PartSet/PartSet_PreviewSketchPlane.cpp +++ b/src/PartSet/PartSet_PreviewSketchPlane.cpp @@ -29,6 +29,7 @@ #include #include +#include #include #include @@ -40,6 +41,8 @@ #include #include +#include + PartSet_PreviewSketchPlane::PartSet_PreviewSketchPlane() : myPreviewIsDisplayed(false), mySizeOfView(0), myIsUseSizeOfView(false) { @@ -91,7 +94,9 @@ void PartSet_PreviewSketchPlane::createSketchPlane(const CompositeFeaturePtr& th double aFaceSize = myIsUseSizeOfView ? mySizeOfView : Config_PropManager::integer(SKETCH_TAB_NAME, "planes_size"); - myShape = GeomAlgoAPI_FaceBuilder::squareFace(anOrigin->pnt(), aNormal->dir(), aFaceSize); + + myShape = GeomAlgoAPI_FaceBuilder::squareFace( + myViewCentralPoint.get() ? myViewCentralPoint : anOrigin->pnt(), aNormal->dir(), aFaceSize); } myPlane = createPreviewPlane(); } @@ -101,10 +106,82 @@ void PartSet_PreviewSketchPlane::createSketchPlane(const CompositeFeaturePtr& th myPreviewIsDisplayed = true; } -void PartSet_PreviewSketchPlane::setSizeOfView(double theSizeOfView, bool isUseSizeOfView) +double maximumSize(double theXmin, double theYmin, double theZmin, + double theXmax, double theYmax, double theZmax) +{ + double aSize = fabs(theXmax - theXmin); + double aSizeToCompare = fabs(theYmax - theYmin); + if (aSizeToCompare > aSize) + aSize = aSizeToCompare; + aSizeToCompare = fabs(theZmax - theZmin); + if (aSizeToCompare > aSize) + aSize = aSizeToCompare; + + return aSize; +} + +bool PartSet_PreviewSketchPlane::getDefaultSizeOfView( + const CompositeFeaturePtr& theSketch, double& theSizeOfView, + std::shared_ptr& theCentralPnt) +{ + if (!PartSet_Tools::sketchPlane(theSketch).get()) + return false; + + AttributeSelectionPtr aSelAttr = std::dynamic_pointer_cast + (theSketch->data()->attribute(SketchPlugin_SketchEntity::EXTERNAL_ID())); + if (aSelAttr) { + myShape = aSelAttr->value(); + // this case is needed by constructing sketch on a plane, where result shape is equal + // to context result, therefore value() returns NULL and we should use shape of context. + if (!myShape.get() && aSelAttr->context().get()) + myShape = aSelAttr->context()->shape(); + } + + if (myShape.get()) + return false; + + Bnd_Box aBox; + for (int aSubFeatureId = 0; aSubFeatureId < theSketch->numberOfSubs(); aSubFeatureId++) { + FeaturePtr aFeature = theSketch->subFeature(aSubFeatureId); + if (!aFeature.get()) + continue; + + std::list aResults = aFeature->results(); + std::list::const_iterator aResultIt; + for (aResultIt = aResults.begin(); aResultIt != aResults.end(); ++aResultIt) { + ResultPtr aResult = *aResultIt; + std::shared_ptr aShapePtr = aResult->shape(); + if (aShapePtr.get()) { + TopoDS_Shape aShape = aShapePtr->impl(); + if (aShape.IsNull()) + continue; + BRepBndLib::Add(aShape, aBox); + } + } + } + if (aBox.IsVoid()) + return 0; + + double aXmin, aXmax, anYmin, anYmax, aZmin, aZmax; + aBox.Get(aXmin, anYmin, aZmin, aXmax, anYmax, aZmax); + + theSizeOfView = maximumSize(aXmin, anYmin, aZmin, aXmax, anYmax, aZmax); + if (theSizeOfView > 0) { + gp_Pnt aCentre(aXmax-fabs(aXmax-aXmin)/2., anYmax-fabs(anYmax-anYmin)/2., + aZmax - fabs(aZmax-aZmin)/2.); + theCentralPnt = std::shared_ptr(new GeomAPI_Pnt(aCentre.X(), aCentre.Y(), + aCentre.Z())); + } + return true; +} + +void PartSet_PreviewSketchPlane::setSizeOfView(double theSizeOfView, bool isUseSizeOfView, + const std::shared_ptr& theCentralPoint) { mySizeOfView = theSizeOfView; myIsUseSizeOfView = isUseSizeOfView; + + myViewCentralPoint = theCentralPoint; } AISObjectPtr PartSet_PreviewSketchPlane::createPreviewPlane() diff --git a/src/PartSet/PartSet_PreviewSketchPlane.h b/src/PartSet/PartSet_PreviewSketchPlane.h index b797b2dd4..5d5fca41a 100644 --- a/src/PartSet/PartSet_PreviewSketchPlane.h +++ b/src/PartSet/PartSet_PreviewSketchPlane.h @@ -21,6 +21,8 @@ #ifndef PartSet_PreviewSketchPlane_H #define PartSet_PreviewSketchPlane_H +#include + class GeomAPI_AISObject; class GeomAPI_Shape; @@ -53,6 +55,16 @@ public: void createSketchPlane(const std::shared_ptr& theSketch, ModuleBase_IWorkshop* theWorkshop); + /// Returns bounding box size covered the sketch sub-elements. + /// If the sketch uses extenal face, it will not have default size and returns false. + /// \param theSketch sources sketch + /// \param [out] theSizeOfView maximum value in X, Y or Z direction + /// \param theCentralPoint central point of the sketch sub features + /// \return boolean value + bool getDefaultSizeOfView(const std::shared_ptr& theSketch, + double& theSizeOfView, + std::shared_ptr& theCentralPnt); + /// Returns whether custom size of view is set /// \return boolean value bool isUseSizeOfView() const { return myIsUseSizeOfView; } @@ -60,7 +72,8 @@ public: /// Sets the size of default created face /// \param theSizeOfView value /// \param isUseSizeOfView state whether the size should be used - void setSizeOfView(double theSizeOfView, bool isUseSizeOfView); + void setSizeOfView(double theSizeOfView, bool isUseSizeOfView, + const std::shared_ptr& theCentralPoint = std::shared_ptr()); private: /// Create a square face by parameters @@ -70,9 +83,11 @@ private: bool myPreviewIsDisplayed; std::shared_ptr myPlane; //! visualized presentation std::shared_ptr myShape; //! current shape to be displayed + std::shared_ptr myViewCentralPoint; //! central point of the default view double mySizeOfView; //! size that should be used by creating a default face bool myIsUseSizeOfView; //! state if the size is custom or from preferences + std::shared_ptr myViewOrigin; //! origin point of sketch if default view is used }; #endif \ No newline at end of file diff --git a/src/PartSet/PartSet_SketcherMgr.cpp b/src/PartSet/PartSet_SketcherMgr.cpp index e34587a07..763985d84 100755 --- a/src/PartSet/PartSet_SketcherMgr.cpp +++ b/src/PartSet/PartSet_SketcherMgr.cpp @@ -942,6 +942,13 @@ void PartSet_SketcherMgr::startSketch(ModuleBase_Operation* theOperation) // Display all sketcher sub-Objects myCurrentSketch = std::dynamic_pointer_cast(aFOperation->feature()); + double aSizeOfView = 0; + std::shared_ptr aCentralPoint; + if (aFOperation->isEditOperation() && + mySketchPlane->getDefaultSizeOfView(myCurrentSketch, aSizeOfView, aCentralPoint)) { + mySketchPlane->setSizeOfView(aSizeOfView, true, aCentralPoint); + } + mySketchPlane->createSketchPlane(myCurrentSketch, myModule->workshop()); XGUI_ModuleConnector* aConnector = dynamic_cast(myModule->workshop()); -- 2.39.2