Salome HOME
22752: [EDF] Provide explicit feedback on what has been done by Shape Processing...
[modules/geom.git] / src / GEOMImpl / GEOMImpl_PipeDriver.cxx
index 21475ee427f61ef7124d705f724cfcb134cd73cd..5f580ddb95ef9f38a6fdeb56811dbe0045affe50 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2014  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
@@ -6,7 +6,7 @@
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Lesser General Public
 // License as published by the Free Software Foundation; either
-// version 2.1 of the License.
+// version 2.1 of the License, or (at your option) any later version.
 //
 // This library is distributed in the hope that it will be useful,
 // but WITHOUT ANY WARRANTY; without even the implied warranty of
 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 //
 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
-
-#include <Standard_Stream.hxx>
+//
 
 #include <GEOMImpl_PipeDriver.hxx>
 
-#include <GEOMImpl_IShapesOperations.hxx>
 #include <GEOMImpl_IPipeDiffSect.hxx>
 #include <GEOMImpl_IPipeShellSect.hxx>
 #include <GEOMImpl_IPipeBiNormal.hxx>
 #include <GEOMImpl_IPipe.hxx>
+#include <GEOMImpl_IPipePath.hxx>
 #include <GEOMImpl_GlueDriver.hxx>
 #include <GEOMImpl_Types.hxx>
+
 #include <GEOM_Function.hxx>
 
+#include <GEOMUtils.hxx>
+
 #include <ShapeAnalysis_FreeBounds.hxx>
 #include <ShapeAnalysis_Edge.hxx>
 #include <ShapeFix_Face.hxx>
 
 #include <BRep_Tool.hxx>
 #include <BRep_Builder.hxx>
+#include <BRepBuilderAPI_Copy.hxx>
+#include <BRepBuilderAPI_MakeFace.hxx>
 #include <BRepBuilderAPI_MakeWire.hxx>
 #include <BRepBuilderAPI_Sewing.hxx>
 #include <BRepCheck_Analyzer.hxx>
+#include <BRepGProp.hxx>
+#include <GeomFill_Trihedron.hxx>
+#include <GeomFill_CorrectedFrenet.hxx>
 #include <BRepOffsetAPI_MakePipe.hxx>
 #include <BRepOffsetAPI_MakePipeShell.hxx>
-#include <GProp_GProps.hxx>
-#include <BRepGProp.hxx>
-#include <BRepBuilderAPI_MakeFace.hxx>
-#include <BRepBuilderAPI_Copy.hxx>
 
 #include <TopAbs.hxx>
 #include <TopExp.hxx>
@@ -68,6 +71,8 @@
 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
 #include <TopTools_ListIteratorOfListOfShape.hxx>
 
+#include <GProp_GProps.hxx>
+
 #include <GeomAPI_ProjectPointOnCurve.hxx>
 #include <GeomAPI_Interpolate.hxx>
 #include <Geom_TrimmedCurve.hxx>
@@ -78,6 +83,7 @@
 #include <Geom_Conic.hxx>
 #include <Geom_BSplineCurve.hxx>
 #include <Geom_BSplineSurface.hxx>
+#include <GeomAdaptor_HCurve.hxx>
 #include <GeomFill_BSplineCurves.hxx>
 #include <GeomConvert_ApproxCurve.hxx>
 #include <GeomConvert.hxx>
 #include <TColStd_HSequenceOfTransient.hxx>
 
 #include <Precision.hxx>
+
 #include <Standard_NullObject.hxx>
 #include <Standard_TypeMismatch.hxx>
 #include <Standard_ConstructionError.hxx>
 
 #include "utilities.h"
 
+
 //=======================================================================
 //function : GetID
 //purpose  :
 //=======================================================================
 const Standard_GUID& GEOMImpl_PipeDriver::GetID()
 {
-  static Standard_GUID aPipeDriver("FF1BBB19-5D14-4df2-980B-3A668264EA16");
+  static Standard_GUID aPipeDriver ("FF1BBB19-5D14-4df2-980B-3A668264EA16");
   return aPipeDriver;
 }
 
