Salome HOME
Preparation of intermediate revision
[modules/geom.git] / src / GEOMImpl / GEOMImpl_PointDriver.cxx
index accc93779831f70536f256e6681b999134903a69..f1d64125d72052ff21222478496b892d9b8b53bc 100644 (file)
@@ -62,6 +62,35 @@ GEOMImpl_PointDriver::GEOMImpl_PointDriver()
 {
 }
 
+//=======================================================================
+//function : getExtremaSolution
+//purpose  : local function
+//=======================================================================
+static Standard_Boolean getExtremaSolution
+(GEOMImpl_IPoint& thePI,
+ TopoDS_Shape&    theRefShape,
+ gp_Pnt& thePnt)
+{
+  gp_Pnt anInitPnt( thePI.GetX(), thePI.GetY(), thePI.GetZ() );
+  BRepBuilderAPI_MakeVertex mkVertex (anInitPnt);
+  TopoDS_Vertex anInitV = TopoDS::Vertex(mkVertex.Shape());
+  
+  BRepExtrema_DistShapeShape anExt( anInitV, theRefShape );
+  if ( !anExt.IsDone() || anExt.NbSolution() < 1 )
+    return Standard_False;
+  thePnt = anExt.PointOnShape2(1);
+  Standard_Real aMinDist2 = anInitPnt.SquareDistance( thePnt );
+  for ( Standard_Integer j = 2, jn = anExt.NbSolution(); j <= jn; j++ )
+  {
+    gp_Pnt aPnt = anExt.PointOnShape2(j);
+    Standard_Real aDist2 = anInitPnt.SquareDistance( aPnt );
+    if ( aDist2 > aMinDist2)
+      continue;
+    aMinDist2 = aDist2;
+    thePnt = aPnt;
+  }
+  return Standard_True;
+}
 
 //=======================================================================
 //function : Execute
@@ -105,6 +134,18 @@ Standard_Integer GEOMImpl_PointDriver::Execute(TFunction_Logbook& log) const
     aP = aFP + (aLP - aFP) * aPI.GetParameter();
     aPnt = aCurve->Value(aP);
   }
+  else if (aType == POINT_CURVE_COORD) {
+    Handle(GEOM_Function) aRefCurve = aPI.GetCurve();
+    TopoDS_Shape aRefShape = aRefCurve->GetValue();
+    if (aRefShape.ShapeType() != TopAbs_EDGE) {
+      Standard_TypeMismatch::Raise
+        ("Point On Curve creation aborted : curve shape is not an edge");
+    }
+    if (!getExtremaSolution( aPI, aRefShape, aPnt ) ) {
+      Standard_ConstructionError::Raise
+        ("Point On Curve creation aborted : cannot project point");
+    }
+  }
   else if (aType == POINT_SURFACE_PAR) {
     Handle(GEOM_Function) aRefCurve = aPI.GetSurface();
     TopoDS_Shape aRefShape = aRefCurve->GetValue();
@@ -121,6 +162,18 @@ Standard_Integer GEOMImpl_PointDriver::Execute(TFunction_Logbook& log) const
     Standard_Real V = V1 + (V2-V1) * aPI.GetParameter2();
     aPnt = aSurf->Value(U,V);
   }
+  else if (aType == POINT_SURFACE_COORD) {
+    Handle(GEOM_Function) aRefCurve = aPI.GetSurface();
+    TopoDS_Shape aRefShape = aRefCurve->GetValue();
+    if (aRefShape.ShapeType() != TopAbs_FACE) {
+      Standard_TypeMismatch::Raise
+        ("Point On Surface creation aborted : surface shape is not a face");
+    }
+    if (!getExtremaSolution( aPI, aRefShape, aPnt ) ) {
+      Standard_ConstructionError::Raise
+        ("Point On Surface creation aborted : cannot project point");
+    }
+  }
   else if (aType == POINT_LINES_INTERSECTION) {
     Handle(GEOM_Function) aRef1 = aPI.GetLine1();
     Handle(GEOM_Function) aRef2 = aPI.GetLine2();