Salome HOME
updated copyright message
[modules/shaper.git] / src / PartSet / PartSet_PreviewSketchPlane.cpp
index 26e5dcad3fee008fe9d48e3a35c538bfccf4a782..8cfb60457045140bf1f4e87f107f3c4a8b74ae24 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2014-2017  CEA/DEN, EDF R&D
+// Copyright (C) 2014-2023  CEA, EDF
 //
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Lesser General Public
 //
 // You should have received a copy of the GNU Lesser General Public
 // License along with this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 //
-// See http://www.salome-platform.org/ or
-// email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
 
 #include "PartSet_PreviewSketchPlane.h"
@@ -54,54 +53,88 @@ void PartSet_PreviewSketchPlane::eraseSketchPlane(ModuleBase_IWorkshop* theWorks
   if (myPreviewIsDisplayed) {
     XGUI_Displayer* aDisp = XGUI_Tools::workshop(theWorkshop)->displayer();
     aDisp->eraseAIS(myPlane, false);
-    if (isClearPlane) {
-      myPlane = std::shared_ptr<GeomAPI_AISObject>();
-      myShape = std::shared_ptr<GeomAPI_Shape>();
-    }
     myPreviewIsDisplayed = false;
   }
+  if (isClearPlane) clearPlanePreview();
 }
 
+void PartSet_PreviewSketchPlane::displaySketchPlane(ModuleBase_IWorkshop* theWorkshop)
+{
+  if (myPlane.get() && (!myPreviewIsDisplayed)) {
+    XGUI_Displayer* aDisp = XGUI_Tools::workshop(theWorkshop)->displayer();
+    aDisp->displayAIS(myPlane, false/*load object in selection*/, 1/*shaded*/, false);
+    myPreviewIsDisplayed = true;
+  }
+}
+
+
+void PartSet_PreviewSketchPlane::clearPlanePreview()
+{
+  myPlane = std::shared_ptr<GeomAPI_AISObject>();
+  myShape = std::shared_ptr<GeomAPI_Shape>();
+}
+
+
 void PartSet_PreviewSketchPlane::createSketchPlane(const CompositeFeaturePtr& theSketch,
                                                    ModuleBase_IWorkshop* theWorkshop)
 {
-  // the preview plane has been already created and displayed
-  if (myPreviewIsDisplayed)
-    return;
-
   // plane is visualized only if sketch plane is filled
   if (!PartSet_Tools::sketchPlane(theSketch).get())
     return;
 
-  if (!myPlane) { // If planes are not created
-    // Create Preview
-    // selected linear face parameters
-    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()) {
-      // Create Preview for default planes
-      std::shared_ptr<GeomDataAPI_Point> anOrigin = std::dynamic_pointer_cast<GeomDataAPI_Point>(
-          theSketch->data()->attribute(SketchPlugin_Sketch::ORIGIN_ID()));
-      std::shared_ptr<GeomDataAPI_Dir> aNormal = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
-          theSketch->data()->attribute(SketchPlugin_Sketch::NORM_ID()));
+  AttributeSelectionPtr aSelAttr = std::dynamic_pointer_cast<ModelAPI_AttributeSelection>
+    (theSketch->data()->attribute(SketchPlugin_SketchEntity::EXTERNAL_ID()));
+  if (!aSelAttr)
+    return;
+
+  if (myShape.get() && myShape->isSame(aSelAttr->value()) && myPlane.get())
+    return;
 
-      double aFaceSize = myIsUseSizeOfView ? mySizeOfView
-        : Config_PropManager::integer(SKETCH_TAB_NAME, "planes_size");
+  XGUI_Displayer* aDisp = XGUI_Tools::workshop(theWorkshop)->displayer();
+  if (myPreviewIsDisplayed) {
+    aDisp->eraseAIS(myPlane, false);
+  }
 
+  // Create Preview
+  // selected linear face parameters
+  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()) {
+    // Create Preview for default planes
+    std::shared_ptr<GeomDataAPI_Point> anOrigin = std::dynamic_pointer_cast<GeomDataAPI_Point>(
+        theSketch->data()->attribute(SketchPlugin_Sketch::ORIGIN_ID()));
+    std::shared_ptr<GeomDataAPI_Dir> aNormal = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
+        theSketch->data()->attribute(SketchPlugin_Sketch::NORM_ID()));
+
+    double aFaceSize = myIsUseSizeOfView ? mySizeOfView
+      : Config_PropManager::real(SKETCH_TAB_NAME, "planes_size");
+    if (aFaceSize <= Precision::Confusion())
+      aFaceSize = 200;   // Set default value
+
+    myShape = GeomAlgoAPI_FaceBuilder::squareFace(
+      myViewCentralPoint.get() ? myViewCentralPoint : anOrigin->pnt(), aNormal->dir(), aFaceSize);
+  }
+  else if (myIsUseSizeOfView && (mySizeOfView > 0)) {
+    std::shared_ptr<GeomAPI_Face> aFace(new GeomAPI_Face(myShape));
+    std::shared_ptr<GeomAPI_Pln> aPlane = aFace->getPlane();
+    if (aPlane.get()) {
+      double anA, aB, aC, aD;
+      aPlane->coefficients(anA, aB, aC, aD);
+      std::shared_ptr<GeomAPI_Dir> aNormDir(new GeomAPI_Dir(anA, aB, aC));
+      std::shared_ptr<GeomAPI_XYZ> aCoords = aNormDir->xyz();
+      std::shared_ptr<GeomAPI_XYZ> aZero(new GeomAPI_XYZ(0, 0, 0));
+      aCoords = aCoords->multiplied(-aD * aCoords->distance(aZero));
+      std::shared_ptr<GeomAPI_Pnt> anOrigPnt(new GeomAPI_Pnt(aCoords));
       myShape = GeomAlgoAPI_FaceBuilder::squareFace(
-        myViewCentralPoint.get() ? myViewCentralPoint : anOrigin->pnt(), aNormal->dir(), aFaceSize);
+        myViewCentralPoint.get() ? myViewCentralPoint : anOrigPnt, aNormDir, mySizeOfView);
     }
-    myPlane = createPreviewPlane();
   }
+  myPlane = createPreviewPlane();
 
-  XGUI_Displayer* aDisp = XGUI_Tools::workshop(theWorkshop)->displayer();
   aDisp->displayAIS(myPlane, false/*load object in selection*/, 1/*shaded*/, false);
   myPreviewIsDisplayed = true;
 }
@@ -141,7 +174,8 @@ bool PartSet_PreviewSketchPlane::getDefaultSizeOfView(
     return false;
 
   Bnd_Box aBox;
-  for (int aSubFeatureId = 0; aSubFeatureId < theSketch->numberOfSubs(); aSubFeatureId++) {
+  int aNumberOfSubs = theSketch->numberOfSubs();
+  for (int aSubFeatureId = 0; aSubFeatureId < aNumberOfSubs; aSubFeatureId++) {
     FeaturePtr aFeature = theSketch->subFeature(aSubFeatureId);
     if (!aFeature.get())
       continue;