Back to index

salome-geom  6.5.0
GEOMImpl_IAdvancedOperations.cxx
Go to the documentation of this file.
00001 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
00002 //
00003 // This library is free software; you can redistribute it and/or
00004 // modify it under the terms of the GNU Lesser General Public
00005 // License as published by the Free Software Foundation; either
00006 // version 2.1 of the License.
00007 //
00008 // This library is distributed in the hope that it will be useful,
00009 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00010 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00011 // Lesser General Public License for more details.
00012 //
00013 // You should have received a copy of the GNU Lesser General Public
00014 // License along with this library; if not, write to the Free Software
00015 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00016 //
00017 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00018 //
00019 //  File   : GEOMImpl_IAdvancedOperations.cxx
00020 //  Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
00021 
00022 #include <Standard_Stream.hxx>
00023 
00024 #include "GEOMImpl_Types.hxx"
00025 #include "GEOMImpl_IAdvancedOperations.hxx"
00026 #include "GEOMImpl_IBasicOperations.hxx"
00027 #include "GEOMImpl_IBooleanOperations.hxx"
00028 #include "GEOMImpl_IShapesOperations.hxx"
00029 #include "GEOMImpl_ITransformOperations.hxx"
00030 #include "GEOMImpl_IBlocksOperations.hxx"
00031 #include "GEOMImpl_I3DPrimOperations.hxx"
00032 #include "GEOMImpl_ILocalOperations.hxx"
00033 #include "GEOMImpl_IHealingOperations.hxx"
00034 
00035 #include "GEOMImpl_Gen.hxx"
00036 
00037 #include <Basics_OCCTVersion.hxx>
00038 
00039 #include <utilities.h>
00040 #include <OpUtil.hxx>
00041 #include <Utils_ExceptHandlers.hxx>
00042 
00043 #include "GEOM_Function.hxx"
00044 #include "GEOM_PythonDump.hxx"
00045 
00046 #include "GEOMImpl_PipeTShapeDriver.hxx"
00047 #include "GEOMImpl_IPipeTShape.hxx"
00048 /*@@ insert new functions before this line @@ do not remove this line @@ do not remove this line @@*/
00049 
00050 #include <TopExp.hxx>
00051 #include <TopExp_Explorer.hxx>
00052 #include <TopoDS.hxx>
00053 #include <TopoDS_Vertex.hxx>
00054 #include <TopTools_IndexedMapOfShape.hxx>
00055 
00056 #include <gp_Pnt.hxx>
00057 #include <gp_Vec.hxx>
00058 #include <gp_Ax3.hxx>
00059 #include <BRepBuilderAPI_Transform.hxx>
00060 #include <BRep_Tool.hxx>
00061 #include <cmath>
00062 
00063 #include <TFunction_DriverTable.hxx>
00064 #include <TFunction_Driver.hxx>
00065 #include <TFunction_Logbook.hxx>
00066 #include <TDF_Tool.hxx>
00067 #include <Standard_Failure.hxx>
00068 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
00069 
00070 #define HALF_LENGTH_MAIN_PIPE     "Main pipe half length" //"Tuyau principal - demi longueur"
00071 #define HALF_LENGTH_INCIDENT_PIPE "Incident pipe half length" //"Tuyau incident - demi longueur"
00072 #define CIRCULAR_QUARTER_PIPE     "Circular quarter of pipe" //"Circulaire - quart de tuyau"
00073 #define THICKNESS                 "Thickness" //"Epaisseur"
00074 #define FLANGE                    "Flange" // "Collerette"
00075 #define CHAMFER_OR_FILLET         "Chamfer or fillet" //"Chanfrein ou Raccord"
00076 #define JUNCTION_FACE_1           "Junction 1" //"Face de jonction 1"
00077 #define JUNCTION_FACE_2           "Junction 2" //"Face de jonction 2"
00078 #define JUNCTION_FACE_3           "Junction 3" //"Face de jonction 3"
00079 
00080 //=============================================================================
00084 //=============================================================================
00085 GEOMImpl_IAdvancedOperations::GEOMImpl_IAdvancedOperations(GEOM_Engine* theEngine, int theDocID) :
00086   GEOM_IOperations(theEngine, theDocID)
00087 {
00088   MESSAGE("GEOMImpl_IAdvancedOperations::GEOMImpl_IAdvancedOperations");
00089   myBasicOperations     = new GEOMImpl_IBasicOperations(GetEngine(), GetDocID());
00090   myBooleanOperations   = new GEOMImpl_IBooleanOperations(GetEngine(), GetDocID());
00091   myShapesOperations    = new GEOMImpl_IShapesOperations(GetEngine(), GetDocID());
00092   myTransformOperations = new GEOMImpl_ITransformOperations(GetEngine(), GetDocID());
00093   myBlocksOperations    = new GEOMImpl_IBlocksOperations(GetEngine(), GetDocID());
00094   my3DPrimOperations    = new GEOMImpl_I3DPrimOperations(GetEngine(), GetDocID());
00095   myLocalOperations     = new GEOMImpl_ILocalOperations(GetEngine(), GetDocID());
00096   myHealingOperations   = new GEOMImpl_IHealingOperations(GetEngine(), GetDocID());
00097 }
00098 
00099 //=============================================================================
00103 //=============================================================================
00104 GEOMImpl_IAdvancedOperations::~GEOMImpl_IAdvancedOperations()
00105 {
00106   MESSAGE("GEOMImpl_IAdvancedOperations::~GEOMImpl_IAdvancedOperations");
00107   delete myBasicOperations;
00108   delete myBooleanOperations;
00109   delete myShapesOperations;
00110   delete myTransformOperations;
00111   delete myBlocksOperations;
00112   delete my3DPrimOperations;
00113   delete myLocalOperations;
00114   delete myHealingOperations;
00115 }
00116 
00117 //=============================================================================
00121 //=============================================================================
00122 gp_Trsf GEOMImpl_IAdvancedOperations::GetPositionTrsf(double theL1, double theL2,
00123                                                       Handle(GEOM_Object) theP1,
00124                                                       Handle(GEOM_Object) theP2,
00125                                                       Handle(GEOM_Object) theP3)
00126 {
00127   // Old Local Coordinates System oldLCS
00128   gp_Pnt P0(0, 0, 0);
00129   gp_Pnt P1(-theL1, 0, 0);
00130   gp_Pnt P2(theL1, 0, 0);
00131   gp_Pnt P3(0, 0, theL2);
00132 
00133   gp_Dir oldX(gp_Vec(P1, P2));
00134   gp_Dir oldZ(gp_Vec(P0, P3));
00135   gp_Ax3 oldLCS(P0, oldZ, oldX);
00136 
00137   // New Local Coordinates System newLCS
00138   double LocX, LocY, LocZ;
00139   gp_Pnt newP1 = BRep_Tool::Pnt(TopoDS::Vertex(theP1->GetValue()));
00140   gp_Pnt newP2 = BRep_Tool::Pnt(TopoDS::Vertex(theP2->GetValue()));
00141   gp_Pnt newP3 = BRep_Tool::Pnt(TopoDS::Vertex(theP3->GetValue()));
00142   LocX = (newP1.X() + newP2.X()) / 2.;
00143   LocY = (newP1.Y() + newP2.Y()) / 2.;
00144   LocZ = (newP1.Z() + newP2.Z()) / 2.;
00145   gp_Pnt newO(LocX, LocY, LocZ);
00146 
00147   gp_Dir newX(gp_Vec(newP1, newP2)); // P1P2 Vector
00148   gp_Dir newZ(gp_Vec(newO, newP3)); // OP3 Vector
00149   gp_Ax3 newLCS = gp_Ax3(newO, newZ, newX);
00150 
00151   gp_Trsf aTrsf;
00152   aTrsf.SetDisplacement(oldLCS, newLCS);
00153 
00154   return aTrsf;
00155 }
00156 
00157 //=============================================================================
00162 //=============================================================================
00163 bool GEOMImpl_IAdvancedOperations::CheckCompatiblePosition(double& theL1, double& theL2,
00164                                                            Handle(GEOM_Object) theP1,
00165                                                            Handle(GEOM_Object) theP2,
00166                                                            Handle(GEOM_Object) theP3,
00167                                                            double theTolerance)
00168 {
00169   SetErrorCode(KO);
00170   gp_Pnt P1 = BRep_Tool::Pnt(TopoDS::Vertex(theP1->GetValue()));
00171   gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(theP2->GetValue()));
00172   gp_Pnt P3 = BRep_Tool::Pnt(TopoDS::Vertex(theP3->GetValue()));
00173 
00174   double d12 = P1.Distance(P2);
00175   double d13 = P1.Distance(P3);
00176   double d23 = P2.Distance(P3);
00177   //    double d2 = newO.Distance(P3);
00178 
00179   if (Abs(d12) <= Precision::Confusion()) {
00180     SetErrorCode("Junctions points P1 and P2 are identical");
00181     return false;
00182   }
00183   if (Abs(d13) <= Precision::Confusion()) {
00184     SetErrorCode("Junctions points P1 and P3 are identical");
00185     return false;
00186   }
00187   if (Abs(d23) <= Precision::Confusion()) {
00188     SetErrorCode("Junctions points P2 and P3 are identical");
00189     return false;
00190   }
00191 
00192 
00193   double newL1 = 0.5 * d12;
00194   double newL2 = sqrt(pow(d13,2)-pow(newL1,2));
00195   //
00196   // theL1*(1-theTolerance) <= newL1 <= theL1*(1+theTolerance)
00197   //
00198   if (fabs(newL1 - theL1) > Precision::Approximation()) {
00199     if ( (newL1 * (1 - theTolerance) -theL1 <= Precision::Approximation()) &&
00200          (newL1 * (1 + theTolerance) -theL1 >= Precision::Approximation()) ) {
00201       //            std::cerr << "theL1 = newL1" << std::endl;
00202       theL1 = newL1;
00203     } else {
00204       theL1 = -1;
00205       SetErrorCode("Dimension for main pipe (L1) is incompatible with new position");
00206       return false;
00207     }
00208   }
00209 
00210   //
00211   // theL2*(1-theTolerance) <= newL2  <= theL2*(1+theTolerance)
00212   //
00213   if (fabs(newL2 - theL2) > Precision::Approximation()) {
00214     if ( (newL2 * (1 - theTolerance) -theL2 <= Precision::Approximation()) &&
00215          (newL2 * (1 + theTolerance) -theL2 >= Precision::Approximation()) ) {
00216       theL2 = newL2;
00217     } else {
00218       theL2 = -1;
00219       SetErrorCode("Dimension for incident pipe (L2) is incompatible with new position");
00220       return false;
00221     }
00222   }
00223 
00224   SetErrorCode(OK);
00225   return true;
00226 
00227 }
00228 
00229 //=============================================================================
00233 //=============================================================================
00234 bool GEOMImpl_IAdvancedOperations::MakeGroups(Handle(GEOM_Object) theShape, int shapeType,
00235                                               double theR1, double theW1, double theL1,
00236                                               double theR2, double theW2, double theL2,
00237                                               Handle(TColStd_HSequenceOfTransient) theSeq,
00238                                               gp_Trsf aTrsf)
00239 {
00240   SetErrorCode(KO);
00241 
00242   if (theShape.IsNull()) return false;
00243 
00244   TopoDS_Shape aShape = theShape->GetValue();
00245   if (aShape.IsNull()) {
00246     SetErrorCode("Shape is not defined");
00247     return false;
00248   }
00249 
00250   gp_Trsf aTrsfInv = aTrsf.Inverted();
00251 
00252 //   int expectedGroups = 0;
00253 //   if (shapeType == TSHAPE_BASIC)
00254 //     if (Abs(theR2+theW2-theR1-theW1) <= Precision::Approximation())
00255 //       expectedGroups = 10;
00256 //     else
00257 //       expectedGroups = 11;
00258 //   else if (shapeType == TSHAPE_CHAMFER || shapeType == TSHAPE_FILLET)
00259 //     expectedGroups = 12;
00260 
00261   double aR1Ext = theR1 + theW1;
00262   double aR2Ext = theR2 + theW2;
00263 
00267 
00268   //
00269   // Comment the following lines when GetInPlace bug is solved
00270   // == BEGIN
00271   // Workaround of GetInPlace bug
00272   // Create a bounding box that fits the shape
00273   Handle(GEOM_Object) aBox = my3DPrimOperations->MakeBoxDXDYDZ(2*theL1, 2*aR1Ext, aR1Ext+theL2);
00274   aBox->GetLastFunction()->SetDescription("");
00275   myTransformOperations->TranslateDXDYDZ(aBox, -theL1, -aR1Ext, -aR1Ext);
00276   aBox->GetLastFunction()->SetDescription("");
00277   // Apply transformation to box
00278   BRepBuilderAPI_Transform aTransformationBox(aBox->GetValue(), aTrsf, Standard_False);
00279   TopoDS_Shape aBoxShapeTrsf = aTransformationBox.Shape();
00280   aBox->GetLastFunction()->SetValue(aBoxShapeTrsf);
00281 
00282   // Get the shell of the box
00283   Handle(GEOM_Object) aShell = Handle(GEOM_Object)::DownCast
00284     (myShapesOperations->MakeExplode(aBox, TopAbs_SHELL, true)->Value(1));
00285   aBox->GetLastFunction()->SetDescription("");
00286   aShell->GetLastFunction()->SetDescription("");
00287   // Get the common shapes between shell and shape
00288   Handle(GEOM_Object) aCommonCompound = myBooleanOperations->MakeBoolean (theShape, aShell, 1); // MakeCommon
00289   if (aCommonCompound.IsNull()) {
00290     SetErrorCode(myBooleanOperations->GetErrorCode());
00291     return false;
00292   }
00293   aCommonCompound->GetLastFunction()->SetDescription("");
00294   // Explode the faces of common shapes => 3 faces
00295   Handle(TColStd_HSequenceOfTransient) aCommonFaces =
00296     myShapesOperations->MakeExplode(aCommonCompound, TopAbs_FACE, true);
00297   aCommonCompound->GetLastFunction()->SetDescription("");
00298   std::list<Handle(GEOM_Object)> aCompoundOfFacesList;
00299 
00300   for (int i=0 ; i<= aCommonFaces->Length()-4 ; i+=4) {
00301     std::list<Handle(GEOM_Object)> aFacesList;
00302     for (int j = 1 ; j <= 4 ; j++) {
00303       Handle(GEOM_Object) aFace = Handle(GEOM_Object)::DownCast(aCommonFaces->Value(i+j)); // Junction faces
00304       if (!aFace.IsNull()) {
00305         aFace->GetLastFunction()->SetDescription("");
00306         aFacesList.push_back(aFace);
00307       }
00308     }
00309     Handle(GEOM_Object) aCompoundOfFaces = myShapesOperations->MakeCompound(aFacesList);
00310     if (!aCompoundOfFaces.IsNull()) {
00311       aCompoundOfFaces->GetLastFunction()->SetDescription("");
00312       aCompoundOfFacesList.push_back(aCompoundOfFaces);
00313     }
00314   }
00315 
00316   if (aCompoundOfFacesList.size() == 3) {
00317     Handle(GEOM_Object) aPln1 = aCompoundOfFacesList.front();
00318     aCompoundOfFacesList.pop_front();
00319     Handle(GEOM_Object) aPln2 = aCompoundOfFacesList.front();
00320     aCompoundOfFacesList.pop_front();
00321     Handle(GEOM_Object) aPln3 = aCompoundOfFacesList.front();
00322     aCompoundOfFacesList.pop_front();
00323     // == END
00324     //
00325 
00326 
00327     //     Uncomment the following lines when GetInPlace bug is solved
00328     //     == BEGIN
00329 //     Handle(GEOM_Object) aP1 = myBasicOperations->MakePointXYZ(-theL1, 0, 0);
00330 //     Handle(GEOM_Object) aP2 = myBasicOperations->MakePointXYZ(-0, 0, theL2);
00331 //     Handle(GEOM_Object) aP3 = myBasicOperations->MakePointXYZ(theL1, 0, 0);
00332 //     aP1->GetLastFunction()->SetDescription("");
00333 //     aP2->GetLastFunction()->SetDescription("");
00334 //     aP3->GetLastFunction()->SetDescription("");
00335 //     Handle(GEOM_Object) aV1 = myBasicOperations->MakeVectorDXDYDZ(-1, 0, 0);
00336 //     Handle(GEOM_Object) aV2 = myBasicOperations->MakeVectorDXDYDZ(0, 0, 1);
00337 //     Handle(GEOM_Object) aV3 = myBasicOperations->MakeVectorDXDYDZ(1, 0, 0);
00338 //     aV1->GetLastFunction()->SetDescription("");
00339 //     aV2->GetLastFunction()->SetDescription("");
00340 //     aV3->GetLastFunction()->SetDescription("");
00341 //     Handle(GEOM_Object) aPln1 = myBasicOperations->MakePlanePntVec(aP1, aV1, 2*(aR1Ext+theL2));
00342 //     Handle(GEOM_Object) aPln2 = myBasicOperations->MakePlanePntVec(aP2, aV2, 2*(aR2Ext));
00343 //     Handle(GEOM_Object) aPln3 = myBasicOperations->MakePlanePntVec(aP3, aV3, 2*(aR1Ext+theL2));
00344 //     aPln1->GetLastFunction()->SetDescription("");
00345 //     aPln2->GetLastFunction()->SetDescription("");
00346 //     aPln3->GetLastFunction()->SetDescription("");
00347 //
00348 //     BRepBuilderAPI_Transform aTransformation1(aPln1->GetValue(), aTrsf, Standard_False);
00349 //     TopoDS_Shape aTrsf_Shape1 = aTransformation1.Shape();
00350 //     aPln1->GetLastFunction()->SetValue(aTrsf_Shape1);
00351 //     BRepBuilderAPI_Transform aTransformation2(aPln2->GetValue(), aTrsf, Standard_False);
00352 //     TopoDS_Shape aTrsf_Shape2 = aTransformation2.Shape();
00353 //     aPln2->GetLastFunction()->SetValue(aTrsf_Shape2);
00354 //     BRepBuilderAPI_Transform aTransformation3(aPln3->GetValue(), aTrsf, Standard_False);
00355 //     TopoDS_Shape aTrsf_Shape3 = aTransformation3.Shape();
00356 //     aPln3->GetLastFunction()->SetValue(aTrsf_Shape3);
00357     //     == END
00358     //
00359 
00360     Handle(GEOM_Object) junctionFaces1 = myShapesOperations->GetInPlace(theShape, aPln1);
00361     if (junctionFaces1.IsNull())
00362       junctionFaces1 = myShapesOperations->GetShapesOnShapeAsCompound
00363         (aPln1, theShape, TopAbs_FACE,  GEOMAlgo_ST_ONIN);
00364     if (!junctionFaces1.IsNull()) {
00365       junctionFaces1->GetLastFunction()->SetDescription("");
00366       junctionFaces1->SetName("JUNCTION_FACE_1");
00367       theSeq->Append(junctionFaces1);
00368     }
00369     else {
00370       SetErrorCode("Junction face 1 not found");
00371       //        theSeq->Append(aPln1);
00372       //        return false;
00373     }
00374     Handle(GEOM_Object) junctionFaces2 = myShapesOperations->GetInPlace(theShape, aPln2);
00375     if (junctionFaces2.IsNull())
00376       junctionFaces2 = myShapesOperations->GetShapesOnShapeAsCompound
00377         (aPln2, theShape, TopAbs_FACE,  GEOMAlgo_ST_ONIN);
00378     if (!junctionFaces2.IsNull()) {
00379       junctionFaces2->GetLastFunction()->SetDescription("");
00380       junctionFaces2->SetName("JUNCTION_FACE_2");
00381       theSeq->Append(junctionFaces2);
00382     }
00383     else {
00384       SetErrorCode("Junction face 2 not found");
00385       //        theSeq->Append(aPln2);
00386       //        return false;
00387     }
00388     Handle(GEOM_Object) junctionFaces3 = myShapesOperations->GetInPlace(theShape, aPln3);
00389     if (junctionFaces3.IsNull())
00390       junctionFaces3 = myShapesOperations->GetShapesOnShapeAsCompound
00391         (aPln3, theShape, TopAbs_FACE,  GEOMAlgo_ST_ONIN);
00392     if (!junctionFaces3.IsNull()) {
00393       junctionFaces3->GetLastFunction()->SetDescription("");
00394       junctionFaces3->SetName("JUNCTION_FACE_3");
00395       theSeq->Append(junctionFaces3);
00396     }
00397     else {
00398       SetErrorCode("Junction face 3 not found");
00399       //        theSeq->Append(aPln3);
00400       //        return false;
00401     }
00402   // Comment the following lines when GetInPlace bug is solved
00403   // == BEGIN
00404   }
00405   //     == END
00409   // Result of propagate
00410 
00411   Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
00412 
00413   TCollection_AsciiString theDesc = aFunction->GetDescription();
00414   Handle(TColStd_HSequenceOfTransient) aSeqPropagate = myBlocksOperations->Propagate(theShape);
00415   if (aSeqPropagate.IsNull() || aSeqPropagate->Length() == 0) {
00416     SetErrorCode("Propagation groups not found");
00417     return false;
00418   }
00419   Standard_Integer nbEdges, aNbGroups = aSeqPropagate->Length();
00420   // Recover previous description to get rid of Propagate dump
00421   aFunction->SetDescription(theDesc);
00422 
00423   bool addGroup;
00424   bool circularFoundAndAdded = false;
00425   bool circularFound10 = false;
00426   bool incidentPipeFound = false;
00427   bool mainPipeFound = false;
00428   bool mainPipeFoundAndAdded = false;
00429   bool radialFound =false;
00430   bool flangeFound = false;
00431   bool flangeFoundAndAdded = false;
00432   bool chamferOrFilletFound = false;
00433 
00434   for (int i=1 ; i<= aNbGroups; i++) {
00435     addGroup = false;
00436 
00437     Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(aSeqPropagate->Value(i));
00438     if(aGroup.IsNull())
00439       continue;
00440 
00441     TopoDS_Shape aGroupShape = aGroup->GetValue();
00442     BRepBuilderAPI_Transform aTransformationShapeInv(aGroupShape, aTrsfInv, Standard_False);
00443     TopoDS_Shape aGroupShapeTrsfInv = aTransformationShapeInv.Shape();
00444 
00445     TopTools_IndexedMapOfShape anEdgesMap;
00446     TopExp::MapShapes(aGroupShapeTrsfInv,TopAbs_EDGE, anEdgesMap);
00447     nbEdges = anEdgesMap.Extent();
00448 
00449     if (shapeType == TSHAPE_BASIC) {
00450       if ((nbEdges == 21) || /*R1Ext = R2Ext*/(nbEdges == 17)){
00451         addGroup = true;
00452         aGroup->SetName("THICKNESS");
00453       }
00454       else if (nbEdges == 6) {
00455         if (!circularFoundAndAdded) {
00456           circularFoundAndAdded = true;
00457           addGroup = true;
00458           aGroup->SetName("CIRCULAR_QUARTER_PIPE");
00459         }
00460       }
00461       else if (nbEdges == 8) {
00462         incidentPipeFound = true;
00463         mainPipeFound = false;
00464         radialFound =false;
00465         flangeFound = false;
00466 
00467         TopExp_Explorer Ex(aGroupShapeTrsfInv,TopAbs_VERTEX);
00468         while (Ex.More()) {
00469           gp_Pnt aP =  BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
00470           double x=aP.X(), y=aP.Y(), z=aP.Z();
00471 
00472 
00473           if ((Abs(x) > aR2Ext + Precision::Confusion()) ||
00474               (Abs(y) > aR2Ext + Precision::Confusion())) {
00475             incidentPipeFound = false;
00476           }
00477 
00478           if ( z < -Precision::Confusion()) {
00479             // length of main pipe
00480             mainPipeFound = true;
00481             if (!mainPipeFoundAndAdded) {
00482               mainPipeFoundAndAdded = true;
00483               addGroup = true;
00484               aGroup->SetName("HALF_LENGTH_MAIN_PIPE");
00485             }
00486           }
00487 
00488           else if (Abs(x) > (theL1-Precision::Confusion())) {
00489             // discretisation circulaire
00490             radialFound = true;
00491             if (!circularFoundAndAdded) {
00492               circularFoundAndAdded = true;
00493               addGroup = true;
00494               aGroup->SetName("CIRCULAR_QUARTER_PIPE");
00495             }
00496           }
00497           Ex.Next();
00498         }
00499         if (incidentPipeFound) {
00500           addGroup = true;
00501           aGroup->SetName("HALF_LENGTH_INCIDENT_PIPE");
00502         }
00503         if (!addGroup && (!incidentPipeFound &&
00504                           !radialFound &&
00505                           !mainPipeFound &&
00506                           !flangeFound)) {
00507           // Flange (collerette)
00508           flangeFound = true;
00509           addGroup = true;
00510           aGroup->SetName("FLANGE");
00511         }
00512       }
00513       else
00514         continue;
00515     }
00516     else if (shapeType == TSHAPE_CHAMFER || shapeType == TSHAPE_FILLET) {
00517       if (nbEdges == 25) {
00518         addGroup = true;
00519         aGroup->SetName("THICKNESS");
00520       }
00521       else if ((nbEdges == 10) || (nbEdges == 6)) {
00522         if (!circularFoundAndAdded) {
00523           addGroup = true;
00524           circularFoundAndAdded = true;
00525           aGroup->SetName("CIRCULAR_QUARTER_PIPE");
00526           if (nbEdges == 10) {
00527             circularFound10 = true;
00528           }
00529         }
00530         else if (!circularFound10 && nbEdges == 10) {
00531           circularFound10 = true;
00532           addGroup = true;
00533           aGroup->SetName("CIRCULAR_QUARTER_PIPE");
00534         }
00535       }
00536       else if (nbEdges == 8) {
00537         incidentPipeFound = true;
00538         mainPipeFound = true;
00539         flangeFound = false;
00540 
00541         bool isNearZ0 = false;
00542         bool isBelowZ0 = false;
00543 
00544         TopExp_Explorer Ex (aGroupShapeTrsfInv,TopAbs_VERTEX);
00545         while (Ex.More()) {
00546           gp_Pnt aP = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
00547           double x=aP.X(), y=aP.Y(), z=aP.Z();
00548 
00549           // tuy_princ_long_avant & tuy_princ_long_apres
00550           //bool isMain = (((z < Precision::Confusion()) || (x < Precision::Confusion())) &&
00551           //               ((y <= aR1Ext + Precision::Confusion()) ||
00552           //                (y <= -(aR1Ext + Precision::Confusion())) ||
00553           //                (y <= theR1 + Precision::Confusion()) ||
00554           //                (y == -(theR1 + Precision::Confusion()))));
00555           bool isMain = ((z < Precision::Confusion() || x < Precision::Confusion()) &&
00556                          (fabs(y) > theR1 - Precision::Confusion() ||
00557                           fabs(y) < Precision::Confusion()));
00558 
00559           if (!isMain) {
00560             mainPipeFound = false;
00561           }
00562 
00563           // collerette
00564           //if (z < Precision::Confusion() && !isMain) {
00565           //  flangeFound = true;
00566           //  if (!flangeFoundAndAdded) {
00567           //    flangeFoundAndAdded = true;
00568           //    addGroup = true;
00569           //    aGroup->SetName("FLANGE");
00570           //  }
00571           //}
00572           if (fabs(z) < Precision::Confusion()) isNearZ0 = true;
00573           if (z < - Precision::Confusion()) isBelowZ0 = true;
00574 
00575           // tuyau incident
00576           if ((Abs(x) > aR2Ext + Precision::Confusion()) ||
00577               (Abs(y) > aR2Ext + Precision::Confusion())) {
00578             incidentPipeFound = false;
00579           }
00580           Ex.Next();
00581         }
00582         if (mainPipeFound) {
00583           addGroup = true;
00584           aGroup->SetName("HALF_LENGTH_MAIN_PIPE");
00585         }
00586         if (incidentPipeFound) {
00587           addGroup = true;
00588           aGroup->SetName("HALF_LENGTH_INCIDENT_PIPE");
00589         }
00590         if (isNearZ0 && !isBelowZ0) {
00591           flangeFound = true;
00592           if (!flangeFoundAndAdded) {
00593             flangeFoundAndAdded = true;
00594             addGroup = true;
00595             aGroup->SetName("FLANGE");
00596           }
00597         }
00598         if (!addGroup && (!incidentPipeFound &&
00599                           !mainPipeFound &&
00600                           !flangeFound &&
00601                           !chamferOrFilletFound)) {
00602           addGroup = true;
00603           chamferOrFilletFound = true;
00604           if (shapeType == TSHAPE_CHAMFER)
00605             aGroup->SetName("CHAMFER");
00606           else
00607             aGroup->SetName("FILLET");
00608         }
00609       }
00610       else
00611         continue;
00612     }
00613     // Add group to the list
00614     if (addGroup)
00615       theSeq->Append(aGroup);
00616   }
00617 
00618   SetErrorCode(OK);
00619   return true;
00620 }
00621 
00622 bool GEOMImpl_IAdvancedOperations::MakePipeTShapePartition(Handle(GEOM_Object) theShape,
00623                                                            double theR1, double theW1, double theL1,
00624                                                            double theR2, double theW2, double theL2,
00625                                                            double theH, double theW,
00626                                                            double theRF, bool isNormal)
00627 {
00628   SetErrorCode(KO);
00629 
00630   // Build tools for partition operation:
00631   // 1 face and 2 planes
00632   // Face
00633   Handle(GEOM_Object) arete_intersect_int;
00634   Handle(GEOM_Object) wire_t, wire_t2, face_t, face_t2;
00635   Handle(GEOM_Object) chan_racc;
00636   Handle(GEOM_Object) vi1, vi2;
00637   Handle(GEOM_Object) Te3;
00638 
00639   try {
00640 #if OCC_VERSION_LARGE > 0x06010000
00641     OCC_CATCH_SIGNALS;
00642 #endif
00643     Handle(GEOM_Object) Vector_Z = myBasicOperations->MakeVectorDXDYDZ(0, 0, 1);
00644     Vector_Z->GetLastFunction()->SetDescription("");
00645 
00646     // Useful values
00647     double aSize = 2*(theL1 + theL2);
00648     double aR1Ext = theR1 + theW1;
00649     double aR2Ext = theR2 + theW2;
00650     double theVertCylinderRadius = aR2Ext + theW + theRF;
00651     double theHoriCylinderRadius = aR1Ext + theH + theRF;
00652 
00653     // Common edges on internal cylinder
00654     Handle(GEOM_Object) box_i = my3DPrimOperations->MakeBoxDXDYDZ(theR2, theR2, theR1);
00655     box_i->GetLastFunction()->SetDescription("");
00656     box_i = myTransformOperations->TranslateDXDYDZ(box_i, -theR2, -theR2, 0);
00657     box_i->GetLastFunction()->SetDescription("");
00658 
00659     Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
00660     TCollection_AsciiString theDesc = aFunction->GetDescription();
00661     Handle(TColStd_HSequenceOfTransient) edges_i =
00662       myShapesOperations->GetShapesOnBox(box_i, theShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
00663     // Recover previous description to get rid of Propagate dump
00664     aFunction->SetDescription(theDesc);
00665     if (edges_i.IsNull() || edges_i->Length() == 0) {
00666       SetErrorCode("Internal edges not found");
00667       return false;
00668     }
00669     for (int i=1; i<=edges_i->Length();i++) {
00670       Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(edges_i->Value(i));
00671       anObj->GetLastFunction()->SetDescription("");
00672     }
00673     arete_intersect_int = Handle(GEOM_Object)::DownCast(edges_i->Value(1));
00674 
00675     // search for vertices located on both internal pipes
00676     aFunction = theShape->GetLastFunction();
00677     theDesc = aFunction->GetDescription();
00678     Handle(TColStd_HSequenceOfTransient) vertices_i =
00679       myShapesOperations->GetShapesOnBox(box_i, theShape, TopAbs_VERTEX, GEOMAlgo_ST_ONIN);
00680     // Recover previous description to get rid of Propagate dump
00681     aFunction->SetDescription(theDesc);
00682     if (vertices_i.IsNull() || vertices_i->Length() == 0) {
00683       SetErrorCode("Internal vertices not found");
00684       return false;
00685     }
00686 
00687     for (int i = 1; i <= vertices_i->Length(); i++) {
00688       Handle(GEOM_Object) v = Handle(GEOM_Object)::DownCast(vertices_i->Value(i));
00689       v->GetLastFunction()->SetDescription("");
00690       TopoDS_Vertex aVertex = TopoDS::Vertex(v->GetValue());
00691       gp_Pnt aP = BRep_Tool::Pnt(aVertex);
00692 //       std::cout << "Coords: " << aP.X() << ", " << aP.Y() << ", " << aP.Z() << std::endl;
00693       if (Abs(aP.X()) <= Precision::Confusion()) {
00694         if (Abs(aP.Y()) - theR1 <= Precision::Confusion()) {
00695           vi1 = v;
00696         }
00697       } else if (Abs(aP.Y()) <= Precision::Confusion()) {
00698         if (Abs(aP.X()) - theR1 <= Precision::Confusion()) {
00699           vi2 = v;
00700         }
00701       }
00702     }
00703 
00704     std::list<Handle(GEOM_Object)> theShapes;
00705 
00706     if (isNormal) {
00707       Handle(GEOM_Object) ve1, ve2;
00708 
00709       Handle(GEOM_Object) box_e = my3DPrimOperations->MakeBoxDXDYDZ(aR2Ext, aR2Ext, aR1Ext);
00710       box_e->GetLastFunction()->SetDescription("");
00711       box_e = myTransformOperations->TranslateDXDYDZ(box_e, -aR2Ext, -aR2Ext, 0);
00712       box_e->GetLastFunction()->SetDescription("");
00713       // Common edges on external cylinder
00714       aFunction = theShape->GetLastFunction();
00715       theDesc = aFunction->GetDescription();
00716       Handle(TColStd_HSequenceOfTransient) edges_e =
00717         myShapesOperations->GetShapesOnBox(box_e, theShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
00718       // Recover previous description to get rid of Propagate dump
00719       aFunction->SetDescription(theDesc);
00720       if (edges_e.IsNull() || edges_e->Length() == 0) {
00721         SetErrorCode("External edges not found");
00722         return false;
00723       }
00724       for (int i=1; i<=edges_e->Length();i++) {
00725         Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(edges_e->Value(i));
00726         anObj->GetLastFunction()->SetDescription("");
00727       }
00728 
00729       // search for vertices located on both external pipes
00730       aFunction = theShape->GetLastFunction();
00731       theDesc = aFunction->GetDescription();
00732       Handle(TColStd_HSequenceOfTransient) vertices_e =
00733         myShapesOperations->GetShapesOnBox(box_e, theShape, TopAbs_VERTEX, GEOMAlgo_ST_ONIN);
00734       // Recover previous description to get rid of Propagate dump
00735       aFunction->SetDescription(theDesc);
00736       if (vertices_e.IsNull() || vertices_e->Length() == 0) {
00737         SetErrorCode("External vertices not found");
00738         return false;
00739       }
00740 
00741       for (int i = 1; i <= vertices_e->Length(); i++) {
00742         Handle(GEOM_Object) v = Handle(GEOM_Object)::DownCast(vertices_e->Value(i));
00743         v->GetLastFunction()->SetDescription("");
00744         TopoDS_Vertex aVertex = TopoDS::Vertex(v->GetValue());
00745         gp_Pnt aP = BRep_Tool::Pnt(aVertex);
00746 //         std::cout << "Coords: " << aP.X() << ", " << aP.Y() << ", " << aP.Z() << std::endl;
00747         if (Abs(aP.X()) <= Precision::Confusion()) {
00748           if (Abs(aP.Y()) - theR2 > Precision::Confusion()) {
00749             ve1 = v;
00750           }
00751         } else if (Abs(aP.Y()) <= Precision::Confusion()) {
00752           if (Abs(aP.X()) - theR2 > Precision::Confusion()) {
00753             ve2 = v;
00754           }
00755         }
00756         if ( !ve1.IsNull() && !ve2.IsNull())
00757           break;
00758       }
00759       Handle(GEOM_Object) edge_e1, edge_e2;
00760       
00761       edge_e1 = myBasicOperations->MakeLineTwoPnt(ve1, vi1);
00762       if (edge_e1.IsNull()) {
00763         SetErrorCode("Edge 1 could not be built");
00764         return false;
00765       }
00766       
00767       edge_e2 = myBasicOperations->MakeLineTwoPnt(ve2, vi2);
00768       if (edge_e2.IsNull()) {
00769         SetErrorCode("Edge 2 could not be built");
00770         return false;
00771       }
00772 
00773       edge_e1->GetLastFunction()->SetDescription("");
00774       edge_e2->GetLastFunction()->SetDescription("");
00775 
00776       std::list<Handle(GEOM_Object)> edge_e_elist;
00777       edge_e_elist.push_back(arete_intersect_int);
00778       edge_e_elist.push_back(edge_e1);
00779       edge_e_elist.push_back(Handle(GEOM_Object)::DownCast(edges_e->Value(1)));
00780       edge_e_elist.push_back(edge_e2);
00781       wire_t = myShapesOperations->MakeWire(edge_e_elist, 1e-7);
00782       if (wire_t.IsNull()) {
00783         SetErrorCode("Impossible to build wire");
00784         return false;
00785       }
00786       wire_t->GetLastFunction()->SetDescription("");
00787       face_t = myShapesOperations->MakeFace(wire_t, false);
00788       if (face_t.IsNull()) {
00789         SetErrorCode("Impossible to build face");
00790         return false;
00791       }
00792       face_t->GetLastFunction()->SetDescription("");
00793       
00794       theShapes.push_back(theShape);
00795       theShapes.push_back(vi1);
00796       theShapes.push_back(vi2);
00797       theShapes.push_back(ve1);
00798       theShapes.push_back(ve2);
00799       theShapes.push_back(edge_e1);
00800       theShapes.push_back(edge_e2);
00801       theShapes.push_back(wire_t);
00802       theShapes.push_back(face_t);
00803     }
00804     else {
00805       Handle(GEOM_Object) P1, P2, P3, P4, P5, P6;
00806       int idP1, idP2, idP3, idP4;
00807       int PZX, PZY;
00808       double ZX=0, ZY=0;
00809       std::vector<int> LX;
00810       std::vector<int> LY;
00811       Handle(GEOM_Object) box_e = my3DPrimOperations->MakeBoxDXDYDZ
00812         (theVertCylinderRadius, theVertCylinderRadius, theHoriCylinderRadius);
00813       box_e->GetLastFunction()->SetDescription("");
00814       box_e = myTransformOperations->TranslateDXDYDZ
00815         (box_e, -theVertCylinderRadius, -theVertCylinderRadius, 0);
00816       box_e->GetLastFunction()->SetDescription("");
00817 
00818       aFunction = theShape->GetLastFunction();
00819       theDesc = aFunction->GetDescription();
00820       Handle(TColStd_HSequenceOfTransient) extremVertices =
00821         myShapesOperations->GetShapesOnBox(box_e, theShape, TopAbs_VERTEX, GEOMAlgo_ST_ONIN);
00822       // Recover previous description to get rid of Propagate dump
00823       aFunction->SetDescription(theDesc);
00824 
00825       if (extremVertices.IsNull() || extremVertices->Length() == 0) {
00826         if (theRF == 0)
00827           SetErrorCode("Vertices on chamfer not found");
00828         else
00829           SetErrorCode("Vertices on fillet not found");
00830         return false;
00831       }
00832 
00833       theShapes.push_back(theShape);
00834       theShapes.push_back(box_e);
00835       if (extremVertices->Length() != 6) {
00836         //           for (int i=1; i<=extremVertices->Length(); i++){
00837         //             theShapes.push_back(Handle(GEOM_Object)::DownCast(extremVertices->Value(i)));
00838         //           }
00839         //           Handle(GEOM_Object) aCompound = myShapesOperations->MakeCompound(theShapes);
00840         //           TopoDS_Shape aCompoundShape = aCompound->GetValue();
00841         //           theShape->GetLastFunction()->SetValue(aCompoundShape);
00842         SetErrorCode("Bad number of vertices on chamfer found");
00843         return false;
00844       }
00845 
00846       for (int i=1; i<=extremVertices->Length(); i++){
00847         Handle(GEOM_Object) aV = Handle(GEOM_Object)::DownCast(extremVertices->Value(i));
00848         aV->GetLastFunction()->SetDescription("");
00849         gp_Pnt aP = BRep_Tool::Pnt(TopoDS::Vertex(aV->GetValue()));
00850 
00851         if (Abs(aP.X()) <= Precision::Confusion()) {
00852           if (Abs(aP.Y()) - theR2 > Precision::Confusion()) {
00853             LX.push_back(i);
00854             if  (aP.Z()-ZX > Precision::Confusion()) {
00855               ZX = aP.Z();
00856               PZX = i;
00857             }
00858           }
00859         }
00860         else {
00861           if (Abs(aP.X()) - theR2 > Precision::Confusion()) {
00862             LY.push_back(i);
00863             if (aP.Z() - ZY > Precision::Confusion()) {
00864               ZY = aP.Z();
00865               PZY = i;
00866             }
00867           }
00868         }
00869       }
00870 
00871       idP2 = PZX;
00872       idP4 = PZY;
00873       idP1 = LX.at(0);
00874       if (LX.at(0) == PZX)
00875         idP1 = LX.at(1);
00876       idP3 = LY.at(0);
00877       if (LY.at(0) == PZY)
00878         idP3 = LY.at(1);
00879 
00880       P1 = Handle(GEOM_Object)::DownCast(extremVertices->Value(idP1));
00881       P2 = Handle(GEOM_Object)::DownCast(extremVertices->Value(idP2));
00882       P3 = Handle(GEOM_Object)::DownCast(extremVertices->Value(idP3));
00883       P4 = Handle(GEOM_Object)::DownCast(extremVertices->Value(idP4));
00884 
00885       Handle(GEOM_Object) Cote_1 = myBasicOperations->MakeLineTwoPnt(P1, vi1);
00886       if (Cote_1.IsNull()) {
00887         SetErrorCode("Impossible to build edge in thickness");
00888         return false;
00889       }
00890       Cote_1->GetLastFunction()->SetDescription("");
00891 
00892       Handle(GEOM_Object) Cote_2 = myBasicOperations->MakeLineTwoPnt(vi2, P3);
00893       if (Cote_2.IsNull()) {
00894         SetErrorCode("Impossible to build edge in thickness");
00895         return false;
00896       }
00897       Cote_2->GetLastFunction()->SetDescription("");
00898 
00899       // edge_chan_princ = arete du chanfrein (ou raccord) sur le tuyau principal
00900       // edge_chan_inc = arete du chanfrein (ou raccord) sur le tuyau incident
00901       //         std::cerr << "Getting chamfer edge on main pipe" << std::endl;
00902       Handle(GEOM_Object) edge_chan_princ = myBlocksOperations->GetEdge(theShape, P1, P3);
00903       if (edge_chan_princ.IsNull()) {
00904         SetErrorCode("Impossible to find edge on main pipe");
00905         return false;
00906       }
00907       edge_chan_princ->GetLastFunction()->SetDescription("");
00908 
00909       Handle(GEOM_Object) edge_chan_inc = myBlocksOperations->GetEdge(theShape, P2, P4);
00910       if (edge_chan_inc.IsNull()) {
00911         SetErrorCode("Impossible to find edge on incident pipe");
00912         return false;
00913       }
00914       edge_chan_inc->GetLastFunction()->SetDescription("");
00915 
00916       std::list<Handle(GEOM_Object)> edgeList1;
00917       edgeList1.push_back(edge_chan_princ);
00918       edgeList1.push_back(Cote_1);
00919       edgeList1.push_back(arete_intersect_int);
00920       edgeList1.push_back(Cote_2);
00921 
00922       //         std::cerr << "Creating wire 1" << std::endl;
00923       wire_t = myShapesOperations->MakeWire(edgeList1, 1e-7);
00924       if (wire_t.IsNull()) {
00925         SetErrorCode("Impossible to build wire");
00926         return false;
00927       }
00928       wire_t->GetLastFunction()->SetDescription("");
00929 
00930       //         std::cerr << "Creating face 1" << std::endl;
00931       face_t = myShapesOperations->MakeFace(wire_t, false);
00932       if (face_t.IsNull()) {
00933         SetErrorCode("Impossible to build face");
00934         return false;
00935       }
00936       face_t->GetLastFunction()->SetDescription("");
00937       theShapes.push_back(face_t);
00938 
00939       gp_Pnt aP2 = BRep_Tool::Pnt(TopoDS::Vertex(P2->GetValue()));
00940       gp_Pnt aP5 = BRep_Tool::Pnt(TopoDS::Vertex(vi1->GetValue()));
00941       double deltaZ = aP2.Z() - aP5.Z();
00942       //         std::cerr << "Creating new point from vi1 with deltaZ = " << deltaZ << std::endl;
00943       Handle(GEOM_Object) P5bis = myTransformOperations->TranslateDXDYDZCopy(vi1, 0, 0, deltaZ);
00944       if (P5bis.IsNull()) {
00945         SetErrorCode("Impossible to translate vertex");
00946         return false;
00947       }
00948       P5bis->GetLastFunction()->SetDescription("");
00949 
00950       gp_Pnt aP4 = BRep_Tool::Pnt(TopoDS::Vertex(P4->GetValue()));
00951       gp_Pnt aP6 = BRep_Tool::Pnt(TopoDS::Vertex(vi2->GetValue()));
00952       deltaZ = aP4.Z() - aP6.Z();
00953       //         std::cerr << "Creating new point from vi2 with deltaZ = " << deltaZ << std::endl;
00954       Handle(GEOM_Object) P6bis = myTransformOperations->TranslateDXDYDZCopy(vi2, 0, 0, deltaZ);
00955       if (P6bis.IsNull()) {
00956         SetErrorCode("Impossible to translate vertex");
00957         return false;
00958       }
00959       P6bis->GetLastFunction()->SetDescription("");
00960 
00961       //         std::cerr << "Creating new line 1 from 2 previous points" << std::endl;
00962       Handle(GEOM_Object) Cote_3 = myBasicOperations->MakeLineTwoPnt(P5bis, P2);
00963       if (Cote_3.IsNull()) {
00964         SetErrorCode("Impossible to build edge in thickness");
00965         return false;
00966       }
00967       Cote_3->GetLastFunction()->SetDescription("");
00968 
00969       //         std::cerr << "Creating new line 2 from 2 previous points" << std::endl;
00970       Handle(GEOM_Object) Cote_4 = myBasicOperations->MakeLineTwoPnt(P6bis, P4);
00971       if (Cote_4.IsNull()) {
00972         SetErrorCode("Impossible to build edge in thickness");
00973         return false;
00974       }
00975       Cote_4->GetLastFunction()->SetDescription("");
00976 
00977       //         std::cerr << "Creating new line 3 from 2 previous points" << std::endl;
00978       Handle(GEOM_Object) Cote_5 = myBasicOperations->MakeLineTwoPnt(P5bis, P6bis);
00979       if (Cote_4.IsNull()) {
00980         SetErrorCode("Impossible to build edge in thickness");
00981         return false;
00982       }
00983       Cote_5->GetLastFunction()->SetDescription("");
00984 
00985       //std::list<Handle(GEOM_Object)> edgeList2;
00986       //edgeList2.push_back(edge_chan_inc);
00987       //edgeList2.push_back(Cote_3);
00988       //edgeList2.push_back(Cote_5);
00989       //edgeList2.push_back(Cote_4);
00990       //         std::cerr << "Creating wire 2" << std::endl;
00991       //wire_t2 = myShapesOperations->MakeWire(edgeList2, 1e-7);
00992       //if (wire_t2.IsNull()) {
00993       //  SetErrorCode("Impossible to build wire");
00994       //  return false;
00995       //}
00996       //wire_t2->GetLastFunction()->SetDescription("");
00997       //         std::cerr << "Creating face 2" << std::endl;
00998       //face_t2 = myShapesOperations->MakeFace(wire_t2, false);
00999       face_t2 = my3DPrimOperations->MakePrismVecH(edge_chan_inc, Cote_4, - 2.0*theR2);
01000       if (face_t2.IsNull()) {
01001         SetErrorCode("Impossible to build face");
01002         return false;
01003       }
01004       face_t2->GetLastFunction()->SetDescription("");
01005       theShapes.push_back(face_t2);
01006     }
01007 
01008     // Planes
01009     Handle(GEOM_Object) aP0 = myBasicOperations->MakePointXYZ(0, 0, 0);
01010     Handle(GEOM_Object) aVZ = myBasicOperations->MakeVectorDXDYDZ(0, 0, 1);
01011     Handle(GEOM_Object) aVXZ = myBasicOperations->MakeVectorDXDYDZ(aR1Ext, 0, 0.5*(theL1+theVertCylinderRadius));
01012     Handle(GEOM_Object) aPlnOZ = myBasicOperations->MakePlanePntVec(aP0, aVZ, aSize);
01013     Handle(GEOM_Object) aPlnOXZ = myBasicOperations->MakePlanePntVec(aP0, aVXZ, aSize);
01014     aP0->GetLastFunction()->SetDescription("");
01015     aVZ->GetLastFunction()->SetDescription("");
01016     aVXZ->GetLastFunction()->SetDescription("");
01017     aPlnOZ->GetLastFunction()->SetDescription("");
01018     aPlnOXZ->GetLastFunction()->SetDescription("");
01019     theShapes.push_back(aPlnOZ);
01020     theShapes.push_back(aPlnOXZ);
01021 
01022     // Partition
01023     Handle(TColStd_HSequenceOfTransient) partitionShapes = new TColStd_HSequenceOfTransient;
01024     Handle(TColStd_HSequenceOfTransient) theTools = new TColStd_HSequenceOfTransient;
01025     Handle(TColStd_HSequenceOfTransient) theKeepInside = new TColStd_HSequenceOfTransient;
01026     Handle(TColStd_HSequenceOfTransient) theRemoveInside = new TColStd_HSequenceOfTransient;
01027     Handle(TColStd_HArray1OfInteger) theMaterials;
01028     partitionShapes->Append(theShape);
01029     theTools->Append(aPlnOZ);
01030     if (Abs(aR1Ext - aR2Ext) > Precision::Confusion() )
01031       theTools->Append(aPlnOXZ);
01032     theTools->Append(face_t);
01033     if (!isNormal)
01034       theTools->Append(face_t2);
01035 
01036     Te3 = myBooleanOperations->MakePartition
01037               (partitionShapes, theTools, theKeepInside, theRemoveInside,
01038               TopAbs_SOLID, false, theMaterials, 0, false);
01039     if (Te3.IsNull()) {
01040       SetErrorCode("Impossible to build partition of TShape");
01041       return false;
01042     }
01043     Te3->GetLastFunction()->SetDescription("");
01044 
01045     // Last verification: result should be a block
01046     std::list<GEOMImpl_IBlocksOperations::BCError> errList;
01047     if (!myBlocksOperations->CheckCompoundOfBlocks(Te3,errList)) {
01048       SetErrorCode("TShape is not a compound of block");
01049       return false;
01050     }
01051     
01052 //     // BEGIN Compound of created shapes - Only for debug purpose
01053 //     theShapes.clear();
01054 //     theShapes.push_back(theShape);
01055 //     theShapes.push_back(aPlnOZ);
01056 //     if (Abs(aR1Ext - aR2Ext) > Precision::Confusion() )
01057 //       theShapes.push_back(aPlnOXZ);
01058 //     theShapes.push_back(face_t);
01059 //     if (!isNormal)
01060 //       theShapes.push_back(face_t2);
01061 // 
01062 //     Handle(GEOM_Object) aCompound = myShapesOperations->MakeCompound(theShapes);
01063 //     TopoDS_Shape aCompoundShape = aCompound->GetValue();
01064 //     theShape->GetLastFunction()->SetValue(aCompoundShape);
01065 //     // END Compound of created shapes - Only for debug purpose
01066     
01067     TopoDS_Shape aShape = Te3->GetValue();
01068     theShape->GetLastFunction()->SetValue(aShape);
01069   } catch (Standard_Failure) {
01070     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
01071     SetErrorCode(aFail->GetMessageString());
01072     return false;
01073   }
01074 
01075   SetErrorCode(OK);
01076   return true;
01077 }
01078 
01079 // Mirror and glue faces
01080 bool GEOMImpl_IAdvancedOperations::MakePipeTShapeMirrorAndGlue(Handle(GEOM_Object) theShape,
01081                                                                double theR1, double theW1, double theL1,
01082                                                                double theR2, double theW2, double theL2)
01083 {
01084   SetErrorCode(KO);
01085 
01086   // Useful values
01087   double aSize = 2*(theL1 + theL2);
01088   double aR1Ext = theR1 + theW1;
01089 
01090   // Planes
01091   Handle(GEOM_Object) aP0 = myBasicOperations->MakePointXYZ(0, 0, 0);
01092   aP0->GetLastFunction()->SetDescription("");
01093   Handle(GEOM_Object) aVX = myBasicOperations->MakeVectorDXDYDZ(1, 0, 0);
01094   Handle(GEOM_Object) aVY = myBasicOperations->MakeVectorDXDYDZ(0, 1, 0);
01095   aVX->GetLastFunction()->SetDescription("");
01096   aVY->GetLastFunction()->SetDescription("");
01097   Handle(GEOM_Object) aPlane_OX = myBasicOperations->MakePlanePntVec(aP0, aVX, 2*(aR1Ext + theL2));
01098   Handle(GEOM_Object) aPlane_OY = myBasicOperations->MakePlanePntVec(aP0, aVY, aSize);
01099   aPlane_OX->GetLastFunction()->SetDescription("");
01100   aPlane_OY->GetLastFunction()->SetDescription("");
01101 
01102   Handle(GEOM_Object) Te4 = myTransformOperations->MirrorPlaneCopy(theShape, aPlane_OX);
01103   if (Te4.IsNull()) {
01104     SetErrorCode("Impossible to build mirror of quarter TShape");
01105     return false;
01106   }
01107 
01108   Handle(GEOM_Object) Te5 = myTransformOperations->MirrorPlaneCopy(theShape, aPlane_OY);
01109   if (Te5.IsNull()) {
01110     SetErrorCode("Impossible to build mirror of half TShape");
01111     return false;
01112   }
01113 
01114   Handle(GEOM_Object) Te6 = myTransformOperations->MirrorPlaneCopy(Te4, aPlane_OY);
01115   if (Te6.IsNull()) {
01116     SetErrorCode("Impossible to build mirror of half TShape");
01117     return false;
01118   }
01119 
01120   std::list<Handle(GEOM_Object)> aShapesList;
01121   aShapesList.push_back(theShape);
01122   aShapesList.push_back(Te4);
01123   aShapesList.push_back(Te5);
01124   aShapesList.push_back(Te6);
01125   Handle(GEOM_Object) Te7 = myShapesOperations->MakeCompound(aShapesList);
01126   if (Te7.IsNull()) {
01127     SetErrorCode("Impossible to build compound");
01128     return false;
01129   }
01130 
01131   Handle(GEOM_Object) Te8 = myShapesOperations->MakeGlueFaces(Te7, 1e-7, true);
01132   if (Te8.IsNull()) {
01133     SetErrorCode("Impossible to glue faces of TShape");
01134     return false;
01135   }
01136 
01137   TopoDS_Shape aShape = Te8->GetValue();
01138 
01139   theShape->GetLastFunction()->SetValue(aShape);
01140 
01141   Te4->GetLastFunction()->SetDescription("");
01142   Te5->GetLastFunction()->SetDescription("");
01143   Te6->GetLastFunction()->SetDescription("");
01144   Te7->GetLastFunction()->SetDescription("");
01145   Te8->GetLastFunction()->SetDescription("");
01146 
01147   SetErrorCode(OK);
01148   return true;
01149 }
01150 
01151 //=============================================================================
01166 //=============================================================================
01167 Handle(TColStd_HSequenceOfTransient)
01168   GEOMImpl_IAdvancedOperations::MakePipeTShape(double theR1, double theW1, double theL1,
01169                                                double theR2, double theW2, double theL2,
01170                                                bool theHexMesh)
01171 {
01172   MESSAGE("GEOMImpl_IAdvancedOperations::MakePipeTShape");
01173   SetErrorCode(KO);
01174   //Add a new object
01175   Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
01176 
01177   //Add a new shape function with parameters
01178   Handle(GEOM_Function) aFunction = aShape->AddFunction(GEOMImpl_PipeTShapeDriver::GetID(), TSHAPE_BASIC);
01179   if (aFunction.IsNull()) return NULL;
01180 
01181   //Check if the function is set correctly
01182   if (aFunction->GetDriverGUID() != GEOMImpl_PipeTShapeDriver::GetID()) return NULL;
01183 
01184   GEOMImpl_IPipeTShape aData(aFunction);
01185 
01186   aData.SetR1(theR1);
01187   aData.SetW1(theW1);
01188   aData.SetL1(theL1);
01189   aData.SetR2(theR2);
01190   aData.SetW2(theW2);
01191   aData.SetL2(theL2);
01192   aData.SetHexMesh(theHexMesh);
01193 
01194   //Compute the resulting value
01195   try {
01196 #if OCC_VERSION_LARGE > 0x06010000
01197     OCC_CATCH_SIGNALS;
01198 #endif
01199     if (!GetSolver()->ComputeFunction(aFunction)) {
01200       SetErrorCode("TShape driver failed");
01201       return NULL;
01202     }
01203     if (theHexMesh) {
01204       if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
01205         return NULL;
01206       if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
01207         return NULL;
01208     }
01209   } catch (Standard_Failure) {
01210     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
01211     SetErrorCode(aFail->GetMessageString());
01212     return NULL;
01213   }
01214 
01215 
01216   Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
01217   aSeq->Append(aShape);
01218 
01219   if (theHexMesh) {
01220     /*
01221      * Get the groups: BEGIN
01222      */
01223     try {
01224       if (!MakeGroups(aShape, TSHAPE_BASIC, theR1, theW1, theL1, theR2, theW2, theL2, aSeq, gp_Trsf()))
01225         return NULL;
01226     }
01227     catch (Standard_Failure) {
01228       Handle(Standard_Failure) aFail = Standard_Failure::Caught();
01229       SetErrorCode(aFail->GetMessageString());
01230       return NULL;
01231     }
01232 
01233     TCollection_AsciiString aListRes, anEntry;
01234     // Iterate over the sequence aSeq
01235     Standard_Integer aNbGroups = aSeq->Length();
01236     Standard_Integer i = 2;
01237     for (; i <= aNbGroups; i++) {
01238       Handle(Standard_Transient) anItem = aSeq->Value(i);
01239       if (anItem.IsNull()) continue;
01240       Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
01241       if (aGroup.IsNull()) continue;
01242       //Make a Python command
01243       TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
01244       aListRes += anEntry + ", ";
01245     }
01246 
01247     aListRes.Trunc(aListRes.Length() - 2);
01248 
01249     //Make a Python command
01250     GEOM::TPythonDump(aFunction)
01251       << "[" << aShape << ", " << aListRes.ToCString() << "] = geompy.MakePipeTShape("
01252       << theR1 << ", " << theW1 << ", " << theL1 << ", " << theR2 << ", " << theW2 << ", " << theL2 << ", "
01253       << theHexMesh << ")";
01254   }
01255   /*
01256    * Get the groups: END
01257    */
01258   else {
01259     //Make a Python command
01260     GEOM::TPythonDump(aFunction)
01261       << "[" << aShape << "] = geompy.MakePipeTShape(" << theR1 << ", " << theW1 << ", "
01262       << theL1 << ", " << theR2 << ", " << theW2 << ", " << theL2 << ", " << theHexMesh << ")";
01263   }
01264 
01265   SetErrorCode(OK);
01266 
01267   return aSeq;
01268 }
01269 
01270 //=============================================================================
01289 //=============================================================================
01290 Handle(TColStd_HSequenceOfTransient)
01291 GEOMImpl_IAdvancedOperations::MakePipeTShapeWithPosition(double theR1, double theW1, double theL1,
01292                                                          double theR2, double theW2, double theL2,
01293                                                          bool theHexMesh,
01294                                                          Handle(GEOM_Object) theP1,
01295                                                          Handle(GEOM_Object) theP2,
01296                                                          Handle(GEOM_Object) theP3)
01297 {
01298   SetErrorCode(KO);
01299   //Add a new object
01300   Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
01302   // TSHAPE CODE
01304   //Add a new shape function with parameters
01305   Handle(GEOM_Function) aFunction = aShape->AddFunction(GEOMImpl_PipeTShapeDriver::GetID(), TSHAPE_BASIC);
01306   if (aFunction.IsNull()) return NULL;
01307 
01308   //Check if the function is set correctly
01309   if (aFunction->GetDriverGUID() != GEOMImpl_PipeTShapeDriver::GetID()) return NULL;
01310 
01311   // Check new position
01312   if (!CheckCompatiblePosition(theL1, theL2, theP1, theP2, theP3, 0.01)) {
01313     return NULL;
01314   }
01315 
01316   GEOMImpl_IPipeTShape aData(aFunction);
01317 
01318   aData.SetR1(theR1);
01319   aData.SetW1(theW1);
01320   aData.SetL1(theL1);
01321   aData.SetR2(theR2);
01322   aData.SetW2(theW2);
01323   aData.SetL2(theL2);
01324   aData.SetHexMesh(theHexMesh);
01325 
01326   //Compute the resulting value
01327   try {
01328 #if OCC_VERSION_LARGE > 0x06010000
01329     OCC_CATCH_SIGNALS;
01330 #endif
01331     if (!GetSolver()->ComputeFunction(aFunction)) {
01332       SetErrorCode("TShape driver failed");
01333       return NULL;
01334     }
01335   } catch (Standard_Failure) {
01336     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
01337     SetErrorCode(aFail->GetMessageString());
01338     return NULL;
01339   }
01340 
01341   if (theHexMesh) {
01342     if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
01343       return NULL;
01344     if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
01345       return NULL;
01346   }
01347 
01348   TopoDS_Shape Te = aShape->GetValue();
01349 
01350   // Set Position
01351   gp_Trsf aTrsf = GetPositionTrsf(theL1, theL2, theP1, theP2, theP3);
01352   BRepBuilderAPI_Transform aTransformation(Te, aTrsf, Standard_False);
01353   TopoDS_Shape aTrsf_Shape = aTransformation.Shape();
01354   aFunction->SetValue(aTrsf_Shape);
01355   Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
01356   aSeq->Append(aShape);
01357 
01358   if (theHexMesh) {
01359     //
01360     // Get the groups: BEGIN
01361     //
01362     try {
01363       if (!MakeGroups(aShape,TSHAPE_BASIC, theR1, theW1, theL1, theR2, theW2, theL2, aSeq, aTrsf)) {
01364         return NULL;
01365       }
01366     }
01367     catch (Standard_Failure) {
01368       Handle(Standard_Failure) aFail = Standard_Failure::Caught();
01369       SetErrorCode(aFail->GetMessageString());
01370       return NULL;
01371     }
01372 
01373     TCollection_AsciiString aListRes, anEntry;
01374     // Iterate over the sequence aSeq
01375     Standard_Integer aNbGroups = aSeq->Length();
01376     Standard_Integer i = 2;
01377     for (; i <= aNbGroups; i++) {
01378       Handle(Standard_Transient) anItem = aSeq->Value(i);
01379       if (anItem.IsNull()) continue;
01380       Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
01381       if (aGroup.IsNull()) continue;
01382       //Make a Python command
01383       TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
01384       aListRes += anEntry + ", ";
01385     }
01386 
01387     aListRes.Trunc(aListRes.Length() - 2);
01388 
01389     //Make a Python command
01390     GEOM::TPythonDump(aFunction)
01391       << "[" << aShape << ", " << aListRes.ToCString() << "] = geompy.MakePipeTShape("
01392       << theR1 << ", " << theW1 << ", " << theL1 << ", " << theR2 << ", " << theW2 << ", " << theL2 << ", "
01393       << theHexMesh << ", " << theP1 << ", " << theP2 << ", " << theP3 << ")";
01394   }
01395   //
01396   // Get the groups: END
01397   //
01398 
01399   else {
01400     //Make a Python command
01401     GEOM::TPythonDump(aFunction)
01402       << "[" << aShape << "] = geompy.MakePipeTShape(" << theR1 << ", " << theW1 << ", "
01403       << theL1 << ", " << theR2 << ", " << theW2 << ", " << theL2 << ", " << theHexMesh << ", " << theP1
01404       << ", " << theP2 << ", " << theP3 << ")";
01405   }
01406 
01407   SetErrorCode(OK);
01408 
01409   return aSeq;
01410 }
01411 
01412 //=============================================================================
01430 //=============================================================================
01431 Handle(TColStd_HSequenceOfTransient)
01432 GEOMImpl_IAdvancedOperations::MakePipeTShapeChamfer(double theR1, double theW1, double theL1,
01433                                                     double theR2, double theW2, double theL2,
01434                                                     double theH, double theW,
01435                                                     bool theHexMesh)
01436 {
01437   SetErrorCode(KO);
01438   //Add a new object
01439   Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
01440   //Add a new shape function with parameters
01441   Handle(GEOM_Function) aFunction = aShape->AddFunction(GEOMImpl_PipeTShapeDriver::GetID(), TSHAPE_CHAMFER);
01442   if (aFunction.IsNull()) return NULL;
01443 
01444   //Check if the function is set correctly
01445   if (aFunction->GetDriverGUID() != GEOMImpl_PipeTShapeDriver::GetID()) return NULL;
01446 
01447   GEOMImpl_IPipeTShape aData(aFunction);
01448 
01449   aData.SetR1(theR1);
01450   aData.SetW1(theW1);
01451   aData.SetL1(theL1);
01452   aData.SetR2(theR2);
01453   aData.SetW2(theW2);
01454   aData.SetL2(theL2);
01455   aData.SetH(theH);
01456   aData.SetW(theW);
01457   aData.SetHexMesh(theHexMesh);
01458 
01459   //Compute the resulting value
01460   try {
01461 #if OCC_VERSION_LARGE > 0x06010000
01462     OCC_CATCH_SIGNALS;
01463 #endif
01464     if (!GetSolver()->ComputeFunction(aFunction)) {
01465       SetErrorCode("TShape driver failed");
01466       return NULL;
01467     }
01468   } catch (Standard_Failure) {
01469     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
01470     SetErrorCode(aFail->GetMessageString());
01471     return NULL;
01472   }
01473 
01474   // BEGIN of chamfer
01475   TopoDS_Shape aShapeShape = aShape->GetValue();
01476   TopTools_IndexedMapOfShape anEdgesIndices;
01477   TopExp::MapShapes(aShapeShape, anEdgesIndices);
01478   // Common edges on external cylinders
01479   Handle(GEOM_Object) box_e;
01480   if (theHexMesh) {
01481     box_e = my3DPrimOperations->MakeBoxDXDYDZ(theR2+theW2, theR2+theW2, theR1+theW1);
01482   }
01483   else {
01484     box_e = my3DPrimOperations->MakeBoxDXDYDZ(2*(theR2+theW2), 2*(theR2+theW2), theR1+theW1);
01485   }
01486   box_e->GetLastFunction()->SetDescription("");
01487   box_e = myTransformOperations->TranslateDXDYDZ(box_e, -(theR2+theW2), -(theR2+theW2), 0);
01488   box_e->GetLastFunction()->SetDescription("");
01489 
01490   Handle(TColStd_HSequenceOfInteger) edges_e =
01491     myShapesOperations->GetShapesOnBoxIDs(box_e, aShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
01492   box_e->GetLastFunction()->SetDescription("");
01493 
01494   if (edges_e.IsNull() || edges_e->Length() == 0) {
01495     SetErrorCode("External edges not found");
01496     return NULL;
01497   }
01498   int nbEdgesInChamfer = 0;
01499   std::list<int> theEdges;
01500   for (int i=1; i<=edges_e->Length();i++) {
01501     int edgeID = edges_e->Value(i);
01502     TopoDS_Shape theEdge = anEdgesIndices.FindKey(edgeID);
01503     TopExp_Explorer Ex(theEdge,TopAbs_VERTEX);
01504     int iv=0;
01505     while (Ex.More()) {
01506       iv ++;
01507       gp_Pnt aPt = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
01508       if (Abs(aPt.Z() - (theR1+theW1)) <= Precision::Confusion()) {
01509         nbEdgesInChamfer ++;
01510         theEdges.push_back(edgeID);
01511       }
01512       Ex.Next();
01513     }
01514     if (theHexMesh && nbEdgesInChamfer == 1)
01515       break;
01516   }
01517   Handle(GEOM_Object) aChamfer;
01518   try {
01519     aChamfer = myLocalOperations->MakeChamferEdges(aShape, theW, theH, theEdges);
01520   }
01521   catch (Standard_Failure) {
01522     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
01523     SetErrorCode(aFail->GetMessageString());
01524     return NULL;
01525   }
01526   if (aChamfer.IsNull()) {
01527     SetErrorCode("Chamfer can not be computed on the given shape with the given parameters");
01528     return NULL;
01529   }
01530   aChamfer->GetLastFunction()->SetDescription("");
01531 
01532   TopoDS_Shape aChamferShape = aChamfer->GetValue();
01533   aFunction->SetValue(aChamferShape);
01534   // END of chamfer
01535 
01536   //   bool doMesh = false;
01537   if (theHexMesh) {
01538     //        doMesh = true;
01539     if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2, theH, theW, 0, false)) {
01540       MESSAGE("PipeTShape partition failed");
01541       //            doMesh = false;
01542       return NULL;
01543     }
01544     if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2)) {
01545       MESSAGE("PipeTShape mirrors and glue failed");
01546       //          doMesh = false;
01547       return NULL;
01548     }
01549   }
01550 
01551   Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
01552   aSeq->Append(aShape);
01553 
01554   //    if (doMesh) {
01555   if (theHexMesh) {
01556     //
01557     //         Get the groups: BEGIN
01558     //
01559     //if (!MakeGroups(aShape, TSHAPE_CHAMFER, theR1, theW1, theL1, theR2, theW2, theL2, aSeq, gp_Trsf())) {
01560     //  //Make a Python command
01561     //  GEOM::TPythonDump(aFunction)
01562     //    << "[" << aShape << "] = geompy.MakePipeTShapeChamfer(" << theR1 << ", " << theW1
01563     //    << ", " << theL1 << ", " << theR2 << ", " << theW2 << ", " << theL2 << ", " << theH << ", " << theW
01564     //    << ", " << theHexMesh << ")";
01565     //}
01566     //else {
01567     try {
01568       if (!MakeGroups(aShape, TSHAPE_CHAMFER, theR1, theW1, theL1, theR2, theW2, theL2, aSeq, gp_Trsf()))
01569         return NULL;
01570     }
01571     catch (Standard_Failure) {
01572       Handle(Standard_Failure) aFail = Standard_Failure::Caught();
01573       SetErrorCode(aFail->GetMessageString());
01574       return NULL;
01575     }
01576 
01577     TCollection_AsciiString aListRes, anEntry;
01578     // Iterate over the sequence aSeq
01579     Standard_Integer aNbGroups = aSeq->Length();
01580     Standard_Integer i = 2;
01581     for (; i <= aNbGroups; i++) {
01582       Handle(Standard_Transient) anItem = aSeq->Value(i);
01583       if (anItem.IsNull()) continue;
01584       Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
01585       if (aGroup.IsNull()) continue;
01586       //Make a Python command
01587       TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
01588       aListRes += anEntry + ", ";
01589     }
01590 
01591     aListRes.Trunc(aListRes.Length() - 2);
01592 
01593     //Make a Python command
01594     GEOM::TPythonDump(aFunction)
01595       << "[" << aShape << ", " << aListRes.ToCString()
01596       << "] = geompy.MakePipeTShapeChamfer(" << theR1 << ", " << theW1 << ", " << theL1 << ", " << theR2
01597       << ", " << theW2 << ", " << theL2 << ", " << theH << ", " << theW << ", " << theHexMesh << ")";
01598     //}
01599   }
01600   //
01601   //     Get the groups: END
01602   //
01603   else {
01604     //Make a Python command
01605     GEOM::TPythonDump(aFunction)
01606       << "[" << aShape << "] = geompy.MakePipeTShapeChamfer(" << theR1 << ", " << theW1
01607       << ", " << theL1 << ", " << theR2 << ", " << theW2 << ", " << theL2 << ", " << theH << ", " << theW
01608       << ", " << theHexMesh << ")";
01609   }
01610 
01611   SetErrorCode(OK);
01612 
01613   return aSeq;
01614 }
01615 
01616 //=============================================================================
01638 //=============================================================================
01639 Handle(TColStd_HSequenceOfTransient)
01640 GEOMImpl_IAdvancedOperations::MakePipeTShapeChamferWithPosition(double theR1, double theW1, double theL1,
01641                                                                 double theR2, double theW2, double theL2,
01642                                                                 double theH, double theW,
01643                                                                 bool theHexMesh,
01644                                                                 Handle(GEOM_Object) theP1,
01645                                                                 Handle(GEOM_Object) theP2,
01646                                                                 Handle(GEOM_Object) theP3)
01647 {
01648   SetErrorCode(KO);
01649   //Add a new object
01650   Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
01651   //Add a new shape function with parameters
01652   Handle(GEOM_Function) aFunction = aShape->AddFunction(GEOMImpl_PipeTShapeDriver::GetID(), TSHAPE_CHAMFER);
01653   if (aFunction.IsNull()) return NULL;
01654 
01655   //Check if the function is set correctly
01656   if (aFunction->GetDriverGUID() != GEOMImpl_PipeTShapeDriver::GetID()) return NULL;
01657 
01658   // Check new position
01659   if (!CheckCompatiblePosition(theL1, theL2, theP1, theP2, theP3, 0.01)) {
01660     return NULL;
01661   }
01662 
01663   GEOMImpl_IPipeTShape aData(aFunction);
01664 
01665   aData.SetR1(theR1);
01666   aData.SetW1(theW1);
01667   aData.SetL1(theL1);
01668   aData.SetR2(theR2);
01669   aData.SetW2(theW2);
01670   aData.SetL2(theL2);
01671   aData.SetH(theH);
01672   aData.SetW(theW);
01673   aData.SetHexMesh(theHexMesh);
01674 
01675   //Compute the resulting value
01676   try {
01677 #if OCC_VERSION_LARGE > 0x06010000
01678     OCC_CATCH_SIGNALS;
01679 #endif
01680     if (!GetSolver()->ComputeFunction(aFunction)) {
01681       SetErrorCode("TShape driver failed");
01682       return NULL;
01683     }
01684   } catch (Standard_Failure) {
01685     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
01686     SetErrorCode(aFail->GetMessageString());
01687     return NULL;
01688   }
01689 
01690   // BEGIN of chamfer
01691   TopoDS_Shape aShapeShape = aShape->GetValue();
01692   TopTools_IndexedMapOfShape anEdgesIndices;
01693   TopExp::MapShapes(aShapeShape, anEdgesIndices);
01694   // Common edges on external cylinders
01695   Handle(GEOM_Object) box_e;
01696   if (theHexMesh) {
01697     box_e = my3DPrimOperations->MakeBoxDXDYDZ(theR2+theW2, theR2+theW2, theR1+theW1);
01698   }
01699   else {
01700     box_e = my3DPrimOperations->MakeBoxDXDYDZ(2*(theR2+theW2), 2*(theR2+theW2), theR1+theW1);
01701   }
01702   box_e->GetLastFunction()->SetDescription("");
01703   box_e = myTransformOperations->TranslateDXDYDZ(box_e, -(theR2+theW2), -(theR2+theW2), 0);
01704   box_e->GetLastFunction()->SetDescription("");
01705 
01706   Handle(TColStd_HSequenceOfInteger) edges_e =
01707     myShapesOperations->GetShapesOnBoxIDs(box_e, aShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
01708   box_e->GetLastFunction()->SetDescription("");
01709 
01710   if (edges_e.IsNull() || edges_e->Length() == 0) {
01711     SetErrorCode("External edges not found");
01712     return NULL;
01713   }
01714   int nbEdgesInChamfer = 0;
01715   std::list<int> theEdges;
01716   for (int i=1; i<=edges_e->Length();i++) {
01717     int edgeID = edges_e->Value(i);
01718     TopoDS_Shape theEdge = anEdgesIndices.FindKey(edgeID);
01719     TopExp_Explorer Ex(theEdge,TopAbs_VERTEX);
01720     while (Ex.More()) {
01721       gp_Pnt aPt = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
01722       if (Abs(aPt.Z() - (theR1+theW1)) <= Precision::Confusion()) {
01723         nbEdgesInChamfer ++;
01724         theEdges.push_back(edgeID);
01725       }
01726       Ex.Next();
01727     }
01728     if (theHexMesh && nbEdgesInChamfer == 1)
01729       break;
01730   }
01731   Handle(GEOM_Object) aChamfer;
01732   try {
01733     aChamfer = myLocalOperations->MakeChamferEdges(aShape, theW, theH, theEdges);
01734   }
01735   catch (Standard_Failure) {
01736     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
01737     SetErrorCode(aFail->GetMessageString());
01738     return NULL;
01739   }
01740   if (aChamfer.IsNull()) {
01741     SetErrorCode("Chamfer can not be computed on the given shape with the given parameters");
01742     return NULL;
01743   }
01744   aChamfer->GetLastFunction()->SetDescription("");
01745 
01746   TopoDS_Shape aChamferShape = aChamfer->GetValue();
01747   aFunction->SetValue(aChamferShape);
01748   // END of chamfer
01749 
01750   if (theHexMesh) {
01751     if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2, theH, theW, 0, false))
01752       return NULL;
01753     if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
01754       return NULL;
01755   }
01756 
01757   TopoDS_Shape Te = aShape->GetValue();
01758 
01759   // Set Position
01760   gp_Trsf aTrsf = GetPositionTrsf(theL1, theL2, theP1, theP2, theP3);
01761   BRepBuilderAPI_Transform aTransformation(Te, aTrsf, Standard_False);
01762   TopoDS_Shape aTrsf_Shape = aTransformation.Shape();
01763   aFunction->SetValue(aTrsf_Shape);
01764   Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
01765   aSeq->Append(aShape);
01766   if (theHexMesh) {
01767     /*
01768      * Get the groups: BEGIN
01769      */
01770     try {
01771       if (!MakeGroups(aShape, TSHAPE_CHAMFER, theR1, theW1, theL1, theR2, theW2, theL2, aSeq, aTrsf))
01772         return NULL;
01773     }
01774     catch (Standard_Failure) {
01775       Handle(Standard_Failure) aFail = Standard_Failure::Caught();
01776       SetErrorCode(aFail->GetMessageString());
01777       return NULL;
01778     }
01779 
01780     TCollection_AsciiString aListRes, anEntry;
01781     // Iterate over the sequence aSeq
01782     Standard_Integer aNbGroups = aSeq->Length();
01783     Standard_Integer i = 2;
01784     for (; i <= aNbGroups; i++) {
01785       Handle(Standard_Transient) anItem = aSeq->Value(i);
01786       if (anItem.IsNull()) continue;
01787       Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
01788       if (aGroup.IsNull()) continue;
01789       //Make a Python command
01790       TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
01791       aListRes += anEntry + ", ";
01792     }
01793 
01794     aListRes.Trunc(aListRes.Length() - 2);
01795 
01796     //Make a Python command
01797     GEOM::TPythonDump(aFunction)
01798       << "[" << aShape << ", " << aListRes.ToCString()
01799       << "] = geompy.MakePipeTShapeChamfer(" << theR1 << ", " << theW1 << ", " << theL1 << ", " << theR2
01800       << ", " << theW2 << ", " << theL2 << ", " << theH << ", " << theW << ", " << theHexMesh << ", "
01801       << theP1 << ", " << theP2 << ", " << theP3 << ")";
01802   }
01803   /*
01804    * Get the groups: END
01805    */
01806   else {
01807     //Make a Python command
01808     GEOM::TPythonDump(aFunction)
01809       << "[" << aShape << "] = geompy.MakePipeTShapeChamfer(" << theR1 << ", " << theW1
01810       << ", " << theL1 << ", " << theR2 << ", " << theW2 << ", " << theL2 << ", " << theH << ", " << theW
01811       << ", " << theHexMesh << ", " << theP1 << ", " << theP2 << ", " << theP3 << ")";
01812   }
01813 
01814   SetErrorCode(OK);
01815 
01816   return aSeq;
01817 }
01818 
01819 //=============================================================================
01836 //=============================================================================
01837 Handle(TColStd_HSequenceOfTransient)
01838 GEOMImpl_IAdvancedOperations::MakePipeTShapeFillet(double theR1, double theW1, double theL1,
01839                                                    double theR2, double theW2, double theL2,
01840                                                    double theRF, bool theHexMesh)
01841 {
01842   SetErrorCode(KO);
01843   //Add a new object
01844   Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
01845   //Add a new shape function with parameters
01846   Handle(GEOM_Function) aFunction = aShape->AddFunction(GEOMImpl_PipeTShapeDriver::GetID(), TSHAPE_FILLET);
01847   if (aFunction.IsNull()) return NULL;
01848 
01849   //Check if the function is set correctly
01850   if (aFunction->GetDriverGUID() != GEOMImpl_PipeTShapeDriver::GetID()) return NULL;
01851 
01852   GEOMImpl_IPipeTShape aData(aFunction);
01853 
01854   aData.SetR1(theR1);
01855   aData.SetW1(theW1);
01856   aData.SetL1(theL1);
01857   aData.SetR2(theR2);
01858   aData.SetW2(theW2);
01859   aData.SetL2(theL2);
01860   aData.SetRF(theRF);
01861   aData.SetHexMesh(theHexMesh);
01862 
01863   //Compute the resulting value
01864   try {
01865 #if OCC_VERSION_LARGE > 0x06010000
01866     OCC_CATCH_SIGNALS;
01867 #endif
01868     if (!GetSolver()->ComputeFunction(aFunction)) {
01869       SetErrorCode("TShape driver failed");
01870       return NULL;
01871     }
01872   } catch (Standard_Failure) {
01873     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
01874     SetErrorCode(aFail->GetMessageString());
01875     return NULL;
01876   }
01877 
01878   // BEGIN of fillet
01879   TopoDS_Shape aShapeShape = aShape->GetValue();
01880   TopTools_IndexedMapOfShape anEdgesIndices;
01881   TopExp::MapShapes(aShapeShape, anEdgesIndices);
01882   // Common edges on external cylinders
01883   Handle(GEOM_Object) box_e;
01884   if (theHexMesh) {
01885     box_e = my3DPrimOperations->MakeBoxDXDYDZ(theR2+theW2, theR2+theW2, theR1+theW1);
01886   }
01887   else {
01888     box_e = my3DPrimOperations->MakeBoxDXDYDZ(2*(theR2+theW2), 2*(theR2+theW2), theR1+theW1);
01889   }
01890   box_e->GetLastFunction()->SetDescription("");
01891   box_e = myTransformOperations->TranslateDXDYDZ(box_e, -(theR2+theW2), -(theR2+theW2), 0);
01892   box_e->GetLastFunction()->SetDescription("");
01893 
01894   Handle(TColStd_HSequenceOfInteger) edges_e =
01895     myShapesOperations->GetShapesOnBoxIDs(box_e, aShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
01896   box_e->GetLastFunction()->SetDescription("");
01897 
01898   if (edges_e.IsNull() || edges_e->Length() == 0) {
01899     SetErrorCode("External edges not found");
01900     return NULL;
01901   }
01902   int nbEdgesInFillet = 0;
01903   std::list<int> theEdges;
01904   for (int i=1; i<=edges_e->Length();i++) {
01905     int edgeID = edges_e->Value(i);
01906     TopoDS_Shape theEdge = anEdgesIndices.FindKey(edgeID);
01907     TopExp_Explorer Ex(theEdge,TopAbs_VERTEX);
01908     while (Ex.More()) {
01909       gp_Pnt aPt = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
01910       if (Abs(aPt.Z() - (theR1+theW1)) <= Precision::Confusion()) {
01911         nbEdgesInFillet ++;
01912         theEdges.push_back(edgeID);
01913       }
01914       Ex.Next();
01915     }
01916     if (theHexMesh && nbEdgesInFillet == 1)
01917       break;
01918   }
01919 
01920   Handle(GEOM_Object) aFillet;
01921   try {
01922     aFillet = myLocalOperations->MakeFilletEdges(aShape, theRF, theEdges);
01923   }
01924   catch (Standard_Failure) {
01925     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
01926     SetErrorCode(aFail->GetMessageString());
01927     return NULL;
01928   }
01929   if (aFillet.IsNull()) {
01930     //SetErrorCode("Fillet can not be computed on the given shape with the given parameters");
01931     SetErrorCode(myLocalOperations->GetErrorCode());
01932     return NULL;
01933   }
01934   aFillet->GetLastFunction()->SetDescription("");
01935 
01936   TopoDS_Shape aFilletShape = aFillet->GetValue();
01937   aFunction->SetValue(aFilletShape);
01938   // END of fillet
01939 
01940 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - BEGIN (1)
01941 // the following block, when enabled, leads to partitioning problems
01942 #if 0
01943 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - END (1)
01944   // BEGIN: Limit tolerances (debug)
01945   Handle(GEOM_Object) aCorr1 = myHealingOperations->LimitTolerance(aShape, 1e-07);
01946   TopoDS_Shape aCorr1Shape = aCorr1->GetValue();
01947   aShape->GetLastFunction()->SetValue(aCorr1Shape);
01948   aCorr1->GetLastFunction()->SetDescription("");
01949   // END: Limit tolerances (debug)
01950 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - BEGIN (2)
01951 #endif
01952 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - END (2)
01953 
01954   if (theHexMesh) {
01955     if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2, 0, 0, theRF, false))
01956       return NULL;
01957     if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
01958       return NULL;
01959   }
01960 
01961   Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
01962   aSeq->Append(aShape);
01963   if (theHexMesh) {
01964     /*
01965      * Get the groups: BEGIN
01966      */
01967     try {
01968       if (!MakeGroups(aShape, TSHAPE_FILLET, theR1, theW1, theL1, theR2, theW2, theL2, aSeq, gp_Trsf()))
01969         return NULL;
01970     }
01971     catch (Standard_Failure) {
01972       Handle(Standard_Failure) aFail = Standard_Failure::Caught();
01973       SetErrorCode(aFail->GetMessageString());
01974       return NULL;
01975     }
01976 
01977     TCollection_AsciiString aListRes, anEntry;
01978     // Iterate over the sequence aSeq
01979     Standard_Integer aNbGroups = aSeq->Length();
01980     Standard_Integer i = 2;
01981     for (; i <= aNbGroups; i++) {
01982       Handle(Standard_Transient) anItem = aSeq->Value(i);
01983       if (anItem.IsNull()) continue;
01984       Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
01985       if (aGroup.IsNull()) continue;
01986       //Make a Python command
01987       TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
01988       aListRes += anEntry + ", ";
01989     }
01990 
01991     aListRes.Trunc(aListRes.Length() - 2);
01992 
01993     //Make a Python command
01994     GEOM::TPythonDump(aFunction)
01995       << "[" << aShape << ", " << aListRes.ToCString()
01996       << "] = geompy.MakePipeTShapeFillet(" << theR1 << ", " << theW1 << ", " << theL1 << ", " << theR2
01997       << ", " << theW2 << ", " << theL2 << ", " << theRF << ", " << theHexMesh << ")";
01998   }
01999   /*
02000    * Get the groups: END
02001    */
02002   else {
02003     //Make a Python command
02004     GEOM::TPythonDump(aFunction)
02005       << "[" << aShape << "] = geompy.MakePipeTShapeFillet(" << theR1 << ", " << theW1
02006       << ", " << theL1 << ", " << theR2 << ", " << theW2 << ", " << theL2 << ", " << theRF << ", "
02007       << theHexMesh << ")";
02008   }
02009 
02010   SetErrorCode(OK);
02011 
02012   return aSeq;
02013 }
02014 
02015 //=============================================================================
02036 //=============================================================================
02037 Handle(TColStd_HSequenceOfTransient)
02038 GEOMImpl_IAdvancedOperations::MakePipeTShapeFilletWithPosition(double theR1, double theW1, double theL1,
02039                                                                double theR2, double theW2, double theL2,
02040                                                                double theRF, bool theHexMesh,
02041                                                                Handle(GEOM_Object) theP1,
02042                                                                Handle(GEOM_Object) theP2,
02043                                                                Handle(GEOM_Object) theP3)
02044 {
02045   SetErrorCode(KO);
02046   //Add a new object
02047   Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
02048   //Add a new shape function with parameters
02049   Handle(GEOM_Function) aFunction = aShape->AddFunction(GEOMImpl_PipeTShapeDriver::GetID(), TSHAPE_FILLET);
02050   if (aFunction.IsNull()) return NULL;
02051 
02052   //Check if the function is set correctly
02053   if (aFunction->GetDriverGUID() != GEOMImpl_PipeTShapeDriver::GetID()) return NULL;
02054 
02055   // Check new position
02056   if (!CheckCompatiblePosition(theL1, theL2, theP1, theP2, theP3, 0.01)) {
02057     return NULL;
02058   }
02059 
02060   GEOMImpl_IPipeTShape aData(aFunction);
02061 
02062   aData.SetR1(theR1);
02063   aData.SetW1(theW1);
02064   aData.SetL1(theL1);
02065   aData.SetR2(theR2);
02066   aData.SetW2(theW2);
02067   aData.SetL2(theL2);
02068   aData.SetRF(theRF);
02069   aData.SetHexMesh(theHexMesh);
02070 
02071   //Compute the resulting value
02072   try {
02073 #if OCC_VERSION_LARGE > 0x06010000
02074     OCC_CATCH_SIGNALS;
02075 #endif
02076     if (!GetSolver()->ComputeFunction(aFunction)) {
02077       SetErrorCode("TShape driver failed");
02078       return NULL;
02079     }
02080   } catch (Standard_Failure) {
02081     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
02082     SetErrorCode(aFail->GetMessageString());
02083     return NULL;
02084   }
02085 
02086   // BEGIN of fillet
02087   TopoDS_Shape aShapeShape = aShape->GetValue();
02088   TopTools_IndexedMapOfShape anEdgesIndices;
02089   TopExp::MapShapes(aShapeShape, anEdgesIndices);
02090   // Common edges on external cylinders
02091   Handle(GEOM_Object) box_e;
02092   if (theHexMesh) {
02093     box_e = my3DPrimOperations->MakeBoxDXDYDZ(theR2+theW2, theR2+theW2, theR1+theW1);
02094   }
02095   else {
02096     box_e = my3DPrimOperations->MakeBoxDXDYDZ(2*(theR2+theW2), 2*(theR2+theW2), theR1+theW1);
02097   }
02098   box_e->GetLastFunction()->SetDescription("");
02099   box_e = myTransformOperations->TranslateDXDYDZ(box_e, -(theR2+theW2), -(theR2+theW2), 0);
02100   box_e->GetLastFunction()->SetDescription("");
02101 
02102   Handle(TColStd_HSequenceOfInteger) edges_e =
02103     myShapesOperations->GetShapesOnBoxIDs(box_e, aShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
02104   box_e->GetLastFunction()->SetDescription("");
02105 
02106   if (edges_e.IsNull() || edges_e->Length() == 0) {
02107     SetErrorCode("External edges not found");
02108     return NULL;
02109   }
02110   int nbEdgesInFillet = 0;
02111   std::list<int> theEdges;
02112   for (int i=1; i<=edges_e->Length();i++) {
02113     int edgeID = edges_e->Value(i);
02114     TopoDS_Shape theEdge = anEdgesIndices.FindKey(edgeID);
02115     TopExp_Explorer Ex(theEdge,TopAbs_VERTEX);
02116     while (Ex.More()) {
02117       gp_Pnt aPt = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
02118       if (Abs(aPt.Z() - (theR1+theW1)) <= Precision::Confusion()) {
02119         nbEdgesInFillet ++;
02120         theEdges.push_back(edgeID);
02121       }
02122       Ex.Next();
02123     }
02124     if (theHexMesh && nbEdgesInFillet == 1)
02125       break;
02126   }
02127 
02128   Handle(GEOM_Object) aFillet;
02129   try {
02130     aFillet = myLocalOperations->MakeFilletEdges(aShape, theRF, theEdges);
02131   }
02132   catch (Standard_Failure) {
02133     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
02134     SetErrorCode(aFail->GetMessageString());
02135     return NULL;
02136   }
02137   if (aFillet.IsNull()) {
02138     SetErrorCode("Fillet can not be computed on the given shape with the given parameters");
02139     return NULL;
02140   }
02141   aFillet->GetLastFunction()->SetDescription("");
02142 
02143   TopoDS_Shape aFilletShape = aFillet->GetValue();
02144   aFunction->SetValue(aFilletShape);
02145   // END of fillet
02146 
02147 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - BEGIN (3)
02148 // the following block, when enabled, leads to partitioning problems
02149 #if 0
02150 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - END (3)
02151   // BEGIN: Limit tolerances (debug)
02152   Handle(GEOM_Object) aCorr1 = myHealingOperations->LimitTolerance(aShape, 1e-07);
02153   TopoDS_Shape aCorr1Shape = aCorr1->GetValue();
02154   aShape->GetLastFunction()->SetValue(aCorr1Shape);
02155   aCorr1->GetLastFunction()->SetDescription("");
02156   // END: Limit tolerances (debug)
02157 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - BEGIN (4)
02158 #endif
02159 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - END (4)
02160 
02161   if (theHexMesh) {
02162     if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2, 0, 0, theRF, false))
02163       return NULL;
02164     if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
02165       return NULL;
02166   }
02167 
02168   TopoDS_Shape Te = aShape->GetValue();
02169 
02170   // Set Position
02171   gp_Trsf aTrsf = GetPositionTrsf(theL1, theL2, theP1, theP2, theP3);
02172   BRepBuilderAPI_Transform aTransformation(Te, aTrsf, Standard_False);
02173   TopoDS_Shape aTrsf_Shape = aTransformation.Shape();
02174   aFunction->SetValue(aTrsf_Shape);
02175   Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
02176   aSeq->Append(aShape);
02177   if (theHexMesh) {
02178     /*
02179      * Get the groups: BEGIN
02180      */
02181     try {
02182       if (!MakeGroups(aShape, TSHAPE_FILLET, theR1, theW1, theL1, theR2, theW2, theL2, aSeq, aTrsf))
02183         return NULL;
02184     }
02185     catch (Standard_Failure) {
02186       Handle(Standard_Failure) aFail = Standard_Failure::Caught();
02187       SetErrorCode(aFail->GetMessageString());
02188       return NULL;
02189     }
02190 
02191     TCollection_AsciiString aListRes, anEntry;
02192     // Iterate over the sequence aSeq
02193     Standard_Integer aNbGroups = aSeq->Length();
02194     Standard_Integer i = 2;
02195     for (; i <= aNbGroups; i++) {
02196       Handle(Standard_Transient) anItem = aSeq->Value(i);
02197       if (anItem.IsNull()) continue;
02198       Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
02199       if (aGroup.IsNull()) continue;
02200       //Make a Python command
02201       TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
02202       aListRes += anEntry + ", ";
02203     }
02204 
02205     aListRes.Trunc(aListRes.Length() - 2);
02206 
02207     //Make a Python command
02208     GEOM::TPythonDump(aFunction)
02209       << "[" << aShape << ", " << aListRes.ToCString()
02210       << "] = geompy.MakePipeTShapeFillet(" << theR1 << ", " << theW1 << ", " << theL1 << ", " << theR2
02211       << ", " << theW2 << ", " << theL2 << ", " << theRF << ", " << theHexMesh << ", " << theP1 << ", "
02212       << theP2 << ", " << theP3 << ")";
02213   }
02214   /*
02215    * Get the groups: END
02216    */
02217   else {
02218     //Make a Python command
02219     GEOM::TPythonDump(aFunction)
02220       << "[" << aShape << "] = geompy.MakePipeTShapeFillet(" << theR1 << ", " << theW1
02221       << ", " << theL1 << ", " << theR2 << ", " << theW2 << ", " << theL2 << ", " << theRF << ", "
02222       << theHexMesh << ", " << theP1 << ", " << theP2 << ", " << theP3 << ")";
02223   }
02224 
02225   SetErrorCode(OK);
02226 
02227   return aSeq;
02228 }
02229 
02230 /*@@ insert new functions before this line @@ do not remove this line @@ do not remove this line @@*/