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