Back to index

salome-geom  6.5.0
GEOMImpl_PipeTShapeDriver.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 
00020 #include <Standard_Stream.hxx>
00021 
00022 #include <GEOMImpl_PipeTShapeDriver.hxx>
00023 #include <GEOMImpl_IPipeTShape.hxx>
00024 #include <GEOMImpl_Types.hxx>
00025 
00026 #include <GEOMImpl_Block6Explorer.hxx>
00027 #include <GEOM_Function.hxx>
00028 
00029 #include <GEOMImpl_IShapesOperations.hxx>
00030 #include "GEOMAlgo_FinderShapeOn1.hxx"
00031 #include "GEOMAlgo_FinderShapeOn2.hxx"
00032 #include <GEOMAlgo_ClsfBox.hxx>
00033 
00034 #include <TFunction_Logbook.hxx>
00035 #include <StdFail_NotDone.hxx>
00036 
00037 // Partition includes
00038 #include <GEOMAlgo_Splitter.hxx>
00039 #include <Geom_CylindricalSurface.hxx>
00040 
00041 #include <gp_Pnt.hxx>
00042 #include <gp_Vec.hxx>
00043 #include <gp_Ax2.hxx>
00044 #include <gp_Pln.hxx>
00045 #include <gp_Dir.hxx>
00046 #include <gp_Trsf.hxx>
00047 
00048 #include <BRepPrimAPI_MakeCylinder.hxx>
00049 #include <BRepAlgoAPI_Fuse.hxx>
00050 #include <BRepAlgoAPI_Cut.hxx>
00051 #include <BRepPrimAPI_MakeBox.hxx>
00052 #include <BRepBuilderAPI_MakeEdge.hxx>
00053 #include <BRepBuilderAPI_MakeFace.hxx>
00054 #include <BRepBuilderAPI_MakeWire.hxx>
00055 #include <BRepBuilderAPI_Transform.hxx>
00056 #include <BRepFilletAPI_MakeFillet.hxx>
00057 #include <BRepFilletAPI_MakeChamfer.hxx>
00058 #include <BRep_Builder.hxx>
00059 #include <TopoDS_Compound.hxx>
00060 #include <TopExp.hxx>
00061 #include <TopExp_Explorer.hxx>
00062 #include <BRep_Tool.hxx>
00063 #include <BRepTools.hxx>
00064 #include <TopoDS.hxx>
00065 #include <TopTools_IndexedMapOfShape.hxx>
00066 #include <TopTools_ListIteratorOfListOfShape.hxx>
00067 
00068 #include <vector>
00069 //@@ include required header files here @@//
00070 
00071 //=======================================================================
00072 //function : GetID
00073 //purpose  :
00074 //=======================================================================
00075 const Standard_GUID& GEOMImpl_PipeTShapeDriver::GetID()
00076 {
00077   static Standard_GUID aGUID("1C3A0F3F-729D-4E83-8232-78E74FC5637C");
00078   return aGUID;
00079 }
00080 
00081 //=======================================================================
00082 //function : GEOMImpl_PipeTShapeDriver
00083 //purpose  :
00084 //=======================================================================
00085 GEOMImpl_PipeTShapeDriver::GEOMImpl_PipeTShapeDriver()
00086 {
00087 }
00088 
00089 //=======================================================================
00090 //function : getShapesOnBoxIDs
00099 //=======================================================================
00100 Handle(TColStd_HSequenceOfInteger)
00101 GEOMImpl_PipeTShapeDriver::GetShapesOnBoxIDs(const TopoDS_Shape& aBox,
00102                     const TopoDS_Shape& aShape,
00103                     const Standard_Integer theShapeType,
00104                     GEOMAlgo_State theState) const
00105 {
00106   Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
00107 
00108   // Check presence of triangulation, build if need
00109   if (!GEOMImpl_IShapesOperations::CheckTriangulation(aShape)) {
00110     StdFail_NotDone::Raise("Cannot build triangulation on the shape");
00111     return aSeqOfIDs;
00112   }
00113 
00114   // Call algo
00115   GEOMAlgo_FinderShapeOn2 aFinder;
00116   Standard_Real aTol = 0.0001; // default value
00117 
00118   Handle(GEOMAlgo_ClsfBox) aClsfBox = new GEOMAlgo_ClsfBox;
00119   aClsfBox->SetBox(aBox);
00120 
00121   aFinder.SetShape(aShape);
00122   aFinder.SetTolerance(aTol);
00123   aFinder.SetClsf(aClsfBox);
00124   aFinder.SetShapeType( (TopAbs_ShapeEnum)theShapeType );
00125   aFinder.SetState(theState);
00126   aFinder.Perform();
00127 
00128   // Interprete results
00129   Standard_Integer iErr = aFinder.ErrorStatus();
00130   // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
00131   if (iErr) {
00132     TCollection_AsciiString aMsg (" iErr : ");
00133     aMsg += TCollection_AsciiString(iErr);
00134     StdFail_NotDone::Raise(aMsg.ToCString());
00135     return aSeqOfIDs;
00136   }
00137 
00138 
00139   const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
00140 
00141   if (listSS.Extent() < 1) {
00142     StdFail_NotDone::Raise(NOT_FOUND_ANY); // NPAL18017
00143     return aSeqOfIDs;
00144   }
00145 
00146   // Fill sequence of object IDs
00147   aSeqOfIDs = new TColStd_HSequenceOfInteger;
00148 
00149   TopTools_IndexedMapOfShape anIndices;
00150   TopExp::MapShapes(aShape, anIndices);
00151 
00152   TopTools_ListIteratorOfListOfShape itSub (listSS);
00153   for (int index = 1; itSub.More(); itSub.Next(), ++index) {
00154     int id = anIndices.FindIndex(itSub.Value());
00155 //    std::cerr << "Shape with ID " << id << " found" << std::endl;
00156     aSeqOfIDs->Append(id);
00157   }
00158 
00159   return aSeqOfIDs;
00160 }
00161 
00162 //=======================================================================
00163 //function : GetShapesOnSurfaceIDs
00172 //=======================================================================
00173 Handle(TColStd_HSequenceOfInteger)
00174   GEOMImpl_PipeTShapeDriver::GetShapesOnSurfaceIDs(const Handle(Geom_Surface)& theSurface,
00175                                                     const TopoDS_Shape&         theShape,
00176                                                     TopAbs_ShapeEnum            theShapeType,
00177                                                     GEOMAlgo_State              theState) const
00178 {
00179   Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
00180 
00181   // Check presence of triangulation, build if need
00182   if (!GEOMImpl_IShapesOperations::CheckTriangulation(theShape)) {
00183     StdFail_NotDone::Raise("Cannot build triangulation on the shape");
00184     return aSeqOfIDs;
00185   }
00186 
00187   // Call algo
00188   GEOMAlgo_FinderShapeOn1 aFinder;
00189   Standard_Real aTol = 1e-6;
00190 
00191   aFinder.SetShape(theShape);
00192   aFinder.SetTolerance(aTol);
00193   aFinder.SetSurface(theSurface);
00194   aFinder.SetShapeType(theShapeType);
00195   aFinder.SetState(theState);
00196 
00197   // Sets the minimal number of inner points for the faces that do not have own
00198   // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
00199   // Default value=3
00200   aFinder.SetNbPntsMin(3);
00201   // Sets the maximal number of inner points for edges or faces.
00202   // It is usefull for the cases when this number is very big (e.g =2000) to improve
00203   // the performance. If this value =0, all inner points will be taken into account.
00204   // Default value=0
00205   aFinder.SetNbPntsMax(0);
00206 
00207   aFinder.Perform();
00208 
00209   // Interprete results
00210   Standard_Integer iErr = aFinder.ErrorStatus();
00211   // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
00212   if (iErr) {
00213 //    MESSAGE(" iErr : " << iErr);
00214     TCollection_AsciiString aMsg (" iErr : ");
00215     aMsg += TCollection_AsciiString(iErr);
00216     StdFail_NotDone::Raise(aMsg.ToCString());
00217     return aSeqOfIDs;
00218   }
00219 //  Standard_Integer iWrn = aFinder.WarningStatus();
00220   // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
00221 //  if (iWrn) {
00222 //    MESSAGE(" *** iWrn : " << iWrn);
00223 //  }
00224 
00225   const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
00226 
00227   if (listSS.Extent() < 1) {
00228     //StdFail_NotDone::Raise("Not a single sub-shape of the requested type found on the given surface");
00229     StdFail_NotDone::Raise(NOT_FOUND_ANY); // NPAL18017
00230     return aSeqOfIDs;
00231   }
00232 
00233   // Fill sequence of object IDs
00234   aSeqOfIDs = new TColStd_HSequenceOfInteger;
00235 
00236   TopTools_IndexedMapOfShape anIndices;
00237   TopExp::MapShapes(theShape, anIndices);
00238 
00239   TopTools_ListIteratorOfListOfShape itSub (listSS);
00240   for (int index = 1; itSub.More(); itSub.Next(), ++index) {
00241     int id = anIndices.FindIndex(itSub.Value());
00242     aSeqOfIDs->Append(id);
00243   }
00244 
00245   return aSeqOfIDs;
00246 }
00247 
00248 //=======================================================================
00249 //function : GetCommonShapesOnCylinders
00250 //purpose  : return the common shapes between 2 cylindrical surfaces
00251 //           along OX and OZ
00252 //=======================================================================
00253 void GEOMImpl_PipeTShapeDriver::GetCommonShapesOnCylinders(const TopoDS_Shape& theShape,
00254                                                  TopAbs_ShapeEnum theShapeType,
00255                                                  double r1, 
00256                                                  double r2,
00257                                                  Handle(TopTools_HSequenceOfShape)& commonShapes) const
00258 {
00259   gp_Pnt aP0 (0, 0, 0);
00260   gp_Vec aVX = gp::DX(), aVZ = gp::DZ();
00261   gp_Ax3 anAxis1 (aP0, aVX), anAxis2 (aP0, aVZ);
00262 
00263   TopTools_IndexedMapOfShape aMapOfShapes;
00264   aMapOfShapes.Clear();
00265   TopExp::MapShapes(theShape, aMapOfShapes);
00266   
00267   commonShapes->Clear();
00268 
00269   int myID;
00270   bool found = false;
00271 
00272   // Create a cylinder surface
00273   Handle(Geom_Surface) aC1Ext = new Geom_CylindricalSurface(anAxis1, r1);
00274   if ( aC1Ext.IsNull() )
00275     StdFail_NotDone::Raise("Couldn't build main cylindrical surface");
00276   // Find object IDs
00277   Handle(TColStd_HSequenceOfInteger) aSeqExt1 = GetShapesOnSurfaceIDs( aC1Ext, theShape, theShapeType, GEOMAlgo_ST_ON );
00278   // Create a cylinder surface
00279   Handle(Geom_Surface) aC2Ext = new Geom_CylindricalSurface(anAxis2, r2);
00280   if ( aC2Ext.IsNull() )
00281     StdFail_NotDone::Raise("Couldn't build incident cylindrical surface");
00282   // Find object IDs
00283   Handle(TColStd_HSequenceOfInteger) aSeqExt2 = GetShapesOnSurfaceIDs( aC2Ext, theShape, theShapeType, GEOMAlgo_ST_ON );
00284   // # Recherche (dans le quart de Te) de l'arete d'intersection des 2 cylindres
00285   // # Search in theShape for common shape of type theShapeType on the intersection of 2 pipes
00286   found = false;
00287   for (int i=1; i<=aSeqExt2->Length();i++) {
00288 //    std::cerr << "aSeqExt2->Value(i): " << aSeqExt2->Value(i) << std::endl;
00289     for (int j=1; j<=aSeqExt1->Length();j++) {
00290 //      std::cerr << "aSeqExt1->Value(j): " << aSeqExt1->Value(j) << std::endl;
00291       if (aSeqExt1->Value(j) == aSeqExt2->Value(i)) {
00292        myID = aSeqExt1->Value(j);
00293        commonShapes->Append(aMapOfShapes.FindKey(myID));
00294        found = true;
00295       }
00296     }
00297   }
00298   if (!found)
00299     StdFail_NotDone::Raise("Common shapes couldn't be found");
00300 }
00301 
00302 //=======================================================================
00303 //function : MakePipeTShape
00304 //purpose  :
00305 //=======================================================================
00306 TopoDS_Shape GEOMImpl_PipeTShapeDriver::MakePipeTShape(const double r1, const double w1, const double l1,
00307                                                  const double r2, const double w2, const double l2) const
00308 {
00309   double r1Ext = r1 + w1;
00310   double r2Ext = r2 + w2;
00311 
00312   gp_Pnt aP0 (0, 0, 0);
00313   gp_Pnt aP1 (-l1, 0, 0);
00314   gp_Vec aVX = gp::DX(), aVY = gp::DY(), aVZ = gp::DZ();
00315   gp_Ax2 anAxes1 (aP1, aVX);
00316   gp_Ax2 anAxes2 (aP0, aVZ);
00317 
00318   // Build the initial pipes
00319   BRepPrimAPI_MakeCylinder C1Int (anAxes1, r1, Abs(2 * l1));
00320   BRepPrimAPI_MakeCylinder C1Ext (anAxes1, r1Ext, Abs(2 * l1));
00321   BRepPrimAPI_MakeCylinder C2Int (anAxes2, r2, Abs(l2));
00322   BRepPrimAPI_MakeCylinder C2Ext (anAxes2, r2Ext, Abs(l2));
00323   C1Int.Build();
00324   C1Ext.Build();
00325   C2Int.Build();
00326   C2Ext.Build();
00327   if (!C1Int.IsDone() || !C1Ext.IsDone() || !C2Int.IsDone() || !C2Ext.IsDone()) {
00328     StdFail_NotDone::Raise("Couldn't build cylinders");
00329   }
00330 
00331   // Fuse the 2 pipes
00332   BRepAlgoAPI_Fuse fuse1 (C1Ext.Shape(), C2Ext.Shape());
00333   if (!fuse1.IsDone()) {
00334     StdFail_NotDone::Raise("Couldn't fuse cylinders");
00335   }
00336 
00337   // Remove small radius main pipe
00338   BRepAlgoAPI_Cut cut1 (fuse1.Shape(), C1Int.Shape());
00339   if (!cut1.IsDone()) {
00340     StdFail_NotDone::Raise("Coudn't cut cylinders");
00341   }
00342 
00343   // Remove small radius incident pipe => Te
00344   BRepAlgoAPI_Cut Te (cut1.Shape(), C2Int.Shape());
00345   if (!Te.IsDone()) {
00346     StdFail_NotDone::Raise("Coudn't cut cylinders");
00347   }
00348 
00349   return Te.Shape();
00350 }
00351 
00352 //=======================================================================
00353 //function : MakeQuarterPipeTShape
00354 //purpose  :
00355 //=======================================================================
00356 TopoDS_Shape GEOMImpl_PipeTShapeDriver::MakeQuarterPipeTShape(const double r1, const double w1, const double l1,
00357                                                 const double r2, const double w2, const double l2) const
00358 {
00359   double r1Ext = r1 + w1;
00360   TopoDS_Shape Te = MakePipeTShape(r1, w1, l1, r2, w2, l2);
00361   if (Te.IsNull())
00362     StdFail_NotDone::Raise("Couldn't build Pipe TShape");
00363 
00364   // Get a quarter of shape => Te2
00365   BRepPrimAPI_MakeBox box1 (gp_Pnt(0,-2*r1Ext,-2*r1Ext),gp_Pnt(Abs(2 * l1), 2*r1Ext, Abs(2*l2)));
00366   BRepPrimAPI_MakeBox box2 (gp_Pnt(0,2*r1Ext,-2*r1Ext),gp_Pnt(-Abs(2 * l1), 0, Abs(2*l2)));
00367   box1.Build();
00368   box2.Build();
00369   if (!box1.IsDone() || !box2.IsDone()) {
00370     StdFail_NotDone::Raise("Couldn't build boxes");
00371   }
00372   BRepAlgoAPI_Cut cut3 (Te, box1.Shape());
00373   if (!cut3.IsDone()) {
00374     StdFail_NotDone::Raise("Couldn't cut Pipe Tshape with box");
00375   }
00376   BRepAlgoAPI_Cut Te4 (cut3.Shape(), box2.Shape());
00377   if (!Te4.IsDone()) {
00378     StdFail_NotDone::Raise("Couldn't cut Pipe Tshape with box");
00379   }
00380 
00381   return Te4.Shape();
00382 }
00383 
00384 //=======================================================================
00385 //function : Execute
00386 //purpose  :
00387 //=======================================================================
00388 Standard_Integer GEOMImpl_PipeTShapeDriver::Execute(TFunction_Logbook& log) const
00389 {
00390   if (Label().IsNull()) return 0;
00391   Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());
00392 
00393   GEOMImpl_IPipeTShape aData (aFunction);
00394   Standard_Integer aType = aFunction->GetType();
00395 
00396   TopoDS_Shape aShape, Te4, Te4Part;
00397 //   TopoDS_Edge arete_intersect_int;
00398 //   Handle(TopTools_HSequenceOfShape) edges_e = new TopTools_HSequenceOfShape;
00399   Handle(TColStd_HSequenceOfInteger) edges_e;
00400 //   Handle(TopTools_HSequenceOfShape) edges_i = new TopTools_HSequenceOfShape;
00401 //   gp_Pnt aP0 (0, 0, 0);
00402 //   gp_Vec aVX = gp::DX(), aVY = gp::DY(), aVZ = gp::DZ();
00403   bool hexMesh = (bool) aData.GetHexMesh();
00404 
00405   // Useful values
00406 //   double aSize = 2*(aData.GetL1() + aData.GetL2());
00407   double epsilon = Precision::Approximation();
00408   double aR1Ext = aData.GetR1() + aData.GetW1();
00409   double aR2Ext = aData.GetR2() + aData.GetW2();
00410   
00411   if (aData.GetR2() > aData.GetR1() + epsilon) {
00412     StdFail_NotDone::Raise("TShape cannot be computed if R2 > R1");
00413   }
00414 
00415   if (aR2Ext > aR1Ext + epsilon) {
00416     StdFail_NotDone::Raise("TShape cannot be computed if R2+W2 > R1+W1");
00417   }
00418   
00419   // external radius are equal
00420   if (fabs(aR2Ext - aR1Ext) < epsilon) {
00421     if (aType == TSHAPE_CHAMFER)
00422       StdFail_NotDone::Raise("TShape with chamfer cannot be computed if R2+W2 = R1+W1");
00423     if (aType == TSHAPE_FILLET)
00424       StdFail_NotDone::Raise("TShape with fillet cannot be computed if R2+W2 = R1+W1");
00425     // internal radius are different => not possible
00426     if (fabs(aData.GetR2() - aData.GetR1()) > epsilon) {
00427       StdFail_NotDone::Raise("TShape cannot be computed if R2+W2 = R1+W1 and R2 != R1");
00428     }
00429   }
00430 
00431 
00432   if (aR1Ext >= aData.GetL2() + epsilon) {
00433     StdFail_NotDone::Raise("TShape cannot be computed if R1+W1 >= L2");
00434   }
00435   if (aR2Ext >=  aData.GetL1() + epsilon) {
00436     StdFail_NotDone::Raise("TShape cannot be computed if R2+W2 >= L1");
00437   }
00438 
00439   if (aType == TSHAPE_CHAMFER) {
00440     if (aData.GetH() >= (aData.GetL2() - aR1Ext + epsilon)) {
00441       StdFail_NotDone::Raise("TShape cannot be computed: height of chamfer is too high");
00442     }
00443 
00444     if (aData.GetW() >= (aData.GetL1() - aR2Ext + epsilon))
00445       StdFail_NotDone::Raise("TShape cannot be computed: width of chamfer is too high");
00446   }
00447 
00448   if (aType == TSHAPE_FILLET) {
00449     if (aData.GetRF() >= (aData.GetL2() - aR1Ext + epsilon) || 
00450       aData.GetRF() >= (aData.GetL1() - aR2Ext + epsilon))
00451       StdFail_NotDone::Raise("TShape cannot be computed: radius of fillet is too high");
00452   }
00453 
00454   if (hexMesh) {
00455     // Create a quarter of a basic T-Shape pipe
00456 //    std::cerr << "Create a quarter of a basic T-Shape pipe" << std::endl;
00457     Te4 = MakeQuarterPipeTShape(aData.GetR1(), aData.GetW1(), aData.GetL1(),
00458       aData.GetR2(), aData.GetW2(), aData.GetL2());
00459   }
00460   else {
00461     // No need to cut pipe t-shape
00462 //    std::cerr << "Create a basic T-Shape pipe" << std::endl;
00463     Te4 = MakePipeTShape(aData.GetR1(), aData.GetW1(), aData.GetL1(),
00464       aData.GetR2(), aData.GetW2(), aData.GetL2());
00465   }
00466   aShape = Te4;
00467 /*
00468   if (aType == TSHAPE_BASIC) {
00469       aShape = Te4;
00470 //       aShape = MakeQuarterPipeTShape(aData.GetR1(), aData.GetW1(), aData.GetL1(),
00471 //       aData.GetR2(), aData.GetW2(), aData.GetL2());
00472   }
00473   else if (aType == TSHAPE_CHAMFER) {
00474     // TShape with chamfer
00475 //     BRep_Builder BB;
00476 //     TopoDS_Compound CC;
00477 //     BB.MakeCompound(CC);
00478     // Create chamfer on the edges edges_e
00479     BRepFilletAPI_MakeChamfer chamfer (Te4);
00480     TopTools_IndexedMapOfShape anEdgesIndices;
00481     TopExp::MapShapes(Te4, anEdgesIndices);
00482 
00483     TopoDS_Shape theBox;
00484     if (hexMesh) {
00485       BRepPrimAPI_MakeBox aBox (gp_Pnt(0,0,0),gp_Pnt(-aR2Ext, -aR2Ext, aR1Ext));
00486       aBox.Build();
00487       if (!aBox.IsDone()) {
00488         StdFail_NotDone::Raise("Couldn't build box");
00489       }
00490       theBox = aBox.Shape();
00491     }
00492     else {
00493       BRepPrimAPI_MakeBox aBox (gp_Pnt(aR2Ext,aR2Ext,0),gp_Pnt(-aR2Ext, -aR2Ext, aR1Ext));
00494       aBox.Build();
00495       if (!aBox.IsDone()) {
00496         StdFail_NotDone::Raise("Couldn't build box");
00497       }
00498       theBox = aBox.Shape();
00499     }
00500     Handle(TColStd_HSequenceOfInteger) edges_e = new TColStd_HSequenceOfInteger;
00501     edges_e = GetShapesOnBoxIDs(theBox, Te4, TopAbs_EDGE, GEOMAlgo_ST_IN);
00502     if (edges_e.IsNull() || edges_e->Length() == 0) {
00503       StdFail_NotDone::Raise("Common edges not found");
00504     }
00505   
00506 
00507     TopTools_IndexedDataMapOfShapeListOfShape M;
00508     GEOMImpl_Block6Explorer::MapShapesAndAncestors(Te4, TopAbs_EDGE, TopAbs_FACE, M);
00509 //     std::cerr << "Number of IDs: " << edges_e->Length() << std::endl;
00510     int nbEdgesInChamfer = 0;
00511     for (int i=1;i<=edges_e->Length();i++) {
00512 //       std::cerr << "Get Edge with ID #" << i << std::endl;
00513       int theId = edges_e->Value(i);
00514 //       std::cerr << "ID #" << i << "= " << theId << std::endl;
00515 //       std::cerr << "Search for edge in shape" << std::endl;
00516       TopoDS_Edge theEdge = TopoDS::Edge(anEdgesIndices.FindKey(theId));
00517 //       std::cerr << "Found" << std::endl;
00518 //       std::cerr << "Keep only edges with a vertex on (x, x, re1)" << std::endl;
00519       TopExp_Explorer ExVertices;
00520       for (ExVertices.Init(theEdge,TopAbs_VERTEX); ExVertices.More(); ExVertices.Next()) {
00521         gp_Pnt aPt = BRep_Tool::Pnt(TopoDS::Vertex(ExVertices.Current()));
00522         if (aPt.Z() - aR1Ext <= epsilon) {
00523 //           std::cerr << "aPt.Z() = aR1Ext => keep this edge" << std::endl;
00524           nbEdgesInChamfer ++;
00525           const TopTools_ListOfShape& aFL = M.FindFromKey(theEdge);
00526           TopoDS_Face F = TopoDS::Face( aFL.First() );
00527           if (hexMesh)
00528             chamfer.Add(aData.GetH(), aData.GetW(), theEdge, F);
00529           else
00530             chamfer.Add(aData.GetW(), aData.GetH(), theEdge, F);
00531           break;
00532         }
00533       }
00534 //       std::cerr << "Test if hexMesh: ";
00535       if (hexMesh && nbEdgesInChamfer == 1) {
00536 //         std::cerr << "Yes => stop after 1 edge" << std::endl;
00537         break;
00538       }
00539 //       std::cerr << "No => continue for other edges" << std::endl;
00540   //  BB.Add(CC, edges_e->Value(i));
00541   //  const TopTools_ListOfShape& aFL = M.FindFromKey(TopoDS::Edge(edges_e->Value(i)));
00542   //  chamfer.Add(aData.GetW(), aData.GetH(), TopoDS::Edge(edges_e->Value(i)), F);
00543     }
00544 //     std::cerr << "Build chamfer with " << nbEdgesInChamfer << " edges" << std::endl;
00545 //     }
00546     chamfer.Build();
00547     if (!chamfer.IsDone()) {
00548       StdFail_NotDone::Raise("Chamfer can not be computed on the given shape with the given parameters");
00549     }
00550     
00551 //     BB.Add(CC, chamfer.Shape());
00552     
00553     
00554 //     aShape = CC;
00555     aShape = chamfer.Shape();
00556   }
00557   else if (aType == TSHAPE_FILLET) {
00558     // TShape with fillet
00559     // Create fillet on the edge arete_intersect_ext
00560     BRepFilletAPI_MakeFillet fill (Te4);
00561     
00562     TopTools_IndexedMapOfShape anIndices;
00563     TopExp::MapShapes(Te4, anIndices);
00564     
00565     TopoDS_Shape theBox;
00566     if (hexMesh) {
00567       BRepPrimAPI_MakeBox aBox (gp_Pnt(0,0,0),gp_Pnt(-aR2Ext, -aR2Ext, aR1Ext));
00568       aBox.Build();
00569       if (!aBox.IsDone()) {
00570         StdFail_NotDone::Raise("Couldn't build box");
00571       }
00572       theBox = aBox.Shape();
00573     }
00574     else {
00575       BRepPrimAPI_MakeBox aBox (gp_Pnt(aR2Ext,aR2Ext,0),gp_Pnt(-aR2Ext, -aR2Ext, aR1Ext));
00576       aBox.Build();
00577       if (!aBox.IsDone()) {
00578         StdFail_NotDone::Raise("Couldn't build box");
00579       }
00580       theBox = aBox.Shape();
00581     }
00582     Handle(TColStd_HSequenceOfInteger) edges_e = new TColStd_HSequenceOfInteger;
00583     edges_e = GetShapesOnBoxIDs(theBox, Te4, TopAbs_EDGE, GEOMAlgo_ST_IN);
00584     if (edges_e.IsNull() || edges_e->Length() == 0) {
00585       StdFail_NotDone::Raise("Common edges not found");
00586     }
00587     
00588 //     fill.Add(TopoDS::Edge(edges_e->Value(1)));
00589 //     if (!hexMesh) {
00590     for (int i=1;i<=edges_e->Length();i++) {
00591       if (hexMesh && (i > 1))
00592         break;
00593       TopoDS_Edge theEdge = TopoDS::Edge(anIndices.FindKey(edges_e->Value(i)));
00594       fill.Add(theEdge);
00595 //             fill.Add(TopoDS::Edge(edges_e->Value(i)));
00596     }
00597 //     }
00598     fill.SetRadius(aData.GetRF(), 1, 1);
00599     fill.Build();
00600     if (!fill.IsDone()) {
00601       StdFail_NotDone::Raise("Fillet can't be computed on the given shape with the given radius");
00602     }
00603 
00604     aShape = fill.Shape();
00605   }
00606   else {
00607     // other construction modes here
00608   }
00609 */
00610   if (aShape.IsNull()) return 0;
00611 
00612   aFunction->SetValue(aShape);
00613 
00614   log.SetTouched(Label());
00615 
00616   return 1;
00617 }
00618 
00619 //=======================================================================
00620 //function :  GEOMImpl_PipeTShapeDriver_Type_
00621 //purpose  :
00622 //=======================================================================
00623 Standard_EXPORT Handle_Standard_Type& GEOMImpl_PipeTShapeDriver_Type_()
00624 {
00625   static Handle_Standard_Type aType1 = STANDARD_TYPE(TFunction_Driver);
00626   if ( aType1.IsNull()) aType1 = STANDARD_TYPE(TFunction_Driver);
00627   static Handle_Standard_Type aType2 = STANDARD_TYPE(MMgt_TShared);
00628   if ( aType2.IsNull()) aType2 = STANDARD_TYPE(MMgt_TShared);
00629   static Handle_Standard_Type aType3 = STANDARD_TYPE(Standard_Transient);
00630   if ( aType3.IsNull()) aType3 = STANDARD_TYPE(Standard_Transient);
00631 
00632   static Handle_Standard_Transient _Ancestors[]= {aType1,aType2,aType3,NULL};
00633   static Handle_Standard_Type _aType = new Standard_Type("GEOMImpl_PipeTShapeDriver",
00634                                                          sizeof(GEOMImpl_PipeTShapeDriver),
00635                                                          1,
00636                                                          (Standard_Address)_Ancestors,
00637                                                          (Standard_Address)NULL);
00638   return _aType;
00639 }
00640 
00641 //=======================================================================
00642 //function : DownCast
00643 //purpose  :
00644 //=======================================================================
00645 const Handle(GEOMImpl_PipeTShapeDriver) Handle(GEOMImpl_PipeTShapeDriver)::DownCast(const Handle(Standard_Transient)& AnObject)
00646 {
00647   Handle(GEOMImpl_PipeTShapeDriver) _anOtherObject;
00648 
00649   if (!AnObject.IsNull()) {
00650      if (AnObject->IsKind(STANDARD_TYPE(GEOMImpl_PipeTShapeDriver))) {
00651        _anOtherObject = Handle(GEOMImpl_PipeTShapeDriver)((Handle(GEOMImpl_PipeTShapeDriver)&)AnObject);
00652      }
00653   }
00654 
00655   return _anOtherObject;
00656 }