Salome HOME
Issue #2208: Tangent constraint position implementation
authorvsv <vsv@opencascade.com>
Wed, 5 Jul 2017 16:44:47 +0000 (19:44 +0300)
committervsv <vsv@opencascade.com>
Wed, 5 Jul 2017 16:45:08 +0000 (19:45 +0300)
src/GeomAPI/GeomAPI_Curve.h
src/SketcherPrs/SketcherPrs_PositionMgr.cpp
src/SketcherPrs/SketcherPrs_PositionMgr.h
src/SketcherPrs/SketcherPrs_Tangent.cpp

index 2d942dd7cf5da18decc27817e35ab4dc41a00d9e..70bafd8299240d441fea44ac9f4d8de6a0a73b2c 100644 (file)
@@ -72,4 +72,7 @@ private:
   double myEnd;
 };
 
+//! Pointer on the object
+typedef std::shared_ptr<GeomAPI_Curve> GeomCurvePtr;
+
 #endif
index d77e0301390a2bc432e1be1c97dbc075d82fab64..1dbe75116261420c424b26c43335b1889d0f8551 100644 (file)
 #include <GeomAPI_Vertex.h>
 #include <GeomAPI_Dir.h>
 
+#include <BRepExtrema_ExtPC.hxx>
+#include <TopoDS_Vertex.hxx>
+#include <Geom_Curve.hxx>
+
 static SketcherPrs_PositionMgr* MyPosMgr = NULL;
 
 // The class is implemented as a singlton
@@ -65,54 +69,78 @@ int SketcherPrs_PositionMgr::getPositionIndex(ObjectPtr theLine,
   }
 }
 
