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