]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Issue #2293 Size of the view of a sketch is lost when pressing Set Plane View
authornds <nds@opencascade.com>
Fri, 29 Dec 2017 08:45:16 +0000 (11:45 +0300)
committernds <nds@opencascade.com>
Fri, 29 Dec 2017 08:51:56 +0000 (11:51 +0300)
src/PartSet/PartSet_PreviewSketchPlane.cpp
src/PartSet/PartSet_PreviewSketchPlane.h
src/PartSet/PartSet_SketcherMgr.cpp

index afd0e268cd9d48722e6319f05b8d4aad9f9487c8..26e5dcad3fee008fe9d48e3a35c538bfccf4a782 100644 (file)
@@ -29,6 +29,7 @@
 #include <ModelAPI_Tools.h>
 
 #include <GeomAPI_AISObject.h>
+#include <GeomAPI_Pnt.h>
 
 #include <XGUI_Tools.h>
 #include <XGUI_Displayer.h>
@@ -40,6 +41,8 @@
 #include <SketchPlugin_Sketch.h>
 #include <SketchPlugin_SketchEntity.h>
 
+#include <BRepBndLib.hxx>
+
 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<GeomAPI_Pnt>& theCentralPnt)
+{
+  if (!PartSet_Tools::sketchPlane(theSketch).get())
+    return false;
+
+  AttributeSelectionPtr aSelAttr = std::dynamic_pointer_cast<ModelAPI_AttributeSelection>
+    (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<ResultPtr> aResults = aFeature->results();
+    std::list<ResultPtr>::const_iterator aResultIt;
+    for (aResultIt = aResults.begin(); aResultIt != aResults.end(); ++aResultIt) {
+      ResultPtr aResult = *aResultIt;
+      std::shared_ptr<GeomAPI_Shape> aShapePtr = aResult->shape();
+      if (aShapePtr.get()) {
+        TopoDS_Shape aShape = aShapePtr->impl<TopoDS_Shape>();
+        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<GeomAPI_Pnt>(new GeomAPI_Pnt(aCentre.X(), aCentre.Y(),
+                                                                 aCentre.Z()));
+  }
+  return true;
+}
+
+void PartSet_PreviewSketchPlane::setSizeOfView(double theSizeOfView, bool isUseSizeOfView,
+  const std::shared_ptr<GeomAPI_Pnt>& theCentralPoint)
 {
   mySizeOfView = theSizeOfView;
   myIsUseSizeOfView = isUseSizeOfView;
+
+  myViewCentralPoint = theCentralPoint;
 }
 
 AISObjectPtr PartSet_PreviewSketchPlane::createPreviewPlane()
index b797b2dd4fbc04c13c2460aa40c8e80f31105c71..5d5fca41ab2d78b8ea2c13aa8f2e8907cf1cdfc6 100644 (file)
@@ -21,6 +21,8 @@
 #ifndef PartSet_PreviewSketchPlane_H
 #define PartSet_PreviewSketchPlane_H
 
+#include <GeomAPI_Pnt.h>
+
 class GeomAPI_AISObject;
 class GeomAPI_Shape;
 
@@ -53,6 +55,16 @@ public:
   void createSketchPlane(const std::shared_ptr<ModelAPI_CompositeFeature>& 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<ModelAPI_CompositeFeature>& theSketch,
+                            double& theSizeOfView,
+                            std::shared_ptr<GeomAPI_Pnt>& 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<GeomAPI_Pnt>& theCentralPoint = std::shared_ptr<GeomAPI_Pnt>());
 
 private:
   /// Create a square face by parameters
@@ -70,9 +83,11 @@ private:
   bool myPreviewIsDisplayed;
   std::shared_ptr<GeomAPI_AISObject> myPlane; //! visualized presentation
   std::shared_ptr<GeomAPI_Shape> myShape; //! current shape to be displayed
+  std::shared_ptr<GeomAPI_Pnt> 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<GeomAPI_Pnt> myViewOrigin; //! origin point of sketch if default view is used
 };
 
 #endif
\ No newline at end of file
index e34587a07b4cbdf0bd3fab5f67b54bc35e25357a..763985d84cc045361a24aacafd7c86a4b50c75df 100755 (executable)
@@ -942,6 +942,13 @@ void PartSet_SketcherMgr::startSketch(ModuleBase_Operation* theOperation)
 
   // Display all sketcher sub-Objects
   myCurrentSketch = std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(aFOperation->feature());
+  double aSizeOfView = 0;
+  std::shared_ptr<GeomAPI_Pnt> aCentralPoint;
+  if (aFOperation->isEditOperation() &&
+      mySketchPlane->getDefaultSizeOfView(myCurrentSketch, aSizeOfView, aCentralPoint)) {
+    mySketchPlane->setSizeOfView(aSizeOfView, true, aCentralPoint);
+  }
+
   mySketchPlane->createSketchPlane(myCurrentSketch, myModule->workshop());
   XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(myModule->workshop());