Salome HOME
updated copyright message
[modules/shaper.git] / src / FeaturesPlugin / FeaturesPlugin_Measurement.cpp
index ee4d1ea1f4ec0ee2d4700df5e766f45e6d640603..2bae620a3255f24e6a675621e3bb419e8426ebbb 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2018-20xx  CEA/DEN, EDF R&D
+// Copyright (C) 2018-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 "FeaturesPlugin_Measurement.h"
 #include <TopoDS.hxx>
 #include <TopoDS_Edge.hxx>
 #include <TopoDS_Shape.hxx>
-#include <AIS_LengthDimension.hxx>
-#include <AIS_RadiusDimension.hxx>
-#include <AIS_AngleDimension.hxx>
+#include <PrsDim_Dimension.hxx>
+#include <PrsDim_LengthDimension.hxx>
+#include <PrsDim_RadiusDimension.hxx>
+#include <PrsDim_AngleDimension.hxx>
 #include <BRepExtrema_DistShapeShape.hxx>
 
+#include <Basics_OCCTVersion.hxx>
+
 #include <iomanip>
 #include <sstream>
+#include <array>
 
 FeaturesPlugin_Measurement::FeaturesPlugin_Measurement() : mySceenScale(1)
 {
@@ -90,12 +93,15 @@ void FeaturesPlugin_Measurement::attributeChanged(const std::string& theID)
     std::dynamic_pointer_cast<ModelAPI_AttributeDoubleArray>(
       attribute(RESULT_VALUES_ID()))->setSize(0);
   }
