]> SALOME platform Git repositories - modules/geom.git/blob - src/GEOMImpl/GEOMImpl_PipeTShapeDriver.cxx
Salome HOME
Update copyright notes (for 2010)
[modules/geom.git] / src / GEOMImpl / GEOMImpl_PipeTShapeDriver.cxx
1 //  Copyright (C) 2007-2010  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 //  This library is free software; you can redistribute it and/or
4 //  modify it under the terms of the GNU Lesser General Public
5 //  License as published by the Free Software Foundation; either
6 //  version 2.1 of the License.
7 //
8 //  This library is distributed in the hope that it will be useful,
9 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
10 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 //  Lesser General Public License for more details.
12 //
13 //  You should have received a copy of the GNU Lesser General Public
14 //  License along with this library; if not, write to the Free Software
15 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 #include <Standard_Stream.hxx>
21
22 #include <GEOMImpl_PipeTShapeDriver.hxx>
23 #include <GEOMImpl_IPipeTShape.hxx>
24 #include <GEOMImpl_Types.hxx>
25
26 #include <GEOMImpl_Block6Explorer.hxx>
27 #include <GEOM_Function.hxx>
28
29 #include <GEOMImpl_IShapesOperations.hxx>
30 #include "GEOMAlgo_FinderShapeOn1.hxx"
31 #include "GEOMAlgo_FinderShapeOn2.hxx"
32 #include <GEOMAlgo_ClsfBox.hxx>
33 #include <GEOMAlgo_Gluer.hxx>
34
35 #include <TFunction_Logbook.hxx>
36 #include <StdFail_NotDone.hxx>
37
38 // Partition includes
39 #include <GEOMAlgo_Splitter.hxx>
40 #include <Geom_CylindricalSurface.hxx>
41
42 #include <gp_Pnt.hxx>
43 #include <gp_Vec.hxx>
44 #include <gp_Ax2.hxx>
45 #include <gp_Pln.hxx>
46 #include <gp_Dir.hxx>
47 #include <gp_Trsf.hxx>
48
49 #include <BRepPrimAPI_MakeCylinder.hxx>
50 #include <BRepAlgoAPI_Fuse.hxx>
51 #include <BRepAlgoAPI_Cut.hxx>
52 #include <BRepPrimAPI_MakeBox.hxx>
53 #include <BRepBuilderAPI_MakeEdge.hxx>
54 #include <BRepBuilderAPI_MakeFace.hxx>
55 #include <BRepBuilderAPI_MakeWire.hxx>
56 #include <BRepBuilderAPI_Transform.hxx>
57 #include <BRepFilletAPI_MakeFillet.hxx>
58 #include <BRepFilletAPI_MakeChamfer.hxx>
59 #include <BRep_Builder.hxx>
60 #include <TopoDS_Compound.hxx>
61 #include <TopExp.hxx>
62 #include <TopExp_Explorer.hxx>
63 #include <BRep_Tool.hxx>
64 #include <BRepTools.hxx>
65 #include <TopoDS.hxx>
66 #include <TopTools_IndexedMapOfShape.hxx>
67 #include <TopTools_ListIteratorOfListOfShape.hxx>
68
69 #include <vector>
70 //@@ include required header files here @@//
71
72 //=======================================================================
73 //function : GetID
74 //purpose  :
75 //=======================================================================
76 const Standard_GUID& GEOMImpl_PipeTShapeDriver::GetID()
77 {
78   static Standard_GUID aGUID("1C3A0F3F-729D-4E83-8232-78E74FC5637C");
79   return aGUID;
80 }
81
82 //=======================================================================
83 //function : GEOMImpl_PipeTShapeDriver
84 //purpose  :
85 //=======================================================================
86 GEOMImpl_PipeTShapeDriver::GEOMImpl_PipeTShapeDriver()
87 {
88 }
89
90 //=======================================================================
91 //function : getShapesOnBoxIDs
92   /*!
93    * \brief Find IDs of subshapes complying with given status about surface
94     * \param theBox - the box to check state of subshapes against
95     * \param theShape - the shape to explore
96     * \param theShapeType - type of subshape of theShape
97     * \param theState - required state
98     * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
99    */
100 //=======================================================================
101 Handle(TColStd_HSequenceOfInteger)
102 GEOMImpl_PipeTShapeDriver::GetShapesOnBoxIDs(const TopoDS_Shape& aBox,
103                     const TopoDS_Shape& aShape,
104                     const Standard_Integer theShapeType,
105                     GEOMAlgo_State theState) const
106 {
107   Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
108
109   // Check presence of triangulation, build if need
110   if (!GEOMImpl_IShapesOperations::CheckTriangulation(aShape)) {
111     StdFail_NotDone::Raise("Cannot build triangulation on the shape");
112     return aSeqOfIDs;
113   }
114
115   // Call algo
116   GEOMAlgo_FinderShapeOn2 aFinder;
117   Standard_Real aTol = 0.0001; // default value
118
119   Handle(GEOMAlgo_ClsfBox) aClsfBox = new GEOMAlgo_ClsfBox;
120   aClsfBox->SetBox(aBox);
121
122   aFinder.SetShape(aShape);
123   aFinder.SetTolerance(aTol);
124   aFinder.SetClsf(aClsfBox);
125   aFinder.SetShapeType( (TopAbs_ShapeEnum)theShapeType );
126   aFinder.SetState(theState);
127   aFinder.Perform();
128
129   // Interprete results
130   Standard_Integer iErr = aFinder.ErrorStatus();
131   // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
132   if (iErr) {
133     TCollection_AsciiString aMsg (" iErr : ");
134     aMsg += TCollection_AsciiString(iErr);
135     StdFail_NotDone::Raise(aMsg.ToCString());
136     return aSeqOfIDs;
137   }
138
139
140   const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
141
142   if (listSS.Extent() < 1) {
143     StdFail_NotDone::Raise(NOT_FOUND_ANY); // NPAL18017
144     return aSeqOfIDs;
145   }
146
147   // Fill sequence of object IDs
148   aSeqOfIDs = new TColStd_HSequenceOfInteger;
149
150   TopTools_IndexedMapOfShape anIndices;
151   TopExp::MapShapes(aShape, anIndices);
152
153   TopTools_ListIteratorOfListOfShape itSub (listSS);
154   for (int index = 1; itSub.More(); itSub.Next(), ++index) {
155     int id = anIndices.FindIndex(itSub.Value());
156     std::cerr << "Shape with ID " << id << " found" << std::endl;
157 //     TopoDS_Shape s = anIndices.FindKey(id);
158     aSeqOfIDs->Append(id);
159 //     aSeqOfIDs->Append(itSub.Value());
160   }
161
162   return aSeqOfIDs;
163 }
164
165 //=======================================================================
166 //function : GetShapesOnSurfaceIDs
167   /*!
168    * \brief Find IDs of subshapes complying with given status about surface
169     * \param theSurface - the surface to check state of subshapes against
170     * \param theShape - the shape to explore
171     * \param theShapeType - type of subshape of theShape
172     * \param theState - required state
173     * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
174    */
175 //=======================================================================
176 Handle(TColStd_HSequenceOfInteger)
177   GEOMImpl_PipeTShapeDriver::GetShapesOnSurfaceIDs(const Handle(Geom_Surface)& theSurface,
178                                                     const TopoDS_Shape&         theShape,
179                                                     TopAbs_ShapeEnum            theShapeType,
180                                                     GEOMAlgo_State              theState) const
181 {
182   Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
183
184   // Check presence of triangulation, build if need
185   if (!GEOMImpl_IShapesOperations::CheckTriangulation(theShape)) {
186     StdFail_NotDone::Raise("Cannot build triangulation on the shape");
187     return aSeqOfIDs;
188   }
189
190   // Call algo
191   GEOMAlgo_FinderShapeOn1 aFinder;
192   Standard_Real aTol = 1e-6;
193
194   aFinder.SetShape(theShape);
195   aFinder.SetTolerance(aTol);
196   aFinder.SetSurface(theSurface);
197   aFinder.SetShapeType(theShapeType);
198   aFinder.SetState(theState);
199
200   // Sets the minimal number of inner points for the faces that do not have own
201   // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
202   // Default value=3
203   aFinder.SetNbPntsMin(3);
204   // Sets the maximal number of inner points for edges or faces.
205   // It is usefull for the cases when this number is very big (e.g =2000) to improve
206   // the performance. If this value =0, all inner points will be taken into account.
207   // Default value=0
208   aFinder.SetNbPntsMax(0);
209
210   aFinder.Perform();
211
212   // Interprete results
213   Standard_Integer iErr = aFinder.ErrorStatus();
214   // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
215   if (iErr) {
216 //    MESSAGE(" iErr : " << iErr);
217     TCollection_AsciiString aMsg (" iErr : ");
218     aMsg += TCollection_AsciiString(iErr);
219     StdFail_NotDone::Raise(aMsg.ToCString());
220     return aSeqOfIDs;
221   }
222 //  Standard_Integer iWrn = aFinder.WarningStatus();
223   // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
224 //  if (iWrn) {
225 //    MESSAGE(" *** iWrn : " << iWrn);
226 //  }
227
228   const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
229
230   if (listSS.Extent() < 1) {
231     //StdFail_NotDone::Raise("Not a single sub-shape of the requested type found on the given surface");
232     StdFail_NotDone::Raise(NOT_FOUND_ANY); // NPAL18017
233     return aSeqOfIDs;
234   }
235
236   // Fill sequence of object IDs
237   aSeqOfIDs = new TColStd_HSequenceOfInteger;
238
239   TopTools_IndexedMapOfShape anIndices;
240   TopExp::MapShapes(theShape, anIndices);
241
242   TopTools_ListIteratorOfListOfShape itSub (listSS);
243   for (int index = 1; itSub.More(); itSub.Next(), ++index) {
244     int id = anIndices.FindIndex(itSub.Value());
245     aSeqOfIDs->Append(id);
246   }
247
248   return aSeqOfIDs;
249 }
250
251 //=======================================================================
252 //function : GetCommonShapesOnCylinders
253 //purpose  : return the common shapes between 2 cylindrical surfaces
254 //           along OX and OZ
255 //=======================================================================
256 void GEOMImpl_PipeTShapeDriver::GetCommonShapesOnCylinders(const TopoDS_Shape& theShape,
257                                                        TopAbs_ShapeEnum theShapeType,
258                                                        double r1, 
259                                                        double r2,
260                                                        Handle(TopTools_HSequenceOfShape)& commonShapes) const
261 {
262   gp_Pnt aP0 (0, 0, 0);
263   gp_Vec aVX = gp::DX(), aVZ = gp::DZ();
264   gp_Ax3 anAxis1 (aP0, aVX), anAxis2 (aP0, aVZ);
265
266   TopTools_IndexedMapOfShape aMapOfShapes;
267   aMapOfShapes.Clear();
268   TopExp::MapShapes(theShape, aMapOfShapes);
269   
270   commonShapes->Clear();
271
272   int myID;
273   bool found = false;
274
275   // Create a cylinder surface
276   Handle(Geom_Surface) aC1Ext = new Geom_CylindricalSurface(anAxis1, r1);
277   if ( aC1Ext.IsNull() )
278     StdFail_NotDone::Raise("Couldn't build main cylindrical surface");
279   // Find object IDs
280   Handle(TColStd_HSequenceOfInteger) aSeqExt1 = GetShapesOnSurfaceIDs( aC1Ext, theShape, theShapeType, GEOMAlgo_ST_ON );
281   // Create a cylinder surface
282   Handle(Geom_Surface) aC2Ext = new Geom_CylindricalSurface(anAxis2, r2);
283   if ( aC2Ext.IsNull() )
284     StdFail_NotDone::Raise("Couldn't build incident cylindrical surface");
285   // Find object IDs
286   Handle(TColStd_HSequenceOfInteger) aSeqExt2 = GetShapesOnSurfaceIDs( aC2Ext, theShape, theShapeType, GEOMAlgo_ST_ON );
287   // # Recherche (dans le quart de Te) de l'arete d'intersection des 2 cylindres
288   // # Search in theShape for common shape of type theShapeType on the intersection of 2 pipes
289   found = false;
290   for (int i=1; i<=aSeqExt2->Length();i++) {
291     std::cerr << "aSeqExt2->Value(i): " << aSeqExt2->Value(i) << std::endl;
292     for (int j=1; j<=aSeqExt1->Length();j++) {
293       std::cerr << "aSeqExt1->Value(j): " << aSeqExt1->Value(j) << std::endl;
294       if (aSeqExt1->Value(j) == aSeqExt2->Value(i)) {
295         myID = aSeqExt1->Value(j);
296         commonShapes->Append(aMapOfShapes.FindKey(myID));
297         found = true;
298       }
299     }
300   }
301   if (!found)
302     StdFail_NotDone::Raise("Common shapes couldn't be found");
303 }
304
305 //=======================================================================
306 //function : MakePipeTShape
307 //purpose  :
308 //=======================================================================
309 TopoDS_Shape GEOMImpl_PipeTShapeDriver::MakePipeTShape(const double r1, const double w1, const double l1,
310                                                        const double r2, const double w2, const double l2) const
311 {
312   double r1Ext = r1 + w1;
313   double r2Ext = r2 + w2;
314
315   gp_Pnt aP0 (0, 0, 0);
316   gp_Pnt aP1 (-l1, 0, 0);
317   gp_Vec aVX = gp::DX(), aVY = gp::DY(), aVZ = gp::DZ();
318   gp_Ax2 anAxes1 (aP1, aVX);
319   gp_Ax2 anAxes2 (aP0, aVZ);
320
321   // Build the initial pipes
322   BRepPrimAPI_MakeCylinder C1Int (anAxes1, r1, Abs(2 * l1));
323   BRepPrimAPI_MakeCylinder C1Ext (anAxes1, r1Ext, Abs(2 * l1));
324   BRepPrimAPI_MakeCylinder C2Int (anAxes2, r2, Abs(l2));
325   BRepPrimAPI_MakeCylinder C2Ext (anAxes2, r2Ext, Abs(l2));
326   C1Int.Build();
327   C1Ext.Build();
328   C2Int.Build();
329   C2Ext.Build();
330   if (!C1Int.IsDone() || !C1Ext.IsDone() || !C2Int.IsDone() || !C2Ext.IsDone()) {
331     StdFail_NotDone::Raise("Couldn't build cylinders");
332   }
333
334   // Fuse the 2 pipes
335   BRepAlgoAPI_Fuse fuse1 (C1Ext.Shape(), C2Ext.Shape());
336   if (!fuse1.IsDone()) {
337     StdFail_NotDone::Raise("Couldn't fuse cylinders");
338   }
339
340   // Remove small radius main pipe
341   BRepAlgoAPI_Cut cut1 (fuse1.Shape(), C1Int.Shape());
342   if (!cut1.IsDone()) {
343     StdFail_NotDone::Raise("Coudn't cut cylinders");
344   }
345
346   // Remove small radius incident pipe => Te
347   BRepAlgoAPI_Cut Te (cut1.Shape(), C2Int.Shape());
348   if (!Te.IsDone()) {
349     StdFail_NotDone::Raise("Coudn't cut cylinders");
350   }
351
352   return Te.Shape();
353 }
354
355 //=======================================================================
356 //function : MakeQuarterPipeTShape
357 //purpose  :
358 //=======================================================================
359 TopoDS_Shape GEOMImpl_PipeTShapeDriver::MakeQuarterPipeTShape(const double r1, const double w1, const double l1,
360                                                       const double r2, const double w2, const double l2) const
361 {
362   double r1Ext = r1 + w1;
363   TopoDS_Shape Te = MakePipeTShape(r1, w1, l1, r2, w2, l2);
364   if (Te.IsNull())
365     StdFail_NotDone::Raise("Couldn't build Pipe TShape");
366
367   // Get a quarter of shape => Te2
368   BRepPrimAPI_MakeBox box1 (gp_Pnt(0,-2*r1Ext,-2*r1Ext),gp_Pnt(Abs(2 * l1), 2*r1Ext, Abs(2*l2)));
369   BRepPrimAPI_MakeBox box2 (gp_Pnt(0,2*r1Ext,-2*r1Ext),gp_Pnt(-Abs(2 * l1), 0, Abs(2*l2)));
370   box1.Build();
371   box2.Build();
372   if (!box1.IsDone() || !box2.IsDone()) {
373     StdFail_NotDone::Raise("Couldn't build boxes");
374   }
375   BRepAlgoAPI_Cut cut3 (Te, box1.Shape());
376   if (!cut3.IsDone()) {
377     StdFail_NotDone::Raise("Couldn't cut Pipe Tshape with box");
378   }
379   BRepAlgoAPI_Cut Te4 (cut3.Shape(), box2.Shape());
380   if (!Te4.IsDone()) {
381     StdFail_NotDone::Raise("Couldn't cut Pipe Tshape with box");
382   }
383
384   return Te4.Shape();
385 }
386
387 //=======================================================================
388 //function : Execute
389 //purpose  :
390 //=======================================================================
391 Standard_Integer GEOMImpl_PipeTShapeDriver::Execute(TFunction_Logbook& log) const
392 {
393   if (Label().IsNull()) return 0;
394   Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());
395
396   GEOMImpl_IPipeTShape aData (aFunction);
397   Standard_Integer aType = aFunction->GetType();
398
399   TopoDS_Shape aShape, Te4, Te4Part;
400 //   TopoDS_Edge arete_intersect_int;
401 //   Handle(TopTools_HSequenceOfShape) edges_e = new TopTools_HSequenceOfShape;
402   Handle(TColStd_HSequenceOfInteger) edges_e;
403 //   Handle(TopTools_HSequenceOfShape) edges_i = new TopTools_HSequenceOfShape;
404 //   gp_Pnt aP0 (0, 0, 0);
405 //   gp_Vec aVX = gp::DX(), aVY = gp::DY(), aVZ = gp::DZ();
406   bool hexMesh = (bool) aData.GetHexMesh();
407
408   // Useful values
409 //   double aSize = 2*(aData.GetL1() + aData.GetL2());
410   double epsilon = Precision::Approximation();
411   double aR1Ext = aData.GetR1() + aData.GetW1();
412   double aR2Ext = aData.GetR2() + aData.GetW2();
413   
414   if (aData.GetR2() > aData.GetR1() + epsilon) {
415     std::cerr << "aData.GetR1(): " << aData.GetR1() << std::endl;
416     std::cerr << "aData.GetR2(): " << aData.GetR2() << std::endl;
417     StdFail_NotDone::Raise("TShape cannot be computed if R2 > R1");
418   }
419
420   if (aR2Ext > aR1Ext + epsilon) {
421     std::cerr << "aR1Ext: " << aR1Ext << std::endl;
422     std::cerr << "aR2Ext: " << aR2Ext << std::endl;
423     StdFail_NotDone::Raise("TShape cannot be computed if R2+W2 > R1+W1");
424   }
425   
426   // external radius are equal
427   if (fabs(aR2Ext - aR1Ext) < epsilon) {
428     if (aType == TSHAPE_CHAMFER)
429       StdFail_NotDone::Raise("TShape with chamfer cannot be computed if R2+W2 = R1+W1");
430     if (aType == TSHAPE_FILLET)
431       StdFail_NotDone::Raise("TShape with fillet cannot be computed if R2+W2 = R1+W1");
432     // internal radius are different => not possible
433     if (fabs(aData.GetR2() - aData.GetR1()) > epsilon) {
434       std::cerr << "R1Ext: " << aR1Ext << std::endl;
435       std::cerr << "R2Ext: " << aR2Ext << std::endl;
436       std::cerr << "R1: " << aData.GetR1() << std::endl;
437       std::cerr << "R2: " << aData.GetR2() << std::endl;
438       StdFail_NotDone::Raise("TShape cannot be computed if R2+W2 = R1+W1 and R2 != R1");
439     }
440   }
441
442
443   if (aR1Ext >= aData.GetL2() + epsilon) {
444     StdFail_NotDone::Raise("TShape cannot be computed if R1+W1 >= L2");
445   }
446   if (aR2Ext >=  aData.GetL1() + epsilon) {
447     StdFail_NotDone::Raise("TShape cannot be computed if R2+W2 >= L1");
448   }
449
450   if (aType == TSHAPE_CHAMFER) {
451     if (aData.GetH() >= (aData.GetL2() - aR1Ext + epsilon)) {
452       std::cerr << "H: " << aData.GetH() << std::endl;
453       std::cerr << "L2: " << aData.GetL2() << std::endl;
454       std::cerr << "R1Ext: " << aR1Ext << std::endl;
455       std::cerr << "aData.GetL2() - aR1Ext: " << aData.GetL2() - aR1Ext << std::endl;
456       StdFail_NotDone::Raise("TShape cannot be computed: height of chamfer is too high");
457     }
458
459     if (aData.GetW() >= (aData.GetL1() - aR2Ext + epsilon))
460       StdFail_NotDone::Raise("TShape cannot be computed: width of chamfer is too high");
461   }
462
463   if (aType == TSHAPE_FILLET) {
464     if (aData.GetRF() >= (aData.GetL2() - aR1Ext + epsilon) || 
465       aData.GetRF() >= (aData.GetL1() - aR2Ext + epsilon))
466       StdFail_NotDone::Raise("TShape cannot be computed: radius of fillet is too high");
467   }
468
469   if (hexMesh) {
470     // Create a quarter of a basic T-Shape pipe
471     std::cerr << "Create a quarter of a basic T-Shape pipe" << std::endl;
472     Te4 = MakeQuarterPipeTShape(aData.GetR1(), aData.GetW1(), aData.GetL1(),
473       aData.GetR2(), aData.GetW2(), aData.GetL2());
474   }
475   else {
476     // No need to cut pipe t-shape
477     std::cerr << "Create a basic T-Shape pipe" << std::endl;
478     Te4 = MakePipeTShape(aData.GetR1(), aData.GetW1(), aData.GetL1(),
479       aData.GetR2(), aData.GetW2(), aData.GetL2());
480   }
481   aShape = Te4;
482 /*
483   if (aType == TSHAPE_BASIC) {
484       aShape = Te4;
485 //       aShape = MakeQuarterPipeTShape(aData.GetR1(), aData.GetW1(), aData.GetL1(),
486 //       aData.GetR2(), aData.GetW2(), aData.GetL2());
487   }
488   else if (aType == TSHAPE_CHAMFER) {
489     // TShape with chamfer
490 //     BRep_Builder BB;
491 //     TopoDS_Compound CC;
492 //     BB.MakeCompound(CC);
493     // Create chamfer on the edges edges_e
494     BRepFilletAPI_MakeChamfer chamfer (Te4);
495     TopTools_IndexedMapOfShape anEdgesIndices;
496     TopExp::MapShapes(Te4, anEdgesIndices);
497
498     TopoDS_Shape theBox;
499     if (hexMesh) {
500       BRepPrimAPI_MakeBox aBox (gp_Pnt(0,0,0),gp_Pnt(-aR2Ext, -aR2Ext, aR1Ext));
501       aBox.Build();
502       if (!aBox.IsDone()) {
503         StdFail_NotDone::Raise("Couldn't build box");
504       }
505       theBox = aBox.Shape();
506     }
507     else {
508       BRepPrimAPI_MakeBox aBox (gp_Pnt(aR2Ext,aR2Ext,0),gp_Pnt(-aR2Ext, -aR2Ext, aR1Ext));
509       aBox.Build();
510       if (!aBox.IsDone()) {
511         StdFail_NotDone::Raise("Couldn't build box");
512       }
513       theBox = aBox.Shape();
514     }
515     Handle(TColStd_HSequenceOfInteger) edges_e = new TColStd_HSequenceOfInteger;
516     edges_e = GetShapesOnBoxIDs(theBox, Te4, TopAbs_EDGE, GEOMAlgo_ST_IN);
517     if (edges_e.IsNull() || edges_e->Length() == 0) {
518       StdFail_NotDone::Raise("Common edges not found");
519     }
520   
521
522     TopTools_IndexedDataMapOfShapeListOfShape M;
523     GEOMImpl_Block6Explorer::MapShapesAndAncestors(Te4, TopAbs_EDGE, TopAbs_FACE, M);
524 //     std::cerr << "Number of IDs: " << edges_e->Length() << std::endl;
525     int nbEdgesInChamfer = 0;
526     for (int i=1;i<=edges_e->Length();i++) {
527 //       std::cerr << "Get Edge with ID #" << i << std::endl;
528       int theId = edges_e->Value(i);
529 //       std::cerr << "ID #" << i << "= " << theId << std::endl;
530 //       std::cerr << "Search for edge in shape" << std::endl;
531       TopoDS_Edge theEdge = TopoDS::Edge(anEdgesIndices.FindKey(theId));
532 //       std::cerr << "Found" << std::endl;
533 //       std::cerr << "Keep only edges with a vertex on (x, x, re1)" << std::endl;
534       TopExp_Explorer ExVertices;
535       for (ExVertices.Init(theEdge,TopAbs_VERTEX); ExVertices.More(); ExVertices.Next()) {
536         gp_Pnt aPt = BRep_Tool::Pnt(TopoDS::Vertex(ExVertices.Current()));
537         if (aPt.Z() - aR1Ext <= epsilon) {
538 //           std::cerr << "aPt.Z() = aR1Ext => keep this edge" << std::endl;
539           nbEdgesInChamfer ++;
540           const TopTools_ListOfShape& aFL = M.FindFromKey(theEdge);
541           TopoDS_Face F = TopoDS::Face( aFL.First() );
542           if (hexMesh)
543             chamfer.Add(aData.GetH(), aData.GetW(), theEdge, F);
544           else
545             chamfer.Add(aData.GetW(), aData.GetH(), theEdge, F);
546           break;
547         }
548       }
549 //       std::cerr << "Test if hexMesh: ";
550       if (hexMesh && nbEdgesInChamfer == 1) {
551 //         std::cerr << "Yes => stop after 1 edge" << std::endl;
552         break;
553       }
554 //       std::cerr << "No => continue for other edges" << std::endl;
555   //  BB.Add(CC, edges_e->Value(i));
556   //  const TopTools_ListOfShape& aFL = M.FindFromKey(TopoDS::Edge(edges_e->Value(i)));
557   //  chamfer.Add(aData.GetW(), aData.GetH(), TopoDS::Edge(edges_e->Value(i)), F);
558     }
559 //     std::cerr << "Build chamfer with " << nbEdgesInChamfer << " edges" << std::endl;
560 //     }
561     chamfer.Build();
562     if (!chamfer.IsDone()) {
563       StdFail_NotDone::Raise("Chamfer can not be computed on the given shape with the given parameters");
564     }
565     
566 //     BB.Add(CC, chamfer.Shape());
567     
568     
569 //     aShape = CC;
570     aShape = chamfer.Shape();
571   }
572   else if (aType == TSHAPE_FILLET) {
573     // TShape with fillet
574     // Create fillet on the edge arete_intersect_ext
575     BRepFilletAPI_MakeFillet fill (Te4);
576     
577     TopTools_IndexedMapOfShape anIndices;
578     TopExp::MapShapes(Te4, anIndices);
579     
580     TopoDS_Shape theBox;
581     if (hexMesh) {
582       BRepPrimAPI_MakeBox aBox (gp_Pnt(0,0,0),gp_Pnt(-aR2Ext, -aR2Ext, aR1Ext));
583       aBox.Build();
584       if (!aBox.IsDone()) {
585         StdFail_NotDone::Raise("Couldn't build box");
586       }
587       theBox = aBox.Shape();
588     }
589     else {
590       BRepPrimAPI_MakeBox aBox (gp_Pnt(aR2Ext,aR2Ext,0),gp_Pnt(-aR2Ext, -aR2Ext, aR1Ext));
591       aBox.Build();
592       if (!aBox.IsDone()) {
593         StdFail_NotDone::Raise("Couldn't build box");
594       }
595       theBox = aBox.Shape();
596     }
597     Handle(TColStd_HSequenceOfInteger) edges_e = new TColStd_HSequenceOfInteger;
598     edges_e = GetShapesOnBoxIDs(theBox, Te4, TopAbs_EDGE, GEOMAlgo_ST_IN);
599     if (edges_e.IsNull() || edges_e->Length() == 0) {
600       StdFail_NotDone::Raise("Common edges not found");
601     }
602     
603 //     fill.Add(TopoDS::Edge(edges_e->Value(1)));
604 //     if (!hexMesh) {
605     for (int i=1;i<=edges_e->Length();i++) {
606       if (hexMesh && (i > 1))
607         break;
608       TopoDS_Edge theEdge = TopoDS::Edge(anIndices.FindKey(edges_e->Value(i)));
609       fill.Add(theEdge);
610 //             fill.Add(TopoDS::Edge(edges_e->Value(i)));
611     }
612 //     }
613     fill.SetRadius(aData.GetRF(), 1, 1);
614     fill.Build();
615     if (!fill.IsDone()) {
616       StdFail_NotDone::Raise("Fillet can't be computed on the given shape with the given radius");
617     }
618
619     aShape = fill.Shape();
620   }
621   else {
622     // other construction modes here
623   }
624 */
625   if (aShape.IsNull()) return 0;
626
627   aFunction->SetValue(aShape);
628
629   log.SetTouched(Label());
630
631   return 1;
632 }
633
634 //=======================================================================
635 //function :  GEOMImpl_PipeTShapeDriver_Type_
636 //purpose  :
637 //=======================================================================
638 Standard_EXPORT Handle_Standard_Type& GEOMImpl_PipeTShapeDriver_Type_()
639 {
640   static Handle_Standard_Type aType1 = STANDARD_TYPE(TFunction_Driver);
641   if ( aType1.IsNull()) aType1 = STANDARD_TYPE(TFunction_Driver);
642   static Handle_Standard_Type aType2 = STANDARD_TYPE(MMgt_TShared);
643   if ( aType2.IsNull()) aType2 = STANDARD_TYPE(MMgt_TShared);
644   static Handle_Standard_Type aType3 = STANDARD_TYPE(Standard_Transient);
645   if ( aType3.IsNull()) aType3 = STANDARD_TYPE(Standard_Transient);
646
647   static Handle_Standard_Transient _Ancestors[]= {aType1,aType2,aType3,NULL};
648   static Handle_Standard_Type _aType = new Standard_Type("GEOMImpl_PipeTShapeDriver",
649                                                          sizeof(GEOMImpl_PipeTShapeDriver),
650                                                          1,
651                                                          (Standard_Address)_Ancestors,
652                                                          (Standard_Address)NULL);
653   return _aType;
654 }
655
656 //=======================================================================
657 //function : DownCast
658 //purpose  :
659 //=======================================================================
660 const Handle(GEOMImpl_PipeTShapeDriver) Handle(GEOMImpl_PipeTShapeDriver)::DownCast(const Handle(Standard_Transient)& AnObject)
661 {
662   Handle(GEOMImpl_PipeTShapeDriver) _anOtherObject;
663
664   if (!AnObject.IsNull()) {
665      if (AnObject->IsKind(STANDARD_TYPE(GEOMImpl_PipeTShapeDriver))) {
666        _anOtherObject = Handle(GEOMImpl_PipeTShapeDriver)((Handle(GEOMImpl_PipeTShapeDriver)&)AnObject);
667      }
668   }
669
670   return _anOtherObject;
671 }