Salome HOME
Update copyright notes (for 2010)
[modules/geom.git] / src / GEOMImpl / GEOMImpl_IAdvancedOperations.cxx
index 7dd16e1aeb83841fcffda4a52659afdae70c7111..b1741c9232b4c7f0f0c3b975bad5a8d16025f66e 100644 (file)
@@ -1,7 +1,4 @@
-//  Copyright (C) 2007-2008  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
+//  Copyright (C) 2007-2010  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 //  This library is free software; you can redistribute it and/or
 //  modify it under the terms of the GNU Lesser General Public
 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 //
 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
-//  
+//
+
 //  File   : GEOMImpl_IAdvancedOperations.cxx
 //  Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
 //
-
 #include <Standard_Stream.hxx>
 #include "GEOMImpl_IBasicOperations.hxx"
 #include "GEOMImpl_IShapesOperations.hxx"
@@ -98,13 +95,14 @@ GEOMImpl_IAdvancedOperations::~GEOMImpl_IAdvancedOperations() {
 gp_Trsf GEOMImpl_IAdvancedOperations::GetPositionTrsf(double theL1, double theL2, Handle(GEOM_Object) theP1,
                Handle(GEOM_Object) theP2, Handle(GEOM_Object) theP3) {
        // Old Local Coordinates System oldLCS
+       gp_Pnt P0(0, 0, 0);
        gp_Pnt P1(-theL1, 0, 0);
        gp_Pnt P2(theL1, 0, 0);
        gp_Pnt P3(0, 0, theL2);
 
        gp_Dir oldX(gp_Vec(P1, P2));
-       gp_Dir oldZ(gp_Vec(gp::Origin(), P3));
-       gp_Ax3 oldLCS(gp::Origin(), oldZ, oldX);
+       gp_Dir oldZ(gp_Vec(P0, P3));
+       gp_Ax3 oldLCS(P0, oldZ, oldX);
 
        // New Local Coordinates System newLCS
        double LocX, LocY, LocZ;
@@ -226,6 +224,8 @@ bool GEOMImpl_IAdvancedOperations::MakeGroups(/*std::vector<GEOM_IOperations*> t
         return false;
     }
 
+    gp_Trsf aTrsfInv = aTrsf.Inverted();
+    
     int expectedGroups = 0;
     if (shapeType == TSHAPE_BASIC)
       if (Abs(theR2+theW2-theR1-theW1) <= Precision::Approximation())
@@ -255,7 +255,7 @@ bool GEOMImpl_IAdvancedOperations::MakeGroups(/*std::vector<GEOM_IOperations*> t
     GEOMImpl_I3DPrimOperations* a3DPrimOperations = new GEOMImpl_I3DPrimOperations(GetEngine(), GetDocID());
     
     //
-    // Uncomment the following lines when GetInPlace bug is solved
+    // Comment the following lines when GetInPlace bug is solved
     // == BEGIN
     // Workaround of GetInPlace bug
     // Create a bounding box that fits the shape
@@ -263,6 +263,11 @@ bool GEOMImpl_IAdvancedOperations::MakeGroups(/*std::vector<GEOM_IOperations*> t
     aBox->GetLastFunction()->SetDescription("");
     aTransformOperations->TranslateDXDYDZ(aBox, -theL1, -aR1Ext, -aR1Ext);
     aBox->GetLastFunction()->SetDescription("");
+    // Apply transformation to box
+    BRepBuilderAPI_Transform aTransformationBox(aBox->GetValue(), aTrsf, Standard_False);
+    TopoDS_Shape aBoxShapeTrsf = aTransformationBox.Shape();
+    aBox->GetLastFunction()->SetValue(aBoxShapeTrsf);
+    
     // Get the shell of the box
     Handle(GEOM_Object) aShell = Handle(GEOM_Object)::DownCast(aShapesOperations->MakeExplode(aBox, TopAbs_SHELL, true)->Value(1));
     aBox->GetLastFunction()->SetDescription("");
@@ -290,9 +295,9 @@ bool GEOMImpl_IAdvancedOperations::MakeGroups(/*std::vector<GEOM_IOperations*> t
         if (!aCompoundOfFaces.IsNull()) {
             aCompoundOfFaces->GetLastFunction()->SetDescription("");
             // Apply transformation to compound of faces
-            BRepBuilderAPI_Transform aTransformationCompoundOfFaces(aCompoundOfFaces->GetValue(), aTrsf, Standard_False);
-            TopoDS_Shape aTrsf_CompoundOfFacesShape = aTransformationCompoundOfFaces.Shape();
-            aCompoundOfFaces->GetLastFunction()->SetValue(aTrsf_CompoundOfFacesShape);
+//             BRepBuilderAPI_Transform aTransformationCompoundOfFaces(aCompoundOfFaces->GetValue(), aTrsf, Standard_False);
+//             TopoDS_Shape aTrsf_CompoundOfFacesShape = aTransformationCompoundOfFaces.Shape();
+//             aCompoundOfFaces->GetLastFunction()->SetValue(aTrsf_CompoundOfFacesShape);
             aCompoundOfFacesList.push_back(aCompoundOfFaces);
         }
     }
@@ -386,7 +391,15 @@ bool GEOMImpl_IAdvancedOperations::MakeGroups(/*std::vector<GEOM_IOperations*> t
     //// Groups of Edges ////
     /////////////////////////
     // Result of propagate
+
     Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
+    
+
+    // Apply inverted transformation to shape
+//    BRepBuilderAPI_Transform aTransformationShapeInv(aShape, aTrsfInv, Standard_False);
+//    TopoDS_Shape aShapeTrsfInv = aTransformationShapeInv.Shape();
+//    aFunction->SetValue(aShapeTrsfInv);
+    
     TCollection_AsciiString theDesc = aFunction->GetDescription();
     Handle(TColStd_HSequenceOfTransient) aSeqPropagate = aBlocksOperations->Propagate(theShape);
     if (aSeqPropagate.IsNull() || aSeqPropagate->Length() == 0) {
@@ -397,6 +410,12 @@ bool GEOMImpl_IAdvancedOperations::MakeGroups(/*std::vector<GEOM_IOperations*> t
     // Recover previous description to get rid of Propagate dump
     aFunction->SetDescription(theDesc);
     
+    
+    // Apply transformation to shape
+//    BRepBuilderAPI_Transform aTransformationShape(theShape->GetValue(), aTrsf, Standard_False);
+//    TopoDS_Shape aShapeTrsf = aTransformationShape.Shape();
+//    aFunction->SetValue(aShapeTrsf);
+    
     bool addGroup;
     bool circularFoundAndAdded = false;
     bool incidentPipeFound = false;
@@ -415,9 +434,11 @@ bool GEOMImpl_IAdvancedOperations::MakeGroups(/*std::vector<GEOM_IOperations*> t
         continue;
       
       TopoDS_Shape aGroupShape = aGroup->GetValue();
+      BRepBuilderAPI_Transform aTransformationShapeInv(aGroupShape, aTrsfInv, Standard_False);
+      TopoDS_Shape aGroupShapeTrsfInv = aTransformationShapeInv.Shape();
       
       TopTools_IndexedMapOfShape anEdgesMap;
-      TopExp::MapShapes(aGroupShape,TopAbs_EDGE, anEdgesMap);
+      TopExp::MapShapes(aGroupShapeTrsfInv,TopAbs_EDGE, anEdgesMap);
       nbEdges = anEdgesMap.Extent();
 
       if (shapeType == TSHAPE_BASIC) {
@@ -438,7 +459,7 @@ bool GEOMImpl_IAdvancedOperations::MakeGroups(/*std::vector<GEOM_IOperations*> t
           radialFound =false;
           flangeFound = false;
           
-          TopExp_Explorer Ex(aGroupShape,TopAbs_VERTEX);
+          TopExp_Explorer Ex(aGroupShapeTrsfInv,TopAbs_VERTEX);
           while (Ex.More()) {
             gp_Pnt aP =  BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
             double x=aP.X(), y=aP.Y(), z=aP.Z();
@@ -504,7 +525,7 @@ bool GEOMImpl_IAdvancedOperations::MakeGroups(/*std::vector<GEOM_IOperations*> t
           mainPipeFound = false;
           flangeFound = false;
           
-          TopExp_Explorer Ex(aGroupShape,TopAbs_VERTEX);
+          TopExp_Explorer Ex(aGroupShapeTrsfInv,TopAbs_VERTEX);
           while (Ex.More()) {
             gp_Pnt aP =  BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
             double x=aP.X(), y=aP.Y(), z=aP.Z();
@@ -566,55 +587,6 @@ bool GEOMImpl_IAdvancedOperations::MakeGroups(/*std::vector<GEOM_IOperations*> t
         theSeq->Append(aGroup);
     }
 
-//     Handle(GEOM_Object) aGroup;
-//     if (shapeType == TSHAPE_BASIC) {
-// //         if (aNbGroups != 11) {
-// //             SetErrorCode("Bad number of propagation groups");
-// //             return false;
-// //         }
-//         aGroup = Handle(GEOM_Object)::DownCast(aSeqPropagate->Value(1));
-//         aGroup->SetName("THICKNESS");
-//         theSeq->Append(aGroup);
-//         aGroup = Handle(GEOM_Object)::DownCast(aSeqPropagate->Value(2));
-//         aGroup->SetName("CIRCULAR_QUARTER_PIPE");
-//         theSeq->Append(aGroup);
-//         aGroup = Handle(GEOM_Object)::DownCast(aSeqPropagate->Value(3));
-//         aGroup->SetName("HALF_LENGTH_MAIN_PIPE");
-//         theSeq->Append(aGroup);
-//         aGroup = Handle(GEOM_Object)::DownCast(aSeqPropagate->Value(6));
-//         aGroup->SetName("HALF_LENGTH_INCIDENT_PIPE");
-//         theSeq->Append(aGroup);
-//         aGroup = Handle(GEOM_Object)::DownCast(aSeqPropagate->Value(5));
-//         aGroup->SetName("FLANGE");
-//         theSeq->Append(aGroup);
-//     } else if (shapeType == TSHAPE_CHAMFER || shapeType == TSHAPE_FILLET) {
-//         if (aNbGroups != 12) {
-//             SetErrorCode("Bad number of propagation groups");
-//             return false;
-//         }
-//         aGroup = Handle(GEOM_Object)::DownCast(aSeqPropagate->Value(3));
-//         aGroup->SetName("THICKNESS");
-//         theSeq->Append(aGroup);
-//         aGroup = Handle(GEOM_Object)::DownCast(aSeqPropagate->Value(1));
-//         aGroup->SetName("CIRCULAR_QUARTER_PIPE");
-//         theSeq->Append(aGroup);
-//         aGroup = Handle(GEOM_Object)::DownCast(aSeqPropagate->Value(4));
-//         aGroup->SetName("HALF_LENGTH_MAIN_PIPE");
-//         theSeq->Append(aGroup);
-//         aGroup = Handle(GEOM_Object)::DownCast(aSeqPropagate->Value(6));
-//         aGroup->SetName("HALF_LENGTH_INCIDENT_PIPE");
-//         theSeq->Append(aGroup);
-//         aGroup = Handle(GEOM_Object)::DownCast(aSeqPropagate->Value(2));
-//         aGroup->SetName("FLANGE");
-//         theSeq->Append(aGroup);
-//         aGroup = Handle(GEOM_Object)::DownCast(aSeqPropagate->Value(7));
-//         if (shapeType == TSHAPE_CHAMFER)
-//             aGroup->SetName("CHAMFER");
-//         else
-//             aGroup->SetName("FILLET");
-//         theSeq->Append(aGroup);
-//     }
-
     SetErrorCode(OK);
     return true;
 }
@@ -1070,89 +1042,89 @@ bool GEOMImpl_IAdvancedOperations::MakePipeTShapePartition(/*std::vector<GEOM_IO
     theShapes.push_back(aPlnOXZ);
 
       // Partition
-    Handle(GEOM_Object) Part0 = aBooleanOperations->MakeHalfPartition(theShape, face_t);
-    if (Part0.IsNull()) {
-        std::cerr << "Impossible to build partition between TShape and 1st face" << std::endl;
-        SetErrorCode("Impossible to build partition between TShape and 1st face");
-        return false;
-    }
-    Part0->GetLastFunction()->SetDescription("");
-    
-    Handle(GEOM_Object) Te3 ;
-    if (isNormal) {
-      if (Abs(aR1Ext - aR2Ext) <= Precision::Approximation()) {
-        std::cerr << "External radius are identical: we do not make partition with plane OXZ" << std::endl;
-        Te3 = aBooleanOperations->MakeHalfPartition(Part0, aPlnOZ);
-      }
-      else {
-        Handle(GEOM_Object) Part1 = aBooleanOperations->MakeHalfPartition(Part0, aPlnOXZ);
-        if (Part1.IsNull()) {
-          std::cerr << "Impossible to build partition between TShape and plane OXZ" << std::endl;
-          SetErrorCode("Impossible to build partition between TShape and plane OXZ");
-          return false;
-        }
-        Part1->GetLastFunction()->SetDescription("");
-        Te3 = aBooleanOperations->MakeHalfPartition(Part1, aPlnOZ);
-      }
-      if (Te3.IsNull()) {
-          std::cerr << "Impossible to build partition between TShape and plane OZ" << std::endl;
-          SetErrorCode("Impossible to build partition between TShape and plane OZ");
-          return false;
-      }
-      Te3->GetLastFunction()->SetDescription("");
-    }
-    else {
-      if (Abs(aR1Ext - aR2Ext) <= Precision::Approximation()){ // We should never go here
-        SetErrorCode("Impossible to build TShape");
-        return false;
-      }
-      else {
-        Handle(GEOM_Object) Part1 = aBooleanOperations->MakeHalfPartition(Part0, aPlnOXZ);
-        if (Part1.IsNull()) {
-        std::cerr << "Impossible to build partition between TShape and plane OXZ" << std::endl;
-          SetErrorCode("Impossible to build partition between TShape and plane OXZ");
-          return false;
-        }
-        Part1->GetLastFunction()->SetDescription("");
-        Handle(GEOM_Object) Part2 = aBooleanOperations->MakeHalfPartition(Part1, aPlnOZ);
-        if (Part2.IsNull()) {
-        std::cerr << "Impossible to build partition between TShape and plane OZ" << std::endl;
-          SetErrorCode("Impossible to build partition between TShape and plane OZ");
-          return false;
-        }
-        Part2->GetLastFunction()->SetDescription("");
-        Te3 = aBooleanOperations->MakeHalfPartition(Part2, face_t2);
-        if (Te3.IsNull()) {
-            std::cerr << "Impossible to build partition between TShape and 2nd face" << std::endl;
-            SetErrorCode("Impossible to build partition between TShape and 2nd face");
-            return false;
-        }
-        Te3->GetLastFunction()->SetDescription("");
-      }
-    }
+//    Handle(GEOM_Object) Part0 = aBooleanOperations->MakeHalfPartition(theShape, face_t);
+//    if (Part0.IsNull()) {
+//        std::cerr << "Impossible to build partition between TShape and 1st face" << std::endl;
+//        SetErrorCode("Impossible to build partition between TShape and 1st face");
+//        return false;
+//    }
+//    Part0->GetLastFunction()->SetDescription("");
+//
+//    Handle(GEOM_Object) Te3 ;
+//    if (isNormal) {
+//      if (Abs(aR1Ext - aR2Ext) <= Precision::Approximation()) {
+//        std::cerr << "External radius are identical: we do not make partition with plane OXZ" << std::endl;
+//        Te3 = aBooleanOperations->MakeHalfPartition(Part0, aPlnOZ);
+//      }
+//      else {
+//        Handle(GEOM_Object) Part1 = aBooleanOperations->MakeHalfPartition(Part0, aPlnOXZ);
+//        if (Part1.IsNull()) {
+//          std::cerr << "Impossible to build partition between TShape and plane OXZ" << std::endl;
+//          SetErrorCode("Impossible to build partition between TShape and plane OXZ");
+//          return false;
+//        }
+//        Part1->GetLastFunction()->SetDescription("");
+//        Te3 = aBooleanOperations->MakeHalfPartition(Part1, aPlnOZ);
+//      }
+//      if (Te3.IsNull()) {
+//          std::cerr << "Impossible to build partition between TShape and plane OZ" << std::endl;
+//          SetErrorCode("Impossible to build partition between TShape and plane OZ");
+//          return false;
+//      }
+//      Te3->GetLastFunction()->SetDescription("");
+//    }
+//    else {
+//      if (Abs(aR1Ext - aR2Ext) <= Precision::Approximation()){ // We should never go here
+//        SetErrorCode("Impossible to build TShape");
+//        return false;
+//      }
+//      else {
+//        Handle(GEOM_Object) Part1 = aBooleanOperations->MakeHalfPartition(Part0, aPlnOXZ);
+//        if (Part1.IsNull()) {
+//        std::cerr << "Impossible to build partition between TShape and plane OXZ" << std::endl;
+//          SetErrorCode("Impossible to build partition between TShape and plane OXZ");
+//          return false;
+//        }
+//        Part1->GetLastFunction()->SetDescription("");
+//        Handle(GEOM_Object) Part2 = aBooleanOperations->MakeHalfPartition(Part1, aPlnOZ);
+//        if (Part2.IsNull()) {
+//        std::cerr << "Impossible to build partition between TShape and plane OZ" << std::endl;
+//          SetErrorCode("Impossible to build partition between TShape and plane OZ");
+//          return false;
+//        }
+//        Part2->GetLastFunction()->SetDescription("");
+//        Te3 = aBooleanOperations->MakeHalfPartition(Part2, face_t2);
+//        if (Te3.IsNull()) {
+//            std::cerr << "Impossible to build partition between TShape and 2nd face" << std::endl;
+//            SetErrorCode("Impossible to build partition between TShape and 2nd face");
+//            return false;
+//        }
+//        Te3->GetLastFunction()->SetDescription("");
+//      }
+//    }
 
-//     Handle(TColStd_HSequenceOfTransient) partitionShapes = new TColStd_HSequenceOfTransient;
-//     Handle(TColStd_HSequenceOfTransient) theTools = new TColStd_HSequenceOfTransient;
-//     Handle(TColStd_HSequenceOfTransient) theKeepInside = new TColStd_HSequenceOfTransient;
-//     Handle(TColStd_HSequenceOfTransient) theRemoveInside = new TColStd_HSequenceOfTransient;
-//     Handle(TColStd_HArray1OfInteger) theMaterials;
-//     partitionShapes->Append(theShape);
-//     theTools->Append(aPlnOZ);
-//     theTools->Append(aPlnOXZ);
-//     theTools->Append(face_t);
-//     if (!isNormal)
-//         theTools->Append(face_t2);
-//         
-//     Handle(GEOM_Object) Te3 = aBooleanOperations->MakePartition(partitionShapes, theTools, theKeepInside, theRemoveInside, TopAbs_SOLID, false, theMaterials, 0, false);
-//     if (Te3.IsNull()) {
-//         SetErrorCode("Impossible to build partition of TShape");
+     Handle(TColStd_HSequenceOfTransient) partitionShapes = new TColStd_HSequenceOfTransient;
+     Handle(TColStd_HSequenceOfTransient) theTools = new TColStd_HSequenceOfTransient;
+     Handle(TColStd_HSequenceOfTransient) theKeepInside = new TColStd_HSequenceOfTransient;
+     Handle(TColStd_HSequenceOfTransient) theRemoveInside = new TColStd_HSequenceOfTransient;
+     Handle(TColStd_HArray1OfInteger) theMaterials;
+     partitionShapes->Append(theShape);
+     theTools->Append(aPlnOZ);
+     theTools->Append(aPlnOXZ);
+     theTools->Append(face_t);
+     if (!isNormal)
+         theTools->Append(face_t2);
+
+     Handle(GEOM_Object) Te3 = aBooleanOperations->MakePartition(partitionShapes, theTools, theKeepInside, theRemoveInside, TopAbs_SOLID, false, theMaterials, 0, false);
+     if (Te3.IsNull()) {
+         SetErrorCode("Impossible to build partition of TShape");
 //         Handle(GEOM_Object) aCompound = aShapesOperations->MakeCompound(theShapes);
 //         TopoDS_Shape aCompoundShape = aCompound->GetValue();
 //         theShape->GetLastFunction()->SetValue(aCompoundShape);
-//         return false;
-//     }
-//     Te3->GetLastFunction()->SetDescription("");
-//
+         return false;
+     }
+     Te3->GetLastFunction()->SetDescription("");
+
 
     TopoDS_Shape aShape = Te3->GetValue();
     theShape->GetLastFunction()->SetValue(aShape);
@@ -1261,8 +1233,8 @@ bool GEOMImpl_IAdvancedOperations::MakePipeTShapeMirrorAndGlue(/*std::vector<GEO
 //=============================================================================
 /*!
  *  MakePipeTShape
- *  Create a T-shape object with specified caracteristics for the main and the
- *  incident pipes (radius, width, half-length).
+ *  Create a T-shape object with specified caracteristics for the main and
+ *  the incident pipes (radius, width, half-length).
  *  Center of the shape is (0,0,0). The main plane of the T-shape is XOY.
  *  \param theR1 Internal radius of main pipe
  *  \param theW1 Width of main pipe
@@ -1394,9 +1366,11 @@ Handle(TColStd_HSequenceOfTransient) GEOMImpl_IAdvancedOperations::MakePipeTShap
 
 //=============================================================================
 /*!
- *  Create a T-shape object with specified caracteristics for the main and the
- *  incident pipes (radius, width, half-length).
- *  Center of the shape is (0,0,0). The main plane of the T-shape is XOY.
+ *  MakePipeTShapeWithPosition
+ *  Create a T-shape object with specified caracteristics for the main and
+ *  the incident pipes (radius, width, half-length).
+ *  The extremities of the main pipe are located on junctions points P1 and P2.
+ *  The extremity of the incident pipe is located on junction point P3.
  *  \param theR1 Internal radius of main pipe
  *  \param theW1 Width of main pipe
  *  \param theL1 Half-length of main pipe
@@ -1539,8 +1513,10 @@ Handle(TColStd_HSequenceOfTransient) GEOMImpl_IAdvancedOperations::MakePipeTShap
 
 //=============================================================================
 /*!
- *  Create a T-shape object with specified caracteristics for the main and the
- *  incident pipes (radius, width, half-length).
+ *  MakePipeTShapeChamfer
+ *  Create a T-shape object with specified caracteristics for the main and
+ *  the incident pipes (radius, width, half-length). A chamfer is created
+ *  on the junction of the pipes.
  *  Center of the shape is (0,0,0). The main plane of the T-shape is XOY.
  *  \param theR1 Internal radius of main pipe
  *  \param theW1 Width of main pipe
@@ -1620,12 +1596,12 @@ Handle(TColStd_HSequenceOfTransient) GEOMImpl_IAdvancedOperations::MakePipeTShap
     else {
       box_e = a3DPrimOperations->MakeBoxDXDYDZ(2*(theR2+theW2), 2*(theR2+theW2), theR1+theW1);
     }
+    box_e->GetLastFunction()->SetDescription("");
     box_e = aTransformOperations->TranslateDXDYDZ(box_e, -(theR2+theW2), -(theR2+theW2), 0);
     box_e->GetLastFunction()->SetDescription("");
     
-    TCollection_AsciiString theDesc = aFunction->GetDescription();
     Handle(TColStd_HSequenceOfInteger) edges_e = aShapesOperations->GetShapesOnBoxIDs(box_e, aShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
-    aFunction->SetDescription(theDesc);
+    box_e->GetLastFunction()->SetDescription("");
 
     if (edges_e.IsNull() || edges_e->Length() == 0) {
 //        std::cerr << "Internal edges not found" << std::endl;
@@ -1664,14 +1640,11 @@ Handle(TColStd_HSequenceOfTransient) GEOMImpl_IAdvancedOperations::MakePipeTShap
     catch (Standard_Failure) {
       Handle(Standard_Failure) aFail = Standard_Failure::Caught();
       SetErrorCode(aFail->GetMessageString());
-      try {
-        aChamfer = aLocalOperations->MakeChamferEdges(aShape, theH, theW, theEdges);
-      }
-      catch (Standard_Failure) {
-        Handle(Standard_Failure) aFail = Standard_Failure::Caught();
-        SetErrorCode(aFail->GetMessageString());
-        return NULL;
-      }
+      return NULL;
+    }
+    if (aChamfer.IsNull()) {
+       SetErrorCode("Chamfer can not be computed on the given shape with the given parameters");
+       return NULL;
     }
     aChamfer->GetLastFunction()->SetDescription("");
     
@@ -1752,9 +1725,12 @@ Handle(TColStd_HSequenceOfTransient) GEOMImpl_IAdvancedOperations::MakePipeTShap
 
 //=============================================================================
 /*!
- *  Create a T-shape object with specified caracteristics for the main and the
- *  incident pipes (radius, width, half-length).
- *  The T-shape is placed at junction points P1, P2 and P3.
+ *  MakePipeTShapeChamferWithPosition
+ *  Create a T-shape object with specified caracteristics for the main and
+ *  the incident pipes (radius, width, half-length). A chamfer is created
+ *  on the junction of the pipes.
+ *  The extremities of the main pipe are located on junctions points P1 and P2.
+ *  The extremity of the incident pipe is located on junction point P3.
  *  \param theR1 Internal radius of main pipe
  *  \param theW1 Width of main pipe
  *  \param theL1 Half-length of main pipe
@@ -1842,12 +1818,12 @@ Handle(TColStd_HSequenceOfTransient) GEOMImpl_IAdvancedOperations::MakePipeTShap
     else {
       box_e = a3DPrimOperations->MakeBoxDXDYDZ(2*(theR2+theW2), 2*(theR2+theW2), theR1+theW1);
     }
+    box_e->GetLastFunction()->SetDescription("");
     box_e = aTransformOperations->TranslateDXDYDZ(box_e, -(theR2+theW2), -(theR2+theW2), 0);
     box_e->GetLastFunction()->SetDescription("");
     
-    TCollection_AsciiString theDesc = aFunction->GetDescription();
     Handle(TColStd_HSequenceOfInteger) edges_e = aShapesOperations->GetShapesOnBoxIDs(box_e, aShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
-    aFunction->SetDescription(theDesc);
+    box_e->GetLastFunction()->SetDescription("");
 
     if (edges_e.IsNull() || edges_e->Length() == 0) {
 //        std::cerr << "Internal edges not found" << std::endl;
@@ -1878,8 +1854,14 @@ Handle(TColStd_HSequenceOfTransient) GEOMImpl_IAdvancedOperations::MakePipeTShap
     try {
       aChamfer = aLocalOperations->MakeChamferEdges(aShape, theW, theH, theEdges);
     }
-    catch (...) {
-      aChamfer = aLocalOperations->MakeChamferEdges(aShape, theH, theW, theEdges);
+    catch (Standard_Failure) {
+      Handle(Standard_Failure) aFail = Standard_Failure::Caught();
+      SetErrorCode(aFail->GetMessageString());
+      return NULL;
+    }
+    if (aChamfer.IsNull()) {
+       SetErrorCode("Chamfer can not be computed on the given shape with the given parameters");
+       return NULL;
     }
     aChamfer->GetLastFunction()->SetDescription("");
     
@@ -1953,9 +1935,10 @@ Handle(TColStd_HSequenceOfTransient) GEOMImpl_IAdvancedOperations::MakePipeTShap
 
 //=============================================================================
 /*!
- *  Create a T-shape object with specified caracteristics for the main and the
- *  incident pipes (radius, width, half-length).A fillet is created on
- *  the junction of the pipes.
+ *  MakePipeTShapeFillet
+ *  Create a T-shape object with specified caracteristics for the main and
+ *  the incident pipes (radius, width, half-length). A fillet is created
+ *  on the junction of the pipes.
  *  Center of the shape is (0,0,0). The main plane of the T-shape is XOY.
  *  \param theR1 Internal radius of main pipe
  *  \param theW1 Width of main pipe
@@ -2033,12 +2016,12 @@ Handle(TColStd_HSequenceOfTransient) GEOMImpl_IAdvancedOperations::MakePipeTShap
     else {
       box_e = a3DPrimOperations->MakeBoxDXDYDZ(2*(theR2+theW2), 2*(theR2+theW2), theR1+theW1);
     }
+    box_e->GetLastFunction()->SetDescription("");
     box_e = aTransformOperations->TranslateDXDYDZ(box_e, -(theR2+theW2), -(theR2+theW2), 0);
     box_e->GetLastFunction()->SetDescription("");
     
-    TCollection_AsciiString theDesc = aFunction->GetDescription();
     Handle(TColStd_HSequenceOfInteger) edges_e = aShapesOperations->GetShapesOnBoxIDs(box_e, aShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
-    aFunction->SetDescription(theDesc);
+    box_e->GetLastFunction()->SetDescription("");
 
     if (edges_e.IsNull() || edges_e->Length() == 0) {
 //        std::cerr << "Internal edges not found" << std::endl;
@@ -2065,8 +2048,20 @@ Handle(TColStd_HSequenceOfTransient) GEOMImpl_IAdvancedOperations::MakePipeTShap
         if (theHexMesh && nbEdgesInFillet == 1)
           break;
     }
-    
-    Handle(GEOM_Object) aFillet = aLocalOperations->MakeFilletEdges(aShape, theRF, theEdges);
+
+    Handle(GEOM_Object) aFillet;
+    try {
+       aFillet = aLocalOperations->MakeFilletEdges(aShape, theRF, theEdges);
+    }
+    catch (Standard_Failure) {
+      Handle(Standard_Failure) aFail = Standard_Failure::Caught();
+      SetErrorCode(aFail->GetMessageString());
+      return NULL;
+    }
+    if (aFillet.IsNull()) {
+       SetErrorCode("Fillet can not be computed on the given shape with the given parameters");
+       return NULL;
+    }
     aFillet->GetLastFunction()->SetDescription("");
     
     TopoDS_Shape aFilletShape = aFillet->GetValue();
@@ -2133,10 +2128,12 @@ Handle(TColStd_HSequenceOfTransient) GEOMImpl_IAdvancedOperations::MakePipeTShap
 
 //=============================================================================
 /*!
- *  Create a T-shape object with specified caracteristics for the main and the
- *  incident pipes (radius, width, half-length). A fillet is created on
- *  the junction of the pipes.
- *  The T-shape is placed at junction points P1, P2 and P3.
+ *  MakePipeTShapeFilletWithPosition
+ *  Create a T-shape object with specified caracteristics for the main and
+ *  the incident pipes (radius, width, half-length). A fillet is created
+ *  on the junction of the pipes.
+ *  The extremities of the main pipe are located on junctions points P1 and P2.
+ *  The extremity of the incident pipe is located on junction point P3.
  *  \param theR1 Internal radius of main pipe
  *  \param theW1 Width of main pipe
  *  \param theL1 Half-length of main pipe
@@ -2222,12 +2219,12 @@ Handle(TColStd_HSequenceOfTransient) GEOMImpl_IAdvancedOperations::MakePipeTShap
     else {
       box_e = a3DPrimOperations->MakeBoxDXDYDZ(2*(theR2+theW2), 2*(theR2+theW2), theR1+theW1);
     }
+    box_e->GetLastFunction()->SetDescription("");
     box_e = aTransformOperations->TranslateDXDYDZ(box_e, -(theR2+theW2), -(theR2+theW2), 0);
     box_e->GetLastFunction()->SetDescription("");
     
-    TCollection_AsciiString theDesc = aFunction->GetDescription();
     Handle(TColStd_HSequenceOfInteger) edges_e = aShapesOperations->GetShapesOnBoxIDs(box_e, aShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
-    aFunction->SetDescription(theDesc);
+    box_e->GetLastFunction()->SetDescription("");
 
     if (edges_e.IsNull() || edges_e->Length() == 0) {
 //        std::cerr << "Internal edges not found" << std::endl;
@@ -2254,8 +2251,20 @@ Handle(TColStd_HSequenceOfTransient) GEOMImpl_IAdvancedOperations::MakePipeTShap
         if (theHexMesh && nbEdgesInFillet == 1)
           break;
     }
-    
-    Handle(GEOM_Object) aFillet = aLocalOperations->MakeFilletEdges(aShape, theRF, theEdges);
+
+    Handle(GEOM_Object) aFillet;
+    try {
+       aFillet = aLocalOperations->MakeFilletEdges(aShape, theRF, theEdges);
+    }
+    catch (Standard_Failure) {
+      Handle(Standard_Failure) aFail = Standard_Failure::Caught();
+      SetErrorCode(aFail->GetMessageString());
+      return NULL;
+    }
+    if (aFillet.IsNull()) {
+       SetErrorCode("Fillet can not be computed on the given shape with the given parameters");
+       return NULL;
+    }
     aFillet->GetLastFunction()->SetDescription("");
     
     TopoDS_Shape aFilletShape = aFillet->GetValue();