@@ -112,6 +120,59 @@ GEOMImpl_PipeDriver::GEOMImpl_PipeDriver()
 {
 }
 
+//=======================================================================
+//function : EvaluateBestSweepMode
+//purpose  : auxilary for right call of MakePipe and MakePipeShell
+//=======================================================================
+static GeomFill_Trihedron EvaluateBestSweepMode(const TopoDS_Shape& Spine)
+{
+  GeomFill_Trihedron theMode = GeomFill_IsFrenet;
+  
+  TopExp_Explorer Explo(Spine, TopAbs_EDGE);
+  for (; Explo.More(); Explo.Next())
+  {
+    TopoDS_Edge anEdge = TopoDS::Edge(Explo.Current());
+    Standard_Real fpar, lpar;
+    Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, fpar, lpar);
+    GeomAdaptor_Curve GAcurve(aCurve, fpar, lpar);
+    Handle(GeomAdaptor_HCurve) GAHcurve = new GeomAdaptor_HCurve(GAcurve);
+
+    Handle(GeomFill_CorrectedFrenet) aCorrFrenet = new GeomFill_CorrectedFrenet(Standard_True); //for evaluation
+    aCorrFrenet->SetCurve(GAHcurve);
+    GeomFill_Trihedron aMode = aCorrFrenet->EvaluateBestMode();
+    if (aMode == GeomFill_IsDiscreteTrihedron)
+    {
+      theMode = aMode;
+      break;
+    }
+    if (aMode == GeomFill_IsCorrectedFrenet)
+      theMode = aMode;
+  }
+
+  return theMode;
+}
+
+//=======================================================================
+//function : BuildPipeShell
+//purpose  : Builds a pipe shell. If failed, try to build in Descrete Trihedron
+//           mode. Returns Standard_True if the building is done successfully.
+//=======================================================================
+static Standard_Boolean BuildPipeShell(BRepOffsetAPI_MakePipeShell &theBuilder)
+{
+  theBuilder.Build();
+
+  Standard_Boolean isDone = theBuilder.IsDone();
+
+  if (!isDone) {
+    // Try to use Descrete Trihedron mode.
+    theBuilder.SetDiscreteMode();
+    theBuilder.Build();
+    isDone = theBuilder.IsDone();
+  }
+
+  return isDone;
+}
+
 //=======================================================================
 //function : FillForOtherEdges
 //purpose  : auxilary for CreatePipeForShellSections()
