Salome HOME
Issue #2504: Dimension presentations were added
[modules/shaper.git] / src / FeaturesPlugin / FeaturesPlugin_Measurement.cpp
index f038ecc954c613a43005cfe84be48b0d4755a247..56cc199db42d8679483f91ab3281795c2f17948b 100644 (file)
 
 #include <GeomAlgoAPI_ShapeTools.h>
 
+#include <Config_PropManager.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 <BRepExtrema_DistShapeShape.hxx>
+
 #include <iomanip>
 #include <sstream>
 
-FeaturesPlugin_Measurement::FeaturesPlugin_Measurement()
+FeaturesPlugin_Measurement::FeaturesPlugin_Measurement() : mySceenScale(1)
 {
 }
 
@@ -305,3 +315,267 @@ void FeaturesPlugin_Measurement::computeAngleByPoints()
   aValues->setSize(1);
   aValues->setValue(0, anAngleValue);
 }
+
+AISObjectPtr FeaturesPlugin_Measurement::getAISObject(AISObjectPtr thePrevious)
+{
+  AISObjectPtr anAIS;
+  std::string aKind = string(MEASURE_KIND())->value();
+  if (aKind == MEASURE_LENGTH())
+    anAIS = lengthDimension(thePrevious);
+  else if (aKind == MEASURE_DISTANCE())
+    anAIS = distanceDimension(thePrevious);
+  else if (aKind == MEASURE_RADIUS())
+    anAIS = radiusDimension(thePrevious);
+  else if (aKind == MEASURE_ANGLE())
+    anAIS = angleDimension(thePrevious);
+  else if (aKind == MEASURE_ANGLE_POINTS())
+    anAIS = angleByPointsDimension(thePrevious);
+  setupDimension(anAIS);
+  return anAIS;
+}
+
+AISObjectPtr FeaturesPlugin_Measurement::lengthDimension(AISObjectPtr thePrevious)
+{
+  AISObjectPtr aAISObj;
+  if (!myScreenPlane.get())
+    return aAISObj;
+
+  AttributeSelectionPtr aSelectedFeature = selection(EDGE_FOR_LENGTH_ID());
+
+  GeomShapePtr aShape;
+  GeomEdgePtr anEdge;
+  if (aSelectedFeature && aSelectedFeature->isInitialized()) {
+    aShape = aSelectedFeature->value();
+    if (!aShape && aSelectedFeature->context())
+      aShape = aSelectedFeature->context()->shape();
+  }
+  if (aShape && aShape->isEdge())
+    anEdge = GeomEdgePtr(new GeomAPI_Edge(aShape));
+  if (anEdge) {
+    TopoDS_Edge aTEdge = TopoDS::Edge(anEdge->impl<TopoDS_Shape>());
+    GeomPointPtr aPoint1 = anEdge->firstPoint();
+    GeomPointPtr aPoint2 = anEdge->lastPoint();
+
+    gp_Pnt aPnt1(aPoint1->impl<gp_Pnt>());
+    gp_Pnt aPnt2(aPoint2->impl<gp_Pnt>());
+
+    double aLength = aPnt1.Distance(aPnt2);
+    gp_Pln aPlane = myScreenPlane->impl<gp_Pln>(); // gce_MP.Value();
+    aPlane.SetLocation(aPnt1);
+
+    Handle(AIS_LengthDimension) aDim;
+    if (thePrevious.get()) {
+      aAISObj = thePrevious;
+      Handle(AIS_InteractiveObject) aAIS = aAISObj->impl<Handle(AIS_InteractiveObject)>();
+      aDim = Handle(AIS_LengthDimension)::DownCast(aAIS);
+      if (aDim.IsNull()) {
+        aDim = new AIS_LengthDimension(aTEdge, aPlane);
+        aAISObj->setImpl(new Handle(AIS_InteractiveObject)(aDim));
+      } else {
+        aDim->SetMeasuredGeometry(aTEdge, aPlane);
+      }
+    } else {
+      aDim = new AIS_LengthDimension(aTEdge, aPlane);
+      aAISObj = AISObjectPtr(new GeomAPI_AISObject());
+      aAISObj->setImpl(new Handle(AIS_InteractiveObject)(aDim));
+    }
+    aDim->SetFlyout(aLength / 3.);
+  }
+  return aAISObj;
+}
+
+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());
+  if (aFirstFeature.get() && aSecondFeature.get()) {
+    GeomShapePtr aShape1;
+    GeomShapePtr aShape2;
+    if (aFirstFeature->isInitialized() && aSecondFeature->isInitialized()) {
+      aShape1 = aFirstFeature->value();
+      if (!aShape1 && aFirstFeature->context())
+        aShape1 = aFirstFeature->context()->shape();
+      aShape2 = aSecondFeature->value();
+      if (!aShape2 && aSecondFeature->context())
+        aShape2 = aSecondFeature->context()->shape();
+    }
+
+    if (aShape1 && aShape2) {
+      const TopoDS_Shape& aShp1 = aShape1->impl<TopoDS_Shape>();
+      const TopoDS_Shape& aShp2 = aShape2->impl<TopoDS_Shape>();
+      BRepExtrema_DistShapeShape aDist(aShp1, aShp2);
+      aDist.Perform();
+      if (aDist.IsDone()) {
+        gp_Pnt aPnt1 = aDist.PointOnShape1(1);
+        gp_Pnt aPnt2 = aDist.PointOnShape2(1);
+        double aDistance = aDist.Value();
+        gp_Pln aPlane = myScreenPlane->impl<gp_Pln>();
+        aPlane.SetLocation(aPnt1);
+
+        Handle(AIS_LengthDimension) aDim;
+        if (thePrevious.get()) {
+          aAISObj = thePrevious;
+          Handle(AIS_InteractiveObject) aAIS = aAISObj->impl<Handle(AIS_InteractiveObject)>();
+          aDim = Handle(AIS_LengthDimension)::DownCast(aAIS);
+          if (aDim.IsNull()) {
+            aDim = new AIS_LengthDimension(aPnt1, aPnt2, aPlane);
+            aAISObj->setImpl(new Handle(AIS_InteractiveObject)(aDim));
+          } else {
+            aDim->SetMeasuredGeometry(aPnt1, aPnt2, aPlane);
+            aDim->SetFlyout(aDistance / 3.);
+          }
+        } else {
+          aAISObj = AISObjectPtr(new GeomAPI_AISObject());
+          aDim = new AIS_LengthDimension(aPnt1, aPnt2, aPlane);
+          aAISObj->setImpl(new Handle(AIS_InteractiveObject)(aDim));
+        }
+        aDim->SetFlyout(aDistance / 3.);
+      }
+    }
+  }
+  return aAISObj;
+}
+
+AISObjectPtr FeaturesPlugin_Measurement::radiusDimension(AISObjectPtr thePrevious)
+{
+  AISObjectPtr aAISObj;
+  AttributeSelectionPtr aSelectedFeature = selection(CIRCULAR_OBJECT_ID());
+
+  GeomShapePtr aShape;
+  if (aSelectedFeature && aSelectedFeature->isInitialized()) {
+    aShape = aSelectedFeature->value();
+    if (!aShape && aSelectedFeature->context())
+      aShape = aSelectedFeature->context()->shape();
+  }
+  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);
+      if (aDim.IsNull()) {
+        aDim = new AIS_RadiusDimension(aShp);
+        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);
+      aAISObj->setImpl(new Handle(AIS_InteractiveObject)(aDim));
+    }
+  }
+  return aAISObj;
+}
+
+AISObjectPtr FeaturesPlugin_Measurement::angleDimension(AISObjectPtr thePrevious)
+{
+  AISObjectPtr aAISObj;
+  AttributeSelectionPtr aFirstFeature = selection(ANGLE_FROM_EDGE_ID());
+  GeomShapePtr aShape1;
+  GeomEdgePtr anEdge1;
+  if (aFirstFeature && aFirstFeature->isInitialized()) {
+    aShape1 = aFirstFeature->value();
+    if (!aShape1 && aFirstFeature->context())
+      aShape1 = aFirstFeature->context()->shape();
+  }
+  if (aShape1 && aShape1->isEdge())
+    anEdge1 = GeomEdgePtr(new GeomAPI_Edge(aShape1));
+
+  AttributeSelectionPtr aSecondFeature = selection(ANGLE_TO_EDGE_ID());
+  GeomShapePtr aShape2;
+  GeomEdgePtr anEdge2;
+  if (aSecondFeature && aSecondFeature->isInitialized()) {
+    aShape2 = aSecondFeature->value();
+    if (!aShape2 && aSecondFeature->context())
+      aShape2 = aSecondFeature->context()->shape();
+  }
+  if (aShape2 && aShape2->isEdge())
+    anEdge2 = GeomEdgePtr(new GeomAPI_Edge(aShape2));
+
+  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;
+    if (thePrevious.get()) {
+      aAISObj = thePrevious;
+      Handle(AIS_InteractiveObject) aAIS = aAISObj->impl<Handle(AIS_InteractiveObject)>();
+      aDim = Handle(AIS_AngleDimension)::DownCast(aAIS);
+      if (aDim.IsNull()) {
+        aDim = new AIS_AngleDimension(aTEdge1, aTEdge2);
+        aAISObj->setImpl(new Handle(AIS_InteractiveObject)(aDim));
+      } else
+        aDim->SetMeasuredGeometry(aTEdge1, aTEdge2);
+    } else {
+      aAISObj = AISObjectPtr(new GeomAPI_AISObject());
+      aDim = new AIS_AngleDimension(aTEdge1, aTEdge2);
+      aAISObj->setImpl(new Handle(AIS_InteractiveObject)(aDim));
+    }
+  }
+  return aAISObj;
+}
+
+AISObjectPtr FeaturesPlugin_Measurement::angleByPointsDimension(AISObjectPtr thePrevious)
+{
+  AISObjectPtr aAISObj;
+  GeomVertexPtr aVertex1 = selectionToVertex(selection(ANGLE_POINT1_ID()));
+  GeomVertexPtr aVertex2 = selectionToVertex(selection(ANGLE_POINT2_ID()));
+  GeomVertexPtr aVertex3 = selectionToVertex(selection(ANGLE_POINT3_ID()));
+
+  if (aVertex1.get() && aVertex2.get() && aVertex3.get()) {
+    GeomPointPtr aPoint1 = aVertex1->point();
+    GeomPointPtr aPoint2 = aVertex2->point();
+    GeomPointPtr aPoint3 = aVertex3->point();
+    gp_Pnt aPnt1(aPoint1->impl<gp_Pnt>());
+    gp_Pnt aPnt2(aPoint2->impl<gp_Pnt>());
+    gp_Pnt aPnt3(aPoint3->impl<gp_Pnt>());
+
+    if (thePrevious.get()) {
+      aAISObj = thePrevious;
+      Handle(AIS_InteractiveObject) aAIS = aAISObj->impl<Handle(AIS_InteractiveObject)>();
+      Handle(AIS_AngleDimension) aDim = Handle(AIS_AngleDimension)::DownCast(aAIS);
+      if (aDim.IsNull()) {
+        aDim = new AIS_AngleDimension(aPnt1, aPnt2, aPnt3);
+        aAISObj->setImpl(new Handle(AIS_InteractiveObject)(aDim));
+      } else
+        aDim->SetMeasuredGeometry(aPnt1, aPnt2, aPnt3);
+    } else {
+      Handle(AIS_AngleDimension) aDim = new AIS_AngleDimension(aPnt1, aPnt2, aPnt3);
+      aAISObj = AISObjectPtr(new GeomAPI_AISObject());
+      aAISObj->setImpl(new Handle(AIS_InteractiveObject)(aDim));
+    }
+  }
+  return aAISObj;
+}
+
+
+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);
+    int aSize = Config_PropManager::integer("Visualization", "dimension_arrow_size");
+    int aTextSize = Config_PropManager::integer("Visualization", "dimension_value_size");
+
+    Handle(Prs3d_DimensionAspect) anAspect = aDim->DimensionAspect();
+    anAspect->MakeArrows3d(false);
+    anAspect->MakeText3d(false);
+    anAspect->MakeTextShaded(false);
+    anAspect->MakeUnitsDisplayed(false);
+    anAspect->MakeUnitsDisplayed(false);
+    anAspect->TextAspect()->SetFont(Config_PropManager::string("Visualization",
+      "dimension_font").c_str());
+    anAspect->TextAspect()->SetHeight(aTextSize / mySceenScale);
+    anAspect->ArrowAspect()->SetLength(aSize / mySceenScale);
+    anAspect->SetExtensionSize((aTextSize / mySceenScale + aSize) / 2.0);
+    aDim->SetDimensionAspect(anAspect);
+
+    aDim->SetZLayer(1);
+    std::vector<int> aColor = Config_PropManager::color("Visualization", "sketch_dimension_color");
+    theDim->setColor(aColor[0], aColor[1], aColor[2]);
+  }
+}