Salome HOME
0023450: Fields are not displayed in GEOM
[modules/geom.git] / src / GEOMImpl / GEOMImpl_ProjectionDriver.cxx
index d226969c88619e2cb3432b6e5d77d08e4ee745fe..966ebc824b40a7a967141c01013d2b987150f6c8 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2016  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -33,6 +33,8 @@
 #include <GEOMUtils_HTrsfCurve2d.hxx>
 
 #include <Approx_Curve2d.hxx>
+#include <Bnd_Box2d.hxx>
+#include <BndLib_Add2dCurve.hxx>
 #include <BRep_Tool.hxx>
 #include <BRepAdaptor_Curve2d.hxx>
 #include <BRepBuilderAPI_Transform.hxx>
@@ -91,7 +93,7 @@ GEOMImpl_ProjectionDriver::GEOMImpl_ProjectionDriver()
 //function : Execute
 //purpose  :
 //======================================================================= 
-Standard_Integer GEOMImpl_ProjectionDriver::Execute(TFunction_Logbook& log) const
+Standard_Integer GEOMImpl_ProjectionDriver::Execute(Handle(TFunction_Logbook)& log) const
 {
   if (Label().IsNull())  return 0;    
   Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());
@@ -158,7 +160,7 @@ Standard_Integer GEOMImpl_ProjectionDriver::Execute(TFunction_Logbook& log) cons
         Standard_ConstructionError::Raise("No solution found");
       }
 
-      Quantity_Parameter U, V;
+      Standard_Real U, V;
       proj.LowerDistanceParameters(U, V);
       gp_Pnt2d aProjPnt (U, V);
 
@@ -168,7 +170,7 @@ Standard_Integer GEOMImpl_ProjectionDriver::Execute(TFunction_Logbook& log) cons
         bool isSol = false;
         double minDist = RealLast();
         for (int i = 1; i <= nbPoints; i++) {
-          Quantity_Parameter Ui, Vi;
+          Standard_Real Ui, Vi;
           proj.Parameters(i, Ui, Vi);
           aProjPnt = gp_Pnt2d(Ui, Vi);
           aClsf.Perform(aFace, aProjPnt, tol);
@@ -245,7 +247,7 @@ Standard_Integer GEOMImpl_ProjectionDriver::Execute(TFunction_Logbook& log) cons
     if (aShape.IsNull()) return 0;
 
     aFunction->SetValue(aShape);
-    log.SetTouched(Label()); 
+    log->SetTouched(Label());
   } else if (aType == PROJECTION_ON_WIRE) {
     // Perform projection of point on a wire or an edge.
     GEOMImpl_IProjection aProj (aFunction);
@@ -428,10 +430,11 @@ Standard_Integer GEOMImpl_ProjectionDriver::Execute(TFunction_Logbook& log) cons
     }
 
     // Get the face.
-    const TopAbs_ShapeEnum aType        = aShape.ShapeType();
-    const Standard_Real    aRadius      = aProj.GetRadius();
-    const Standard_Real    aStartAngle  = aProj.GetStartAngle();
-    const Standard_Real    aLengthAngle = aProj.GetAngleLength();
+    const TopAbs_ShapeEnum aType          = aShape.ShapeType();
+    const Standard_Real    aRadius        = aProj.GetRadius();
+    const Standard_Real    aStartAngle    = aProj.GetStartAngle();
+    const Standard_Real    aLengthAngle   = aProj.GetAngleLength();
+    const Standard_Real    aRotationAngle = aProj.GetAngleRotation();
 
     if (aType != TopAbs_WIRE && aType != TopAbs_FACE) {
       return 0;
@@ -441,8 +444,8 @@ Standard_Integer GEOMImpl_ProjectionDriver::Execute(TFunction_Logbook& log) cons
       return 0;
     }
 