-gp_Pnt SketcherPrs_PositionMgr::getPosition(ObjectPtr theShape,
-                                            const SketcherPrs_SymbolPrs* thePrs,
-                                            double theStep)
+
+gp_Vec getVector(ObjectPtr theShape, GeomDirPtr theDir, gp_Pnt theP)
 {
+  gp_Vec aVec;
   std::shared_ptr<GeomAPI_Shape> aShape = SketcherPrs_Tools::getShape(theShape);
-  gp_Pnt aP; // Central point
-  gp_Vec aVec1; // main vector
   if (aShape->isEdge()) {
     std::shared_ptr<GeomAPI_Curve> aCurve =
       std::shared_ptr<GeomAPI_Curve>(new GeomAPI_Curve(aShape));
-    std::shared_ptr<GeomAPI_Pnt> aPnt1; // Start point of main vector
-    std::shared_ptr<GeomAPI_Pnt> aPnt2; // End point of main vector
-    if (aCurve->isLine()) {
-      std::shared_ptr<GeomAPI_Edge> aEdge =
-        std::shared_ptr<GeomAPI_Edge>(new GeomAPI_Edge(aShape));
 
-      aPnt1 = aEdge->firstPoint();
-      aPnt2 = aEdge->lastPoint();
+    if (aCurve->isCircle()) {
+      GeomEdgePtr aEdgePtr(new GeomAPI_Edge(aShape));
+      GeomVertexPtr aVertexPtr(new GeomAPI_Vertex(theP.X(), theP.Y(), theP.Z()));
+      BRepExtrema_ExtPC aExtrema(aVertexPtr->impl<TopoDS_Vertex>(),
+                                 aEdgePtr->impl<TopoDS_Edge>());
+      int aNb = aExtrema.NbExt();
+      if (aNb > 0) {
+        for (int i = 1; i <= aNb; i++) {
+          if (aExtrema.IsMin(i)) {
+            double aParam = aExtrema.Parameter(i);
+            Handle(Geom_Curve) aCurv = aCurve->impl<Handle_Geom_Curve>();
+            gp_Pnt aP;
+            aCurv->D1(aParam, aP, aVec);
+            break;
+          }
+        }
+      }
+    } else {
+      double aMidParam = (aCurve->startParam() + aCurve->endParam()) / 2.;
+      GeomPointPtr aPnt1 = aCurve->getPoint((aMidParam + aCurve->endParam()) / 2.);
+      GeomPointPtr aPnt2 = aCurve->getPoint((aMidParam + aCurve->startParam()) / 2.);
 
-      // Find the middle point
-      aP = gp_Pnt((aPnt1->x() + aPnt2->x())/2.,
-                  (aPnt1->y() + aPnt2->y())/2.,
-                  (aPnt1->z() + aPnt2->z())/2.);
+      aVec = gp_Vec(aPnt1->impl<gp_Pnt>(), aPnt2->impl<gp_Pnt>());
+    }
+  } else {
+    aVec = gp_Vec(theDir->impl<gp_Dir>());
+  }
+  return aVec;
+}
 
-    } else {
+gp_Pnt SketcherPrs_PositionMgr::getPosition(ObjectPtr theShape,
+                                            const SketcherPrs_SymbolPrs* thePrs,
+                                            double theStep, GeomPointPtr thePnt)
+{
+  std::shared_ptr<GeomAPI_Shape> aShape = SketcherPrs_Tools::getShape(theShape);
+  gp_Pnt aP; // Central point
+
+  if (thePnt.get()) {
+    aP = thePnt->impl<gp_Pnt>();
+  } else {
+    if (aShape->isEdge()) {
+      std::shared_ptr<GeomAPI_Curve> aCurve =
+        std::shared_ptr<GeomAPI_Curve>(new GeomAPI_Curve(aShape));
       // this is a circle or arc
       double aMidParam = (aCurve->startParam() + aCurve->endParam()) / 2.;
       std::shared_ptr<GeomAPI_Pnt> aPnt = aCurve->getPoint(aMidParam);
       aP = aPnt->impl<gp_Pnt>();
-
-      aPnt1 = aCurve->getPoint((aMidParam + aCurve->endParam()) / 2.);
-      aPnt2 = aCurve->getPoint((aMidParam + aCurve->startParam()) / 2.);
+    } else {
+      // This is a point
+      std::shared_ptr<GeomAPI_Vertex> aVertex =
+        std::shared_ptr<GeomAPI_Vertex>(new GeomAPI_Vertex(aShape));
+      std::shared_ptr<GeomAPI_Pnt> aPnt = aVertex->point();
+      aP = aPnt->impl<gp_Pnt>();
     }
-    aVec1 = gp_Vec(aPnt1->impl<gp_Pnt>(), aPnt2->impl<gp_Pnt>());
-  } else {
-    // This is a point
-    std::shared_ptr<GeomAPI_Vertex> aVertex =
-      std::shared_ptr<GeomAPI_Vertex>(new GeomAPI_Vertex(aShape));
-    std::shared_ptr<GeomAPI_Pnt> aPnt = aVertex->point();
-    aP = aPnt->impl<gp_Pnt>();
-
-    std::shared_ptr<GeomAPI_Dir> aDir = thePrs->plane()->dirX();
-    aVec1 = gp_Vec(aDir->impl<gp_Dir>());
   }
+  // main vector
+  gp_Vec aVec1 = getVector(theShape, thePrs->plane()->dirX(), aP);
+
   // Compute shifting vector for a one symbol
   gp_Vec aShift = aVec1.Crossed(thePrs->plane()->normal()->impl<gp_Dir>());
   aShift.Normalize();
-  aShift.Multiply(theStep * 0.8);
+  // For point based symbols step = 1.2, for line based = 0.8
+  aShift.Multiply(theStep * (thePnt.get()? 1.2 : 0.8));
 
   // Shift the position coordinate according to position index
   int aPos = getPositionIndex(theShape, thePrs);
index d9bb444ee17776a7470a45417ff5352a4c3f8c28..8de0204b44bbd09f1d0e733f11c48360deffa756 100644 (file)
@@ -24,6 +24,7 @@
 #include "SketcherPrs_SymbolPrs.h"
 
 #include <GeomAPI_Shape.h>
+#include <GeomAPI_Pnt.h>
 #include <gp_Pnt.hxx>
 #include <ModelAPI_Object.h>
 
@@ -44,7 +45,8 @@ public:
   /// \param theLine constrained object
   /// \param thePrs a presentation of constraint
   /// \param theStep step between symbols
-  gp_Pnt getPosition(ObjectPtr theLine, const SketcherPrs_SymbolPrs* thePrs, double theStep = 20);
+  gp_Pnt getPosition(ObjectPtr theLine, const SketcherPrs_SymbolPrs* thePrs,
+                     double theStep = 20, GeomPointPtr thePnt = GeomPointPtr());
 
   /// Deletes constraint object from internal structures. Has to be called on constraint delete.
   /// \param thePrs a constraint presentation
index 5a7d2a538e4a613c23111f57c1d417837ace3ae8..74ee2ed6910eb2b0978f1ceb9624cce8972e05a5 100644 (file)
@@ -68,13 +68,29 @@ bool SketcherPrs_Tangent::updateIfReadyToDisplay(double theStep, bool withColor)
   ObjectPtr aObj2 =
     SketcherPrs_Tools::getResult(myConstraint, SketchPlugin_Constraint::ENTITY_B());
 
+  GeomShapePtr aShp1 = SketcherPrs_Tools::getShape(aObj1);
+  GeomShapePtr aShp2 = SketcherPrs_Tools::getShape(aObj2);
+
+  GeomCurvePtr aCurv1 = std::shared_ptr<GeomAPI_Curve>(new GeomAPI_Curve(aShp1));
+  GeomCurvePtr aCurv2 = std::shared_ptr<GeomAPI_Curve>(new GeomAPI_Curve(aShp2));
+
+  GeomPointPtr aPnt1_1 = aCurv1->getPoint(aCurv1->startParam());
+  GeomPointPtr aPnt1_2 = aCurv1->getPoint(aCurv1->endParam());
+
+  GeomPointPtr aPnt2_1 = aCurv2->getPoint(aCurv2->startParam());
+  GeomPointPtr aPnt2_2 = aCurv2->getPoint(aCurv2->endParam());
+
+  GeomPointPtr aPnt;
+  if (aPnt1_1->isEqual(aPnt2_1) || aPnt1_1->isEqual(aPnt2_2))
+    aPnt = aPnt1_1;
+  else if (aPnt1_2->isEqual(aPnt2_1) || aPnt1_2->isEqual(aPnt2_2))
+    aPnt = aPnt1_2;
+
   // Compute points coordinates
   SketcherPrs_PositionMgr* aMgr = SketcherPrs_PositionMgr::get();
-  gp_Pnt aP1 = aMgr->getPosition(aObj1, this, theStep);
-  gp_Pnt aP2 = aMgr->getPosition(aObj2, this, theStep);
-  myPntArray = new Graphic3d_ArrayOfPoints(2, withColor);
+  gp_Pnt aP1 = aMgr->getPosition(aObj1, this, theStep, aPnt);
+  myPntArray = new Graphic3d_ArrayOfPoints(1, withColor);
   myPntArray->AddVertex(aP1);
-  myPntArray->AddVertex(aP2);
   return true;
 }