@@ -207,12 +268,17 @@ static bool FillCorrespondingEdges(const TopoDS_Shape& FS1,
   TopExp_Explorer expw2(FS2,TopAbs_WIRE);
   TopoDS_Wire aWire2 = TopoDS::Wire(expw2.Current());
   BRepOffsetAPI_MakePipeShell aBuilder(aWirePath);
+  GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(aWirePath);
+  if (theBestMode == GeomFill_IsDiscreteTrihedron)
+    aBuilder.SetDiscreteMode();
   aBuilder.Add(aWire1, aLoc1);
   aBuilder.Add(aWire2, aLoc2);
   if (!aBuilder.IsReady()) {
     return false;
   }
-  aBuilder.Build();
+
+  BuildPipeShell(aBuilder);
+
   TopoDS_Shape aShape = aBuilder.Shape();
   /*
   TopoDS_Compound C;
@@ -637,6 +703,7 @@ TopoDS_Shape GEOMImpl_PipeDriver::CreatePipeWithDifferentSections
   TopTools_SequenceOfShape aSeqBases;
   TopTools_SequenceOfShape aSeqLocs;
   TopTools_SequenceOfShape aSeqFaces;
+  Standard_Boolean NeedCreateSolid = Standard_False;
 
   Standard_Integer i = 1;
   for (i = 1; i <= nbBases; i++) {
@@ -653,7 +720,6 @@ TopoDS_Shape GEOMImpl_PipeDriver::CreatePipeWithDifferentSections
 
     //if for section was specified face with a few wires then a few
     //    pipes were build and make solid
-    Standard_Boolean NeedCreateSolid = Standard_False;
     if (aTypeBase == TopAbs_SHELL) {
       // create wire as boundary contour if shell is no closed
       // get free boundary shapes
@@ -814,14 +880,17 @@ TopoDS_Shape GEOMImpl_PipeDriver::CreatePipeWithDifferentSections
   // and seguences of shapes, perform pipe for each
   // and make sewing after that
   double fp,lp;
-  Handle(Geom_Curve) C = BRep_Tool::Curve(TopoDS::Edge(Edges.Value(1)),fp,lp);
   gp_Pnt P1,P2;
   gp_Vec Vec1,Vec2;
-  C->D1(fp,P1,Vec1);
-  C->D1(lp,P2,Vec2);
-  double SumAng = fabs(Vec1.Angle(Vec2));
-  Vec1 = Vec2;
-  P1 = P2;
+  double SumAng = 0;
+  if ( Edges.Length() > 0 ) {
+    Handle(Geom_Curve) C = BRep_Tool::Curve(TopoDS::Edge(Edges.Value(1)),fp,lp);
+    C->D1(fp,P1,Vec1);
+    C->D1(lp,P2,Vec2);
+    SumAng = fabs(Vec1.Angle(Vec2));
+    Vec1 = Vec2;
+    P1 = P2;
+  }
   TColStd_SequenceOfInteger SplitEdgeNums,SplitLocNums;
   int LastLoc = 1;
   //cout<<"Edges.Length()="<<Edges.Length()<<endl;
@@ -871,6 +940,9 @@ TopoDS_Shape GEOMImpl_PipeDriver::CreatePipeWithDifferentSections
         num2 = SplitLocNums.Value(nn);
         // make pipe
         BRepOffsetAPI_MakePipeShell aBuilder(tmpW);
+        GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(tmpW);
+        if (theBestMode == GeomFill_IsDiscreteTrihedron)
+          aBuilder.SetDiscreteMode();
         Standard_Integer nbShapes = aTmpSeqBases.Length();
         for (i=1; i<=nbShapes; i++) {
           TopoDS_Shape aShapeLoc = aTmpSeqLocs.Value(i);
@@ -880,7 +952,9 @@ TopoDS_Shape GEOMImpl_PipeDriver::CreatePipeWithDifferentSections
         if (!aBuilder.IsReady()) {
           Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid");
         }
-        aBuilder.Build();
+
+        BuildPipeShell(aBuilder);
+
         TopoDS_Shape resShape = aBuilder.Shape();
         aSeqRes.Append(resShape);
       }
@@ -899,6 +973,9 @@ TopoDS_Shape GEOMImpl_PipeDriver::CreatePipeWithDifferentSections
       }
       // make pipe for last part
       BRepOffsetAPI_MakePipeShell aBuilder(tmpW);
+      GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(tmpW);
+      if (theBestMode == GeomFill_IsDiscreteTrihedron)
+        aBuilder.SetDiscreteMode();
       Standard_Integer nbShapes = aTmpSeqBases.Length();
       for (i=1; i<=nbShapes; i++) {
         TopoDS_Shape aShapeLoc = aTmpSeqLocs.Value(i);
@@ -908,7 +985,9 @@ TopoDS_Shape GEOMImpl_PipeDriver::CreatePipeWithDifferentSections
       if (!aBuilder.IsReady()) {
         Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid");
       }
-      aBuilder.Build();
+
+      BuildPipeShell(aBuilder);
+
       TopoDS_Shape resShape = aBuilder.Shape();
       aSeqRes.Append(resShape);
       // make sewing for result
@@ -926,6 +1005,9 @@ TopoDS_Shape GEOMImpl_PipeDriver::CreatePipeWithDifferentSections
   else {
       // old implementation without splitting
       BRepOffsetAPI_MakePipeShell aBuilder(aWirePath);
+      GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(aWirePath);
+      if (theBestMode == GeomFill_IsDiscreteTrihedron)
+        aBuilder.SetDiscreteMode();
 
       Standard_Integer nbShapes = aSeqBases.Length();
       Standard_Integer step = nbShapes/nbBases;
@@ -934,6 +1016,9 @@ TopoDS_Shape GEOMImpl_PipeDriver::CreatePipeWithDifferentSections
         Standard_ConstructionError::Raise("Invalid sections were specified for building pipe");
       }
       Standard_Integer ind =0;
+      Standard_Real aTolConf = Precision::Confusion();
+      Standard_Real aTolAng  = Precision::Angular();
+
       for (i = 1; i <= nbShapes && ind < nbShapes; i++) { //i+nbBases <= nbShapes
         TopTools_SequenceOfShape usedBases;
         Standard_Integer j = 1;
@@ -952,22 +1037,23 @@ TopoDS_Shape GEOMImpl_PipeDriver::CreatePipeWithDifferentSections
         if (!aBuilder.IsReady()) {
           Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid");
         }
-        aBuilder.Build();
+      
+        aBuilder.SetTolerance(aTolConf, aTolConf, aTolAng);
+
+        Standard_Boolean isDone = BuildPipeShell(aBuilder);
+
+        if (isDone && NeedCreateSolid) {
+          isDone = aBuilder.MakeSolid();
+        }
+
+        if (!isDone) {
+          Standard_ConstructionError::Raise("Pipe construction failure");
+        }
         aShape = aBuilder.Shape();
         aSeqFaces.Append(aShape);
         for (j = 1; j <=usedBases.Length(); j++)
           aBuilder.Delete(usedBases.Value(j));
       }
-
-      //for case if section is face
-      if (aSeqFaces.Length() >1) {
-        BRep_Builder aB;
-        TopoDS_Compound aComp;
-        aB.MakeCompound(aComp);
-        for (i = 1; i <= aSeqFaces.Length(); i++)
-          aB.Add(aComp,aSeqFaces.Value(i));
-        aShape = aComp;
-      }
   }
 
   return aShape;
@@ -1439,6 +1525,9 @@ static TopoDS_Shape CreatePipeForShellSections(const TopoDS_Wire& aWirePath,
       if (!aWire1.IsNull() && !aWire2.IsNull()) {
         //BRepOffsetAPI_MakePipeShell aBuilder(aWirePath);
         BRepOffsetAPI_MakePipeShell aBuilder(WPath);
+        GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(WPath);
+        if (theBestMode == GeomFill_IsDiscreteTrihedron)
+          aBuilder.SetDiscreteMode();
         aBuilder.Add(aWire1, TopoDS::Vertex(VLocs(i)),
                      aWithContact, aWithCorrect);
         aBuilder.Add(aWire2, TopoDS::Vertex(VLocs(i+1)),
@@ -1447,7 +1536,9 @@ static TopoDS_Shape CreatePipeForShellSections(const TopoDS_Wire& aWirePath,
           if (aCI) delete aCI;
           Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid");
         }
-        aBuilder.Build();
+
+        BuildPipeShell(aBuilder);
+
         TopoDS_Shape aShape = aBuilder.Shape();
         TopoDS_Shell aShell;
         B.MakeShell(aShell);
@@ -1674,6 +1765,9 @@ static TopoDS_Shape CreatePipeForShellSections(const TopoDS_Wire& aWirePath,
         // make pipe using aWire1 and aWire2
         if (!aWire1.IsNull() && !aWire2.IsNull()) {
           BRepOffsetAPI_MakePipeShell aBuilder(WPath);
+          GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(WPath);
+          if (theBestMode == GeomFill_IsDiscreteTrihedron)
+            aBuilder.SetDiscreteMode();
           aBuilder.Add(aWire1, TopoDS::Vertex(VLocs(i)),
                        aWithContact, aWithCorrect);
           aBuilder.Add(aWire2, TopoDS::Vertex(VLocs(i+1)),
@@ -1682,7 +1776,9 @@ static TopoDS_Shape CreatePipeForShellSections(const TopoDS_Wire& aWirePath,
             if (aCI) delete aCI;
             Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid");
           }
-          aBuilder.Build();
+
+          BuildPipeShell(aBuilder);
+
           TopoDS_Shape aShape = aBuilder.Shape();
           TopoDS_Shell aShell;
           B.MakeShell(aShell);
@@ -2265,8 +2361,10 @@ static TopoDS_Shape CreatePipeBiNormalAlongVector(const TopoDS_Wire& aWirePath,
   gp_Vec aVec(BRep_Tool::Pnt(V1), BRep_Tool::Pnt(V2));
   gp_Dir BiNormal(aVec);
   PipeBuilder.SetMode(BiNormal);
-  PipeBuilder.Build();
-  if (aShapeBase.ShapeType() == TopAbs_FACE) {
+
+  Standard_Boolean isDone = BuildPipeShell(PipeBuilder);
+
+  if (isDone && aShapeBase.ShapeType() == TopAbs_FACE) {
       PipeBuilder.MakeSolid();
   }
 
@@ -2277,23 +2375,23 @@ static TopoDS_Shape CreatePipeBiNormalAlongVector(const TopoDS_Wire& aWirePath,
 //function : Execute
 //purpose  :
 //=======================================================================
-Standard_Integer GEOMImpl_PipeDriver::Execute(TFunction_Logbook& log) const
+Standard_Integer GEOMImpl_PipeDriver::Execute (TFunction_Logbook& log) const
 {
-  //cout<<"PipeDriver::Execute"<<endl;
   if (Label().IsNull()) return 0;
   Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());
-  GEOMImpl_IPipe* aCI= 0;
   Standard_Integer aType = aFunction->GetType();
+
+  GEOMImpl_IPipe* aCI = 0;
   if (aType == PIPE_BASE_PATH)
-    aCI = new GEOMImpl_IPipe(aFunction);
+    aCI = new GEOMImpl_IPipe (aFunction);
   else if (aType == PIPE_DIFFERENT_SECTIONS)
-    aCI = new GEOMImpl_IPipeDiffSect(aFunction);
+    aCI = new GEOMImpl_IPipeDiffSect (aFunction);
   else if (aType == PIPE_SHELL_SECTIONS)
-    aCI = new GEOMImpl_IPipeShellSect(aFunction);
+    aCI = new GEOMImpl_IPipeShellSect (aFunction);
   else if (aType == PIPE_SHELLS_WITHOUT_PATH)
-    aCI = new GEOMImpl_IPipeShellSect(aFunction);
+    aCI = new GEOMImpl_IPipeShellSect (aFunction);
   else if (aType == PIPE_BI_NORMAL_ALONG_VECTOR)
-    aCI = new GEOMImpl_IPipeBiNormal(aFunction);
+    aCI = new GEOMImpl_IPipeBiNormal (aFunction);
   else
     return 0;
 
@@ -2376,9 +2474,10 @@ Standard_Integer GEOMImpl_PipeDriver::Execute(TFunction_Logbook& log) const
       if (FaceBuilder.IsDone())
         Sweep.SetMode(FaceBuilder.Face());
       Sweep.Add(Profile);
-      Sweep.Build();
-      
-      if (!Sweep.IsDone())
+
+      Standard_Boolean isDone = BuildPipeShell(Sweep);
+
+      if (!isDone)
       {
         if (aCI) delete aCI;
         Standard_ConstructionError::Raise("MakePipeShell failed");
@@ -2388,7 +2487,22 @@ Standard_Integer GEOMImpl_PipeDriver::Execute(TFunction_Logbook& log) const
       
     }
     else
-      aShape = BRepOffsetAPI_MakePipe(aWirePath, aShapeBase);
+    {
+      GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(aWirePath);
+      BRepOffsetAPI_MakePipe aMkPipe(aWirePath, aShapeBase, theBestMode);
+
+      if (aMkPipe.IsDone()) {
+        aShape = aMkPipe.Shape();
+      } else if (theBestMode != GeomFill_IsDiscreteTrihedron) {
+        // Try to use Descrete Trihedron mode.
+        BRepOffsetAPI_MakePipe aMkPipeDescrete
+          (aWirePath, aShapeBase, GeomFill_IsDiscreteTrihedron);
+
+        if (aMkPipeDescrete.IsDone()) {
+          aShape = aMkPipeDescrete.Shape();
+        }
+      }
+    }
   }
 
   //building pipe with different sections
@@ -2473,64 +2587,99 @@ Standard_Integer GEOMImpl_PipeDriver::Execute(TFunction_Logbook& log) const
       Standard_ConstructionError::Raise("Algorithm have produced an invalid shape result");
   }
 
-  // Glue (for bug 0020207)
-  TopExp_Explorer anExpV (aShape, TopAbs_VERTEX);
-  if (anExpV.More()) {
-    Standard_Real aVertMaxTol = -RealLast();
-    for (; anExpV.More(); anExpV.Next()) {
-      TopoDS_Vertex aVertex = TopoDS::Vertex(anExpV.Current());
-      Standard_Real aTol = BRep_Tool::Tolerance(aVertex);
-      if (aTol > aVertMaxTol)
-        aVertMaxTol = aTol;
-    }
-    aVertMaxTol += Precision::Confusion();
-    aShape = GEOMImpl_GlueDriver::GlueFaces(aShape, aVertMaxTol, Standard_True);
-    //aShape = GEOMImpl_GlueDriver::GlueFaces(aShape, Precision::Confusion(), Standard_True);
+  if (aType != PIPE_BASE_PATH &&
+      aType != PIPE_SHELLS_WITHOUT_PATH) {
+    TopExp_Explorer anExpV (aShape, TopAbs_VERTEX);
+    if (anExpV.More()) {
+      Standard_Real aVertMaxTol = -RealLast();
+      for (; anExpV.More(); anExpV.Next()) {
+        TopoDS_Vertex aVertex = TopoDS::Vertex(anExpV.Current());
+        Standard_Real aTol = BRep_Tool::Tolerance(aVertex);
+        if (aTol > aVertMaxTol)
+          aVertMaxTol = aTol;
+      }
+      aVertMaxTol += Precision::Confusion();
+      aShape = GEOMImpl_GlueDriver::GlueFaces(aShape, aVertMaxTol, Standard_True);
+      //aShape = GEOMImpl_GlueDriver::GlueFaces(aShape, Precision::Confusion(), Standard_True);
+    }
   }
 
-  TopoDS_Shape aRes = GEOMImpl_IShapesOperations::CompsolidToCompound(aShape);
+  TopoDS_Shape aRes = GEOMUtils::CompsolidToCompound(aShape);
   aFunction->SetValue(aRes);
 
   log.SetTouched(Label());
   return 1;
 }
 
-//=======================================================================
-//function :  GEOMImpl_PipeDriver_Type_
-//purpose  :
-//=======================================================================
-Standard_EXPORT Handle_Standard_Type& GEOMImpl_PipeDriver_Type_()
-{
-  static Handle_Standard_Type aType1 = STANDARD_TYPE(TFunction_Driver);
-  if (aType1.IsNull()) aType1 = STANDARD_TYPE(TFunction_Driver);
-  static Handle_Standard_Type aType2 = STANDARD_TYPE(MMgt_TShared);
-  if (aType2.IsNull()) aType2 = STANDARD_TYPE(MMgt_TShared);
-  static Handle_Standard_Type aType3 = STANDARD_TYPE(Standard_Transient);
-  if (aType3.IsNull()) aType3 = STANDARD_TYPE(Standard_Transient);
-
-  static Handle_Standard_Transient _Ancestors[]= {aType1,aType2,aType3,NULL};
-  static Handle_Standard_Type _aType = new Standard_Type("GEOMImpl_PipeDriver",
-                                                         sizeof(GEOMImpl_PipeDriver),
-                                                         1,
-                                                         (Standard_Address)_Ancestors,
-                                                         (Standard_Address)NULL);
-
-  return _aType;
-}
+//================================================================================
+/*!
+ * \brief Returns a name of creation operation and names and values of creation parameters
+ */
+//================================================================================
 
-//=======================================================================
-//function : DownCast
-//purpose  :
-//=======================================================================
-const Handle(GEOMImpl_PipeDriver) Handle(GEOMImpl_PipeDriver)::DownCast(const Handle(Standard_Transient)& AnObject)
+bool GEOMImpl_PipeDriver::
+GetCreationInformation(std::string&             theOperationName,
+                       std::vector<GEOM_Param>& theParams)
 {
-  Handle(GEOMImpl_PipeDriver) _anOtherObject;
-
-  if (!AnObject.IsNull()) {
-     if (AnObject->IsKind(STANDARD_TYPE(GEOMImpl_PipeDriver))) {
-       _anOtherObject = Handle(GEOMImpl_PipeDriver)((Handle(GEOMImpl_PipeDriver)&)AnObject);
-     }
+  if (Label().IsNull()) return 0;
+  Handle(GEOM_Function) function = GEOM_Function::GetFunction(Label());
+  Standard_Integer aType = function->GetType();
+
+  switch ( aType ) {
+  case PIPE_BASE_PATH:
+  {
+    theOperationName = "PIPE";
+    GEOMImpl_IPipe aCI( function );
+    AddParam( theParams, "Base Object", aCI.GetBase() );
+    AddParam( theParams, "Path Object", aCI.GetPath() );
+    break;
   }
-
-  return _anOtherObject;
+  case PIPE_BI_NORMAL_ALONG_VECTOR:
+  {
+    theOperationName = "PIPE";
+    GEOMImpl_IPipeBiNormal aCI( function );
+    AddParam( theParams, "Base Object", aCI.GetBase() );
+    AddParam( theParams, "Path Object", aCI.GetPath() );
+    AddParam( theParams, "BiNormal", aCI.GetVector() );
+    break;
+  }
+  case PIPE_DIFFERENT_SECTIONS:
+  {
+    theOperationName = "PIPE";
+    GEOMImpl_IPipeDiffSect aCI( function );
+    AddParam( theParams, "Bases", aCI.GetBases() );
+    AddParam( theParams, "Locations", aCI.GetLocations() );
+    AddParam( theParams, "Path", aCI.GetPath() );
+    AddParam( theParams, "With contact", aCI.GetWithContactMode() );
+    AddParam( theParams, "With correction", aCI.GetWithCorrectionMode() );
+    break;
+  }
+  case PIPE_SHELL_SECTIONS:
+  {
+    theOperationName = "PIPE";
+    GEOMImpl_IPipeShellSect aCI( function );
+    AddParam( theParams, "Bases", aCI.GetBases() );
+    AddParam( theParams, "Sub-Bases", aCI.GetSubBases() );
+    AddParam( theParams, "Locations", aCI.GetLocations() );
+    AddParam( theParams, "Path", aCI.GetPath() );
+    AddParam( theParams, "With contact", aCI.GetWithContactMode() );
+    AddParam( theParams, "With correction", aCI.GetWithCorrectionMode() );
+    break;
+  }
+  case PIPE_SHELLS_WITHOUT_PATH:
+  {
+    theOperationName = "PIPE"; // MakePipeShellsWithoutPath
+    GEOMImpl_IPipeShellSect aCI( function );
+    AddParam( theParams, "Bases", aCI.GetBases() );
+    AddParam( theParams, "Locations", aCI.GetLocations() );
+    break;
+  }
+  default:
+    return false;
+  }
+  
+  return true;
 }
+
+IMPLEMENT_STANDARD_HANDLE (GEOMImpl_PipeDriver,GEOM_BaseDriver);
+IMPLEMENT_STANDARD_RTTIEXT (GEOMImpl_PipeDriver,GEOM_BaseDriver);