-    TopoDS_Shape aProjShape =
-      projectOnCylinder(aShape, aRadius, aStartAngle, aLengthAngle);
+    TopoDS_Shape aProjShape = projectOnCylinder
+      (aShape, aRadius, aStartAngle, aLengthAngle, aRotationAngle);
 
     if (aProjShape.IsNull()) {
       return 0;
@@ -473,41 +476,45 @@ GetCreationInformation(std::string&             theOperationName,
 
   switch ( aType ) {
   case PROJECTION_COPY:
-    {
-      GEOMImpl_IMirror aCI( function );
+  {
+    GEOMImpl_IMirror aCI( function );
 
-      AddParam( theParams, "Source object", aCI.GetOriginal() );
-      AddParam( theParams, "Target face", aCI.GetPlane() );
-      break;
-    }
+    AddParam( theParams, "Source object", aCI.GetOriginal() );
+    AddParam( theParams, "Target face", aCI.GetPlane() );
+    break;
+  }
   case PROJECTION_ON_WIRE:
-    {
-      GEOMImpl_IProjection aProj (function);
+  {
+    GEOMImpl_IProjection aProj (function);
 
-      AddParam(theParams, "Point", aProj.GetPoint());
-      AddParam(theParams, "Shape", aProj.GetShape());
+    AddParam(theParams, "Point", aProj.GetPoint());
+    AddParam(theParams, "Shape", aProj.GetShape());
 
-      break;
-    }
+    break;
+  }
   case PROJECTION_ON_CYLINDER:
-    {
-      GEOMImpl_IProjOnCyl aProj (function);
-      const Standard_Real aLengthAngle = aProj.GetAngleLength();
+  {
+    theOperationName = "PROJ_ON_CYL";
 
-      AddParam(theParams, "Shape",        aProj.GetShape());
-      AddParam(theParams, "Radius",       aProj.GetRadius());
-      AddParam(theParams, "Start angle",  aProj.GetStartAngle());
+    GEOMImpl_IProjOnCyl aProj (function);
+    const Standard_Real aLengthAngle = aProj.GetAngleLength();
 
-      if (aLengthAngle >= 0.) {
-        AddParam(theParams, "Length angle", aLengthAngle);
-      }
+    AddParam(theParams, "Shape",        aProj.GetShape());
+    AddParam(theParams, "Radius",       aProj.GetRadius());
+    AddParam(theParams, "Start angle",  aProj.GetStartAngle());
 
-      break;
+    if (aLengthAngle >= 0.) {
+      AddParam(theParams, "Length angle", aLengthAngle);
     }
+
+    AddParam(theParams, "Rotation angle", aProj.GetAngleRotation());
+
+    break;
+  }
   default:
     return false;
   }
-  
+
   return true;
 }
 
@@ -521,7 +528,8 @@ TopoDS_Shape GEOMImpl_ProjectionDriver::projectOnCylinder
                                 (const TopoDS_Shape  &theShape,
                                  const Standard_Real  theRadius,
                                  const Standard_Real  theStartAngle,
-                                 const Standard_Real  theAngleLength) const
+                                 const Standard_Real  theAngleLength,
+                                 const Standard_Real  theAngleRotation) const
 {
   TopoDS_Shape aResult;
 
@@ -594,8 +602,6 @@ TopoDS_Shape GEOMImpl_ProjectionDriver::projectOnCylinder
 
   // Compute 2d translation transformation.
   TopoDS_Wire            anOuterWire = BRepTools::OuterWire(aFace);
-  Standard_Real          aU[2];
-  Standard_Real          aV[2];
   BRepTools_WireExplorer aOWExp(anOuterWire, aFace);
 
   if (!aOWExp.More()) {
@@ -603,21 +609,63 @@ TopoDS_Shape GEOMImpl_ProjectionDriver::projectOnCylinder
     return aResult;
   }
 
-  // Compute anisotropic transformation from a face's 2d space
-  // to cylinder's 2d space.
-  BRepTools::UVBounds(aFace, anOuterWire, aU[0], aU[1], aV[0], aV[1]);
-
+  // Rotate 2D presentation of face.
   TopoDS_Vertex       aFirstVertex = aOWExp.CurrentVertex();
   TopoDS_Edge         aFirstEdge   = aOWExp.Current();
   gp_Pnt              aPnt         = BRep_Tool::Pnt(aFirstVertex);
   BRepAdaptor_Curve2d anAdaptorCurve(aFirstEdge, aFace);
   Standard_Real       aParam       =
     BRep_Tool::Parameter(aFirstVertex, aFirstEdge, aFace);
-  gp_Pnt2d            aPntUV       = anAdaptorCurve.Value(aParam);
+  gp_Pnt2d            aPntUV;
+  gp_Vec2d            aVecUV;
+  gp_Vec2d            aVecU0(1., 0);
+
+  anAdaptorCurve.D1(aParam, aPntUV, aVecUV);
+
+  if (aVecUV.Magnitude() <= gp::Resolution()) {
+    return aResult;
+  }
+
+  if (aFirstEdge.Orientation() == TopAbs_REVERSED) {
+    aVecUV.Reverse();
+  }
 
+  const Standard_Real    anAngle    = aVecUV.Angle(aVecU0) + theAngleRotation;
+  const Standard_Boolean isToRotate = Abs(anAngle) > Precision::Angular();
+  gp_Trsf2d              aRotTrsf;
+  Bnd_Box2d              aUVBox;
+  Standard_Real          aPar[2];
+
+  if (isToRotate) {
+    aRotTrsf.SetRotation(aPntUV, anAngle);
+  }
+
+  for (; aOWExp.More(); aOWExp.Next()) {
+    TopoDS_Edge                 anEdge   = aOWExp.Current();
+    Handle(Geom2d_Curve)        aCurve   =
+        BRep_Tool::CurveOnSurface(anEdge, aFace, aPar[0], aPar[1]);
+
+    if (aCurve.IsNull()) {
+      continue;
+    }
+
+    if (isToRotate) {
+      aCurve = Handle(Geom2d_Curve)::DownCast(aCurve->Transformed(aRotTrsf));
+    }
+
+    BndLib_Add2dCurve::Add(aCurve, aPar[0], aPar[1], 0., aUVBox);
+  }
+
+  Standard_Real aU[2];
+  Standard_Real aV[2];
+
+  aUVBox.Get(aU[0], aV[0], aU[1], aV[1]);
+
+  // Compute anisotropic transformation from a face's 2d space
+  // to cylinder's 2d space.
   GEOMUtils::Trsf2d aTrsf2d
             (1./theRadius, 0., theStartAngle - aU[0]/theRadius,
-             0.,           1., aPnt.Z() - 0.5*(aV[1] - aV[0]) - aPntUV.Y());
+             0.,           1., aPnt.Z() - aPntUV.Y());
 
   // Compute scaling trsf.
   const Standard_Boolean isToScale = theAngleLength >= Precision::Angular();
@@ -638,7 +686,6 @@ TopoDS_Shape GEOMImpl_ProjectionDriver::projectOnCylinder
     new Geom_CylindricalSurface(gp_Ax3(), theRadius);
   GeomAdaptor_Surface  aGACyl(aCylinder);
   TopExp_Explorer      anExp(aFace, TopAbs_WIRE);
-  Standard_Real        aPar[2];
   TopTools_ListOfShape aWires;
   Standard_Real        aUResol = aGACyl.UResolution(Precision::Confusion());
   Standard_Real        aVResol = aGACyl.VResolution(Precision::Confusion());
@@ -657,11 +704,15 @@ TopoDS_Shape GEOMImpl_ProjectionDriver::projectOnCylinder
         continue;
       }
 
+      if (isToRotate) {
+        aCurve = Handle(Geom2d_Curve)::DownCast(aCurve->Transformed(aRotTrsf));
+      }
+
       // Transform the curve to cylinder's parametric space.
-      GEOMUtils::Handle(HTrsfCurve2d) aTrsfCurve =
+      Handle(GEOMUtils::HTrsfCurve2d) aTrsfCurve =
         new GEOMUtils::HTrsfCurve2d(aCurve, aPar[0], aPar[1], aTrsf2d);
       Approx_Curve2d                  aConv (aTrsfCurve, aPar[0], aPar[1],
-                                                        aUResol, aVResol, GeomAbs_C1,
+                                                         aUResol, aVResol, GeomAbs_C1,
                                              9, 1000);
 
       if (!aConv.IsDone() && !aConv.HasResult()) {
@@ -748,5 +799,4 @@ TopoDS_Shape GEOMImpl_ProjectionDriver::projectOnCylinder
   return aResult;
 }
 
-IMPLEMENT_STANDARD_HANDLE (GEOMImpl_ProjectionDriver,GEOM_BaseDriver);
 IMPLEMENT_STANDARD_RTTIEXT (GEOMImpl_ProjectionDriver,GEOM_BaseDriver);