-  if (theID != RESULT_ID()) {
+  else if (theID != RESULT_ID() &&
+           theID != RESULT_VALUES_ID()) {
     std::string aKind = string(MEASURE_KIND())->value();
     if (aKind == MEASURE_LENGTH())
       computeLength();
     else if (aKind == MEASURE_DISTANCE())
       computeDistance();
+    else if (aKind == MEASURE_PROXIMITY())
+      computeProximity();
     else if (aKind == MEASURE_RADIUS())
       computeRadius();
     else if (aKind == MEASURE_ANGLE())
@@ -125,6 +131,15 @@ void FeaturesPlugin_Measurement::computeLength()
 
   std::ostringstream anOutput;
   anOutput << "Length = " << std::setprecision(10) << anEdge->length();
+  if(anEdge->isLine())
+  {
+    auto point1 = anEdge->firstPoint();
+    auto point2 = anEdge->lastPoint();
+
+    anOutput <<"\n|dx| = " <<  std::setprecision(10) << std::abs(point2->x() - point1->x())
+        <<"\n|dy| = " <<  std::setprecision(10) << std::abs(point2->y() - point1->y())
+        <<"\n|dz| = " <<  std::setprecision(10) << std::abs(point2->z() - point1->z());
+  }
   string(RESULT_ID())->setValue(anOutput.str());
 
   AttributeDoubleArrayPtr aValues =
@@ -156,10 +171,49 @@ void FeaturesPlugin_Measurement::computeDistance()
     return;
   }
 
-  double aDistance = GeomAlgoAPI_ShapeTools::minimalDistance(aShape1, aShape2);
+  std::array<double, 3> fromShape1To2;
+  double aDistance = GeomAlgoAPI_ShapeTools::minimalDistance(aShape1, aShape2, fromShape1To2);
+
+  std::ostringstream anOutput;
+  anOutput << "Distance = " << std::setprecision(10) << aDistance
+           <<"\n|dx| = " <<  std::setprecision(10) << std::abs(fromShape1To2[0])
+      <<"\n|dy| = " <<  std::setprecision(10) << std::abs(fromShape1To2[1])
+      <<"\n|dz| = " <<  std::setprecision(10) << std::abs(fromShape1To2[2]);
+  string(RESULT_ID())->setValue(anOutput.str());
+
+  AttributeDoubleArrayPtr aValues =
+      std::dynamic_pointer_cast<ModelAPI_AttributeDoubleArray>(attribute(RESULT_VALUES_ID()));
+  aValues->setSize(1);
+  aValues->setValue(0, aDistance);
+}
+
+void FeaturesPlugin_Measurement::computeProximity()
+{
+  AttributeSelectionPtr aFirstFeature = selection(DISTANCE_FROM_OBJECT_ID());
+  GeomShapePtr aShape1;
+  if (aFirstFeature && aFirstFeature->isInitialized()) {
+    aShape1 = aFirstFeature->value();
+    if (!aShape1 && aFirstFeature->context())
+      aShape1 = aFirstFeature->context()->shape();
+  }
+
+  AttributeSelectionPtr aSecondFeature = selection(DISTANCE_TO_OBJECT_ID());
+  GeomShapePtr aShape2;
+  if (aSecondFeature && aSecondFeature->isInitialized()) {
+    aShape2 = aSecondFeature->value();
+    if (!aShape2 && aSecondFeature->context())
+      aShape2 = aSecondFeature->context()->shape();
+  }
+
+  if (!aShape1 || !aShape2) {
+    string(RESULT_ID())->setValue("");
+    return;
+  }
+
+  double aDistance = GeomAlgoAPI_ShapeTools::shapeProximity(aShape1, aShape2);
 
   std::ostringstream anOutput;
-  anOutput << "Distance = " << std::setprecision(10) << aDistance;
+  anOutput << "Proximity = " << std::setprecision(10) << aDistance;
   string(RESULT_ID())->setValue(anOutput.str());
 
   AttributeDoubleArrayPtr aValues =
@@ -318,6 +372,18 @@ void FeaturesPlugin_Measurement::computeAngleByPoints()
 
 AISObjectPtr FeaturesPlugin_Measurement::getAISObject(AISObjectPtr thePrevious)
 {
+  AttributeDoubleArrayPtr aValues =
+    std::dynamic_pointer_cast<ModelAPI_AttributeDoubleArray>(attribute(RESULT_VALUES_ID()));
+  if ((aValues->size() == 0) || (aValues->value(0) <= Precision::Confusion()))
+    return AISObjectPtr();
+
+  if (!myScreenPlane) {
+    // initialize a default plane for dimension
+    GeomPointPtr anOrigin(new GeomAPI_Pnt(0., 0., 0.));
+    GeomDirPtr aNormal(new GeomAPI_Dir(0., 0., 1.));
+    myScreenPlane = GeomPlanePtr(new GeomAPI_Pln(anOrigin, aNormal));
+  }
+
   AISObjectPtr anAIS;
   std::string aKind = string(MEASURE_KIND())->value();
   if (aKind == MEASURE_LENGTH())
@@ -337,8 +403,6 @@ AISObjectPtr FeaturesPlugin_Measurement::getAISObject(AISObjectPtr thePrevious)
 AISObjectPtr FeaturesPlugin_Measurement::lengthDimension(AISObjectPtr thePrevious)
 {
   AISObjectPtr aAISObj;
-  if (!myScreenPlane.get())
-    return aAISObj;
 
   AttributeSelectionPtr aSelectedFeature = selection(EDGE_FOR_LENGTH_ID());
 
@@ -371,13 +435,14 @@ AISObjectPtr FeaturesPlugin_Measurement::lengthDimension(AISObjectPtr thePreviou
         aPlane = gp_Pln(aPnt1, aPlane.XAxis().Direction());
       }
 
-      Handle(AIS_LengthDimension) aDim;
+      Handle(PrsDim_LengthDimension) aDim;
       if (thePrevious.get()) {
         aAISObj = thePrevious;
         Handle(AIS_InteractiveObject) aAIS = aAISObj->impl<Handle(AIS_InteractiveObject)>();
-        aDim = Handle(AIS_LengthDimension)::DownCast(aAIS);
+        aDim = Handle(PrsDim_LengthDimension)::DownCast(aAIS);
         if (aDim.IsNull()) {
-          aDim = new AIS_LengthDimension(aTEdge, aPlane);
+          aDim = new PrsDim_LengthDimension(aTEdge, aPlane);
+          aAISObj = AISObjectPtr(new GeomAPI_AISObject());
           aAISObj->setImpl(new Handle(AIS_InteractiveObject)(aDim));
         }
         else {
@@ -385,7 +450,7 @@ AISObjectPtr FeaturesPlugin_Measurement::lengthDimension(AISObjectPtr thePreviou
         }
       }
       else {
-        aDim = new AIS_LengthDimension(aTEdge, aPlane);
+        aDim = new PrsDim_LengthDimension(aTEdge, aPlane);
         aAISObj = AISObjectPtr(new GeomAPI_AISObject());
         aAISObj->setImpl(new Handle(AIS_InteractiveObject)(aDim));
       }
@@ -398,8 +463,6 @@ AISObjectPtr FeaturesPlugin_Measurement::lengthDimension(AISObjectPtr thePreviou
 AISObjectPtr FeaturesPlugin_Measurement::distanceDimension(AISObjectPtr thePrevious)
 {
   AISObjectPtr aAISObj;
-  if (!myScreenPlane.get())
-    return aAISObj;
 
   AttributeSelectionPtr aFirstFeature = selection(DISTANCE_FROM_OBJECT_ID());
   AttributeSelectionPtr aSecondFeature = selection(DISTANCE_TO_OBJECT_ID());
@@ -435,13 +498,14 @@ AISObjectPtr FeaturesPlugin_Measurement::distanceDimension(AISObjectPtr thePrevi
             aPlane = gp_Pln(aPnt1, aPlane.XAxis().Direction());
           }
 
-          Handle(AIS_LengthDimension) aDim;
+          Handle(PrsDim_LengthDimension) aDim;
           if (thePrevious.get()) {
             aAISObj = thePrevious;
             Handle(AIS_InteractiveObject) aAIS = aAISObj->impl<Handle(AIS_InteractiveObject)>();
-            aDim = Handle(AIS_LengthDimension)::DownCast(aAIS);
+            aDim = Handle(PrsDim_LengthDimension)::DownCast(aAIS);
             if (aDim.IsNull()) {
-              aDim = new AIS_LengthDimension(aPnt1, aPnt2, aPlane);
+              aDim = new PrsDim_LengthDimension(aPnt1, aPnt2, aPlane);
+              aAISObj = AISObjectPtr(new GeomAPI_AISObject());
               aAISObj->setImpl(new Handle(AIS_InteractiveObject)(aDim));
             }
             else {
@@ -451,7 +515,7 @@ AISObjectPtr FeaturesPlugin_Measurement::distanceDimension(AISObjectPtr thePrevi
           }
           else {
             aAISObj = AISObjectPtr(new GeomAPI_AISObject());
-            aDim = new AIS_LengthDimension(aPnt1, aPnt2, aPlane);
+            aDim = new PrsDim_LengthDimension(aPnt1, aPnt2, aPlane);
             aAISObj->setImpl(new Handle(AIS_InteractiveObject)(aDim));
           }
           aDim->SetFlyout(aDistance / 3.);
@@ -475,19 +539,19 @@ AISObjectPtr FeaturesPlugin_Measurement::radiusDimension(AISObjectPtr thePreviou
   }
   if (aShape.get()) {
     TopoDS_Shape aShp = aShape->impl<TopoDS_Shape>();
-    Handle(AIS_RadiusDimension) aDim;
     if (thePrevious.get()) {
       aAISObj = thePrevious;
       Handle(AIS_InteractiveObject) aAIS = aAISObj->impl<Handle(AIS_InteractiveObject)>();
-      Handle(AIS_RadiusDimension) aDim = Handle(AIS_RadiusDimension)::DownCast(aAIS);
+      Handle(PrsDim_RadiusDimension) aDim = Handle(PrsDim_RadiusDimension)::DownCast(aAIS);
       if (aDim.IsNull()) {
-        aDim = new AIS_RadiusDimension(aShp);
+        aDim = new PrsDim_RadiusDimension(aShp);
+        aAISObj = AISObjectPtr(new GeomAPI_AISObject());
         aAISObj->setImpl(new Handle(AIS_InteractiveObject)(aDim));
       } else
         aDim->SetMeasuredGeometry(aShp);
     } else {
       aAISObj = AISObjectPtr(new GeomAPI_AISObject());
-      Handle(AIS_RadiusDimension) aDim = new AIS_RadiusDimension(aShp);
+      Handle(PrsDim_RadiusDimension) aDim = new PrsDim_RadiusDimension(aShp);
       aAISObj->setImpl(new Handle(AIS_InteractiveObject)(aDim));
     }
   }
@@ -522,19 +586,21 @@ AISObjectPtr FeaturesPlugin_Measurement::angleDimension(AISObjectPtr thePrevious
   if (anEdge1.get() && anEdge2.get()) {
     TopoDS_Edge aTEdge1 = TopoDS::Edge(anEdge1->impl<TopoDS_Shape>());
     TopoDS_Edge aTEdge2 = TopoDS::Edge(anEdge2->impl<TopoDS_Shape>());
-    Handle(AIS_AngleDimension) aDim;
+
+    Handle(PrsDim_AngleDimension) aDim;
     if (thePrevious.get()) {
       aAISObj = thePrevious;
       Handle(AIS_InteractiveObject) aAIS = aAISObj->impl<Handle(AIS_InteractiveObject)>();
-      aDim = Handle(AIS_AngleDimension)::DownCast(aAIS);
+      aDim = Handle(PrsDim_AngleDimension)::DownCast(aAIS);
       if (aDim.IsNull()) {
-        aDim = new AIS_AngleDimension(aTEdge1, aTEdge2);
+        aDim = new PrsDim_AngleDimension(aTEdge1, aTEdge2);
+        aAISObj = AISObjectPtr(new GeomAPI_AISObject());
         aAISObj->setImpl(new Handle(AIS_InteractiveObject)(aDim));
       } else
         aDim->SetMeasuredGeometry(aTEdge1, aTEdge2);
     } else {
       aAISObj = AISObjectPtr(new GeomAPI_AISObject());
-      aDim = new AIS_AngleDimension(aTEdge1, aTEdge2);
+      aDim = new PrsDim_AngleDimension(aTEdge1, aTEdge2);
       aAISObj->setImpl(new Handle(AIS_InteractiveObject)(aDim));
     }
   }
@@ -556,17 +622,23 @@ AISObjectPtr FeaturesPlugin_Measurement::angleByPointsDimension(AISObjectPtr the
     gp_Pnt aPnt2(aPoint2->impl<gp_Pnt>());
     gp_Pnt aPnt3(aPoint3->impl<gp_Pnt>());
 
+    if (aPnt1.IsEqual(aPnt2, Precision::Confusion()) ||
+      aPnt1.IsEqual(aPnt3, Precision::Confusion()) ||
+      aPnt2.IsEqual(aPnt3, Precision::Confusion()))
+      return thePrevious;
+
     if (thePrevious.get()) {
       aAISObj = thePrevious;
       Handle(AIS_InteractiveObject) aAIS = aAISObj->impl<Handle(AIS_InteractiveObject)>();
-      Handle(AIS_AngleDimension) aDim = Handle(AIS_AngleDimension)::DownCast(aAIS);
+      Handle(PrsDim_AngleDimension) aDim = Handle(PrsDim_AngleDimension)::DownCast(aAIS);
       if (aDim.IsNull()) {
-        aDim = new AIS_AngleDimension(aPnt1, aPnt2, aPnt3);
+        aDim = new PrsDim_AngleDimension(aPnt1, aPnt2, aPnt3);
+        aAISObj = AISObjectPtr(new GeomAPI_AISObject());
         aAISObj->setImpl(new Handle(AIS_InteractiveObject)(aDim));
       } else
         aDim->SetMeasuredGeometry(aPnt1, aPnt2, aPnt3);
     } else {
-      Handle(AIS_AngleDimension) aDim = new AIS_AngleDimension(aPnt1, aPnt2, aPnt3);
+      Handle(PrsDim_AngleDimension) aDim = new PrsDim_AngleDimension(aPnt1, aPnt2, aPnt3);
       aAISObj = AISObjectPtr(new GeomAPI_AISObject());
       aAISObj->setImpl(new Handle(AIS_InteractiveObject)(aDim));
     }
@@ -579,12 +651,18 @@ void FeaturesPlugin_Measurement::setupDimension(AISObjectPtr theDim)
 {
   if (theDim.get()) {
     Handle(AIS_InteractiveObject) aAIS = theDim->impl<Handle(AIS_InteractiveObject)>();
-    Handle(AIS_Dimension) aDim = Handle(AIS_Dimension)::DownCast(aAIS);
+    Handle(PrsDim_Dimension) aDim = Handle(PrsDim_Dimension)::DownCast(aAIS);
     int aSize = Config_PropManager::integer("Visualization", "dimension_arrow_size");
     int aTextSize = Config_PropManager::integer("Visualization", "dimension_value_size");
     std::string aFont = Config_PropManager::string("Visualization", "dimension_font");
 
     Handle(Prs3d_DimensionAspect) anAspect = aDim->DimensionAspect();
+#if OCC_VERSION_LARGE >= 0x07070000
+    if (anAspect.IsNull()) {
+      aDim->Attributes()->SetupOwnDefaults();
+      anAspect = aDim->DimensionAspect();
+    }
+#endif
     anAspect->MakeArrows3d(false);
     anAspect->MakeText3d(false);
     anAspect->MakeTextShaded(false);
@@ -596,7 +674,7 @@ void FeaturesPlugin_Measurement::setupDimension(AISObjectPtr theDim)
     anAspect->SetExtensionSize((aTextSize / mySceenScale + aSize) / 2.0);
     aDim->SetDimensionAspect(anAspect);
 
-    aDim->SetZLayer(1);
+    aDim->SetZLayer(Graphic3d_ZLayerId_Top);
     std::vector<int> aColor = Config_PropManager::color("Visualization", "sketch_dimension_color");
     theDim->setColor(aColor[0], aColor[1], aColor[2]);
   }